OpenGL —— 2.1、绘制第一个三角形(附源码,glfw+glad)

<think>好的,用户现在想要一个使用OpenGLGLADGLFW和GLM库绘制三角形网格的完整代码示例。我需要先回顾之前的对话和用户提供的引用内容,确保满足他们的需求。 首先,用户在上一次的问题中已经询问了三维渲染的基础教程,我给出了初始化环境、顶点缓冲、着色器配置、坐标变换和渲染循环的示例。现在用户需要完整代码,可能希望有一个可以直接编译运行的例子,这样他们可以快速上手。 接下来,用户提到了参考站内的引用,特别是引用[1]关于Geometry Shader实现法线可视化和引用[2]关于实例化渲染。不过用户这次的问题并没有提到需要法线可视化或实例化,所以可能这些引用只是作为背景信息,当前需求更基础,是绘制三角形网格。不过,我需要注意是否需要将这些引用内容整合进去,但根据用户的问题,他们明确要求的是绘制三角形网格的完整代码,所以暂时可能不需要包括Geometry Shader或实例化的部分,除非用户特别说明。 现在,我需要构建一个完整代码示例,涵盖GLFW窗口的创建、GLAD的初始化、顶点数据的定义、VAO/VBO的设置、着色器的编译、模型视图投影矩阵的应用以及渲染循环。用户提到的库包括GLADGLFW和GLM,所以必须确保代码中正确使用这些库的功能。 首先,考虑代码结构:初始化GLFW,创建窗口,初始化GLAD,设置视口,处理输入。然后是着色器的编,顶点和片段着色器需要正确读取顶点数据并应用变换矩阵。顶点数据部分需要定义一个三角形网格,可能使用多个三角形组成一个简单的形状,比如立方体或平面网格。但用户请求的是三角形网格,可能一个简单的例子更合适,比如两个三角形组成的四边形,或者单个三角形。不过为了展示网格,可能使用多个三角形更好。 然后,设置VAO和VBO,绑定顶点数据,配置顶点属性指针。接着是着色器的编译和链接,确保uniform变量正确传递模型、视图、投影矩阵。使用GLM库来生成这些矩阵,例如视图矩阵使用lookAt,投影矩阵使用perspective。 在渲染循环中,清除颜色和深度缓冲,设置uniform矩阵,绘制顶点数组。同时处理窗口的交换缓冲和事件轮询。需要启用深度测试以确保正确的三维渲染效果,这在之前的回答中已经提到过优化建议,所以代码中应包括glEnable(GL_DEPTH_TEST)。 还需要处理窗口大小调整的回调函数,以正确更新视口。输入处理部分,比如按下ESC关闭窗口。 检查用户可能需要的额外功能,比如颜色变化,可能在片段着色器中添加颜色属性,或者随时间旋转模型,以展示动态效果。例如,在模型矩阵中加入旋转,根据时间变化,让三角形网格旋转起来,这样用户可以看到效果。 需要确保代码完整性和正确性,用户应该能够复制代码,安装必要的库后直接编译运行。因此,代码中的每个步骤都要详细,包括头文件的包含、库的链接说明,以及可能的编译指令。 可能还需要注意GLAD的初始化顺序,必须在GLFW的上下文创建之后初始化。GLFW窗口的创建参数,比如OpenGL版本设为3.3,核心配置文件,这对现代OpenGL是必要的。 最后,生成相关问题,考虑用户可能接下来会问的内容,比如如何添加纹理、光照,或者如何处理更复杂的网格,以及性能优化等问题。这些问题需要与当前主题相关,帮助用户进一步学习。</think>以下是使用OpenGL核心模式配合GLAD/GLFW/GLM实现三角形网格的完整代码示例,包含关键注释和实现细节: ### 完整代码实现 ```cpp #include <glad/glad.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <iostream> // 顶点着色器源码 const char* vertexShaderSource = R"( #version 330 core layout (location = 0) in vec3 aPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(aPos, 1.0); } )"; // 片段着色器源码 const char* fragmentShaderSource = R"( #version 330 core out vec4 FragColor; void main() { FragColor = vec4(0.2, 0.6, 1.0, 1.0); // 蓝色调 } )"; // 窗口回调函数 void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } 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(800, 600, "Triangle Mesh", NULL, NULL); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // 初始化GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // 定义三角形网格顶点数据(两个三角形组成四边形) float vertices[] = { // 第一个三角形 -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, // 第二个三角形 0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.0f }; // 创建VAO/VBO unsigned int VAO, VBO; 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, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // 编译着色器 unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // 创建着色器程序 unsigned int shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // 启用深度测试 glEnable(GL_DEPTH_TEST); // 渲染循环 while (!glfwWindowShouldClose(window)) { // 清除缓冲 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 创建变换矩阵 glm::mat4 model = glm::rotate(glm::mat4(1.0f), (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f)); glm::mat4 view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f); // 传递矩阵到着色器 glUseProgram(shaderProgram); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &model[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &projection[0][0]); // 绘制网格 glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 6); glfwSwapBuffers(window); glfwPollEvents(); } // 清理资源 glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteProgram(shaderProgram); glfwTerminate(); return 0; } ``` ### 关键特性说明 1. **现代OpenGL特性**: - 使用核心模式(Core Profile) - 顶点数组对象(VAO)管理状态 - 矩阵变换通过GLM实现[^2] 2. **运行效果**: - 两个旋转的蓝色三角形组成动态四边形 - 启用深度测试防止绘制顺序错误 - 摄像机使用`glm::lookAt`实现三维观察 3. **编译说明**: - 需要链接GLFW3、GLAD、GLM库 - 建议使用CMake管理项目 - OpenGL版本要求3.3+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信必诺

嗨,支持下哥们呗。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值