(OpenGL入门教程:从零开始绘制你的第一个三角形)
1. 🛠 环境准备
在开始开发OpenGL应用程序之前,我们需要准备好开发环境。我们将使用GLFW来创建窗口和处理输入,并使用GLEW来加载OpenGL函数。
1.1 安装OpenGL和GLFW
1.1.1 在Ubuntu上安装
在Ubuntu上,你可以使用包管理器安装GLFW和GLEW:
sudo apt-get update
sudo apt-get install libglfw3-dev libglew-dev
1.1.2 在Windows上安装
- 下载并安装MinGW或Visual Studio。
- 从GLFW官网(https://www.glfw.org/download.html)下载GLFW库。
- 从GLEW官网(http://glew.sourceforge.net/)下载GLEW库。
2. 🎨 创建一个简单的OpenGL程序
下面是一个简单的OpenGL程序,它创建一个窗口并在其中绘制一个三角形。
2.1 代码示例
首先,我们创建一个新的C++文件(例如main.cpp
),并添加以下代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
// 顶点着色器代码
const char* vertexShaderSource = R"(
#version 330 core
layout(location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0);
}
)";
// 片段着色器代码
const char* fragmentShaderSource = R"(
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.5, 0.2, 1.0);
}
)";
int main() {
// 初始化GLFW
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", NULL, NULL);
if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// 初始化GLEW
if (glewInit() != GLEW_OK) {
std::cerr << "Failed to initialize GLEW" << std::endl;
return -1;
}
// 编译顶点着色器
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// 检查顶点着色器编译错误
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cerr << "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::cerr << "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::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
// 删除着色器
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// 定义顶点数据
float vertices[] = {
0.0f, 0.5f, 0.0f, // 顶点1
-0.5f, -0.5f, 0.0f, // 顶点2
0.5f, -0.5f, 0.0f // 顶点3
};
// 创建顶点缓冲对象 (VBO) 和顶点数组对象 (VAO)
GLuint VBO, VAO;
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);
// 解绑VAO
glBindVertexArray(0);
// 渲染循环
while (!glfwWindowShouldClose(window)) {
// 处理输入
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
// 渲染
glClear(GL_COLOR_BUFFER_BIT);
// 使用着色器程序
glUseProgram(shaderProgram);
// 绑定VAO
glBindVertexArray(VAO);
// 绘制三角形
glDrawArrays(GL_TRIANGLES, 0, 3);
// 交换缓冲
glfwSwapBuffers(window);
// 轮询事件
glfwPollEvents();
}
// 删除资源
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
// 终止GLFW
glfwTerminate();
return 0;
}
2.2 代码解析
- 初始化GLFW:调用
glfwInit()
函数初始化GLFW库,如果初始化失败则退出程序。 - 创建窗口:使用
glfwCreateWindow()
函数创建一个800x600的窗口,并将其上下文设置为当前线程的上下文。 - 初始化GLEW:调用
glewInit()
函数初始化GLEW库,如果初始化失败则退出程序。 - 编译和链接着色器:
- 创建顶点着色器和片段着色器。
- 编译着色器并检查编译错误。
- 链接着色器程序并检查链接错误。
- 定义顶点数据:定义一个包含三角形顶点数据的数组。
- 创建VBO和VAO:生成并绑定顶点缓冲对象(VBO)和顶点数组对象(VAO),将顶点数据传递到缓冲区,并设置顶点属性指针。
- 渲染循环:在渲染循环中处理输入、渲染三角形、交换缓冲并轮询事件。
- 删除资源并终止GLFW:在退出程序前删除所有资源并终止GLFW。
2.3 编译和运行
将上述代码保存为main.cpp
,然后使用以下命令编译并运行:
在Linux上
g++ main.cpp -o opengl_example -lglfw -lGLEW -lGL
./opengl_example
在Windows上(使用MinGW)
g++ main.cpp -o opengl_example -lglfw3 -lglew32 -lopengl32
./opengl_example.exe
3. 🚀 总结
恭喜你!你已经成功创建了一个使用OpenGL绘制简单三角形的程序。接下来,你可以尝试以下扩展:
- 添加颜色:修改顶点着色器和片段着色器,为每个顶点添加颜色属性。
- 纹理映射:学习如何在三角形上应用纹理。
- 3D图形:探索如何使用OpenGL绘制3D图形和实现相机视角。
希望这篇博客能帮助你更好地理解和应用OpenGL。