[英]Draw multiple objects using VBOs with PyQt5 and OpenGL?
我正在嘗試使用 pyqt5 在 pyopengl 中渲染多個對象。 按照教程之后,我創建了一個 3D 網格,它上傳了一個波前 obj 文件並用紋理渲染它。 這對我有用:
class Model:
def __init__(self, file_name, texture_name):
self.object = ObjectLoader()
self.object.load_model(file_name)
//creating and compiling shaders
glUseProgram(shader)
vertex_buffer_object = GLuint(0)
glGenBuffers(1, vertex_buffer_object)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object)
glBufferData(GL_ARRAY_BUFFER, len(self.object.model) * 4, self.object.c_model, GL_DYNAMIC_DRAW)
glDrawArrays(GL_TRIANGLES, 0, len(self.object.vertex_index))
# vertices
vertex_offset = 0
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 3, ctypes.c_void_p(vertex_offset))
glEnableVertexAttribArray(0)
# textures
texture_offset = len(self.object.vertex_index) * 12
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 2, ctypes.c_void_p(texture_offset))
glEnableVertexAttribArray(1)
# normals
normal_offset = texture_offset + len(self.object.texture_index) * 8
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 3, ctypes.c_void_p(normal_offset))
glEnableVertexAttribArray(2)
texture = GLuint(0)
glGenTextures(1, texture)
glBindTexture(GL_TEXTURE_2D, texture)
# texture wrapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
image = Image.open(texture_name)
flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
image_data = image.convert("RGB").tobytes()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data)
// setting the view, projection etc matrix
因為我正在使用 PyQt5,所以我在加載對象時有這個類:
class Obj(QOpenGLWidget):
def __init__(self, parent):
QOpenGLWidget.__init__(self, parent)
def initializeGL(self):
glClearColor(82/255, 95/255, 107/255, 1.0)
glEnable(GL_DEPTH_TEST)
self.model = Model("....obj", "texture.png")
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glDrawArrays(GL_TRIANGLES, 0, len(self.model.object.vertex_index))
self.update()
def resizeGL(self, width, height):
glViewport(0, 0, width, height)
我正在努力的是在Obj
類中創建另一個Model
。 我嘗試在initializeGL
創建它並使用另一個glDrawArrays
調用在paintGL
渲染,但沒有發生任何事情,或者沒有任何預期......知道我做錯了什么嗎?
您必須使用Vertex Array Object 。 頂點數組對象存儲提供頂點數據所需的所有狀態。
模型的構造函數只創建所有必需的 OpenGL 對象。 着色器程序不是模型的一部分。 對所有型號使用相同的程序:
class Model:
def __init__(self, file_name, texture_name):
self.object = ObjectLoader()
self.object.load_model(file_name)
# create vertex array object
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
vertex_buffer_object = GLuint(0)
glGenBuffers(1, vertex_buffer_object)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object)
glBufferData(GL_ARRAY_BUFFER, len(self.object.model) * 4, self.object.c_model, GL_DYNAMIC_DRAW)
glDrawArrays(GL_TRIANGLES, 0, len(self.object.vertex_index))
# vertices
vertex_offset = 0
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 3, ctypes.c_void_p(vertex_offset))
glEnableVertexAttribArray(0)
# textures
texture_offset = len(self.object.vertex_index) * 12
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 2, ctypes.c_void_p(texture_offset))
glEnableVertexAttribArray(1)
# normals
normal_offset = texture_offset + len(self.object.texture_index) * 8
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, self.object.model.itemsize * 3, ctypes.c_void_p(normal_offset))
glEnableVertexAttribArray(2)
# create texture
self.texture = GLuint(0)
glGenTextures(1, self.texture)
glBindTexture(GL_TEXTURE_2D, self.texture)
# texture wrapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
image = Image.open(texture_name)
flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
image_data = image.convert("RGB").tobytes()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data)
向綁定 OpenGL 對象(VAO 和紋理)並繪制網格的類添加一個方法:
class Model:
# [...]
def draw(self):
// bind texture
glBindTexture(GL_TEXTURE_2D, self.texture)
// create vertex array object
glBindVertexArray(self.vao)
// draw object
glDrawArrays(GL_TRIANGLES, 0, len(self.object.vertex_index))
通過此設置,您可以繪制多個模型:
class Obj(QOpenGLWidget):
def __init__(self, parent):
QOpenGLWidget.__init__(self, parent)
def initializeGL(self):
glClearColor(82/255, 95/255, 107/255, 1.0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.model1 = Model("....obj", "texture.png")
self.model2 = Model("....obj", "texture2.png")
# [...]
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# install program
glUseProgram(self.shader)
# setting the view, projection etc matrix
# [...]
self.model1.draw()
self.model2.draw()
# [...]
self.update()
def resizeGL(self, width, height):
glViewport(0, 0, width, height)
這些模型也可以組織在一個列表中:
class Obj(QOpenGLWidget):
# [...]
def initializeGL(self):
# [...]
self.models = [
Model("....obj", "texture.png"),
Model("....obj", "texture2.png")
# [...]
]
def paintGL(self):
# [...]
for model in self.models:
model.draw()
# [...]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.