OpenGL.Tutorial03_Matrices_测试

1、

2、

// ZC: 工程-->右键-->属性--> 配置属性:
// ZC:    C/C++ -->常规-->附加包含目录,里面添加:
// ZC:        E:OpenGL_somethingglfw-3.2.1.bin.WIN32include
// ZC:        E:OpenGL_somethingglm-0.9.8.5
// ZC:        E:OpenGL_somethingglew-2.1.0include
// ZC:    链接器-->输入-->附加依赖项,里面添加:
// ZC:        E:OpenGL_somethingglfw-3.2.1.bin.WIN32lib-vc2010glfw3.lib        这个应该是静态链接的lib(动态的貌似是glfw3dll.lib[ZC:我是看文件大小判断的...])
// ZC:        E:OpenGL_somethingglew-2.1.0libReleaseWin32glew32.lib
// ZC:        opengl32.lib
// ZC:        glu32.lib
// ZC:        kernel32.lib
// ZC:        user32.lib
// ZC:        gdi32.lib
// ZC:        winspool.lib
// ZC:        shell32.lib
// ZC:        ole32.lib
// ZC:        oleaut32.lib
// ZC:        uuid.lib
// ZC:        comdlg32.lib
// ZC:        advapi32.lib
// ZC: 关于使用glew32.lib还是glew32s.lib: 
// ZC:    看文件大小判断 静态链接的lib应该是glew32s.lib,但是我在编译的时候,发现无法定位函数grewInit(...)... 于是只能使用动态的glew32s.lib
// ZC:    于是还要将"E:OpenGL_somethingglew-2.1.0inReleaseWin32glew32.dll"复制到项目的"E:Project_VS10OpenGL_Console_zzTestTest"中


// Include standard headers
#include <stdio.h>
#include <stdlib.h>

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <GLFW/glfw3.h>
extern GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

#include <common/shader.hpp>

