OpenGL绘制运动的正方体
时间: 2023-06-16 12:02:39 浏览: 185
要绘制运动的正方体,需要使用OpenGL中的变换操作和定时器,具体步骤如下:
1. 创建OpenGL窗口和上下文。
2. 设置透视投影矩阵和视图矩阵。
3. 创建正方体的顶点数据和索引数据,并将其上传到显存中。
4. 创建顶点着色器和片段着色器,并编译链接它们。
5. 创建一个定时器,用于控制正方体的运动。
6. 在定时器回调函数中更新正方体的位置和旋转角度。
7. 在渲染函数中,将变换矩阵传递给着色器,绘制正方体。
下面是一个示例代码,可以绘制一个运动的正方体:
```c++
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
const GLuint WIDTH = 800, HEIGHT = 600;
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLfloat vertices[] = {
// positions // colors
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f
};
GLuint VBO, VAO;
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 color;\n"
"out vec3 ourColor;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
" gl_Position = projection * view * model * vec4(position, 1.0f);\n"
" ourColor = color;\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"in vec3 ourColor;\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
" color = vec4(ourColor, 1.0f);\n"
"}\n\0";
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void do_movement()
{
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
glViewport(0, 0, WIDTH, HEIGHT);
glfwSetKeyCallback(window, key_callback);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
do_movement();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.5f, -0.5f, 0.0f));
model = glm::rotate(model, (GLfloat)glfwGetTime() * 50.0f, glm::vec3(0.5f, 1.0f, 0.0f));
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
```
在以上代码中,我们使用了glm库来进行矩阵变换和投影,可以通过以下命令安装:
```sh
sudo apt-get install libglm-dev
```
运行该程序,可以看到一个运动的正方体。
阅读全文