简体   繁体   English

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

[英]First triangle does not render after using GLSL-shaders

I'm currently learning OpenGL (and GLSL) from this tutorial . 我目前正在学习本教程中的 OpenGL(和GLSL)。 So far I made it to Tutorial 2: The First Triangle. 到目前为止,我已经完成了教程2:第一个三角形。 My code is a bit different since I'm more comfortable programming C, instead of the more common C++. 我的代码有点不同,因为我更喜欢编程C,而不是更常见的C ++。 Also, I used glfw3 to open my window, where the tutorial uses glfw, I believe. 此外,我使用glfw3打开我的窗口,我相信教程使用glfw。 As for now I've been able to write everything in C, and everything worked til the point where I used my first shaders. 至于现在,我已经能够用C编写所有内容,并且所有内容都工作到我使用第一个着色器的位置。 Whenever i use them, my triangle wont render. 每当我使用它们时,我的三角形都不会渲染。 I'm on a Mac and I haven't had the time to upgrade to OSX 10.9 (Mavericks) and therefore I'm forced to use OpenGL 3.2 and GLSL 1.2. 我在Mac上,我没有时间升级到OSX 10.9(小牛队),因此我不得不使用OpenGL 3.2和GLSL 1.2。

tl;dr: problem: My triangle will not render whenever I use the shaders. tl; dr:问题:每当我使用着色器时,我的三角形都不会渲染。

Here's my code: 这是我的代码:

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;
}

And here is my VertexShader: 这是我的VertexShader:

#version 120
vec3 vertexPosition_modelspace;

void main() {
    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;
}

My FragmentShader: 我的FragmentShader:

#version 120
vec3 color;

void main() {
    color = vec3(1, 0, 0);
}

I think it might have something to do with shadersfiles, I think I might have translated them wrong from the tutorial (he uses GLSL 3.3). 我认为它可能与shadersfiles有关,我想我可能从教程中将它们翻译错了(他使用GLSL 3.3)。

There are two main things that are wrong with your shaders and the crux of the problem boils down to how you are declaring the variables intended for shader input and output. 您的着色器有两个主要问题,问题的症结归结为如何声明用于着色器输入和输出的变量。

In your vertex shader, you have an input: vec3 vertexPosition_modelspace 在顶点着色器中,您有一个输入: vec3 vertexPosition_modelspace

  • Using GLSL 1.20 syntax this should be attribute vec3 vertexPosition_modelspace . 使用GLSL 1.20语法,这应该是attribute vec3 vertexPosition_modelspace

In your fragment shader you have an output: vec3 color (which would be out vec3 color in a GLSL 3.30 tutorial) 在你的片段着色器中你有一个输出: vec3 color (在GLSL 3.30教程中它将是out vec3 color

  • You cannot declare arbitrary variables as fragment shader outputs in GLSL 1.20, you have to use gl_FragColor or if you want to output to a specific draw buffer: gl_FragData [n] . 您不能在GLSL 1.20中将任意变量声明为片段着色器输出,您必须使用gl_FragColor或者如果要输出到特定的绘制缓冲区: gl_FragData [n]

    Side note: Never mix and match the two. 旁注:永远不要混淆和匹配两者。


Corrected Vertex Shader: 修正了顶点着色器:

 #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;
 }

Corrected Fragment Shader: 修正片段着色器:

 #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);
 }

On a final note, you have to match the attribute binding location to your attribute pointer location. 最后,您必须将属性绑定位置与属性指针位置相匹配。 Since GLSL 1.20 does not support layout qualifiers the best way to do this would be to add an additional line of code to your program: 由于GLSL 1.20不支持layout限定符,因此最好的方法是在程序中添加一行代码:

glBindAttribLocation (programID, 0, "vertexPosition_modelspace");

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

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