C++/OpenGL 入门(9):复制同一立方体进行多物体运动
#include <string> #include <iostream> #include <fstream> #include <cmath> #include "glm\glm.hpp" #include "glm\gtc\type_ptr.hpp" #include "glm\gtc\matrix_transform.hpp" #include "Utils\4.1 Utils.h" using namespace std; #define numVAOs 1 #define numVBOs 2 float cameraX, cameraY, cameraZ; float cubeLocX, cubeLocY, cubeLocZ; GLuint renderingProgram; GLuint vao[numVAOs]; GLuint vbo[numVBOs]; // allocate variables used in display() function, // so that they won’t need to be allocated during rendering GLuint mvLoc, projLoc; int width, height; float aspect; glm::mat4 pMat, vMat, mMat, mvMat; glm::mat4 tMat, rMat;//为了动画而添加的内容 void setupVertices(void) { // 36 vertices, 12 triangles, makes 2x2x2 cube placed at origin float vertexPositions[108] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); glGenBuffers(numVBOs, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); } void init(GLFWwindow* window) { //renderingProgram = createShaderProgram("add/4.1 vertShader.glsl", "add/4.1 fragShader.glsl"); renderingProgram = createShaderProgram("add/4.12 vertShader.glsl", "add/4.12 fragShader.glsl"); cameraX = 0.0f; cameraY = 0.0f; cameraZ = 50.0f; cubeLocX = 0.0f; cubeLocY = -2.0f; cubeLocZ = 0.0f; // shift down Y to reveal perspective setupVertices(); } void display(GLFWwindow* window, double currentTime) { glClear(GL_DEPTH_BUFFER_BIT); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); // 每一次都将背景清理(clear)为黑色 glUseProgram(renderingProgram); // get the uniform variables for the MV and projection matrices mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix"); projLoc = glGetUniformLocation(renderingProgram, "proj_matrix"); // build perspective matrix glfwGetFramebufferSize(window, &width, &height); aspect = (float)width / (float)height; pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f); // 1.0472 radians = 60 degrees // build view matrix, model matrix, and model-view matrix for (int i = 0; i < 24; i++) { float tf = currentTime + i; // ============ 以下是为了动画而添加的内容 // use current time to compute different translations in x, y, and z tMat = glm::translate(glm::mat4(1.0f), glm::vec3(sin(0.35f*tf)*10.0f, cos(0.52f*tf)*10.0f, sin(0.7f*tf)*10.0f)); rMat = glm::rotate(glm::mat4(1.0f), 1.75f*tf, glm::vec3(0.0f, 1.0f, 0.0f)); rMat = glm::rotate(rMat, 1.75f*tf, glm::vec3(1.0f, 0.0f, 0.0f)); rMat = glm::rotate(rMat, 1.75f*tf, glm::vec3(0.0f, 0.0f, 1.0f)); // the 1.75 adjusts the rotation speed mMat = tMat * rMat; // ============ 结束 vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ)); mvMat = vMat * mMat; // copy perspective and MV matrices to corresponding uniform variables glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat)); // associate VBO with the corresponding vertex attribute in the vertex shader glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); // adjust OpenGL settings and draw model glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDrawArrays(GL_TRIANGLES, 0, 36); } } int main(void) { // main() is unchanged from before if (!glfwInit()) { exit(EXIT_FAILURE); } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); GLFWwindow* window = glfwCreateWindow(600, 600, "Chapter 4 - program 1", NULL, NULL); glfwMakeContextCurrent(window); if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); } glfwSwapInterval(1); init(window); while (!glfwWindowShouldClose(window)) { display(window, glfwGetTime()); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }
#version 430 layout (location=0) in vec3 position; uniform mat4 mv_matrix; uniform mat4 proj_matrix; out vec4 varyingColor; void main(void) { gl_Position = proj_matrix * mv_matrix * vec4(position,1.0); varyingColor = vec4(position,1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5); }
#version 430 in vec4 varyingColor; out vec4 color; uniform mat4 mv_matrix; uniform mat4 proj_matrix; void main(void) { color = varyingColor; }