gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 09:31:49 25 4
gpt4 key购买 nike

我遇到一个奇怪的问题,我试图使用两个不同的 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 数据明显不同时,为什么两个 glDrawArray 产生相同的结果?这是 PyOpenGL 中的错误还是我在这里遗漏了一些基本的东西?

最佳答案

它不是定义通用顶点属性数据数组的绑定(bind)顶点缓冲区对象,而是存储在默认顶点数组对象中的状态。

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

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

# 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)

关于python - PyOpenGL,无法使用两个不同的VBO进行绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49894819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com