首页 文章

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

提问于
浏览
1

Update 这是通过安装最新的显卡驱动程序(AMD Radeon HD 7600M系列)来解决的 . 见答案 .

OpenGL SuperBible第6版(适用于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似乎没有什么区别 .

另请注意,顶点着色器没有输入 .

发生了什么事?

  • 编译器/图形卡认为顶点着色器什么都不做并删除它?我觉得这是显卡(驱动程序) .

  • 这是OpenGL的预期还是因为显卡?

  • 我对缓冲区,VAO和着色器的理解缺乏什么?


其他可能有用的信息

  • GLEW 1.10.0

  • GLFW 3.0.3

片段着色器:

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

OS详细信息:

  • Linux:3.2.0-4-amd64

  • Distro:Debian 7.3 Wheezy

  • uname -m:x86_64

编译器细节

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

OpenGL细节:

  • OpenGL提供商: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:

  • server glx version string:1.4

  • 客户端glx版本字符串:1.4

  • GLX版本:1.4

  • OpenGL版本字符串:4.2.11762兼容性配置文件上下文

  • OpenGL着色语言版本字符串:4.20

  • server glx供应商字符串:ATI

  • 客户端glx供应商字符串:ATI


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

  • Windows 8

  • 64位

  • 在ATI Technologies Inc.的AMD Radeon HD 7670M上运行

  • OpenGL版本4.2.11762支持兼容性配置文件上下文

AMD有一个新版本13.12的Linux驱动程序(我使用的是13.4) . 我有空的时候会尝试一下,因为上次安装并不容易 .

我也记录了issue 984 on Unofficial AMD Bugzilla . 但也许它在13.12修正了 .


但是,该程序可以正常运行(两者都不使用空缓冲区和空缓冲区)

  • Windows 7专业版

  • 64位

  • NVIDIA GeForce GT 520M(驱动程序日期:2013/10/15,驱动程序版本:9.18.13.3158)

并且

  • Windows 8

  • 64位

  • 在英特尔的英特尔(R)HD Graphics 4000上运行,

  • OpenGL 4.0.0版 - Build 9.17.10.2849

3 回答

  • 2

    不,信不信由 glDrawArrays (...) 与哪个顶点缓冲区绑定无关 . 顶点缓冲区绑定仅在设置顶点指针时很重要,因为它定义了您传递的指针相对于的地址空间 . 从那时起,绑定的VBO就无关紧要了 . By the way, 如果在严格的GLSL实现上运行此片段着色器,它将警告/拒绝工作,因为没有 #version 指令,它应该假设片段着色器是针对GLSL 1.10规范编写的,它不支持 out 阶段变量(你需要 gl_FragData [0] 而不是) .

    或者,简单地在顶点着色器中添加 #version 420 core ...版本指令实际上比你想象的更重要,特别是因为在它缺席时发生的行为在供应商之间变化很大 . 这样做可能无法解决您的问题,但它仍然是您应该解决的问题 .

    至于移除VAO的问题,这是可以预料的 . 在核心OpenGL 3.2上下文中,您必须具有非零VAO绑定才能使 glDrawArrays (...) 工作 . 实际上,VAO成为顶点绘制命令的上下文 . 如果没有一个绑定,你就无法操作它们 .

  • 0

    请记住,顶点着色器只能操纵现有顶点 . 它无法创建它们 . 即使位置在着色器中是硬编码的,您仍然需要为它进行转换 .

  • 0

    不,看起来这是AMD Radeon HD 7600M系列驱动程序中的一个错误(13.4)

    我安装了latest AMD driver,它解决了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 bit drivers and the libGL.so.1 error,它解释了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创建符号链接/ usr / lib64指向/ lib / usr sudo ln -s / usr / lib / usr / lib64再次安装驱动程序sudo ./amd-driver-installer-catalyst-13.1-legacy-linux-x86.x86_64.run --force重启sudo重启

相关问题