OSX 10.8.3,Python,PyOpenGL。
我正在尝试使用VBO在PyOpenGL中组合一个基本的地形绘制功能。有几个问题我不知道如何解决,主要是因为我不完全理解VBO的工作方式。这是一个基本的测试沙箱,当我将项目更改为VBO时遇到了太多困难,所以它在某些地方很邋((参见:frame counter)。
旋转时的当前状态:http://i.imgur.com/4Db4qYJ.png
一直使用http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=8作为我最成功的指南。
我真的很感激这方面的一些指导 - 我在网上找到的单一资源都没有解释这一切,这不是一个复杂的主题。
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.arrays import vbo
from math import sin, cos, tan, radians, sqrt
from numpy import *
from random import random
hWindow = 0
frameno = 0
sr2 = sqrt(0.75)
def InitGL( nWidth, nHeight ):
glClearColor( 0.0, 0.0, 0.0, 0.0 )
glClearDepth( 1.0 )
glDepthFunc( GL_LESS )
glEnable( GL_DEPTH_TEST )
glShadeModel( GL_SMOOTH )
print str(glGetString( GL_VERSION ))
global terrain_vbo, index_vbo, color_vbo
# these two will produce a working (huge) triangle
#terrain_array = array([[ 0,0,0 ], [ 9,0,0 ], [ 0,9,0 ], [ 0,0,9 ]], dtype=float32)
#index_array = array([ 0,1, 0,2, 0,3, 2,3, 2,1],dtype=ubyte)
terrain_array = array([ [[0,0,0], [0,0,1], [0,0,2]],
[[1,0.5,0], [1,0.5,1], [1,0.5,2]],
[[2,2,0], [2,2,1], [2,2,2]] ], dtype=float32)
index_array = array([ 0, 3, 1, 4, 2, 5,
8, 4, 7, 3, 6 ], dtype=ubyte )
color_array = zeros( (9, 3) )
for i in range(9):
color_array[i] += (1.0, 1.0, 1.0)
'''
color_array[0] = [1.0, 0.0, 0.0]
color_array[1] = [0.0, 1.0, 0.0]
color_array[2] = [0.0, 0.0, 1.0]
color_array[3] = [1.0, 1.0, 1.0]
color_array[4] = [1.0, 1.0, 0.0]
'''
#for i in range(len(terrain_array)):
#index_array[i][0] = i
for i in range(len(terrain_array)):
print terrain_array[i]
terrain_vbo = vbo.VBO(terrain_array)
#index_vbo = vbo.VBO( zeros((1,3)), target=GL_ELEMENT_ARRAY_BUFFER )
index_vbo = vbo.VBO(index_array, target=GL_ELEMENT_ARRAY_BUFFER)
color_vbo = vbo.VBO(color_array)
ResizeGLScene( nWidth, nHeight )
def ResizeGLScene( nWidth, nHeight ):
# prevent a divide-by-zero error if the window is too small
if nHeight == 0:
nHeight = 1
# reset the current viewport and recalculate the perspective transformation
# for the projection matrix
glViewport( 0, 0, nWidth, nHeight )
glMatrixMode( GL_PROJECTION )
glLoadIdentity( )
gluPerspective( 45.0, float( nWidth )/float( nHeight ), 0.1, 100.0 )
# return to the modelview matrix mode
glMatrixMode( GL_MODELVIEW )
#
# Draw the scene.
#
def DrawGLScene( ):
# clear the screen and depth buffer
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
# reset the matrix stack with the identity matrix
glLoadIdentity( )
global frameno
frameno = frameno + 1
glTranslatef( 0.0, -0.2, -2.0 )
glRotatef( frameno/6, 0.0, sr2, 0.0 )
# draw code
#glTranslatef( 0.0, 0.0, -3.0 )
glScalef( 0.5, 0.5, 0.5 )
glColor3f( 1.0, 1.0, 1.0 )
global index_vbo, terrain_vbo, color_vbo
color_vbo.bind()
glEnableClientState( GL_COLOR_ARRAY )
glColorPointer( 3, GL_FLOAT, 0, color_vbo )
terrain_vbo.bind()
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer( 3, GL_FLOAT, 0, None )
index_vbo.bind()
glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_BYTE,None)
glDisableClientState( GL_COLOR_ARRAY )
glDisableClientState( GL_VERTEX_ARRAY )
index_vbo.unbind()
terrain_vbo.unbind()
color_vbo.unbind()
glutSwapBuffers( )
def KeyPressed( key, x, y ):
key = ord(key)
if key == 27:
glutDestroyWindow( hWindow )
sys.exit( )
def main( ):
global hWindow
# initialise GLUT and a few other things
glutInit( "" )
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH )
glutInitWindowSize( 640, 480 )
glutInitWindowPosition( 0, 0 )
# create our window
hWindow = glutCreateWindow( "VBO testing" )
# setup the display function callback
glutDisplayFunc( DrawGLScene )
# go full-screen if we want to
glutFullScreen( )
# setup the idle function callback -- if we idle, we just want to keep
# drawing the screen
glutIdleFunc( DrawGLScene )
# setup the window resize callback -- this is only needed if we arent going
# full-screen
glutReshapeFunc( ResizeGLScene )
# setup the keyboard function callback to handle key presses
glutKeyboardFunc( KeyPressed )
# call our init function
InitGL( 640, 480 )
# enter the window's main loop to set things rolling
glutMainLoop( )
print "Hit ESC key to quit."
main( )