PyOpenGL中的顶点缓冲对象 - 顶点,索引和颜色

时间:2013-05-15 07:07:07

标签: macos opengl numpy vbo pyopengl

OSX 10.8.3,Python,PyOpenGL。

我正在尝试使用VBO在PyO​​penGL中组合一个基本的地形绘制功能。有几个问题我不知道如何解决,主要是因为我不完全理解VBO的工作方式。这是一个基本的测试沙箱,当我将项目更改为VBO时遇到了太多困难,所以它在某些地方很邋((参见:frame counter)。

  • 我已经硬编码了一个基本的3x3地形数组和相应的索引数组,但它似乎只绘制了三行中的两行(它是y = 0行,y = 0.5但不是y = 2.0)。我对numpy不太满意,所以这可能是原因。
  • 颜色数组的内容对最终颜色只有不稳定的影响:为数组分配numpy.zeros()会产生黑屏,指定numpy.ones()产生绿色和紫色条纹而不是白色表面I'我期待着。最初是使用随机颜色,但没有做任何不同的()。我真的不明白OpenGL应该如何确定这是一个颜色VBO而不是其他任何东西。
  • 当我到达时,三角绘图算法会有问题 - 我不知道如何在不使用GL_PRIMITIVE_RESTART的情况下绘制多行,这在GLUT中是不可用的(我只想改为GLFW或类似于万不得已)。现在,我不太关心它。用这样的条画画并不是我想要的:http:// www.matrix44.net/cms/notes/opengl-3d-graphics/understanding-gl_triangle_strip(对不起,没有10个声誉)

旋转时的当前状态: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( )

0 个答案:

没有答案