繁体   English   中英

OpenGL是否消除没有绑定顶点缓冲区的顶点着色器?

[英]Does OpenGL eliminate a vertex shader with no bound vertex buffer?

OpenGL SuperBible 6th Ed(对于OpenGL 4.3)具有使用顶点着色器的示例,这些着色器没有顶点属性输入,但是具有硬编码的顶点,例如

#version 420 core
void main(void) 
{                                                                 
    const vec4 vertices[] = vec4[](vec4( 0.4, -0.4, 0.5, 1.0), 
                                   vec4(-0.4, -0.4, 0.5, 1.0),    
                                   vec4( 0.4,  0.4, 0.5, 1.0));   
    gl_Position = vertices[gl_VertexID];  
 }

当我运行样本时,窗口将被清除,但没有其他任何反应。

通过实验,我发现将空缓冲区绑定到上下文时,程序按预期运行。 下面是示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h> /
#include <GLFW/glfw3.h> 
#define GLM_MESSAGES
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/vector_angle.hpp>

int main(int argc, char* argv[]) {
    GLuint program;
    GLuint vao;
    GLuint vbo;

    glfwInit();
    GLFWwindow* window = glfwCreateWindow(640, 480, "gl_InstanceID", NULL, NULL);
    glfwMakeContextCurrent(window);

    glewInit();
    program = glCreateProgram();
    GLuint vs = load("vertex.glsl", GL_VERTEX_SHADER, true);
    GLuint fs = load("frag.glsl", GL_FRAGMENT_SHADER, true);
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program); 
    glDeleteShader(vs);
    glDeleteShader(fs);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

//**************************************
//no triangle drawn when below these lines commented out
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 4, NULL, GL_DYNAMIC_COPY);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);
//***************************************

    do {
        static const GLfloat green[] = { 0.0f, 0.2f, 0.0f, 1.0f };
        glClearBufferfv(GL_COLOR, 0, green);
        glUseProgram(program);
        glDrawArrays(GL_TRIANGLES, 0, 3); //OR glDrawArraysInstanced(GL_TRIANGLES, 0, 3,1);
        glfwSwapBuffers(window);

        glfwPollEvents();
        if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE)) {
            glfwSetWindowShouldClose(window, 1);
        }
    } while (!glfwWindowShouldClose(window));
    glfwTerminate();
    return 0;
}

星号之间添加代码时,将绘制三角形。 如果没有缓冲区,则不会绘制三角形。

同样,当顶点阵列对象(VAO)被删除(或如上使用)时,三角形也不会显示。 仅使用VAO和(空)VBO绘制三角形。 删除VAO但有缓冲区会显示三角形。 没有缓冲区,没有三角形。 VAO似乎没有任何作用。

还要注意,顶点着色器没有输入。

发生什么事了?

  1. 编译器/图形卡认为顶点着色器不执行任何操作并将其删除? 我感觉是图形卡(驱动程序)。
  2. 这是OpenGL所期望的,还是因为显卡?
  3. 我对缓冲区,VAO和着色器的了解缺少什么?

其他可能有用的信息

  • GLEW 1.10.0
  • GLFW 3.0.3

片段着色器:

#version 420 core
out vec4 color;
void main(void)
{
color = vec4(1.0);
}

操作系统详细信息:

  • Linux:3.2.0-4-amd64
  • 发行版:Debian 7.3 Wheezy
  • ame -m:x86_64

编译器详细信息

  • g ++ --version:g ++(Debian 4.7.2-5)4.7.2

OpenGL详细信息:

  • OpenGL Provider:Advanced Micro Devices(来自AMD Catalyst Control Center)
  • OpenGL渲染器:AMD Radeon HD 7600M系列(来自AMD Catalyst Control Center)
  • OpenGL版本:4.2.11762兼容性配置文件上下文(来自AMD Catalyst Control Center)
  • glxinfo:
  • 服务器glx版本字符串:1.4
  • 客户端glx版本字符串:1.4
  • GLX版本:1.4
  • OpenGL版本字符串:4.2.11762兼容性配置文件上下文
  • OpenGL着色语言版本字符串:4.20
  • 服务器glx供应商字符串:ATI
  • 客户端glx供应商字符串:ATI

