如何将模型矩阵传递到着色器并使三角形旋转

时间:2016-02-27 18:17:55

标签: opengl glm-math

我正在使用OpenGL和GLM库,我尝试将模型矩阵传递给着色器并使三角形旋转。我已经获得了基本代码并在顶点着色器中获取变量的ID。虽然我不知道如何设置它们。

    #include <GL/GLEW.h>
    #include <GL/freeglut.h>
    #include <stdio.h>

    #include <glm/vec3.hpp> // glm::vec3
    #include <glm/vec4.hpp> // glm::vec4
    #include <glm/mat4x4.hpp> // glm::mat4
    #include <glm/gtc/matrix_transform.hpp> // glm::translate/rotate/scale/etc
    #include <glm/gtc/type_ptr.hpp> // glm::value_ptr



    #define BUFFER_OFFSET(i) ((char *)NULL + (i))

    glm::mat4 M;
    glm::mat4 V;
    glm::mat4 P;
    glm::mat4 trans;
    glm::mat4 rot;
    float rotAmount = 0.0f;

    GLint umM;
    GLint umV;
    GLint umP;

    void func(GLuint LocationMVP, float Translate, glm::vec2 const & Rotate)
    {
        glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.f);
        glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate));
        glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f));
        glm::mat4 View = glm::rotate(ViewRotateX, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f));
        glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
        glm::mat4 MVP = Projection * View * Model;
        glUniformMatrix4fv(LocationMVP, 1, GL_FALSE, glm::value_ptr(MVP));
    }

    void render() 
    {

        trans = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, -1));
        rot = glm::rotate(glm::mat4(1.0f), rotAmount, glm::vec3(0, 1, 0));
        M = trans*rot;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, NULL);
        glutSwapBuffers();
        glutPostRedisplay();
    }

    void specialKeys(int key, int x, int y) {
        switch (key) {
        case GLUT_KEY_UP: printf("The UP key was pressed\n"); break;
        case GLUT_KEY_DOWN: printf("The DOWN key was pressed\n"); break;
        }
    }

    void mousePressed(int button, int state, int x, int y) 
    {
        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) {
            //printf("Mouse clicked at %d %d\n", x, y);
        }
    }

    void mouseMoved(int x, int y) {
        //printf("Mouse moved at %d %d\n", x, y);
    }

    void mouseDragged(int x, int y) {
        //printf("Mouse dragged at %d %d\n", x, y);
    }



    int main(int argc, char** argv) 
    {


        glutInit(&argc, argv);              // Initialize GLUT
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); // Set up buffers
        glutInitWindowPosition(200, 200);   // Optional: position the upper-left of the window
        glutInitWindowSize(800, 600);       // Set the window size
        glutCreateWindow("Lab 5");          // Create the window and give it a title

        glewInit();                         // Ask the driver for all the OpenGL functions

        // Some callback functions
        glutDisplayFunc(render);            // Use the render function to draw
        glutSpecialFunc(specialKeys);       // Use the specialKeys function for Up/Down/Left/Right keys
        glutMouseFunc(mousePressed);        // Use for mouse clicks
        glutMotionFunc(mouseDragged);       // Use for mouse dragging
        glutPassiveMotionFunc(mouseMoved); // Use for mouse moving

    #pragma region SHADER_STUFF
        // =========  SHADER STUFF  ===============
        const GLchar* vertexShaderCode = "#version 150\n\
                                in vec4 vPosition;\n\
                                in vec4 vColor;\n\
                                out vec4 color;\n\
                                void main () {\n\
                                    color = vColor;\n\
                                    \tgl_Position = vPosition;\n\
                                 }\n";

