삼각형에서는 좌표들(coords) 배열을 9개(3차원 점 * 3개의 점)만 정의했으니, 더 많은 좌표를 추가하면 다각형이 될 것이다.
하지만 그리는 것은 다르다.
OpenGL에서는 그리는 모드에 따라 각 점을 해석하는 방식이 다르다.
이전에 삼각형을 그릴 때 사용한 모드는 GL_TRIANGLES
이다.
3개씩 묶어서 만들어지는 삼각형 면을 채우는 방식이다.
이 모드로 사각형을 그린다면, 점의 순서를 아래와 같이 바꿔야한다.
(x1, y1, z1)를 1번 정점이라고 하면, 사각형을 그리기 위해서는 (1번-2번-3번)의 삼각형 하나와, (1번, 3번, 4번)의 삼각형, 총 2개의 삼각형을 그려야한다.
여기에는 방법이 다시 2가지가 있는데, 하나는 coords[]
배열에 점을 3개씩 끊어서 순서대로 직접 모두 저장하거나, 점의 순서를 저장해두고 나중에 렌더링할 때 그리는 순서를 결정하는 방법이 있다.
순서대로 직접 모두 저장하는 방식은 아래와 같다.
static float squareCoords[] = {
x1, y1, z1,
x2, y2, z2,
x3, y3, z3, // 여기서 삼각형 하나 완성
x1, y1, z1,
x3, y3, z3,
x4, y4, z4 // 두번째 삼각형 완성
};
점의 순서를 지정하는 코드는 아래와 같다.
public class Square {
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer; // drawListBuffer에 점의 순서를 저장한다.
static float squareCoords[]; // 생략
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
public Square() {
// ...
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
drawOrder.length * 2); // short은 2바이트라서 2를 곱한다.
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
}
// Renderer에서 호출하면 그린다.
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(mProgram);
// ...
// glDrawArrays 대신 아래와 같이 바꾼다.
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// ...
}
}
Renderer에서 호출되는 부분은 아래와 같다.
@Override
public void onDrawFrame(GL10 unused) {
// ...
// 카메라 에 맞춰 적절히 projection된 매트릭스가 넘어간다.
mShape.draw(mMVPMatrix);
}
Links