簡體   English   中英

使用帶有 PyQt5 和 OpenGL 的 VBO 繪制多個對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM