OpenGL에서는 Vertex의 시작과 끝을 명시하고 점을 찍으면 객체가 만들어 졌던것 같은데 ES는 그렇지 않습니다.
적어도 안드로이드에서는, ByteBuffer를 이용하여 vertex의 내용을 보여줘야 합니다.
private float vertices[] = {
-1.0f, 1.0f, 0.0f, // 0, Top Left
-1.0f, -1.0f, 0.0f, // 1, Bottom Left
1.0f, -1.0f, 0.0f, // 2, Bottom Right
1.0f, 1.0f, 0.0f, // 3, Top Right
};
// a float is 4 bytes, therefore we multiply the number if vertices with 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
source code와 같이 vertex를 배열로 선언한 후 이를 ByteBuffer -> (해당타입)Buffer 로 옮겨서 사용하는 방식입니다.
이는 vertex를 사용할때 매번 거치는 일이므로, 객체등의 생성자에서 할만한 일입니다.
그리고 OpenGL에서 begin, end로 명시하고 vertex를 생성하는 방법과 하나 더 다른점은 매번 index도 설정해 줘야 합니다.
index의 생성방법도 마찬가지로 같습니다.
private short[] indices = { 0, 1, 2, 0, 2, 3 };
// short is 2 bytes, therefore we multiply the number if vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
개인적으로, OpenGL만 보고 OpenGL ES를 대충 보았을 때는 begin, end 없이 제작하는것이 혼란스러웠습니다.
ByteOrder 같은것을 왜하는지도 모르고 직관적이지 못해서 더 어렵다고 생각했는데 막상 하고나서 그냥 매번 해줘야 하는 일이구나, 라고 생각하니
vertex를 생성하는것에 대해서는 크게 더 어렵거나 하진 않은것 같습니다.
마지막으로 이런식으로 생성된 vertexBuffer, indexBuffer가 있다고 했을시에 Renderer의 onDrawFrame 함수 내부에서는 이런 일을 하며 됩니다.
gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
// Enable face culling.
gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
// What faces to remove with the face culling.
gl.glCullFace(GL10.GL_BACK); // OpenGL docs
// Enabled the vertices buffer for writing and to be used during
// rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// OpenGL docs.
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,// OpenGL docs
GL10.GL_UNSIGNED_SHORT, indexBuffer);
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
// Disable face culling.
gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
gl은 OnDrawFrame함수에서 파라미터로 받아온 것 GL10의 이름입니다.
시계반대방향을 정면으로 설정하고 은면도 설정하고 하는 부분은 OpenGL 에서 vertex를 사용할때와 동일합니다.
다른것은 실제 렌더링 하는 부분인데 glEnableClientState에서 어떤 Array가 들어오는지 설정하고 glVertexPointer를 설정합니다.
함수설명을 보면 나오지만 1번째는 한번에 가져오는 개수, 2번째는 타입, 3번째는 offset, 4번째는 buffer를 넘겨줍니다.
그리고 glDrawElements를 이용해서 실제로 그리게 되는데 어떻게 렌더링할 것인지와 index에 관한 설정을 넘겨줍니다.
이 후 glDisableClientState를 이용해서 vertex의 입력을 끝내게 됩니다.
해당 소스코드와 더 자세한 설명은 OpenGL ES Tutorial for Android – Part II – Building a polygon 에서 보실 수 있습니다.
반응형
'Programming' 카테고리의 다른 글
OpenGL에서 GLSL을 GPGPU 목적으로 사용하기 (0) | 2012.04.12 |
---|---|
Google Reader API를 이용하기 위해 SID와 Token 얻어오기 (0) | 2012.03.11 |
Android OpenGL ES 사용에 앞서 알아두면 좋은것 (0) | 2012.01.05 |
[Android] Soundpool 사용하기 + 사용하면서 안 것. (0) | 2011.02.14 |
[Android]Android MapView 간단한 정리. (0) | 2010.11.04 |