ćwiczenie 4z - Robert Arsoba

Transkrypt

ćwiczenie 4z - Robert Arsoba
Zagadnienia uzupełniające programowanie
w systemie Android
dr inż. Robert Arsoba
Ćwiczenie 4
Rysowanie obiektów trójwymiarowych
Cel ćwiczenia
Celem ćwiczenia jest praktyczne zapoznanie się z definiowaniem i rysowaniem obiektów
trójwymiarowych przy użyciu biblioteki OpenGL ES. Omawiany jest przykład aplikacji,
w której rysowany jest sześcian w reprezentacji krawędziowej. Zakres ćwiczenia obejmuje
definiowanie reprezentacji punktowej, krawędziowej i wypełnianej wybranych brył oraz ich
odrysowywanie na ekranie.
Przygotowanie się do ćwiczenia



Zapoznać się z wykładem „Grafika trójwymiarowa”.
 Zwrócić szczególną uwagę na opis reprezentacji punktowej, krawędziowej
i wypełnianej obiektów trójwymiarowych.
 Przeanalizować opis tworzenia bufora wierzchołków i bufora indeksów.
 Zapoznać się z podstawowymi metodami API dotyczącymi rysowania.
Na podstawie dokumentacji Android SDK:
http://developer.android.com/reference/packages.html zapoznać się
w podstawowym zakresie z klasami GLSurfaceView i GL10ES.
Zapoznać się z przykładową aplikacją zamieszczoną w opisie ćwiczenia.
 Przeanalizować kod źródłowy aplikacji.
 Zwrócić uwagę na budowę klasy NaszRenderer.
 Przeanalizować definicję reprezentacji krawędziowej sześcianu.
 Zwrócić szczególną uwagę na metody dotyczące operacji rysowania
i ustawień parametrów rysowania (metody o nazwach z przedrostkiem gl).
 Zwrócić szczególną uwagę na metodę onDrawFrame i zaprogramowany
