OpenGL 3/GLFW 空白视口

Posted

技术标签:

【中文标题】OpenGL 3/GLFW 空白视口【英文标题】:OpenGL 3/GLFW Blank Viewport 【发布时间】:2014-09-07 20:20:57 【问题描述】:

我正在阅读http://www.open.gl 的第二个“章节”,遇到了一个我无法弄清楚的绘图问题。

int main()

    //Initialize GLFW, create the window and the context
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    GLFWwindow* window = glfwCreateWindow(1024, 768, "Open.GL Drawing 1", nullptr, nullptr);

    glfwMakeContextCurrent(window);

    //initialize GLEW after context creation
    glewExperimental = GL_TRUE;
    glewInit();

    //loading, compiling, and checking shaders takes place here
    [...]

    //create, link, and use the shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    //create and bind the vao for the position data
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    //triangle vertecies
    GLfloat verticies[] = 
         0.0f,  0.5f,
         0.5f, -0.5f,
        -0.5f, -0.5f
    ;

    //vbo for verticies
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);

    //link, define, and enable the position attribute (aka, the verticies)
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posAttrib);

    //main loop!
    while(!glfwWindowShouldClose(window))
    
        glfwPollEvents();

        if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
    

    //clean up after yourself
    glfwTerminate();

    glDeleteProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);

    return EXIT_SUCCESS;

顶点着色器:

#version 150

in vec2 position;

void main()

    gl_Position = vec4(position, 0.0, 1.0);

片段着色器:

#version 150

out vec4 outColor;

void mian()

    outColor = vec4(1.0, 1.0, 1.0, 1.0);

编译时使用

g++ -fdiagnostics-color -Wall -Wextra -std=c++11 -lGLEW -lGLU -lGL  -lglfw -o drawing1 drawing1.cpp

我没有收到任何警告,但程序运行时出现空白屏幕。我检查了example code 他的链接以及示例源的github copy。不幸的是,他使用的是 SFML,而我使用的是 GLFW,所以我试图弥补这种差异。

我尽力模仿他的示例代码(事物的顺序等),并添加了main() 的最后几行和主循环(没有提到删除着色器或清除视口的颜色)教程,但这些语句出现在他的示例代码中)但仍然得到相同的结果。检查glGetError() 给了我一个无效的枚举错误,但this post 说这可能是glewExperimental 的预期行为。

在那之后,我不确定如何进一步隔离问题。我期待有人指出这显然是一个简单的错误。 =)

【问题讨论】:

两件事:首先,尝试将glGetError() 放在glewInit() 之后,这样它会重置错误标志;然后将glGetError() 放在其他位置,它应该显示0 或另一个与GLEW 无关的错误代码。其次,链接着色器程序可能会导致链接错误,您应该检查这些错误;否则你的着色器可能会在你不知情的情况下被破坏(检查标题 Linking 处的opengl.org/sdk/docs/tutorials/ClockworkCoders/loading.php,了解如何为程序完成此操作)。 哦,问题可能出在哪里:片段着色器的主要功能实际上称为mian。编译着色器后是否检查错误日志?这个错误很容易被发现。检查错误日志以及着色器是否实际编译成功确实是可取的:) 哈哈哈哈哈哈。是的。 mian 不会引发编译错误,但我确信 GL 在发生这种情况时会感到困惑。 XD 我喜欢在 GLEW 的 init 之后调用 glGetError 以清除该错误的想法,不过,感谢您的两个想法! =) 当然!还尝试验证您的着色器是否成功链接,如果成功则打印错误日志并尝试查明给出错误的确切语句。你现在应该可以这样做了 :) 一旦你查明了错误的来源,我们会听到更多 是的,在我修正错字后它起作用了。 =)如果我添加您在第一条评论中链接的 GLSL 链接检查,那会抱怨吗?为了练习起见,无论如何我都会添加它,但如果它指出它,我会将其包含在此问题的“答案”中。 【参考方案1】:

正如Joey Dewd 所指出的,我没有很好地校对我的着色器代码。作为记录,是我在片段着色器中输入mian 而不是main 导致了问题。根据他的建议,我添加了代码来检查链接中的错误(我已经在检查编译错误),果然,当我重新创建错字时,链接器抱怨了。

Fragment info
-------------
(0) : error C3001: no program defined

谢谢乔伊。 =)

【讨论】:

以上是关于OpenGL 3/GLFW 空白视口的主要内容,如果未能解决你的问题,请参考以下文章

opengl 3 qt渲染空白屏幕

OpenGL 显示空白屏幕

尝试在openGL中创建空白窗口时出现异常输出

VC++ 中是不是有某种空白的 openGL 和 freeglut 项目?

具有独特着色器的 OpenGL 多次绘制调用会产生空白屏幕

SDL 3d OpenGL:立方体上的纹理产生空白屏幕