用两个着色器程序打开两个不同的三角形

时间:2018-03-21 18:18:52

标签: c++ visual-studio-2010 opengl glfw

我想创建2个不同颜色的三角形,当我按下" Tab"时,它们会变为线框模式。我的问题是我有两个VBO和两个着色器程序,但它只编译一个三角形

    #include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <iostream>

bool flag;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

const char* vertex_shader = 
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
"     gl_Position = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";


const char* fragment_shader = 
"#version 110 \n"
"void main (void) \n"
"{ \n"
"     gl_FragColor = vec4(0.7,0.3,0.3, 1.0); \n"
"} \n";

const char* vertex_shader1 = 
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
"     gl_Position1 = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";


const char* fragment_shader1 = 
"#version 110 \n"
"void main (void) \n"
"{ \n"
"     gl_FragColor1 = vec4(0.4,0.7,0.3, 1.0); \n"
"} \n";


int main()
{
    //Initialize GLFW
    if (!glfwInit()) //if GLFW is not initialized correctly, exit
    {
        std::cout << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    //Create the window
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
    if (window == NULL) //if the window was not created correctly, exit
    { 
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    //Specify OpenGL version
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

    //Make the context that was created the current one
    glfwMakeContextCurrent(window);

    //Initialize GLEW
    if (glewInit() != GLEW_OK) //if GLEW was not initialized correctly, exit
    { 
        std::cout << "Failed to initialize GLEW" << std::endl;
        glfwTerminate();
        return -1;
    }  

    //Set the viewport size changing function
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 



    //Rectangle vertices, to uncomment select the area and press Ctr+K,Ctr+U
    float vertices[] = 
    { 
        // first triangle 
        0.55f, 0.5f, 0.0f,     // top right 
        0.55f, -0.5f, 0.0f,   // bottom right
        -0.45f, 0.5f, 0.0f,  // top left 

    }; 

    float vertices1[] = 
    { 

        // second triangle 
        0.45f, -0.5f, 0.0f,   // bottom right 
        -0.55f, -0.5f, 0.0f, // bottom left
        -0.55f, 0.5f, 0.0f  // top left 
    }; 


    //Create the triangle VBO
    GLuint triangle_vbo;
    glGenBuffers(1, &triangle_vbo); //generate a unique buffer ID 
    glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO to the context
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//copy user-defined data into the currently bound buffer
    glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the VBO

    //Create a vertex shader object
    GLuint vertexShader; 
    vertexShader = glCreateShader(GL_VERTEX_SHADER); //ID of the shader object
    glShaderSource(vertexShader, 1, &vertex_shader, NULL); //attach the shader source code to the shader object
    glCompileShader(vertexShader);//compile the shader

    //Create a fragment shader object
    GLuint fragmentShader;
    fragmentShader  = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
    glCompileShader(fragmentShader);

    //Create a shader program object
    GLuint shaderProgram; 
    shaderProgram = glCreateProgram(); //create the program ID
    glAttachShader(shaderProgram, vertexShader); //attach the shaders to the program
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram); // link the program

    //Delete the vertex andd fragment shader objects
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    //Create the triangle VBO
    GLuint triangle_vbo1;
    glGenBuffers(1, &triangle_vbo1); //generate a unique buffer ID 
    glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1); //bind the VBO to the context
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);//copy user-defined data into the currently bound buffer
    glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the VBO

    //Create a vertex shader object
    GLuint vertexShader1; 
    vertexShader1 = glCreateShader(GL_VERTEX_SHADER); //ID of the shader object
    glShaderSource(vertexShader1, 1, &vertex_shader1, NULL); //attach the shader source code to the shader object
    glCompileShader(vertexShader1);//compile the shader

    //Create a fragment shader object
    GLuint fragmentShader1;
    fragmentShader1  = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader1, 1, &fragment_shader1, NULL);
    glCompileShader(fragmentShader1);

    //Create a shader program object
    GLuint shaderProgram1; 
    shaderProgram1 = glCreateProgram(); //create the program ID
    glAttachShader(shaderProgram1, vertexShader1); //attach the shaders to the program
    glAttachShader(shaderProgram1, fragmentShader1);
    glLinkProgram(shaderProgram1); // link the program

    //Delete the vertex andd fragment shader objects
    glDeleteShader(vertexShader1);
    glDeleteShader(fragmentShader1);


    //Rendering loop
    while(!glfwWindowShouldClose(window))
    {
        //Process input
        processInput(window);

        //Clear the buffers
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //dark green
        //glClearColor(0.5f, 0.0f, 0.0f, 1.0f); //maroon
        glClear(GL_COLOR_BUFFER_BIT);

            if(flag==true)
{
                glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
            }
            else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


        //Render objects...
        glUseProgram(shaderProgram); //use a shader program

        glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO

        //tell OpenGL how to read and assign the VBO to the attribute
        GLint in_pos = glGetAttribLocation(shaderProgram, "in_position");
        glVertexAttribPointer(in_pos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
        glEnableVertexAttribArray(in_pos); 

        glUseProgram(shaderProgram);
        glUseProgram(shaderProgram1);

        glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1);

        GLint in_pos1 = glGetAttribLocation(shaderProgram1, "in_position");
        glVertexAttribPointer(in_pos1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
        glEnableVertexAttribArray(in_pos1);

        glDrawArrays(GL_TRIANGLES, 0, 6); //draw the triangle


        //Swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        glfwSwapBuffers(window);
        glfwPollEvents();    
    }

    //Terminate GLFW before exit
    glfwTerminate();
    return 0;
}


//Viewport size changing function
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}  

//Input
void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    if(glfwGetKey(window, GLFW_KEY_TAB) == GLFW_PRESS)
        flag=true;
    else flag=false;
}

Tab键切换到线框模式,因为我长按“&#34; Tab&#34;”。我想只需点击一下即可更改,再次点击更改为默认

1 个答案:

答案 0 :(得分:1)

第二个顶点着色器和片段着色器将无法编译,因为gl_Position1gl_FragColor1不是有效的输出变量。您必须使用gl_Positiongl_FragColor。请参阅Vertex ShaderFragment Shader

const char* vertex_shader1 = 
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
"     gl_Position = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";

const char* fragment_shader1 = 
"#version 110 \n"
"void main (void) \n"
"{ \n"
"     gl_FragColor = vec4(0.4,0.7,0.3, 1.0); \n"
"} \n";

我建议使用glGetShaderiv来验证着色器代码是否已成功编译。

e.g。

GLint status;
glGetShaderiv(vertex_shader1, GL_COMPILE_STATUS, &status);

通过参数GL_LINK_STATUS调用glGetProgramiv,检查程序是否成功链接。


每个3个顶点有2个顶点缓冲区,因此您必须调用glDrawArrays(GL_TRIANGLES, 0, 3);两次,而不是一次glDrawArrays(GL_TRIANGLES, 0, 6);
绑定缓冲区,定义并启用通用顶点属性数据数组,然后绘制三角形:

glUseProgram(shaderProgram);

glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO
GLint in_pos = glGetAttribLocation(shaderProgram, "in_position");
glVertexAttribPointer(in_pos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos); 
glDrawArrays(GL_TRIANGLES, 0, 3); //draw the 1st triangle

glUseProgram(shaderProgram1);

glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1);
GLint in_pos1 = glGetAttribLocation(shaderProgram1, "in_position");
glVertexAttribPointer(in_pos1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos1);
glDrawArrays(GL_TRIANGLES, 0, 3); //draw the 2nd triangle

查看预览: enter image description here