我的glfw窗口为什么不显示任何内容?
我最近在使用GLFW的时候遇到了一个奇怪的问题。
我有一段代码是用来在GLFW窗口里画一个彩色立方体的。但是屏幕上什么都没有显示,完全是空白,也没有报错。下面是我用Python写的最简代码:
import glfw
from OpenGL.GL import *
import numpy as np
from OpenGL import GL as gl
from OpenGL.GL import shaders
def load_shaders(vertex_shader, fragment_shader):
vertex_shader = open(vertex_shader, "r").read()
fragment_shader = open(fragment_shader, "r").read()
active_shader = shaders.compileProgram(
shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER),
)
return active_shader
if not glfw.init():
raise Exception("glfw can not be initialized!")
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, glfw.TRUE)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(640, 480, "glfw test", None, None)
glfw.make_context_current(window)
gl.glEnable(GL_DEPTH_TEST)
glfw.swap_interval(1)
l = -0.5
h = 0.5
verts = np.array([
l, l, h, h, l, h, l, h, h, h, h, h, # FRONT
l, l, l, l, h, l, h, l, l, h, h, l, # BACK
l, l, h, l, h, h, l, l, l, l, h, l, # LEFT
h, l, l, h, h, l, h, l, h, h, h, h, # RIGHT
l, h, h, h, h, h, l, h, l, h, h, l, # TOP
l, l, h, l, l, l, h, l, h, h, l, l # BOTTOM
], dtype=np.float32).reshape(-1, 3)
colors = np.array([
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
], dtype=np.float32).reshape(-1, 3)
vao = glGenVertexArrays(1)
glBindVertexArray(vao)
shader = load_shaders(
"shaders/copy_vert.glsl", "shaders/copy_frag.glsl")
pos = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, pos)
glBufferData(GL_ARRAY_BUFFER, verts.nbytes, verts.reshape(-1), GL_STATIC_DRAW)
glVertexAttribPointer(0, verts.shape[-1], GL_FLOAT, False, 0, 0)
glEnableVertexAttribArray(0)
frag = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, frag)
glBufferData(GL_ARRAY_BUFFER, colors.nbytes,
colors.reshape(-1), GL_STATIC_DRAW)
glVertexAttribPointer(1, colors.shape[-1], GL_FLOAT, False, 0, 0)
glEnableVertexAttribArray(1)
while not glfw.window_should_close(window):
glClearColor(0.0, 0.0, 0.4, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader)
glBindVertexArray(vao)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 24)
glUseProgram(0)
glBindVertexArray(0)
glDisableVertexAttribArray(0)
glDisableVertexAttribArray(1)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.destroy_window(window)
glfw.terminate()
这是我的着色器:
#version 330 core
out vec3 color;
void main(){
color = vec3(1.0, 1.0, 0.0);
}
#version 330 core
layout(location = 0) in vec3 pos;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(pos, 1.0);
}
问题是,如果我把GL_TRIANGLE_STRIP
改成GL_POINTS
,我能在窗口的原点看到一个亮点,这明显说明缓冲区里没有数据。但我很确定我的缓冲区是没问题的。
我使用的是glfw==2.7.0
和PyOpenGL==3.1.7
。这个程序在M1的Mac和一台运行Ubuntu22.04的Linux机器上测试过,结果都是一样的。我是不是漏掉了什么?
如果我使用这段代码,绘制效果就很好,我能看到立方体的红色面朝着我:
import glfw
from OpenGL.GL import *
import numpy as np
from OpenGL import GL as gl
from OpenGL.GL import shaders
def load_shaders(vertex_shader, fragment_shader):
vertex_shader = open(vertex_shader, "r").read()
fragment_shader = open(fragment_shader, "r").read()
active_shader = shaders.compileProgram(
shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER),
)
return active_shader
if not glfw.init():
raise Exception("glfw can not be initialized!")
window = glfw.create_window(640, 480, "glfw test", None, None)
glfw.make_context_current(window)
gl.glEnable(GL_DEPTH_TEST)
glfw.swap_interval(1)
l = -0.5
h = 0.5
verts = np.array([
l, l, h, h, l, h, l, h, h, h, h, h, # FRONT
l, l, l, l, h, l, h, l, l, h, h, l, # BACK
l, l, h, l, h, h, l, l, l, l, h, l, # LEFT
h, l, l, h, h, l, h, l, h, h, h, h, # RIGHT
l, h, h, h, h, h, l, h, l, h, h, l, # TOP
l, l, h, l, l, l, h, l, h, h, l, l # BOTTOM
], dtype=np.float32).reshape(-1, 3)
colors = np.array([
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
], dtype=np.float32).reshape(-1, 3)
while not glfw.window_should_close(window):
glClearColor(0.0, 0.0, 0.4, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glVertexPointer(3, GL_FLOAT, 0, verts)
glEnableClientState(GL_VERTEX_ARRAY)
glColor4f(1.0, 0.0, 0.0, 1.0)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4)
glColor4f(0.0, 1.0, 0.0, 1.0)
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4)
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4)
glColor4f(0.0, 0.0, 1.0, 1.0)
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4)
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4)
glDisableClientState(GL_VERTEX_ARRAY)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.destroy_window(window)
glfw.terminate()
可惜这不是我想要的效果,不使用glsl真是太麻烦了。
1 个回答
-1
我只需要把这个:
glVertexAttribPointer(0, verts.shape[-1], GL_FLOAT, False, 0, 0)
glVertexAttribPointer(1, colors.shape[-1], GL_FLOAT, False, 0, 0)
改成这个:
glVertexAttribPointer(0, verts.shape[-1], GL_FLOAT, False, 0, None)
glVertexAttribPointer(1, colors.shape[-1], GL_FLOAT, False, 0, None)
就解决了我的问题。