int mainTutorial03Matrices( void )
{
    // Initialise GLFW
    if( !glfwInit() )
    {
        fprintf( stderr, "Failed to initialize GLFW
" );
        getchar();
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL 

    // Open a window and create its OpenGL context
    /*window = glfwCreateWindow( 1024, 768, "Tutorial 03 - Matrices", NULL, NULL);*/
    window = glfwCreateWindow( 683, 384, "Tutorial 03 - Matrices", NULL, NULL);
    if( window == NULL ){
        fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.
" );
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLEW
    glewExperimental = true; // Needed for core profile
    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW
");
        getchar();
        glfwTerminate();
        return -1;
    }

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // Dark blue background
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Create and compile our GLSL program from the shaders
    GLuint programID = LoadShaders( "../Test/shaders/SimpleTransform_03.vertexshader", "../Test/shaders/SingleColor_03.fragmentshader" );

    // Get a handle for our "MVP" uniform
    GLuint MatrixID = glGetUniformLocation(programID, "MVP");

    // Projection matrix : 45?Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    //glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);
    glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);
    // Or, for an ortho camera :
    //glm::mat4 Projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.0f, 100.0f); // In world coordinates

    // Camera matrix
    //glm::mat4 View       = glm::lookAt(
    //                            glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
    //                            glm::vec3(0,0,0), // and looks at the origin
    //                            glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
    //                       );
    glm::mat4 View       = glm::lookAt(
        glm::vec3(0,0,10),// Camera is at (4,3,3), in World Space
        glm::vec3(0,0,0), // and looks at the origin
        glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
        );
    // ZC: 上面的参数的理解:
    // ZC:    第一个参数:摄像机所在的位置(世界坐标系)
    // ZC:    第二个参数:摄像机往哪个点看过去(摄像机往哪个点的方向看去)        (ZC: 这个应该是参与计算的)
    // ZC:    第三个参数:头的位置(这里的"头" 实际就是指"摄像机"):            (ZC: 这个稍微测试了一下,发现 应该就是指方向[即 其次坐标的"w"是0])
    // ZC:        (0,1,0):就是正常的人类头顶朝上的样子,
    // ZC:        (1,0,0):就是头往X轴正方向倒90°,
    // ZC:        (0,0,1):应该就是头朝Z轴正方向倒90°(也就是往后倒,稍微验证了一下,应该就是这样子的)

    // Model matrix : an identity matrix (model will be at the origin)
    glm::mat4 Model      = glm::mat4(1.0f);
    //glm::mat4 Model      = glm::mat4(
    //    2.0f, 0.0f, 0.0f, 0.0f,
    //    0.0f, 2.0f, 0.0f, 0.0f,
    //    0.0f, 0.0f, 2.0f, 0.0f,
    //    0.0f, 0.0f, 0.0f, 1.0f);
    printf("%f, %f, %f, %f
", Model[0].x, Model[0].y, Model[0].z, Model[0].w);
    printf("%f, %f, %f, %f
", Model[1].x, Model[1].y, Model[1].z, Model[1].w);
    printf("%f, %f, %f, %f
", Model[2].x, Model[2].y, Model[2].z, Model[2].w);
    printf("%f, %f, %f, %f
", Model[3].x, Model[3].y, Model[3].z, Model[3].w);
    printf("
");

    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    printf("%f, %f, %f, %f
", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w);
    printf("%f, %f, %f, %f
", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w);
    printf("%f, %f, %f, %f
", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w);
    printf("%f, %f, %f, %f
", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w);
    printf("
");

    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,
    };
    //static const GLfloat g_vertex_buffer_data[] = { 
    //    -2.0f, -2.0f, 0.0f,
    //    2.0f, -2.0f, 0.0f,
    //    0.0f,  2.0f, 0.0f,
    //};

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    do{

        // Clear the screen
        glClear( GL_COLOR_BUFFER_BIT );

        // Use our shader
        glUseProgram(programID);

        // Send our transformation to the currently bound shader, 
        // in the "MVP" uniform
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
            0,                  // attribute. 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
            );

        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

        glDisableVertexAttribArray(0);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0 );

    // Cleanup VBO and shader
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteProgram(programID);
    glDeleteVertexArrays(1, &VertexArrayID);

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}

3、改变中间的一段代码 用于测试:

 3.1、上面的代码执行的现象:

  

 3.2、放大2倍(方式1):

    // Model matrix : an identity matrix (model will be at the origin)
    //glm::mat4 Model      = glm::mat4(1.0f);  // ZC: 变化的是这里,把X/Y/Z坐标都扩大了2倍
    glm::mat4 Model      = glm::mat4(
        2.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 2.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 2.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);
    printf("%f, %f, %f, %f
", Model[0].x, Model[0].y, Model[0].z, Model[0].w);
    printf("%f, %f, %f, %f
", Model[1].x, Model[1].y, Model[1].z, Model[1].w);
    printf("%f, %f, %f, %f
", Model[2].x, Model[2].y, Model[2].z, Model[2].w);
    printf("%f, %f, %f, %f
", Model[3].x, Model[3].y, Model[3].z, Model[3].w);
    printf("
");

    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    printf("%f, %f, %f, %f
", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w);
    printf("%f, %f, %f, %f
", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w);
    printf("%f, %f, %f, %f
", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w);
    printf("%f, %f, %f, %f
", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w);
    printf("
");

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

 现象:

  

 3.3、放大2倍(方式2):

    // Model matrix : an identity matrix (model will be at the origin)
    glm::mat4 Model      = glm::mat4(1.0f);  // ZC: 这里没改变
    //glm::mat4 Model      = glm::mat4(
    //    2.0f, 0.0f, 0.0f, 0.0f,
    //    0.0f, 2.0f, 0.0f, 0.0f,
    //    0.0f, 0.0f, 2.0f, 0.0f,
    //    0.0f, 0.0f, 0.0f, 1.0f);
    printf("%f, %f, %f, %f
", Model[0].x, Model[0].y, Model[0].z, Model[0].w);
    printf("%f, %f, %f, %f
", Model[1].x, Model[1].y, Model[1].z, Model[1].w);
    printf("%f, %f, %f, %f
", Model[2].x, Model[2].y, Model[2].z, Model[2].w);
    printf("%f, %f, %f, %f
", Model[3].x, Model[3].y, Model[3].z, Model[3].w);
    printf("
");

    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    printf("%f, %f, %f, %f
", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w);
    printf("%f, %f, %f, %f
", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w);
    printf("%f, %f, %f, %f
", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w);
    printf("%f, %f, %f, %f
", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w);
    printf("
");//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,
    //};
    static const GLfloat g_vertex_buffer_data[] = { // ZC: 这里改变了,手动的将 三角形的3个点的坐标放大了
        -2.0f, -2.0f, 0.0f,
        2.0f, -2.0f, 0.0f,
        0.0f,  2.0f, 0.0f,
    };

 现象:

  

 3.4、测试:刚开始 放大 是使用的 “glm::mat4 Model = glm::mat4(2.0f);”,实际这是没有 放大效果的(视觉上 大小没变化),原因寻找:Model的矩阵信息为:

  2.0f  0.0f  0.0f  0.0f
  0.0f  2.0f  0.0f  0.0f
  0.0f  0.0f  2.0f  0.0f
  0.0f  0.0f  0.0f  2.0f

  ∵ 它把 X/Y/Z轴的数据放大了,但是 它的最后一行数据“0.0f 0.0f 0.0f 2.0f” 实现了类似这样的功能:把摄像机拉远了一倍距离。这个的数学解释 我暂时还不太明白,只是做了一个实验 验证了一下

  3.4.1、

    glm::mat4 View       = glm::lookAt(
        glm::vec3(0,0,10),// Camera is at (4,3,3), in World Space
        glm::vec3(0,0,0), // and looks at the origin
        glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
        );

    // Model matrix : an identity matrix (model will be at the origin)
    //glm::mat4 Model      = glm::mat4(1.0f);
    glm::mat4 Model      = glm::mat4(2.0f);  // ZC: 改了这里
    //glm::mat4 Model      = glm::mat4(
    //    2.0f, 0.0f, 0.0f, 0.0f,
    //    0.0f, 2.0f, 0.0f, 0.0f,
    //    0.0f, 0.0f, 2.0f, 0.0f,
    //    0.0f, 0.0f, 0.0f, 1.0f);
    printf("%f, %f, %f, %f
", Model[0].x, Model[0].y, Model[0].z, Model[0].w);
    printf("%f, %f, %f, %f
", Model[1].x, Model[1].y, Model[1].z, Model[1].w);
    printf("%f, %f, %f, %f
", Model[2].x, Model[2].y, Model[2].z, Model[2].w);
    printf("%f, %f, %f, %f
", Model[3].x, Model[3].y, Model[3].z, Model[3].w);
    printf("
");

    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    printf("%f, %f, %f, %f
", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w);
    printf("%f, %f, %f, %f
", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w);
    printf("%f, %f, %f, %f
", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w);
    printf("%f, %f, %f, %f
", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w);
    printf("
");

   现象:

  

  3.4.2、

    glm::mat4 View       = glm::lookAt(
        glm::vec3(0,0,20),// ZC: 这里,手动将摄像机 拉远了一倍距离
        glm::vec3(0,0,0), // and looks at the origin
        glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
        );

    // Model matrix : an identity matrix (model will be at the origin)
    //glm::mat4 Model      = glm::mat4(1.0f);
    //glm::mat4 Model      = glm::mat4(2.0f);
    glm::mat4 Model      = glm::mat4(  // ZC: 这里,将 X/Y/Z轴数据放大1倍
        2.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 2.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 2.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f);
    printf("%f, %f, %f, %f
", Model[0].x, Model[0].y, Model[0].z, Model[0].w);
    printf("%f, %f, %f, %f
", Model[1].x, Model[1].y, Model[1].z, Model[1].w);
    printf("%f, %f, %f, %f
", Model[2].x, Model[2].y, Model[2].z, Model[2].w);
    printf("%f, %f, %f, %f
", Model[3].x, Model[3].y, Model[3].z, Model[3].w);
    printf("
");

    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    printf("%f, %f, %f, %f
", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w);
    printf("%f, %f, %f, %f
", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w);
    printf("%f, %f, %f, %f
", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w);
    printf("%f, %f, %f, %f
", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w);
    printf("
");

  现象:

  

   ZC:可以看到,虽然 矩阵Model 的信息不同,但是 最后的 矩阵MVP 的信息是一样的,∴ 肉眼看起来 效果一样...

4、尝试 C++中计算好位置,直接传入 GLSL(不要再在 GLSL中去做乘法计算)

  ZC:貌似 这个例子中使用的 "glDrawArrays(GL_TRIANGLES, 0, 3);"的方式,暂时不支持实现 这个尝试,看后面会不会 学习到别的方式,或者 后面水平高了再来尝试吧...

5、

原文地址:https://www.cnblogs.com/cppskill/p/10622282.html