PyOpenGL,无法使用两个不同的VBO进行绘制

时间:2018-04-18 08:30:00

标签: python python-3.x opengl shader pyopengl

我遇到一个奇怪的问题,我试图使用两个不同的VBO并使用glDrawArrays()。但是,即使VBO数据不同,glDrawArrays()也会绘制完全相同的数字

import ctypes
import numpy as np
import pygame as pg
from pygame.locals import *
from array import array
SCREEN_SIZE = (800, 600)


from OpenGL.GL import *
from OpenGL.GLU import *

def resize(width, height):

    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(60.0, float(width)/height, .1, 1000.)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()




def create_shader(shader_type,source):
    shader = glCreateShader(shader_type)
    glShaderSource(shader,source)
    glCompileShader(shader)
    print(glGetShaderiv(shader, GL_COMPILE_STATUS, None))
    return shader

pg.init()
screen = pg.display.set_mode(SCREEN_SIZE, HWSURFACE|OPENGL|DOUBLEBUF)

resize(*SCREEN_SIZE)

#creating and compiling fragment shader
fragment = create_shader(GL_FRAGMENT_SHADER,"""

#version 130

out vec4 finalColor; 

void main()
{
    finalColor = vec4(.0,0.0,1.0,1.0);
}
""")

#creating and compiling vertex shader
vertex = create_shader(GL_VERTEX_SHADER,"""

#version 130


in vec3 pos;

void main()
{   

    gl_Position=gl_ProjectionMatrix*gl_ModelViewMatrix *vec4(pos,1.0);



}
""")

#create and link program
program = glCreateProgram()
glAttachShader(program, fragment)
glAttachShader(program, vertex)
glLinkProgram(program)
#get location of the position variable in vertex shader
posAttrib = glGetAttribLocation(program, "pos")


vbo=glGenBuffers(1)

vbo2=glGenBuffers(1)

#vao=glGenVertexArrays(1)

#glBindVertexArray(vao)

glBindBuffer(GL_ARRAY_BUFFER, vbo)
vertices=[1.5, -0.5, -4.0, 0.5, -0.5, -4.0, 0.5, 0.5, -4.0]

nparray = np.array(vertices,dtype=np.dtype('<f4'))
glBufferData(GL_ARRAY_BUFFER, nparray, GL_STATIC_DRAW)

vertices=[2., -0.5, -4.0, -0.5, -0.5, -2.0, 0.5, 0.5, -1.0]
#vertices=[1.5, -0.5, -4.0, 0.5, -0.5, -4.0, 0.5, 0.5, -4.0]
nparray = np.array(vertices,dtype=np.dtype('<f4'))
glBindBuffer(GL_ARRAY_BUFFER, vbo2)
glBufferData(GL_ARRAY_BUFFER, nparray, GL_STATIC_DRAW)

#specify how the variable pos gets data from the buffer data
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4,ctypes.cast(0, ctypes.c_void_p))

while 1:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(1.0, 1.0, 1.0, 0.0)


    glUseProgram(program)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    print('vbo 1:',glGetInteger(GL_ARRAY_BUFFER_BINDING))
    print('vbo data 1:',glGetBufferSubData(GL_ARRAY_BUFFER,0,3*3*4,None))


#    glDrawArrays(GL_TRIANGLES, 0, 3)

    glBindBuffer(GL_ARRAY_BUFFER, vbo2)
    print('vbo 2:',glGetInteger(GL_ARRAY_BUFFER_BINDING))
    print('vbo data 2:',glGetBufferSubData(GL_ARRAY_BUFFER,0,3*3*4,None))

    glDrawArrays(GL_TRIANGLES, 0, 3)


    pg.display.flip()
    pg.time.delay(100)

代码的重要部分是我使用glBufferData和绘图命令glDrawArrays上传数据的地方。如果你试图注释掉一个或另一个glDrawArrays(),你会发现代码实际上绘制了完全相同的数字。但是,我已经将不同的数据上传到两个VBO(通过打印glGetBufferSubData获得的数据可以看到)。这很奇怪。当VBO数据明显不同时,为什么两个glDrawArrays产生相同的结果?这是PyOpenGL中的一个错误,还是我错过了一些基本的东西?

1 个答案:

答案 0 :(得分:1)

它不是绑定的顶点缓冲区对象,它定义了一般顶点属性数据的数组,但它是存储在默认顶点数组对象中的状态。

当您调用glVertexAttribPointer时,将定义通用顶点属性数据数组。如果此时绑定了数组缓冲区,则数组定义引用缓冲区对象。

这意味着您必须在绘制对象之前切换数组定义:

# define an array of generic vertex attribute data which refers to "vbo" 
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 0,ctypes.cast(0, ctypes.c_void_p))
glEnableVertexAttribArray(posAttrib)
glDrawArrays(GL_TRIANGLES, 0, 3)

# define an array of generic vertex attribute data which refers to "vbo2" 
glBindBuffer(GL_ARRAY_BUFFER, vbo2)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 0,ctypes.cast(0, ctypes.c_void_p))
glEnableVertexAttribArray(posAttrib)
glDrawArrays(GL_TRIANGLES, 0, 3)


作为替代方案,您可以使用2 Vertex Array Objects

# vertex data 1
vertices=[1.5, -0.5, -4.0, 0.5, -0.5, -4.0, 0.5, 0.5, -4.0]
nparray = np.array(vertices,dtype=np.dtype('<f4'))
vbo=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBufferData(GL_ARRAY_BUFFER, nparray, GL_STATIC_DRAW)

# vertex data 2
vertices=[2., -0.5, -4.0, -0.5, -0.5, -2.0, 0.5, 0.5, -1.0]
nparray = np.array(vertices,dtype=np.dtype('<f4'))
vbo2=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbo2)
glBufferData(GL_ARRAY_BUFFER, nparray, GL_STATIC_DRAW)

# vertex array object 1
vao=glGenVertexArrays(1)
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4,ctypes.cast(0, ctypes.c_void_p))

# vertex array object 2
vao2=glGenVertexArrays(1)
glBindVertexArray(vao2)
glBindBuffer(GL_ARRAY_BUFFER, vbo2)
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4,ctypes.cast(0, ctypes.c_void_p))

glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)

# draw vertex array 1
glBindVertexArray(vao)
glDrawArrays(GL_TRIANGLES, 0, 3)

# draw vertex array 2
glBindVertexArray(vao2)
glDrawArrays(GL_TRIANGLES, 0, 3)