使用GLSL着色器后,第一个三角形不会渲染

时间:2013-12-07 20:44:59

标签: opengl glsl

我目前正在学习这个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)。

1 个答案:

答案 0 :(得分:2)

您的着色器有两个主要问题,问题的症结归结为您如何声明用于着色器输入和输出的变量。

在您的顶点着色器中,您有一个输入: vec3 vertexPosition_modelspace

  • 使用GLSL 1.20语法,这应该是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");