FBO, color buffer, depth buffer를 사용하는 프로젝트이다. FBO 등에 관한 설명은 생략한다.
회전하는 teapot을 회전하는 정육면체의 각 면에 color buffer와 depth buffer를 사용해서 그린다.
#include#include #include "glext.h" const int window_height = 380, window_width = 630, tex_height = 512, tex_width = 512; GLuint fboId = 1, texId = 0, drbId = 0; GLfloat xRotated, yRotated, zRotated, rot = 0.0; double cubePos = -6.0; static GLfloat cubeVertices[26][3] = { // Front face {-1,-1,1}, {1,-1,1}, {-1,1,1}, {1,1,1}, // Right face {1,1,1}, {1,-1,1}, {1,1,-1}, {1,-1,-1}, // Back face {1,-1,-1}, {-1,-1,-1}, {1, 1, -1}, {-1, 1, -1}, // Left face {-1,1,-1}, {-1,-1,-1}, {-1,1,1}, {-1,-1,1}, // Bottom face {-1,-1,1}, {-1,-1,-1}, {1,-1,1},{1,-1,-1}, // move to top {1,-1,-1}, {-1,1,1}, // Top Face {-1,1,1}, {1,1,1}, {-1,1,-1}, {1,1,-1} }; void drawf1f3f5() { glBegin(GL_TRIANGLES); // front face glNormal3f(0, 0, 1); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[3]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[2]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[0]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[0]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[1]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[3]); // right face glNormal3f(1, 0, 0); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[4]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[5]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[7]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[7]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[6]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[4]); // top face glNormal3f(0, 1, 0); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[23]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[25]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[24]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[24]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[22]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[23]); glEnd(); } void drawf2f4f6() { glBegin(GL_TRIANGLES); // left face glNormal3f(-1, 0, 0); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[14]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[12]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[13]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[13]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[15]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[14]); // bottom face glNormal3f(0, -1, 0); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[17]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[19]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[18]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[18]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[16]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[17]); // back face glNormal3f(0, 0, -1); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[8]); glTexCoord2f(1, 0); glVertex3fv(cubeVertices[9]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[11]); glTexCoord2f(1, 1); glVertex3fv(cubeVertices[11]); glTexCoord2f(0, 1); glVertex3fv(cubeVertices[10]); glTexCoord2f(0, 0); glVertex3fv(cubeVertices[8]); glEnd(); } void draw() { drawf1f3f5(); drawf2f4f6(); } void display(void) { float angle = rot; // go to texture viewport (render to texture) glViewport(0, 0, tex_width, tex_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, tex_width / (double)tex_height, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, cubePos); //bind FBO and clear buffer glBindFramebuffer(GL_FRAMEBUFFER, fboId); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { glPushMatrix(); glRotatef(angle*0.5f, 1, 0, 0); glRotatef(angle, 0, 1, 0); glRotatef(angle*0.7f, 0, 0, 1); glColor3f(1, 0, 0); glutSolidTeapot(1); glPopMatrix(); } // unbind glBindFramebuffer(GL_FRAMEBUFFER, 0); //clear default buffer glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //go to normal viewport glViewport(0, 0, window_width, window_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (double)(window_width) / (double)window_height, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //draw left side cube, used only color buffer (texId) { glPushMatrix(); glTranslatef(-2.0, 0, cubePos); glRotatef(xRotated, 1, 0, 0); glRotatef(yRotated, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, texId); glColor4f(1, 1, 1, 1); draw(); glBindTexture(GL_TEXTURE_2D, 0); glPopMatrix(); } //draw part of center cube, used color buffer (texId) { glPushMatrix(); glTranslatef(0, 1.5, cubePos); glRotatef(xRotated, 1, 0, 0); glRotatef(yRotated, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, texId); glColor4f(1, 1, 1, 1); drawf1f3f5(); glBindTexture(GL_TEXTURE_2D, 0); glPopMatrix(); } //go to normal viewport glEnable(GL_TEXTURE_2D); glViewport(0, 0, window_width, window_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (double)(window_width) / (double)window_height, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //draw right side cube, used only depth buffer (drbId) { glPushMatrix(); glTranslatef(2.0, 0, cubePos); glRotatef(xRotated, 1, 0, 0); glRotatef(yRotated, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, drbId); glColor3f(1, 0, 0); draw(); glBindTexture(GL_TEXTURE_2D, 0); glPopMatrix(); } //draw rest of center cube, used depth buffer { glPushMatrix(); glTranslatef(0, 1.5, cubePos); glRotatef(xRotated, 1, 0, 0); glRotatef(yRotated, 0, 1, 0); glBindTexture(GL_TEXTURE_2D, drbId); glColor4f(1, 1, 1, 1); drawf2f4f6(); glBindTexture(GL_TEXTURE_2D, 0); glPopMatrix(); } glutSwapBuffers(); } void idle() { yRotated += 0.5; xRotated += 1.0; rot += 1.0; glutPostRedisplay(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowPosition(100, 100); glutInitWindowSize(window_width, window_height); glutCreateWindow("OpenGL Sample 02"); glutDisplayFunc(display); glutIdleFunc(idle); glShadeModel(GL_SMOOTH); // shading mathod: GL_SMOOTH or GL_FLAT glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glClearColor(0, 0, 0, 0); // background color glClearStencil(0); // clear stencil buffer glClearDepth(1.0f); // 0 is near, 1 is far glDepthFunc(GL_LEQUAL); //lights GLfloat lightKa[] = { .2f, .2f, .2f, 1.0f }; //ambient light GLfloat lightKd[] = { .7f, .7f, .7f, 1.0f }; //diffuse light GLfloat lightKs[] = { 1, 1, 1, 1 }; //specular light glLightfv(GL_LIGHT0, GL_AMBIENT, lightKa); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightKd); glLightfv(GL_LIGHT0, GL_SPECULAR, lightKs); float lightPos[4] = { 0, 0, 20, 1 }; glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glEnable(GL_LIGHT0); //framebuffer object glGenFramebuffers(1, &fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId); //color buffer glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); //depth buffer glBindFramebuffer(GL_FRAMEBUFFER, fboId); glGenTextures(1, &drbId); glBindTexture(GL_TEXTURE_2D, drbId); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); int level = 0; glTexImage2D(GL_TEXTURE_2D, level, GL_DEPTH_COMPONENT, tex_width, tex_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, drbId, level); //unbind glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glutMainLoop(); return 0; }
'openGL - 저장용' 카테고리의 다른 글
derive projections(perspective/orthogonal) matrix (0) | 2017.09.05 |
---|---|
teapot 회전하는 애니메이션 구현 (0) | 2017.04.25 |