在使用与Linux中相同的图形卡的Windows中,也会发生此问题,即

  • Windows 8
  • 64位
  • 在ATI Technologies Inc.的AMD Radeon HD 7670M上运行。
  • 支持OpenGL 4.2.11762版兼容性配置文件上下文

AMD的Linux驱动程序具有新版本13.12(我正在使用13.4)。 如果有一段时间,我会尝试一下,因为上次安装并不容易。

我还在非官方的AMD Bugzilla上记录了问题984 但也许它已在13.12中修复。


但是,该程序可以运行(在不使用空缓冲区且没有空缓冲区的情况下)

  • Windows 7专业版
  • 64位
  • NVIDIA GeForce GT 520M(驱动程序日期:2013/10/15,驱动程序版本:9.18.13.3158)

继续

  • Windows 8
  • 64位
  • 在Intel的Intel®HD Graphics 4000上运行,
  • OpenGL版本4.0.0-内部版本9.17.10.2849

不,不管您相信与否, glDrawArrays (...)与绑定顶点缓冲区无关。 顶点缓冲区绑定仅在您设置顶点指针时才重要,因为它定义了您传递的指针所相对的地址空间。 从这一点来看,绑定的VBO无关紧要。 顺便说一句,如果你运行在严格执行GLSL它会警告这个片段着色器/拒绝没有因为工作#version它应该承担的片段着色器对GLSL 1.10规范的书面指令,不支持out阶段变量(您需要gl_FragData [0]代替)。

或像在顶点着色器中那样简单地添加#version 420 core ...版本指令实际上比您想象的要重要,尤其是因为在缺少它的情况下,不同厂商之间的行为存在很大差异。 这样做可能无法解决您的问题,但仍然是您应该解决的问题。

至于删除VAO的问题,这是可以预料的。 在核心OpenGL 3.2+上下文中,必须具有非零VAO绑定才能使glDrawArrays (...)正常工作。 实际上,VAO成为顶点绘制命令的上下文。 没有界限,您就没有上下文可操作。

请记住,顶点着色器只能操纵现有的顶点。 它无法创建它们。 即使在着色器中对该位置进行了硬编码,您仍然必须将其进行某种转换。

否,这似乎是AMD Radeon HD 7600M系列(13.4)驱动程序中的错误

我安装了最新的AMD驱动程序 ,它在Windows和Linux中均解决了该问题。

Linux:安装了amd-catalyst-13.12-linux-x86.x86_64.zip

Windows:安装了amd_catalyst_13.11_mobility_betav9.5.exe


要在Linux上重新安装AMD驱动程序,我先卸载AMD安装(amd-catalyst-previous-version.run --uninstall),删除所有包含名称fglrx的软件包(使用aptitude),将符号链接调整为/ usr / lib64(请参见下文),然后运行新的amd-catalyst-13.12-linux-x86.x86_64.run。

我碰到了此页面AMD 13.1 64位驱动程序和libGL.so.1错误该错误说明了AMD安装程序将libGL.so文件放在何处

安装程序会将lib文件放在/ usr / lib64中。 但是,如果有Ubuntu,则64位库位于/ usr / lib中。 我做了以下事情来解决我的问题。

卸载驱动程序sudo ./amd-driver-installer-catalyst-13.1-legacy-linux-x86.x86_64.run --uninstall

删除/ usr / lib64文件夹sudo rm -Rf / usr / lib64

创建一个指向/ lib / usr的符号链接/ usr / lib64 sudo ln -s / usr / lib / usr / lib64

再次安装驱动程序sudo ./amd-driver-installer-catalyst-13.1-legacy-linux-x86.x86_64.run --force

重新启动sudo重新启动

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM