openGL(pyglet) 3d 场景无法在 AMD 显卡上正确渲染
openGL(pyglet) 3d scene not rendering properly on AMD Graphics card
我找到了使用 pyglet 渲染立方体的代码,我观看了与代码一起出现的视频,它显示了在 Nvidia 显卡上正确渲染的立方体。当我在我的 AMD 显卡上尝试代码时它坏了,我该如何解决这个问题?
github link: https://github.com/obiwac/python-minecraft-clone/tree/master/episode-7
视频link:https://www.youtube.com/watch?v=U9Ldr_PeRA8
我得到的:
视频显示的内容:
代码来自 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 link.
我已经在 discord 上与创作者交谈,他已确认他使用的是 Nvidia 显卡,非常感谢任何解决此问题的帮助!
您必须确保 pyglet window 的默认帧缓冲区具有深度缓冲区。见 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)
我找到了使用 pyglet 渲染立方体的代码,我观看了与代码一起出现的视频,它显示了在 Nvidia 显卡上正确渲染的立方体。当我在我的 AMD 显卡上尝试代码时它坏了,我该如何解决这个问题?
github link: https://github.com/obiwac/python-minecraft-clone/tree/master/episode-7
视频link:https://www.youtube.com/watch?v=U9Ldr_PeRA8
我得到的:
视频显示的内容:
代码来自 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 link.
我已经在 discord 上与创作者交谈,他已确认他使用的是 Nvidia 显卡,非常感谢任何解决此问题的帮助!
您必须确保 pyglet window 的默认帧缓冲区具有深度缓冲区。见 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)