OpenGL覚え書き4 隠面消去
隠面消去を行うには、バックフェースカリング、奥行きソート法、スキャンライン法、zバッファ法などいくつかの手法が知られています。
zバッファ法は、ウインドウの各画素について投影面から物体の距離(デプス)の値が保存されたバッファを作成して、距離が大きい画素から描画する方法です。OpenGLでzバッファ法を利用して立体を表示させるためには次の3つのコマンドを実行します。
デプスバッファによる表示を指示するためのコマンド(フラグGLUT_DEPTHを引数に追加する)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH)
デプスバッファを利用可能状態にするコマンド
glEnable(GL_DEPTH_TEST)
デプスを最大値に設定するコマンド(フラグGL_DEPTH_BUFFER_BITを引数に追加する)
描画前に全ての画素についてz座標を最大に設定しておきます。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
zバッファ法による隠面処理で四面体を描画した例です。原点に位置する物体をマウスで動かすことができます。
from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * from math import* import sys class AppBase: def __init__(self): self.__mouseX = 0 self.__mouseY = 0 self.__xrot = 0 self.__yrot = 0 glutDisplayFunc(self._draw) glutMouseFunc(self._mousePressed) glutMotionFunc(self._mouseDragged) glutReshapeFunc(self._resize) glClearColor(0.0,0.0,0.0,0.0) glEnable(GL_DEPTH_TEST) def _draw(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) #modeling transform glLoadIdentity() glRotatef(self.__xrot,1.0,0.0,0.0) glRotatef(self.__yrot,0.0,1.0,0.0) #draw x,y,z axis glBegin(GL_LINES); glColor3f(1.0,1.0,1.0) glVertex3f(-1,0,0) glVertex3f(1,0,0) glVertex3f(0,-1,0) glVertex3f(0,1,0) glVertex3f(0,0,-1) glVertex3f(0,0,1) glEnd() #draw solid model r = 0.4 glBegin(GL_TRIANGLES) glColor3f(0.9,0.9,0.7) glVertex3f(0,r,0) glVertex3f(r,0,0) glVertex3f(0,0,r) glColor3f(0.7,0.7,1.0) glVertex3f(0,0,0) glVertex3f(r,0,0) glVertex3f(0,r,0) glColor3f(0.7,1.0,0.7) glVertex3f(0,0,0) glVertex3f(0,r,0) glVertex3f(0,0,r) glColor3f(1.0,0.7,0.7) glVertex3f(0,0,0) glVertex3f(r,0,0) glVertex3f(0,0,r) glEnd() glutSwapBuffers() def _mousePressed(self,button,state,x,y): if(state == GLUT_DOWN): glutIdleFunc(self._draw) else: glutIdleFunc(0) self.__mouseX = x self.__mouseY = y def _mouseDragged(self,x,y): self.__xrot += y - self.__mouseY self.__yrot += x - self.__mouseX self.__mouseX = x self.__mouseY = y def _resize(self,width, height): glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(15.0, float(width) / float(height), 3.0, 15.0) gluLookAt(0.0,0.0,5.0,0.0,0.0,-1.0,0.0,1.0,0.0) glMatrixMode(GL_MODELVIEW) def main(): glutInit(sys.argv) glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH) glutInitWindowSize(600, 600) glutCreateWindow("PyOpenGL") app = AppBase() glutMainLoop() main()