为了账号安全,请及时绑定邮箱和手机立即绑定

使用 PyQt5 和 OpenGL 使用 VBO 绘制多个对象?

使用 PyQt5 和 OpenGL 使用 VBO 绘制多个对象?

狐的传说 2023-07-18 17:43:40
我正在尝试使用 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)我正在努力解决的是在Obj课堂上创造另一个Model。我尝试创建它并通过另一个调用initializeGL进行渲染,但没有发生任何事情,或者没有预期的结果......知道我做错了什么吗?paintGLglDrawArrays
查看完整描述

1 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

您必须使用顶点数组对象。顶点数组对象存储提供顶点数据所需的所有状态。

模型的构造函数仅创建所有必需的 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()


        # [...] 


查看完整回答
反对 回复 2023-07-18
  • 1 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信