返回
从零开始入门OpenGL--球体世界及纹理
IOS
2023-09-08 16:19:56
前言
OpenGL是一个跨平台的图形库,被广泛用于3D图形编程领域。它提供了丰富的函数和工具,可以帮助开发者创建出令人惊叹的3D视觉效果。本教程将带领您从零开始学习OpenGL,并使用C++语言构建一个球体世界。我们将涵盖从基本概念到纹理和镜像显示的各个方面,帮助您快速掌握OpenGL的基础知识,并能够创建出令人惊叹的3D图形应用程序。
OpenGL简介
OpenGL是一个跨平台的图形库,它提供了一系列函数和工具,允许开发者创建和渲染3D图形。OpenGL是独立于操作系统的,这意味着它可以在各种平台上运行,包括Windows、macOS、Linux等。
OpenGL被广泛用于游戏、虚拟现实、动画等领域。它也被用于科学可视化、医学成像、CAD等专业领域。
OpenGL的基本概念
在学习OpenGL之前,我们需要了解一些基本的概念。
- 坐标系 :OpenGL使用右手坐标系,这意味着X轴指向右,Y轴指向上,Z轴指向外。
- 投影矩阵 :投影矩阵将3D坐标转换为2D坐标,以便在屏幕上显示。
- 模型视图矩阵 :模型视图矩阵将对象从模型空间转换到世界空间。
- 视口 :视口是屏幕上的一个矩形区域,用于显示3D图形。
- 纹理 :纹理是用来给3D对象添加细节和颜色的图像。
- 着色器 :着色器是用来计算每个像素颜色的程序。
构建球体世界
现在,我们已经了解了OpenGL的一些基本概念,我们可以开始构建球体世界了。
首先,我们需要创建一个OpenGL上下文。OpenGL上下文是一个用来存储OpenGL状态信息的结构体。
GLFWwindow* window;
// 初始化GLFW
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// 创建窗口
window = glfwCreateWindow(800, 600, "球体世界", NULL, NULL);
if (window == NULL)
{
glfwTerminate();
return -1;
}
// 设置当前上下文
glfwMakeContextCurrent(window);
接下来,我们需要加载纹理。纹理是一个用来给3D对象添加细节和颜色的图像。
GLuint texture;
// 加载纹理
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 加载纹理图像
int width, height, nrChannels;
unsigned char *data = stbi_load("earth.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
现在,我们可以开始渲染球体了。
GLuint VAO, VBO, EBO;
// 顶点数据
float vertices[] = {
// 位置 // 法线 // 纹理坐标
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f