CP07:贴图
>>理解Element Buffer Object(EBO), 理解glDrawElements()
例如上图要绘制一个长方形,上一篇- OPENGL2 - 最后一章用的glDrawArrays(GL_QUADS,0 ,NPTS) 绘制。
此章绘制用glDrawElements().如上图,绘制可以为2个三角形,那就是绘制6个顶点。
// triangle indices static GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE };
第一种方法:直接绘制方法就是在main loop中:
glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , indices); // draw six verticles
第二种方法:
如果建立了EBO对象就不用这么绘制可以先创建 EBO:
glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0);
然后在main loop中写:
glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL); // draw six verticles
显然第一种简单。
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> using namespace std; const int NPTS = 4; static GLuint VBO,VAO,EBO; // load shader static LoadShader shader; // Texture static GLuint texture; void init(){ static const GLfloat verticles[NPTS][8] = { // positions // colors // texture coords {0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}, // top right {0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, // bottom right {-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, // bottom left {-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f} // top left }; GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); // Vertex Array Object glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // Vertex Buffer Object glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); // Create Element buffer object glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // position Attrib glVertexAttribPointer(0, // LOCATION 3, // vector is 3 length GL_FLOAT, // float type GL_FALSE, // not normalized 8 * sizeof(float), // stride (void*)0 ); // offset glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); // st Attrib glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) ); glEnableVertexAttribArray(2); //glGenTextures(1,&texture); glCreateTextures(GL_TEXTURE_2D, 1, &texture); // same as above method glBindTexture(GL_TEXTURE_2D, texture); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // same as above methods glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_REPEAT); glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // load imag int width,height,nchans; unsigned char *data = stbi_load("texture_02.jpg",&width, &height, &nchans, 0); cout << "WIDTH:" << width << "HEIGHT:" <<height <<endl; if(data){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateTextureMipmap(texture); } else{ cout << "Load texture error" <<endl; } stbi_image_free(data); } void display(){ static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f}; glClearBufferfv(GL_COLOR,0,black); //glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //glClear(GL_COLOR_BUFFER_BIT); //glBindTexture(GL_TEXTURE_2D, texture); glBindVertexArray(VAO); //glDrawArrays(GL_QUADS,0 ,NPTS); glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL); // draw six verticles } int main() { cout << sizeof(float) <<endl; glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
>> 两个贴图时候的情况:
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,texture2); GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1"); GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2"); glUniform1i(texture1_location,0); glUniform1i(texture2_location,1);
mask.png:
wendy.jpg:
OGL:
#version 450 core layout ( location = 0 ) in vec4 vPosition; // c++ pos layout ( location = 1 ) in vec4 vColor; // c++ attribute color layout ( location = 2 ) in vec2 vTexCoord; // c++ attribute st //out vec4 ourColor; // OUT TO OUR ->fragment //out vec2 ourTexCoord; // OUT TO OUR ->fragment out block{ vec4 ourColor; vec2 ourTexCoord; }; void main(){ gl_Position = vPosition; ourColor = vColor; ourTexCoord = vTexCoord; }
#version 450 core out vec4 fColor; // out to our fragment shader color //in vec4 ourColor; // from the vertex shader src //in vec2 ourTexCoord; in block{ vec4 ourColor; vec2 ourTexCoord; }; uniform sampler2D texture1; uniform sampler2D texture2; // Mask Texture void main(){ vec4 df = texture(texture1,ourTexCoord); vec4 mask = texture(texture2,ourTexCoord); fColor = mix( df , vec4(0,0.5,0.5,1), mask.a ); }
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> using namespace std; const int NPTS = 4; static GLuint VBO,VAO,EBO; // load shader static LoadShader shader; static GLuint texture1,texture2; void processInput(GLFWwindow *window); void init(){ static const GLfloat verticles[NPTS][8] = { // positions // colors // texture coords {0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}, // top right {0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, // bottom right {-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, // bottom left {-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f} // top left }; GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); // Vertex Array Object glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // Vertex Buffer Object glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); // Create Element buffer object glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // position Attrib glVertexAttribPointer(0, // LOCATION 3, // vector is 3 length GL_FLOAT, // float type GL_FALSE, // not normalized 8 * sizeof(float), // stride (void*)0 ); // offset glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); // st Attrib glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) ); glEnableVertexAttribArray(2); // ------------------ LOADING TEXTURE1 --------------------------------- // Texture //glGenTextures(1,&texture); glCreateTextures(GL_TEXTURE_2D, 1, &texture1); // same as above method glBindTexture(GL_TEXTURE_2D, texture1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // same as above methods //glTextureParameteri(texture1, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTextureParameteri(texture1, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTextureParameteri(texture1, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTextureParameteri(texture1, GL_TEXTURE_MAG_FILTER, GL_LINEAR); stbi_set_flip_vertically_on_load(true); int width,height,nchans; unsigned char *data = stbi_load("wendy.jpg",&width, &height, &nchans, 0); cout << "Texture1 WIDTH:" << width << "HEIGHT:" <<height <<endl; if(data){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateTextureMipmap(texture1); } else{ cout << "Load texture1 error" <<endl; } stbi_image_free(data); // ------------------ LOADING TEXTURE2 --------------------------------- glCreateTextures(GL_TEXTURE_2D,1 , &texture2); glBindTexture(GL_TEXTURE_2D, texture2); glTextureParameteri(texture2, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(texture2, GL_TEXTURE_WRAP_T, GL_REPEAT); glTextureParameteri(texture2, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTextureParameteri(texture2, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("mask.png",&width, &height, &nchans, 0); cout << "Texture2 WIDTH:" << width << "HEIGHT:" <<height <<endl; if(data){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width,height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateTextureMipmap(texture2); } else{ cout << "Load texture2 error" <<endl; } shader.use(); stbi_image_free(data); // free image2 mem glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,texture2); GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1"); GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2"); glUniform1i(texture1_location,0); glUniform1i(texture2_location,1); cout << "tex1 loc:" <<texture1_location <<endl; cout << "tex2 loc:" <<texture1_location <<endl; } void display(){ static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f}; glClearBufferfv(GL_COLOR,0,black); //glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,texture2); shader.use(); glBindVertexArray(VAO); //glDrawArrays(GL_QUADS,0 ,NPTS); glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL); // draw six verticles } int main() { cout << sizeof(float) <<endl; glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); processInput(window); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
同样做个测试,如果给材质中作个
#version 450 core out vec4 fColor; // out to our fragment shader color //in vec4 ourColor; // from the vertex shader src //in vec2 ourTexCoord; in block{ vec4 ourColor; vec2 ourTexCoord; }; uniform sampler2D texture1; uniform sampler2D texture2; // Mask Texture uniform sampler2D texture3; // Test void main(){ vec4 df = texture(texture1,ourTexCoord); vec4 mask = texture(texture2,ourTexCoord); vec4 test = texture(texture3,ourTexCoord); fColor = test; }
源码中只读取了2个贴图,第一个是wendy.jpg,第二个是mask.png,可以看到 OPENGL是他妈的先读取的贴图就是是0,然后一次递增。
GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1"); GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2"); GLint texture3_location = glGetUniformLocation(shader.shaderProgram, "texture3"); glUniform1i(texture1_location,0); glUniform1i(texture2_location,1); glUniform1i(texture3_location,0); // 0 is wendy.png , 1 is mask.png
OPENGL右手坐标系!了解下
CP08:
GLM简单的测试:
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> int main(){ glm::vec4 vec(5.0f, 0.0f, 0.0f, 1.0f) ; glm::mat4 trans = glm::mat4(1.0f); trans= glm::translate(trans,glm::vec3(1.0f,2.0f,3.0f)); vec = trans * vec; cout << vec.x << " " << vec.y << " " << vec.z <<endl; cout <<*glm::value_ptr(vec)<< *(glm::value_ptr(vec)+1) << *(glm::value_ptr(vec) + 2)<< endl; glm::vec3 dir1(1.0f,0.0f,0.0f); glm::vec3 dir2(0.0f,0.0f,1.0f); float dot_result = glm::dot(dir1,dir2); cout << dot_result <<endl; glm::vec3 crs_result = glm::cross(dir2,dir1); cout << crs_result.x << " "<< crs_result.y <<" "<< crs_result.z << endl; glm::vec3 p1(1.0f); glm::vec3 p2(2.0f); float dot_result2 = glm::dot(p1,p2); cout << dot_result2 << endl; return 0; }
GLM+OGL:
vert:
#version 450 core layout ( location = 0 ) in vec4 vPosition; // c++ pos layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st out vec2 ourTexCoord; // OUT TO OUR ->fragment uniform mat4 transform; void main(){ gl_Position = transform * vPosition; ourTexCoord = vTexCoord; }
fs:
#version 450 core out vec4 fColor; // out to our fragment shader color in vec2 ourTexCoord; uniform sampler2D texture1; void main(){ vec4 df = texture(texture1,ourTexCoord); fColor = df; }
main.cpp
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const int NPTS = 4; static GLuint VAO,VBO,EBO; static LoadShader shader; void init(); void display(); void showFPS(GLFWwindow *); void init(){ GLfloat verticels[NPTS][5] = { // positions // texture coords {0.5f, 0.5f, 0.0f, 1.0f, 1.0f}, // top right {0.5f, -0.5f, 0.0f, 1.0f, 0.0f}, // bottom right {-0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, // bottom left {-0.5f, 0.5f, 0.0f, 0.0f, 1.0f} // top left }; GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateVertexArrays(1, &VAO); glCreateBuffers(1, &VBO); glCreateBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0); glBufferData(GL_ARRAY_BUFFER,sizeof(verticels), verticels, GL_STATIC_DRAW); glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // VERTEX POINTS ATTRIBUTES glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // POS at location 0 glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1 glEnableVertexAttribArray(1); cout << "GEN Texture "; // loading one texture GLuint textureID; glCreateTextures(GL_TEXTURE_2D,1 , &textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char *data = stbi_load("wendy.jpg", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } cout << "FREE IMAGE "; stbi_image_free(data); } void display(){ glm::mat4 transform = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first //transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f)); transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f)); GLuint transformlocation = glGetUniformLocation(shader.shaderProgram, "transform"); glUniformMatrix4fv(transformlocation, 1, GL_FALSE, glm::value_ptr(transform)); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); shader.use(); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL); // draw six verticles } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(1280,720,"HelloWorld",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
CP09:
一些重要的空间概念在这篇文章里。
对于GLM 传递到uniform的矩阵作者做了3种形式,实际上是一样的:
// create transformations glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f)); view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); // retrieve the matrix uniform locations unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model"); unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view"); // pass them to the shaders (3 different ways) glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]); // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once. ourShader.setMat4("projection", projection);
1,实现Projection * View * Model * verticlesP
2,尝试 实现用键盘控制 W A S D
键盘控制就是使用glfw
void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { offset_w_s += 0.02f; } if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { offset_w_s -= 0.02f; } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { offset_a_d += 0.02f; } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { offset_a_d -= 0.02f; } }
#version 450 core layout ( location = 0 ) in vec4 vPosition; // c++ pos layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st out vec2 ourTexCoord; // OUT TO OUR ->fragment uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection *view * model * vPosition; ourTexCoord = vTexCoord; }
#version 450 core out vec4 fColor; // out to our fragment shader color in vec2 ourTexCoord; uniform sampler2D texture1; void main(){ vec4 df = texture(texture1,ourTexCoord); fColor = df; }
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const unsigned int SRC_WIDTH = 800; const unsigned int SRC_HEIGHT = 600; const int NPTS = 4; static GLuint VAO,VBO,EBO; static LoadShader shader; void init(); void display(); void showFPS(GLFWwindow *); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); static float offset_w_s = -1.0f; static float offset_a_d = 0.0f; void init(){ GLfloat verticels[NPTS][5] = { // positions // texture coords {0.5f, 0.5f, 0.0f, 1.0f, 1.0f}, // top right {0.5f, -0.5f, 0.0f, 1.0f, 0.0f}, // bottom right {-0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, // bottom left {-0.5f, 0.5f, 0.0f, 0.0f, 1.0f} // top left }; GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateVertexArrays(1, &VAO); glCreateBuffers(1, &VBO); glCreateBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0); glBufferData(GL_ARRAY_BUFFER,sizeof(verticels), verticels, GL_STATIC_DRAW); glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // VERTEX POINTS ATTRIBUTES glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // POS at location 0 glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1 glEnableVertexAttribArray(1); cout << "GEN Texture "; // loading one texture GLuint textureID; glCreateTextures(GL_TEXTURE_2D,1 , &textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char *data = stbi_load("wendy.jpg", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } cout << "FREE IMAGE "; stbi_image_free(data); } void display(){ glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); model = glm::rotate(model, glm::radians(-55.0f),glm::vec3(1.0f,0.0f,0.0f)); view = glm::translate(view,glm::vec3(offset_a_d, 0.0f ,offset_w_s)); // BIND KEY projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f, 1000.0f); GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model"); GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view"); GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection"); glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection)); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); shader.use(); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL); // draw six verticles } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glewInit(); init(); // RENDER-------------- while(!glfwWindowShouldClose(window)){ processInput(window); display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { offset_w_s += 0.02f; } if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { offset_w_s -= 0.02f; } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { offset_a_d += 0.02f; } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { offset_a_d -= 0.02f; } }
CP10:
1,理解ZBUFFER
glEnable(GL_DEPTH_TEST); // RENDER LOOP CODE: glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2,理解R S T 顺序
for (unsigned int i = 0; i < 10; i++) { // calculate the model matrix for each object and pass it to shader before drawing glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, cubePositions[i]); float angle = 20.0f * i; model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f)); ourShader.setMat4("model", model); glDrawArrays(GL_TRIANGLES, 0, 36); }
如上,对一个model矩阵操作 位移,操作旋转, 结果是不可预期的。经过测试,代码确实是以原点旋转位移过的物体。
如果我想先旋转, 然后再位移:
for (unsigned int i = 0; i < 10; i++) { // RULE : RST // FIRST WE ROTATION glm::mat4 tempRot = glm::mat4(1.0f); tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f)); // then translate glm::mat4 tempTrans = glm::mat4(1.0f); tempTrans = glm::translate(tempTrans,cubePositions[i]); // final combine one matrix glm::mat4 model = glm::mat4(1.0f); model = tempTrans * tempRot; // send to opengl GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model"); glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES,0,36); }
ALL CODE:
#version 450 core layout ( location = 0 ) in vec4 vPosition; // c++ pos layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st out vec2 ourTexCoord; // OUT TO OUR ->fragment uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection *view * model * vPosition; ourTexCoord = vTexCoord; }
#version 450 core out vec4 fColor; // out to our fragment shader color in vec2 ourTexCoord; uniform sampler2D texture1; void main(){ vec4 df = texture(texture1,ourTexCoord); fColor = df; }
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const unsigned int SRC_WIDTH = 800; const unsigned int SRC_HEIGHT = 600; const int NPTS = 4; static GLuint VAO,VBO,EBO; static LoadShader shader; void init(); void display(); void showFPS(GLFWwindow *); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); static float offset_w_s = -1.0f; static float offset_a_d = 0.0f; // world space positions of our cubes static glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; void init(){ float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; glEnable(GL_DEPTH_TEST); GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateVertexArrays(1, &VAO); glCreateBuffers(1, &VBO); glCreateBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0); glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW); glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // VERTEX POINTS ATTRIBUTES glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // POS at location 0 glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1 glEnableVertexAttribArray(1); cout << "GEN Texture "; // loading one texture GLuint textureID; glCreateTextures(GL_TEXTURE_2D,1 , &textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } cout << "FREE IMAGE "; stbi_image_free(data); } void display(){ glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view"); GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection"); view = glm::translate(view,glm::vec3(offset_a_d, 0.0f ,offset_w_s)); // BIND KEY projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f, 1000.0f); //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection)); for (unsigned int i = 0; i < 10; i++) { // RULE : RST // FIRST WE ROTATION glm::mat4 tempRot = glm::mat4(1.0f); tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f)); // then translate glm::mat4 tempTrans = glm::mat4(1.0f); tempTrans = glm::translate(tempTrans,cubePositions[i]); // final combine one matrix glm::mat4 model = glm::mat4(1.0f); model = tempTrans * tempRot; // send to opengl GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model"); glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES,0,36); } } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glewInit(); init(); // RENDER-------------- while(!glfwWindowShouldClose(window)){ processInput(window); display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { offset_w_s += 0.05f; } if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { offset_w_s -= 0.05f; } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { offset_a_d += 0.05f; } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { offset_a_d -= 0.05f; } }
CP11
1,CamSpace/ViewSpace
2,LookAt Matrix:
3,实现教程中得键盘控制 W A S D
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <cmath> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const unsigned int SRC_WIDTH = 800; const unsigned int SRC_HEIGHT = 600; const int NPTS = 4; static GLuint VAO,VBO,EBO; static LoadShader shader; void init(); void display(); void showFPS(GLFWwindow *); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // camera static glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); static glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); static glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; // world space positions of our cubes static glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; void init(){ float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; glEnable(GL_DEPTH_TEST); GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateVertexArrays(1, &VAO); glCreateBuffers(1, &VBO); glCreateBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0); glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW); glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // VERTEX POINTS ATTRIBUTES glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // POS at location 0 glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1 glEnableVertexAttribArray(1); cout << "GEN Texture "; // loading one texture GLuint textureID; glCreateTextures(GL_TEXTURE_2D,1 , &textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } cout << "FREE IMAGE "; stbi_image_free(data); } void display(){ // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view"); GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection"); projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f, 1000.0f); //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection)); // view matrix view = glm::lookAt(cameraPos , cameraPos + cameraFront , cameraUp); glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view)); for (unsigned int i = 0; i < 10; i++) { // RULE : RST // FIRST WE ROTATION glm::mat4 tempRot = glm::mat4(1.0f); tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f)); // then translate glm::mat4 tempTrans = glm::mat4(1.0f); tempTrans = glm::translate(tempTrans,cubePositions[i]); // final combine one matrix glm::mat4 model = glm::mat4(1.0f); model = tempTrans * tempRot; // send to opengl GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model"); glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES,0,36); } } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glewInit(); init(); // RENDER-------------- while(!glfwWindowShouldClose(window)){ processInput(window); display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); float cameraSpeed = 2.5 * deltaTime; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) cameraPos += cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) cameraPos -= cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; }
CP12
1,实现Maya得控制视角方式
2,修改了教程得控制视角方式,测试了众多得事件。
3,跟QT得事件实际上套路类似,而且更加简单,C语言callback使用起来就是那么难用。
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include <cmath> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const unsigned int SRC_WIDTH = 800; const unsigned int SRC_HEIGHT = 600; const int NPTS = 4; static GLuint VAO,VBO,EBO; static LoadShader shader; void init(); void display(); void showFPS(GLFWwindow *); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); // Test not used! // camera static glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); static glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); static glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); static float yaw = -90.0f; // yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right so we initially rotate a bit to the left. static float pitch = 0.0f; static float lastX = float(SRC_WIDTH) / 2.0; static float lastY = float(SRC_HEIGHT) / 2.0; static float fov = 45.0f; // default fov static bool firstMouse = true; // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; // world space positions of our cubes static glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; void init(){ float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; glEnable(GL_DEPTH_TEST); GLuint indices[6] = { 0, 1, 3, // FIRST TRIANGLE 1, 2, 3 // SECOND TRIANGLE }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateVertexArrays(1, &VAO); glCreateBuffers(1, &VBO); glCreateBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0); glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW); glCreateBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glNamedBufferStorage(EBO, sizeof(indices), indices , 0); // VERTEX POINTS ATTRIBUTES glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // POS at location 0 glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1 glEnableVertexAttribArray(1); cout << "GEN Texture "; // loading one texture GLuint textureID; glCreateTextures(GL_TEXTURE_2D,1 , &textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } cout << "FREE IMAGE "; stbi_image_free(data); } void display(){ // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view"); GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection"); projection = glm::perspective(glm::radians(fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f, 1000.0f); //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection)); // view matrix view = glm::lookAt(cameraPos , cameraPos + cameraFront , cameraUp); glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view)); for (unsigned int i = 0; i < 10; i++) { // RULE : RST // FIRST WE ROTATION glm::mat4 tempRot = glm::mat4(1.0f); tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f)); // then translate glm::mat4 tempTrans = glm::mat4(1.0f); tempTrans = glm::translate(tempTrans,cubePositions[i]); // final combine one matrix glm::mat4 model = glm::mat4(1.0f); model = tempTrans * tempRot; // send to opengl GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model"); glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES,0,36); } } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window,mouse_callback); glfwSetScrollCallback(window, scroll_callback); //glfwSetKeyCallback(window, key_callback); // Key event //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glewInit(); init(); // RENDER-------------- while(!glfwWindowShouldClose(window)){ processInput(window); display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); float cameraSpeed = 2.5 * deltaTime; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) cameraPos += cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) cameraPos -= cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; } // ROTATE VIEW DIR void mouse_callback(GLFWwindow* window, double xpos, double ypos) { int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT); if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) { if (firstMouse){ lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; float sensitivity = 0.2f; // change this value to your liking xoffset *= sensitivity; yoffset *= sensitivity; yaw += xoffset; pitch += yoffset; // make sure that when pitch is out of bounds, screen doesn't get flipped if (pitch > 89.0f) pitch = 89.0f; if (pitch < -89.0f) pitch = -89.0f; glm::vec3 front; front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); front.y = sin(glm::radians(pitch)); front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); cameraFront = glm::normalize(front); } if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){ firstMouse = true; } } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){ //cout << "scroll_callback " << xoffset << " " << yoffset <<endl; if(fov >= 1.0f && fov <= 45.0f){ fov -= yoffset; } if(fov <=1.0f){ fov = 1.0f; } if(fov >= 45.0f){ fov = 45.0f; } } // void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { //cout << "--->" << xpos << "/" << ypos <<endl; int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); if (key == GLFW_KEY_LEFT_ALT && (action == GLFW_PRESS||action == GLFW_REPEAT) ) { } }