为什么我的glfw窗口不是。显示什么?

问题描述 投票:0回答:1

我一直在与 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 是痛苦的。

python opengl glsl glfw
1个回答
0
投票

经过一番挖掘,我找到了困扰我太久的答案: 只需更改即可

glVertexAttribPointer(0, verts.shape[-1], GL_FLOAT, False, 0, 0)
glVertexAttribPointer(0, colors.shape[-1], GL_FLOAT, False, 0, 0)

glVertexAttribPointer(0, verts.shape[-1], GL_FLOAT, False, 0, None)
glVertexAttribPointer(0, colors.shape[-1], GL_FLOAT, False, 0, None)

为我解决了问题。我把它放在这里以防有人需要它。 我已经多次查看过这个函数的 OpenGL 文档,但是描述真的一点帮助都没有!

© www.soinside.com 2019 - 2024. All rights reserved.