我目前正在学习这个tutorial的OpenGL(和GLSL)。到目前为止,我已经完成了教程2:第一个三角形。我的代码有点不同,因为我更喜欢编程C,而不是更常见的C ++。此外,我使用glfw3打开我的窗口,我相信教程使用glfw。至于现在,我已经能够用C编写所有内容,并且所有内容都工作到我使用第一个着色器的位置。每当我使用它们时,我的三角形都不会渲染。我在Mac上并没有时间升级到OSX 10.9(小牛队),因此我被迫使用OpenGL 3.2和GLSL 1.2。
tl; dr:问题:每当我使用着色器时,我的三角形都不会渲染。
这是我的代码:
int main(void) {
GLFWwindow* window;
/* Initialize the library */
if(!glfwInit()) {
return -1;
}
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Tutorial 1", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Initialize GLEW */
glewExperimental = GL_TRUE; // Needed in core profile
if(glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
/* Triangle's vertices */
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders("VertexShader.txt", "FragmentShader.txt");
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window)) {
/* Render here */
// 1rst attribute buffer : vertices
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Use our shader
glUseProgram(programID);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
这是我的VertexShader:
#version 120
vec3 vertexPosition_modelspace;
void main() {
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
My FragmentShader:
#version 120
vec3 color;
void main() {
color = vec3(1, 0, 0);
}
我认为它可能与shadersfiles有关,我想我可能从教程中错误地翻译它们(他使用GLSL 3.3)。
答案 0 :(得分:2)
您的着色器有两个主要问题,问题的症结归结为您如何声明用于着色器输入和输出的变量。
在您的顶点着色器中,您有一个输入: vec3 vertexPosition_modelspace
attribute vec3 vertexPosition_modelspace
。在片段着色器中,您有一个输出: vec3 color
(在GLSL 3.30教程中为out vec3 color
)
您无法在GLSL 1.20中将任意变量声明为片段着色器输出,您必须使用gl_FragColor
或者如果要输出到特定的绘制缓冲区:gl_FragData [n]
。
旁注:永远不要混淆和匹配两者。
#version 120
attribute vec3 vertexPosition_modelspace;
//in vec3 vertexPosition_modelspace;
//^^ It was probably written this way in the GLSL 3.30 tutorial
void main() {
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
#version 120
//out vec3 color; -- DO NOT DO THIS IN GLSL 1.20
void main() {
//color = vec3(1, 0, 0);
gl_FragColor = vec4 (1.0, 0.0, 0.0, 0.0);
}
最后,您必须将属性绑定位置与属性指针位置相匹配。由于GLSL 1.20不支持layout
限定符,因此最好的方法是在程序中添加一行代码:
glBindAttribLocation (programID, 0, "vertexPosition_modelspace");