w niej fragment dotyczący rysowania sześcianu.
Zadania do wykonania
1. Uruchomić przykładową aplikację zamieszczoną w opisie ćwiczenia i przetestować
jej działanie.
2. Zmodyfikować fragment kodu źródłowego w metodzie onDrawFrame
odpowiedzialny za rysowanie sześcianu. Wzorując się na ćwiczeniu 3, uzupełnić tę
metodę o polecenia powodujące animację sześcianu (obrót wokół wybranej osi).
3. Wzorując się na reprezentacji krawędziowej sześcianu zaprogramowanej
w metodzie definiuj_obiekt, zdefiniować w podobny sposób reprezentację
krawędziową dla ostrosłupa. Odrysować tak zdefiniowany ostrosłup na ekranie.
4. Zdefiniować reprezentację wypełnianą wybranej bryły (np. sześcian lub ostrosłup)
i odrysować ją na ekranie w taki sposób, aby każda ścianka miała inny kolor.
Materiały przygotowano w ramach projektu
„Inżynier pilnie poszukiwany”
Strona 1
Zagadnienia uzupełniające programowanie
w systemie Android
dr inż. Robert Arsoba
Przykładowa aplikacja – plik głównej aktywności OpenGLActivity.java
Należy zwrócić uwagę na włączone ustawienie GLSurfaceView.RENDERMODE_WHEN_DIRTY.
Powoduje ono, że w przypadku grafiki statycznej, zawartość powierzchni rysowania jest
odrysowywana tylko w razie konieczności (po zmianie zawartości powierzchni).
package org.przyklad;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class OpenGLActivity extends Activity
{
private GLSurfaceView sv; // powierzchnia rysowania
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sv = new GLSurfaceView(this);
sv.setRenderer(new NaszRenderer()); // ustalenie obiektu kontrolującego rysowanie (tzw. renderer)
// odrysowanie tylko w razie potrzeby (należy włączyć dla grafiki statycznej):
sv.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
setContentView(sv); // zawartość widoku to powierzchnia rysowania
}
@Override
public void onPause()
{
super.onPause();
sv.onPause();
}
@Override
public void onResume()
{
super.onResume();
sv.onResume();
}
}
Przykładowa aplikacja – plik NaszRenderer.java
package org.przyklad;
import
import
import
import
import
import
import
import
java.nio.ByteBuffer;
java.nio.ByteOrder;
java.nio.FloatBuffer;
java.nio.ShortBuffer;
javax.microedition.khronos.egl.EGLConfig;
javax.microedition.khronos.opengles.GL10;
android.opengl.GLSurfaceView;
android.opengl.GLU;
public class NaszRenderer implements GLSurfaceView.Renderer
{
private int VERTICES;
// liczba wierzchołków
private int INDEXES;
// liczba indeksów
private FloatBuffer vb; // bufor wierzchołków (vertex buffer)
private ShortBuffer ib; // bufor indeksów (index buffer)
Materiały przygotowano w ramach projektu
„Inżynier pilnie poszukiwany”
Strona 2
Zagadnienia uzupełniające programowanie
w systemie Android
dr inż. Robert Arsoba
public void definiuj_obiekt() // definicja sześcianu
{
float punkty[] = // kolejność przeciwna do wskazówek zegara
{
// układ współrzędnych prawoskrętny
// przednia ścianka (do obserwatora)
-0.5f, 0.5f, 0.5f, // 0 LG
0 LG
2 PG
0.5f, -0.5f, 0.5f, // 1 PD
0.5f, 0.5f, 0.5f, // 2 PG
3 LD
1 PD
-0.5f, -0.5f, 0.5f, // 3 LD
// tylna ścianka (wgłąb ekranu)
-0.5f, 0.5f, -0.5f, // 4 LG
4 LG
0.5f, -0.5f, -0.5f, // 5 PD
0.5f, 0.5f, -0.5f, // 6 PG
7 LD
-0.5f, -0.5f, -0.5f // 7 LD
6 PG
5 PD
};
short indeksy[] = { 0,
4,
0,
2,
};
VERTICES = 8;
INDEXES = 24;
3,
7,
4,
6,
3,
7,
3,
1,
1,
5,
7,
5
1,
5,
//
//
2, 2, 0, // przednia ścianka
6, 6, 4, // tylna ścianka
lewa ścianka
prawa ścianka
// liczba wierzchołków
// liczba indeksów
ByteBuffer vbuf = ByteBuffer.allocateDirect(VERTICES*3*4); // 3 współrzędne * 4 bajty (float)
vbuf.order(ByteOrder.nativeOrder());
vb = vbuf.asFloatBuffer(); // tworzenie bufora wierzchołków
vb.put(punkty);
// na podstawie tablicy wierzchołków
vb.position(0);
ByteBuffer ibuf = ByteBuffer.allocateDirect(INDEXES*2); // * 2 bajty (short)
ibuf.order(ByteOrder.nativeOrder());
ib = ibuf.asShortBuffer(); // tworzenie bufora indeksów
ib.put(indeksy);
// na podstawie tablicy indeksów
ib.position(0);
}
public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig)
{
// metoda wywoływana tylko raz do utworzenia powierzchni rysowania
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// kolor tła szary (model koloru RGBA)
definiuj_obiekt();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // włączone użycie bufora indeksów
}
public void onSurfaceChanged(GL10 gl, int szer, int wys)
{
// metoda wywoływana automat. po zmianie wymiarów pow. rysowania (np. zmiana orientacji urządzenia)
gl.glViewport(0, 0, szer, wys);
// parametry ekranu (płaszczyzny rzutowania)
float aspekt = (float) szer/wys;
// proporcje ekranu
gl.glMatrixMode(GL10.GL_PROJECTION); // tryb macierzy rzutowania
gl.glLoadIdentity();
// ustawienie macierzy jednostkowej (stan domyślny)
gl.glFrustumf(-aspekt, aspekt, -1, 1, 3, 7); // macierz rzutowania
}
public void onDrawFrame(GL10 gl)
{
// metoda wywoływana automat. w przypadku konieczności odrysowania zawartości powierzchni rysowania
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // wyczyszczenie pow. rysowania
gl.glMatrixMode(GL10.GL_MODELVIEW); // tryb macierzy MODELVIEW
gl.glLoadIdentity(); // ustawienie macierzy jednostkowej (stan domyślny)
GLU.gluLookAt(gl, 0, 0, 5, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); // parametry kamery
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f); // kolor rysowania zielony (model koloru RGBA)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vb); // bufor wierzchołków
gl.glDrawElements(GL10.GL_LINES, INDEXES, GL10.GL_UNSIGNED_SHORT, ib); // linie z bufora indeksów
}
}
Materiały przygotowano w ramach projektu
„Inżynier pilnie poszukiwany”
Strona 3
Zagadnienia uzupełniające programowanie
w systemie Android
dr inż. Robert Arsoba
Wygląd interfejsu użytkownika aplikacji
Rysunek przedstawia wynik działania aplikacji – sześcian odrysowany w reprezentacji
krawędziowej.
Przykładowa aplikacja – plik strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, OpenGLActivity!</string>
<string name="app_name">Rysowanie 3D</string>
</resources>
Materiały przygotowano w ramach projektu
„Inżynier pilnie poszukiwany”
Strona 4

Podobne dokumenty