Programming

Android OpenGL ES 1.1에서 사각형 그리기

라우드니스 2012. 1. 5. 21:11

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 에서 보실 수 있습니다.

반응형