1 回答

TA貢獻1796條經(jīng)驗 獲得超10個贊
您必須使用頂點數(shù)組對象。頂點數(shù)組對象存儲提供頂點數(shù)據(jù)所需的所有狀態(tài)。
模型的構(gòu)造函數(shù)僅創(chuàng)建所有必需的 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 和紋理)并繪制網(wǎng)格:
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()
? ? ? ? # [...]?
添加回答
舉報