所以我很确定我在这里调用 OpenGL 的方式出了问题。 我在下面提供了一个示例,其中大约 30% 的时间显示红色背景顶部的半透明顶点彩色方块。另外 70% 的时间它只显示红色背景。我尝试注释掉各种 opengl 命令,看看是否可以让它可靠地工作。这是我从一个更大的程序中尝试“最小”可重现的示例。
我尝试向这些点添加 z 坐标并设置 GL_DEPTH_TEST 但没有什么区别,70% 的时间仍然无法工作。
奇怪的是,有时它会进入一种状态,程序每隔一段时间就会工作几次,但这也许只是巧合。
此外,当它确实工作时,它工作正常,并循环不同方块的所有颜色,直到程序终止,所以这让我认为初始化或某些竞争条件或其他东西出了问题。
import OpenGL.GL as gl
import numpy as np
import pygame as pg
from pygame import locals as pg_locals
import time
class OpenGLWindow:
def __init__(self):
self.use_color_buffer = 0
flags = pg_locals.DOUBLEBUF | pg_locals.OPENGL | pg_locals.RESIZABLE
self.pg_window = pg.display.set_mode(
(800, 600),
flags,
vsync=1,
)
# gl.glTexEnvf(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE)
# gl.glEnable(gl.GL_DEPTH_TEST) # we are disabling this for now because the texture z depth and overlay elements aren't configured right yet.
gl.glEnable(gl.GL_BLEND)
gl.glEnable(gl.GL_COLOR_MATERIAL)
gl.glColorMaterial(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
# gl.glEnable(gl.GL_TEXTURE_2D)
# gl.glLoadIdentity()
self.setup_buffers_2()
def setup_buffers_2(self):
self._vertexBuffer = gl.glGenBuffers(1)
self._colorBuffers = gl.glGenBuffers(3)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertexBuffer)
vertices = np.array(
[0.5, 0.5, 0, 0.5, 0, 0, 0.5, 0, -0.5, -0.5, 0, -0.5, 0, 0, -0.5, 0],
dtype="float32",
)
gl.glBufferData(gl.GL_ARRAY_BUFFER, vertices, gl.GL_STATIC_DRAW) # Error
for n in range(3):
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._colorBuffers[n])
colors = []
for p in range(8):
for c in range(3):
colors.append((p % 4) * 0.25 if c == n else 0)
colors.append((p % 4) * 0.25)
print(colors)
gl.glBufferData(
gl.GL_ARRAY_BUFFER, np.array(colors, dtype="float32"), gl.GL_STATIC_DRAW
)
def cleanup_buffers_2(self):
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertexBuffer)
gl.glDeleteBuffers(1, self._vertexBuffer)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
for n in range(3):
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._colorBuffers[n])
gl.glDeleteBuffers(3, self._colorBuffers)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
def render_opengl_2(self):
gl.glClearColor(1.0, 0.0, 0.0, 1.0)
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertexBuffer)
gl.glVertexPointer(2, gl.GL_FLOAT, 0, 0)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._colorBuffers[self.use_color_buffer])
gl.glColorPointer(4, gl.GL_FLOAT, 0, 0)
gl.glDrawArrays(gl.GL_QUADS, 0, 8)
pg.display.flip()
self.use_color_buffer += 1
self.use_color_buffer %= 3
window = OpenGLWindow()
# window.render_opengl_2()
# time.sleep(1)
# window.cleanup_buffers_2()
try:
for _ in range(30):
window.render_opengl_2()
time.sleep(0.1)
finally:
window.cleanup_buffers_2()
glVertexPointer
的最后一个参数的类型为const GLvoid *
。所以参数必须是 None
或 ctypes.c_void_p(0)
,但不是 0:
gl.glVertexPointer(2, gl.GL_FLOAT, 0, 0)
gl.glVertexPointer(2, gl.GL_FLOAT, 0, None)
glColorPointer
。