从点到线:绘制一条直线
2023-12-25 13:30:11
从点到线:使用 OpenGL 绘制直线
绘制点的回顾
在上一篇博客中,我们探讨了如何使用 OpenGL 绘制一个点。现在,我们将踏入更复杂的世界,学习如何绘制一条直线。与点不同,一条直线需要两个顶点(点)来定义,因此我们需要更新我们的顶点着色器和片段着色器。
更新顶点着色器
#version 330 core
layout (location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
与绘制点时使用的顶点着色器相比,这里唯一的区别是顶点数据现在是一个包含三个浮点数的向量 vec3
,而不是一个包含一个浮点数的向量 vec1
。这三个浮点数分别代表顶点的 x、y 和 z 坐标。
片段着色器保持不变
片段着色器与绘制点时使用的片段着色器完全相同,因为它只是简单地将片段的颜色设置为红色:
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
传递顶点数据
现在我们已经更新了顶点着色器,我们需要将两个顶点的数据传递给 OpenGL。我们可以使用 glVertexAttribPointer()
函数来实现:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
这个函数告诉 OpenGL,我们要使用名为 position
的顶点属性,它是一个包含三个浮点数的向量。这些浮点数存储在 vertices
数组中。
接下来,我们需要启用 position
顶点属性:
glEnableVertexAttribArray(0);
绘制直线
现在,我们可以使用 glDrawArrays()
函数来绘制直线:
glDrawArrays(GL_LINES, 0, 2);
这个函数告诉 OpenGL,我们要绘制两条线段,从顶点数组的第一个顶点开始,到第二个顶点结束。
完整示例
以下是一个完整的示例代码,展示了如何使用 OpenGL 绘制一条直线:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
int main() {
// 初始化 GLFW
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// 创建 GLFW 窗口
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL 直线绘制", NULL, NULL);
if (window == NULL) {
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// 初始化 GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
glfwTerminate();
return -1;
}
// 顶点着色器
const char* vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}";
// 片段着色器
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main() {\n"
" FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}";
// 编译并链接着色器程序
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// 创建顶点数据
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f
};
// 创建顶点缓冲对象
unsigned int VBO;
glGenBuffers(1, &VBO);
// 绑定顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 将顶点数据复制到顶点缓冲对象
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 启用顶点属性
glEnableVertexAttribArray(0);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// 渲染循环
while (!glfwWindowShouldClose(window)) {
// 清除颜色缓冲
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 使用着色器程序
glUseProgram(shaderProgram);
// 绘制直线
glDrawArrays(GL_LINES, 0, 2);
// 交换前后缓冲
glfwSwapBuffers(window);
// 处理事件
glfwPollEvents();
}
// 释放资源
glDeleteVertexArrays(1, &VBO);
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
// 终止 GLFW
glfwTerminate();
return 0;
}
常见问题解答
1. 我如何更改直线的颜色?
- 通过在片段着色器中修改
FragColor
变量,您可以更改直线的颜色。
2. 我如何绘制多条直线?
- 使用
glDrawArrays()
函数并增加最后一个参数,您可以绘制多条直线。
3. 我如何旋转直线?
- 您可以通过在顶点着色器中使用
mat4
投影矩阵来旋转直线。
4. 我如何平移直线?
- 与旋转类似,您可以通过在顶点着色器中使用
mat4
平移矩阵来平移直线。
5. 我如何缩放直线?
- 最后,您可以通过在顶点着色器中使用
mat4
缩放矩阵来缩放直线。
结论
在本文中,我们详细介绍了如何使用 OpenGL 绘制一条直线。我们了解了如何更新顶点着色器、传递顶点数据并使用 glDrawArrays()
函数绘制直线。最后,我们提供了一个完整的示例代码供您参考。我希望本教程对您有用,欢迎提出任何问题或提供反馈。让我们一起探索 OpenGL 的神奇世界,绘制令人惊叹的图形!