OpenGL学习-立方体+圆柱体

OpenGL学习-立方体+圆柱体

开发环境搭建参考:https://lexiaoyuan.blog.csdn.net/article/details/120059213


通用配置步骤

  • Visual Studio,创建一个新的空项目
  • 复制glad.c文件到你的工程中
  • 选中项目,右键选择属性–> C/C++目录–> 常规–> 包含目录:加上头文件存放的目录
  • 选中项目,右键选择属性–> C/C++目录–> 常规–> 库目录:加上lib文件存放的目录
  • 选中项目,右键选择属性–> 链接器–> 输入–> 附加依赖项:加入opengl32.lib;glfw3.lib;
  • 选中项目,右键选择属性–> C/C++目录–> 预处理器–> 与处理器定义:加上_CRT_SECURE_NO_WARNINGS

代码

#include 
#include 
#include #include 
#include 
#include // 视口的回调函数
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
// 鼠标缩放和移动
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
// 输入控制
void processInput(GLFWwindow* window);// 设置
const unsigned int SCR_WIDTH = 600;
const unsigned int SCR_HEIGHT = 600;// 相机
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);bool firstMouse = true;
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.
float pitch = 0.0f;
float lastX = 600.0f / 2.0;
float lastY = 600.0 / 2.0;
float fov = 45.0f;// timing
float deltaTime = 0.0f;	// time between current frame and last frame
float lastFrame = 0.0f;// ========== 立方体 =========
// 定义顶点着色器
const char* cube_vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\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(aPos, 1.0);\n"
"   ourColor = aColor;\n"
"}\0";// 定义片段着色器
const char* cube_fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;"
"void main()\n"
"{\n"
"   FragColor = vec4(ourColor, 1.0);\n"
"}\0";// ========== 圆柱 =========
// 定义顶点着色器
const char* cylinder_vertexShaderSource = "#version 330 core\n"
"layout (location = 2) in vec3 aPos;\n"
"layout (location = 3) in vec3 aColor;\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(aPos, 1.0);\n"
"   ourColor = aColor;\n"
"}\0";// 定义片段着色器
const char* cylinder_fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;"
"void main()\n"
"{\n"
"   FragColor = vec4(ourColor, 1.0);\n"
"}\0";int main()
{// 实例化GLFW窗口glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 创建窗口对象GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "lexiaoyuan", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);// tell GLFW to capture our mouseglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// 初始化gladif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// 启用深度测试glEnable(GL_DEPTH_TEST);// ========== 立方体 =========// 定义顶点坐标float cube_vertices[] = {// 位置            // 颜色0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,  // A0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 1.0f,  // B-0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 0.0f,  // C-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,  // D0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f,  // E0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f,  // F-0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f,  // G-0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 0.0f   // H};// 定义索引数组unsigned int cube_indices[] = { // 注意索引从0开始! 0, 1, 3, 1, 2, 3, // 下 ABCD1, 2, 5, 2, 6, 5, // 右 BCGF4, 5, 7, 5, 6, 7, // 上 EFGH0, 3, 4, 3, 7, 4, // 左 ADHE0, 1, 5, 5, 4, 0, // 前 ABFE3, 2, 6, 6, 7, 3  // 后 DCGH};// 定义顶点缓冲对象unsigned int cube_VBO;glGenBuffers(1, &cube_VBO);// 定义顶点数组对象unsigned int cube_VAO;glGenVertexArrays(1, &cube_VAO);// 定义索引缓冲对象unsigned int cube_EBO;glGenBuffers(1, &cube_EBO);// 绑定顶点缓冲对象glBindBuffer(GL_ARRAY_BUFFER, cube_VBO);// 复制顶点数据到缓冲内存glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);// 绑定顶点数组对象glBindVertexArray(cube_VAO);// 绑定索引缓冲对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_indices), cube_indices, GL_STATIC_DRAW);// 创建顶点着色器对象unsigned int cube_vertexShader;cube_vertexShader = glCreateShader(GL_VERTEX_SHADER);// 附加顶点着色器代码到顶点着色器对象glShaderSource(cube_vertexShader, 1, &cube_vertexShaderSource, NULL);// 编译顶点着色器glCompileShader(cube_vertexShader);// 创建片段着色器对象unsigned int cube_fragmentShader;cube_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);// 附加片段着色器代码到片段着色器对象glShaderSource(cube_fragmentShader, 1, &cube_fragmentShaderSource, NULL);// 编译片段着色器glCompileShader(cube_fragmentShader);// 创建一个着色器程序对象unsigned int cube_shaderProgram;cube_shaderProgram = glCreateProgram();// 把着色器对象附加到程序上glAttachShader(cube_shaderProgram, cube_vertexShader);glAttachShader(cube_shaderProgram, cube_fragmentShader);// 链接着色器程序glLinkProgram(cube_shaderProgram);// 着色器对象链接成功后可以删掉了glDeleteShader(cube_vertexShader);glDeleteShader(cube_fragmentShader);// 位置属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// 颜色属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// 定义视口glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);// 注册回调函数glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// ========== 圆柱 =========// 定义圆柱坐标float cylinder_vertices[120000];unsigned int cylinder_indices[10000];float p = 0.0f, r = 0.5f;for (int i = 0; i < 20000; i += 2){p = i * 3.14f / 180;cylinder_vertices[i * 6] = cos(p) * r;cylinder_vertices[i * 6 + 1] = -0.5f;cylinder_vertices[i * 6 + 2] = sin(p) * r;// 颜色cylinder_vertices[i * 6 + 3] = 1.0f;cylinder_vertices[i * 6 + 4] = 1.0f;cylinder_vertices[i * 6 + 5] = 0.0f;cylinder_vertices[(i + 1) * 6] = cos(p) * r;cylinder_vertices[(i + 1) * 6 + 1] = 0.5f;cylinder_vertices[(i + 1) * 6 + 2] = sin(p) * r;// 颜色cylinder_vertices[(i + 1) * 6 + 3] = 1.0f;cylinder_vertices[(i + 1) * 6 + 4] = 0.0f;cylinder_vertices[(i + 1) * 6 + 5] = 1.0f;}for (int i = 0; i < 10000; i++){cylinder_indices[i] = i;}// 定义顶点缓冲对象unsigned int cylinder_VBO;glGenBuffers(1, &cylinder_VBO);// 定义顶点数组对象unsigned int cylinder_VAO;glGenVertexArrays(1, &cylinder_VAO);// 定义索引缓冲对象unsigned int cylinder_EBO;glGenBuffers(1, &cylinder_EBO);// 绑定顶点缓冲对象glBindBuffer(GL_ARRAY_BUFFER, cylinder_VBO);// 复制顶点数据到缓冲内存glBufferData(GL_ARRAY_BUFFER, sizeof(cylinder_vertices), cylinder_vertices, GL_STATIC_DRAW);// 绑定顶点数组对象glBindVertexArray(cylinder_VAO);// 绑定索引缓冲对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cylinder_EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cylinder_indices), cylinder_indices, GL_STATIC_DRAW);// 创建顶点着色器对象unsigned int cylinder_vertexShader;cylinder_vertexShader = glCreateShader(GL_VERTEX_SHADER);// 附加顶点着色器代码到顶点着色器对象glShaderSource(cylinder_vertexShader, 1, &cylinder_vertexShaderSource, NULL);// 编译顶点着色器glCompileShader(cylinder_vertexShader);// 创建片段着色器对象unsigned int cylinder_fragmentShader;cylinder_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);// 附加片段着色器代码到片段着色器对象glShaderSource(cylinder_fragmentShader, 1, &cylinder_fragmentShaderSource, NULL);// 编译片段着色器glCompileShader(cylinder_fragmentShader);// 创建一个着色器程序对象unsigned int cylinder_shaderProgram;cylinder_shaderProgram = glCreateProgram();// 把着色器对象附加到程序上glAttachShader(cylinder_shaderProgram, cylinder_vertexShader);glAttachShader(cylinder_shaderProgram, cylinder_fragmentShader);// 链接着色器程序glLinkProgram(cylinder_shaderProgram);// 着色器对象链接成功后可以删掉了glDeleteShader(cylinder_vertexShader);glDeleteShader(cylinder_fragmentShader);// 位置属性glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(2);// 颜色属性glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(3);// 定义视口glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);// 注册回调函数glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// ===================== 立方体 + 圆柱 =====================// 渲染循环while (!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;processInput(window);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// ========= 立方体 ========// 激活着色器程序对象glUseProgram(cube_shaderProgram);glBindVertexArray(cube_VAO);// 绑定索引缓冲对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_EBO);// 定义模型矩阵glm::mat4 cube_model = glm::mat4(1.0f);cube_model = glm::translate(cube_model, glm::vec3(0.4f, 0.4f, 0.4f));cube_model = glm::rotate(cube_model, (float)glfwGetTime() * glm::radians(45.0f), glm::vec3(0.5f, 1.0f, 0.0f));// 定义观察矩阵glm::mat4 cube_view = glm::mat4(1.0f);// 注意,我们将矩阵向我们要进行移动场景的反方向移动。// cube_view = glm::translate(cube_view, glm::vec3(0.0f, 0.0f, -3.0f));cube_view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);// 定义投影矩阵glm::mat4 cube_projection = glm::mat4(1.0f);cube_projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);// 检索矩阵的统一位置unsigned int cube_modelLoc = glGetUniformLocation(cube_shaderProgram, "model");unsigned int cube_viewLoc = glGetUniformLocation(cube_shaderProgram, "view");unsigned int cube_projectionLoc = glGetUniformLocation(cube_shaderProgram, "projection");// 将它们传递给着色器glUniformMatrix4fv(cube_modelLoc, 1, GL_FALSE, glm::value_ptr(cube_model));glUniformMatrix4fv(cube_viewLoc, 1, GL_FALSE, &cube_view[0][0]);glUniformMatrix4fv(cube_projectionLoc, 1, GL_FALSE, &cube_projection[0][0]);// 绘制glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);// ========= 圆柱 ========// 激活着色器程序对象glUseProgram(cylinder_shaderProgram);glBindVertexArray(cylinder_VAO);// 绑定索引缓冲对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cylinder_EBO);// 定义模型矩阵glm::mat4 cylinder_model = glm::mat4(1.0f);cylinder_model = glm::translate(cylinder_model, glm::vec3(0.2f, 0.0f, 0.0f));cylinder_model = glm::rotate(cylinder_model, (float)glfwGetTime() * glm::radians(45.0f), glm::vec3(0.5f, 1.0f, 0.0f));// 定义观察矩阵glm::mat4 cylinder_view = glm::mat4(1.0f);// 注意,我们将矩阵向我们要进行移动场景的反方向移动。// cylinder_view = glm::translate(cylinder_view, glm::vec3(0.0f, 0.0f, -3.0f));cylinder_view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);// 定义投影矩阵glm::mat4 cylinder_projection = glm::mat4(1.0f);cylinder_projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);// 检索矩阵的统一位置unsigned int cylinder_modelLoc = glGetUniformLocation(cylinder_shaderProgram, "model");unsigned int cylinder_viewLoc = glGetUniformLocation(cylinder_shaderProgram, "view");unsigned int cylinder_projectionLoc = glGetUniformLocation(cylinder_shaderProgram, "projection");// 将它们传递给着色器glUniformMatrix4fv(cylinder_modelLoc, 1, GL_FALSE, glm::value_ptr(cylinder_model));glUniformMatrix4fv(cylinder_viewLoc, 1, GL_FALSE, &cylinder_view[0][0]);glUniformMatrix4fv(cylinder_projectionLoc, 1, GL_FALSE, &cylinder_projection[0][0]);// 绘制glDrawElements(GL_TRIANGLES, 10000, GL_UNSIGNED_INT, 0);glfwSwapBuffers(window);glfwPollEvents();}// 释放资源glDeleteVertexArrays(1, &cube_VAO);glDeleteBuffers(1, &cube_VBO);glDeleteProgram(cube_shaderProgram);// 释放资源glDeleteVertexArrays(1, &cylinder_VAO);glDeleteBuffers(1, &cylinder_VBO);glDeleteProgram(cylinder_shaderProgram);// 释放之前分配的资源glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
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;
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
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);
}// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}float xoffset = xpos - lastX;float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to toplastX = xpos;lastY = ypos;float sensitivity = 0.1f; // change this value to your likingxoffset *= sensitivity;yoffset *= sensitivity;yaw += xoffset;pitch += yoffset;// make sure that when pitch is out of bounds, screen doesn't get flippedif (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);
}// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{fov -= (float)yoffset;if (fov < 1.0f)fov = 1.0f;if (fov > 45.0f)fov = 45.0f;
}

运行

在这里插入图片描述

创作不易,喜欢的话加个关注点个赞,❤谢谢谢谢❤


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部