const GLchar* fragmentShaderCode = "#version 150\n\n\
                                    out vec4 fColor;\n\
                                    in vec4 color;\n\
                                    void main () {\
                                       fColor = color;\n\
                                    }";
        // Vertex Shader 
        GLint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShaderID, 1, &vertexShaderCode, NULL);
        glCompileShader(vertexShaderID);
        GLint compiled = -10;
        glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &compiled);
        printf("Vertex compile status %d!\n", compiled);
        printf("Vertex shader ID is %d\n", vertexShaderID);

        // Fragment Shader 
        GLint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShaderID, 1, &fragmentShaderCode, NULL);
        glCompileShader(fragmentShaderID);
        GLint compiled2 = -19;
     glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &compiled2);

        printf("Fragment compile status %d!\n", compiled2);
        printf("Fragment shader ID is %d\n", fragmentShaderID);

        // Make the program
        GLint shaderProgram;
        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShaderID);
        glAttachShader(shaderProgram, fragmentShaderID);
        glLinkProgram(shaderProgram);
        GLint linkedStatus = 14;
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkedStatus);
        printf("Link status is %d\n", linkedStatus);
        printf("Shader program ID is %d\n", shaderProgram);

        glUseProgram(shaderProgram);
    #pragma endregion SHADER_STUFF

        // Positions
        GLfloat vertices[] = { -0.5f, -0.5f, 0.0f,  // 0
            -0.25f, 0.0f, 0.0f, // 1
            0.0f, 0.5f, 0.0f, // 2
            0.0f, -0.5f, 0.0f, // 3
            0.25f, 0.0f, 0.0f, // 4
            0.5f, -0.5f, 0.0f, // 5
        };

        // Color information
        GLfloat colors[] = { 1.0f, 0.73f, 0.0f, 1.0f, //0
            1.0f, 1.0f, 0.0f, 1.0f, // 1
            1.0f, 1.0f, 0.0f, 1.0f, // 2
            1.0f, 0.73f, 0.0f, 1.0f, // 3
            1.0f, 0.65f, 0.0f, 1.0f, // 4
            1.0f, 0.65f, 0.0f, 1.0f, // 5
        };

        // Connect the dots
        GLuint index_buffer[] = { 0, 3, 1, 2, 1, 4, 4, 3, 5 };

        int numVertices = 6;

        GLuint vao;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao); // Use the Vertex Array Object we created above

        GLuint vbo;     // The Vertex Buffer Object ID
        glGenBuffers(1, &vbo);  // Ask the GPU driver for a buffer array. "vbo" now has the ID
        glBindBuffer(GL_ARRAY_BUFFER, vbo); // Make this buffer the active one for subsequent operations (below)

        // Specify how big the buffer is, but don't pass the data yet (see NULL).  We *could* have, but I wanted to show glBufferSubData
        glBufferData(GL_ARRAY_BUFFER, numVertices * 7 * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
        // NOW we copy the data in as a separate step. There is an "offset" of 0 - meaning the beginning of the buffer. 
        // We specify the size of the data we want to copy, followed by a pointer to the actual data
        glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * 3 * sizeof(GLfloat), vertices);
        glBufferSubData(GL_ARRAY_BUFFER, numVertices * 3 * sizeof(GLfloat), numVertices * 4 * sizeof(GLfloat), colors);

        // Figure out where vPosition is in our shader and get its ID
        GLuint loc = glGetAttribLocation(shaderProgram, "vPosition");
        GLuint loc2 = glGetAttribLocation(shaderProgram, "vColor");
        glEnableVertexAttribArray(loc);
    glEnableVertexAttribArray(loc2);

        printf("vPosition ID is %d\n", loc);
        printf("vColor ID is %d\n", loc2);

        // When it's time for vPosition to find information, we need to tell it where the data is (or how the data should be parsed)
        // Here, we're saying that "vPosition" (loc from above) should look for 3 GLfloats. The data isn't normalized or interlaced, 
        // and starts at index 0 (the beginning of the current buffer)
        glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glVertexAttribPointer(loc2, 4, GL_FLOAT, GL_FALSE, 0,         BUFFER_OFFSET(numVertices * 3 * sizeof(GLfloat)));


        GLuint index_vbo;
        // Ask the graphics card (driver) for another buffer – same as the old code
        glGenBuffers(1, &index_vbo);
        // We still want the VAO active to remember these settings
        glBindVertexArray(vao);
        // Here's where we tell the driver that it's an index buffer.  
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);
        // This time, we'll just go ahead and pass the data off to the buffer because
        // we're not packing multiple data sets into the buffer - only indices

        umM = glGetUniformLocation(shaderProgram, "mM"); // Find the mM variable
        umV = glGetUniformLocation(shaderProgram, "mV"); // Find the mV variable
        umP = glGetUniformLocation(shaderProgram, "mP"); // Find the mP variable

        if (umP != -1)
        {
    glUniformMatrix4fv(umP, 1, GL_FALSE, glm::value_ptr(P));
     }
        if (umV != -1)
        {
            glUniformMatrix4fv(umV, 1, GL_FALSE, glm::value_ptr(V));
        }

        glBufferData(GL_ELEMENT_ARRAY_BUFFER, 9*sizeof(GLuint), index_buffer, GL_STATIC_DRAW);

        P = glm::perspective(-60.0f, 1.3f, 0.1f, 1000.0f);
        V = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0));

        glm::mat4 T = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
        glm::mat4 Rx = glm::rotate(T, rotation_x, glm::vec3(1.0f, 0.0f, 0.0f));
        glm::mat4 Ry = glm::rotate(Rx, rotation_y, glm::vec3(0.0f, 1.0f, 0.0f));
        glm::mat4 M = glm::rotate(Ry, rotation_z, glm::vec3(0.0f, 0.0f, 1.0f));
        glm::mat4 MVP = P*V*M;

        glutMainLoop();                     // Start listening for events
    }

并且我的着色器文件就像

    #version 150
    in vec4 vPosition;
    uniform mat4 mM; // The matrix for the pose of the model
    uniform mat4 mV; // The matrix for the pose of the camera
    uniform mat4 mP; // The perspective matrix

    void main()
    {
        gl_Position = mP*mV*mM*vPosition;


    }

任何人都可以帮助我,或者教我如何设置它们吗?

0 个答案:

没有答案