python - openGL(pyglet) 3d 场景无法在 AMD 显卡上正确渲染

标签 python python-3.x 3d pyglet

我找到了使用 pyglet 渲染立方体的代码,并且观看了该代码附带的视频,它在 Nvidia 显卡上正确显示了立方体渲染。当我在我的 AMD 显卡上尝试代码时,它崩溃了,我该如何修复这个问题?

github链接:https://github.com/obiwac/python-minecraft-clone/tree/master/episode-7

视频链接:https://www.youtube.com/watch?v=U9Ldr_PeRA8

我得到了什么:

What I get

视频显示的内容:

What the video shows

来自 main.py 的代码

import math
import ctypes
import pyglet

pyglet.options["shadow_window"] = False
pyglet.options["debug_gl"] = False

import pyglet.gl as gl

import matrix
import shader
import camera

import block_type
import texture_manager

class Window(pyglet.window.Window):
    def __init__(self, **args):
        super().__init__(**args)

        # create blocks

        self.texture_manager = texture_manager.Texture_manager(16, 16, 256)

        self.cobblestone = block_type.Block_type(self.texture_manager, "cobblestone", {"all": "cobblestone"})
        self.grass = block_type.Block_type(self.texture_manager, "grass", {"top": "grass", "bottom": "dirt", "sides": "grass_side"})
        self.dirt = block_type.Block_type(self.texture_manager, "dirt", {"all": "dirt"})
        self.stone = block_type.Block_type(self.texture_manager, "stone", {"all": "stone"})
        self.sand = block_type.Block_type(self.texture_manager, "sand", {"all": "sand"})
        self.planks = block_type.Block_type(self.texture_manager, "planks", {"all": "planks"})
        self.log = block_type.Block_type(self.texture_manager, "log", {"top": "log_top", "bottom": "log_top", "sides": "log_side"})

        self.texture_manager.generate_mipmaps()

        # create vertex array object

        self.vao = gl.GLuint(0)
        gl.glGenVertexArrays(1, ctypes.byref(self.vao))
        gl.glBindVertexArray(self.vao)

        # create vertex position vbo

        self.vertex_position_vbo = gl.GLuint(0)
        gl.glGenBuffers(1, ctypes.byref(self.vertex_position_vbo))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_position_vbo)

        gl.glBufferData(
            gl.GL_ARRAY_BUFFER,
            ctypes.sizeof(gl.GLfloat * len(self.grass.vertex_positions)),
            (gl.GLfloat * len(self.grass.vertex_positions)) (*self.grass.vertex_positions),
            gl.GL_STATIC_DRAW)
        
        gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glEnableVertexAttribArray(0)

        # create tex coord vbo

        self.tex_coord_vbo = gl.GLuint(0)
        gl.glGenBuffers(1, ctypes.byref(self.tex_coord_vbo))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.tex_coord_vbo)

        gl.glBufferData(
            gl.GL_ARRAY_BUFFER,
            ctypes.sizeof(gl.GLfloat * len(self.grass.tex_coords)),
            (gl.GLfloat * len(self.grass.tex_coords)) (*self.grass.tex_coords),
            gl.GL_STATIC_DRAW)
        
        gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glEnableVertexAttribArray(1)

        # create shading value vbo

        self.shading_value_vbo = gl.GLuint(0)
        gl.glGenBuffers(1, ctypes.byref(self.shading_value_vbo))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.shading_value_vbo)

        gl.glBufferData(
            gl.GL_ARRAY_BUFFER,
            ctypes.sizeof(gl.GLfloat * len(self.grass.shading_values)),
            (gl.GLfloat * len(self.grass.shading_values)) (*self.grass.shading_values),
            gl.GL_STATIC_DRAW)
        
        gl.glVertexAttribPointer(2, 1, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glEnableVertexAttribArray(2)

        # create index buffer object

        self.ibo = gl.GLuint(0)
        gl.glGenBuffers(1, self.ibo)
        gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo)

        gl.glBufferData(
            gl.GL_ELEMENT_ARRAY_BUFFER,
            ctypes.sizeof(gl.GLuint * len(self.grass.indices)),
            (gl.GLuint * len(self.grass.indices)) (*self.grass.indices),
            gl.GL_STATIC_DRAW)
        
        # create shader

        self.shader = shader.Shader("vert.glsl", "frag.glsl")
        self.shader_sampler_location = self.shader.find_uniform(b"texture_array_sampler")
        self.shader.use()

        # pyglet stuff

        pyglet.clock.schedule_interval(self.update, 1.0 / 60)
        self.mouse_captured = False

        # camera stuff

        self.camera = camera.Camera(self.shader, self.width, self.height)
    
    def on_draw(self):
        self.camera.update_matrices()

        # bind textures

        gl.glActiveTexture(gl.GL_TEXTURE0)
        gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, self.texture_manager.texture_array)
        gl.glUniform1i(self.shader_sampler_location, 0)

        # draw stuff

        gl.glEnable(gl.GL_DEPTH_TEST)
        gl.glClearColor(0.0, 0.0, 0.0, 1.0)
        self.clear()

        gl.glDrawElements(
            gl.GL_TRIANGLES,
            len(self.grass.indices),
            gl.GL_UNSIGNED_INT,
            None)

*注意:省略了部分相机移动代码,要查看完整代码,请参阅github链接。

我已经与不和谐的创建者进行了交谈,他已确认他使用的是 Nvidia 卡,非常感谢解决此问题的任何帮助!

最佳答案

您必须确保 pyglet 窗口的默认帧缓冲区具有深度缓冲区。请参阅Creating an OpenGL context :

config = pyglet.gl.Config(depth_size = 24)
window = pyglet.window.Window(config = config)

如果您的硬件不支持 24 位深度缓冲区,您可能需要尝试 16 位:

config = pyglet.gl.Config(depth_size = 16)
window = pyglet.window.Window(config = config)

关于python - openGL(pyglet) 3d 场景无法在 AMD 显卡上正确渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64828949/

相关文章:

OpenGL 如何一次绑定(bind)(数万个)数千个纹理?

java - 捕获内存不足错误的正确位置

python - 重新格式化嵌套的元组列表时出现问题?

python-3.x - 图像无法使用 Image.open(fnames) 打开,并且代码有 "' 列表'对象没有属性 'read'“错误

python - 将字典列表中的两个列表合并为一个

java - 如何在android中显示3D模型?

python - 如何通过将列的类别分成集合来过滤数据框?

python - 在Ubuntu 20.04上安装pip2

python - 为什么 np.array([1e5])**2 与 Python 中的 np.array([100000])**2 不同?

java - 将 P3D 对象放置在默认渲染器中