《OpenGL超级圣经第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)被移除(或像上面那样使用)时,三角形也不会显示。只有带有(空的)VBO和VAO时才会绘制三角形。
移除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);
}
操作系统详细信息:
- Linux版本:3.2.0-4-amd64
- 发行版: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 Series(来自AMD Catalyst Control Center)
- OpenGL版本: 4.2.11762 Compatibility Profile Context(来自AMD Catalyst Control Center)
- glxinfo:
- server glx version string: 1.4
- client glx version string: 1.4
- GLX version: 1.4
- OpenGL version string: 4.2.11762 Compatibility Profile Context
- OpenGL shading language version string: 4.20
- server glx vendor string: ATI
- client glx vendor string: ATI
在Windows上,使用与Linux相同的显卡时也会出现问题,即:
- Windows 8
- 64位
- 运行在一个来自ATI Technologies Inc.的AMD Radeon HD 7670M上。
- 支持OpenGL版本4.2.11762 Compatibility Profile Context
AMD有一个新的Linux驱动程序版本13.12(我正在使用13.4)。当我有时间时,我会尝试安装它,因为上次的安装并不容易。
我还记录了Unofficial AMD Bugzilla上的问题984。但也许在13.12中已经修复了。
然而,该程序在以下系统上运行正常(无论是否使用空缓冲区):
- Windows 7 Pro
- 64位
- NVIDIA GeForce GT 520M(驱动程序日期:2013/10/15,驱动程序版本:9.18.13.3158)
和
- Windows 8
- 64位
- 运行在Intel(R) HD Graphics 4000下
- OpenGL版本4.0.0 - Build 9.17.10.2849