[iPhone] OpenGL 프로그래밍..2
// Updates the OpenGL view
- (void)drawView
{
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat matrix[4][4], length;
//Make sure we have a big enough acceleration vector
length = sqrtf(accel[0] * accel[0] + accel[1] * accel[1] + accel[2] * accel[2]);
//Setup model view matrix
glLoadIdentity();
glTranslatef(0.0, -0.1, -1.0);
glScalef(kTeapotScale, kTeapotScale, kTeapotScale);
if(length >= 0.1)
{
//Clear matrix to be used to rotate from the current referential to one based on the gravity vector
bzero(matrix, sizeof(matrix));
matrix[3][3] = 1.0;
//Setup first matrix column as gravity vector
matrix[0][0] = accel[0] / length;
matrix[0][1] = accel[1] / length;
matrix[0][2] = accel[2] / length;
//Setup second matrix column as an arbitrary vector in the plane perpendicular to the gravity vector {Gx, Gy, Gz} defined by by the equation "Gx * x + Gy * y + Gz * z = 0" in which we arbitrarily set x=0 and y=1
matrix[1][0] = 0.0;
matrix[1][1] = 1.0;
matrix[1][2] = -accel[1] / accel[2];
length = sqrtf(matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1] + matrix[1][2] * matrix[1][2]);
matrix[1][0] /= length;
matrix[1][1] /= length;
matrix[1][2] /= length;
//Setup third matrix column as the cross product of the first two
matrix[2][0] = matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1];
matrix[2][1] = matrix[1][0] * matrix[0][2] - matrix[1][2] * matrix[0][0];
matrix[2][2] = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
//Finally load matrix
glMultMatrixf((GLfloat*)matrix);
// Rotate a bit more so that its where we want it.
glRotatef(90.0, 0.0, 0.0, 1.0);
}
// If we're in the simulator we'd like to do something more interesting than just sit there
// But if we're on a device, we want to just let the accelerometer do the work for us without a fallback.
#if TARGET_IPHONE_SIMULATOR
else
{
static GLfloat spinX = 0.0, spinY = 0.0;
glRotatef(spinX, 0.0, 0.0, 1.0);
glRotatef(spinY, 0.0, 1.0, 0.0);
glRotatef(90.0, 1.0, 0.0, 0.0);
spinX += 1.0;
spinY += 0.25;
}
#endif
// Draw teapot. The new_teapot_indicies array is an RLE (run-length encoded) version of the teapot_indices array in teapot.h
for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1)
{
glDrawElements(GL_TRIANGLE_STRIP, new_teapot_indicies[i], GL_UNSIGNED_SHORT, &new_teapot_indicies[i+1]);
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
주석에서 설명이 되어있으므로 주요한 설명은 안해도 될 것 같습니다.
여기서 3차원 도형을 그리기 위한 주요한 내용만 다시 보겠습니다.
단순히 도형만 그린다면 아래와 같이 고쳐볼 수 있습니다.
- (void)drawView
{
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Setup model view matrix
glLoadIdentity();
glTranslatef(0.0, -0.1, -1.0);
glScalef(kTeapotScale, kTeapotScale, kTeapotScale);
// Draw teapot. The new_teapot_indicies array is an RLE (run-length encoded) version of the teapot_indices array in teapot.h
for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1)
{
glDrawElements(GL_TRIANGLE_STRIP, new_teapot_indicies[i], GL_UNSIGNED_SHORT, &new_teapot_indicies[i+1]);
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
위에서 glDrawElements 함수가 도형정보를 그리는 부분입니다.
주석에서처럼 teapot.h 파일에 num_teapot_indices, new_teapot_indices[i] 가 정의되어 있지요.
이 부분이 어떻게 정의되는 지는 다음 포스트에서 봅시다.