OpenGL.Tutorial03_Matrices_测试
1、
2、
// ZC: 工程-->右键-->属性--> 配置属性: // ZC: C/C++ -->常规-->附加包含目录,里面添加: // ZC: E:\OpenGL_something\glfw-3.2.1.bin.WIN32\include // ZC: E:\OpenGL_something\glm-0.9.8.5 // ZC: E:\OpenGL_something\glew-2.1.0\include // ZC: 链接器-->输入-->附加依赖项,里面添加: // ZC: E:\OpenGL_something\glfw-3.2.1.bin.WIN32\lib-vc2010\glfw3.lib 这个应该是静态链接的lib(动态的貌似是glfw3dll.lib[ZC:我是看文件大小判断的...]) // ZC: E:\OpenGL_something\glew-2.1.0\lib\Release\Win32\glew32.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_something\glew-2.1.0\bin\Release\Win32\glew32.dll"复制到项目的"E:\Project_VS10\OpenGL_Console_zz\Test\Test"中 // 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\n" ); 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.\n" ); getchar(); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); 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\n", Model[0].x, Model[0].y, Model[0].z, Model[0].w); printf("%f, %f, %f, %f\n", Model[1].x, Model[1].y, Model[1].z, Model[1].w); printf("%f, %f, %f, %f\n", Model[2].x, Model[2].y, Model[2].z, Model[2].w); printf("%f, %f, %f, %f\n", Model[3].x, Model[3].y, Model[3].z, Model[3].w); printf("\n"); // 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\n", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w); printf("%f, %f, %f, %f\n", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w); printf("%f, %f, %f, %f\n", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w); printf("%f, %f, %f, %f\n", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w); printf("\n"); 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\n", Model[0].x, Model[0].y, Model[0].z, Model[0].w); printf("%f, %f, %f, %f\n", Model[1].x, Model[1].y, Model[1].z, Model[1].w); printf("%f, %f, %f, %f\n", Model[2].x, Model[2].y, Model[2].z, Model[2].w); printf("%f, %f, %f, %f\n", Model[3].x, Model[3].y, Model[3].z, Model[3].w); printf("\n"); // 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\n", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w); printf("%f, %f, %f, %f\n", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w); printf("%f, %f, %f, %f\n", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w); printf("%f, %f, %f, %f\n", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w); printf("\n"); 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\n", Model[0].x, Model[0].y, Model[0].z, Model[0].w); printf("%f, %f, %f, %f\n", Model[1].x, Model[1].y, Model[1].z, Model[1].w); printf("%f, %f, %f, %f\n", Model[2].x, Model[2].y, Model[2].z, Model[2].w); printf("%f, %f, %f, %f\n", Model[3].x, Model[3].y, Model[3].z, Model[3].w); printf("\n"); // 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\n", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w); printf("%f, %f, %f, %f\n", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w); printf("%f, %f, %f, %f\n", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w); printf("%f, %f, %f, %f\n", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w); printf("\n");//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\n", Model[0].x, Model[0].y, Model[0].z, Model[0].w); printf("%f, %f, %f, %f\n", Model[1].x, Model[1].y, Model[1].z, Model[1].w); printf("%f, %f, %f, %f\n", Model[2].x, Model[2].y, Model[2].z, Model[2].w); printf("%f, %f, %f, %f\n", Model[3].x, Model[3].y, Model[3].z, Model[3].w); printf("\n"); // 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\n", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w); printf("%f, %f, %f, %f\n", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w); printf("%f, %f, %f, %f\n", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w); printf("%f, %f, %f, %f\n", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w); printf("\n");
现象:
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\n", Model[0].x, Model[0].y, Model[0].z, Model[0].w); printf("%f, %f, %f, %f\n", Model[1].x, Model[1].y, Model[1].z, Model[1].w); printf("%f, %f, %f, %f\n", Model[2].x, Model[2].y, Model[2].z, Model[2].w); printf("%f, %f, %f, %f\n", Model[3].x, Model[3].y, Model[3].z, Model[3].w); printf("\n"); // 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\n", MVP[0].x, MVP[0].y, MVP[0].z, MVP[0].w); printf("%f, %f, %f, %f\n", MVP[1].x, MVP[1].y, MVP[1].z, MVP[1].w); printf("%f, %f, %f, %f\n", MVP[2].x, MVP[2].y, MVP[2].z, MVP[2].w); printf("%f, %f, %f, %f\n", MVP[3].x, MVP[3].y, MVP[3].z, MVP[3].w); printf("\n");
现象:
ZC:可以看到,虽然 矩阵Model 的信息不同,但是 最后的 矩阵MVP 的信息是一样的,∴ 肉眼看起来 效果一样...
4、尝试 C++中计算好位置,直接传入 GLSL(不要再在 GLSL中去做乘法计算)
ZC:貌似 这个例子中使用的 "glDrawArrays(GL_TRIANGLES, 0, 3);"的方式,暂时不支持实现 这个尝试,看后面会不会 学习到别的方式,或者 后面水平高了再来尝试吧...
5、