返回
OpenGL 初探:动手打造穿越时空隧道体验
IOS
2024-02-24 11:53:22
OpenGL 入门第八课:从理论到实践,创建一个穿越时空隧道的案例
大家好,欢迎来到 OpenGL 入门第八课。在前面几节课中,我们学习了 OpenGL 的基本知识和理论,现在是时候通过一个案例来巩固我们的知识了。
本节课,我们将创建一个穿越时空隧道的场景。这个场景将使用 OpenGL 来实现,并通过键盘控制视角的移动。
首先,我们来看一下效果图。
[图片:隧道场景效果图]
是不是很像之前玩的 cf 里面的隧道地图?没错,这就是我们本节课要实现的效果。
好了,效果图已经看到了,那么接下来我们就不闲话少说了,直接上代码吧!
// 初始化 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, "穿越时空隧道", NULL, NULL);
// 初始化 GLEW 库
glewExperimental = true;
glewInit();
// 设置视口
glViewport(0, 0, 800, 600);
// 创建着色器程序
GLuint program = glCreateProgram();
// 加载并编译顶点着色器
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
// 加载并编译片段着色器
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
// 将着色器附加到程序上
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
// 链接程序
glLinkProgram(program);
// 使用程序
glUseProgram(program);
// 创建一个顶点数组对象
GLuint vao;
glGenVertexArrays(1, &vao);
// 绑定顶点数组对象
glBindVertexArray(vao);
// 创建一个顶点缓冲区对象
GLuint vbo;
glGenBuffers(1, &vbo);
// 绑定顶点缓冲区对象
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// 将顶点数据复制到缓冲区
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// 设置颜色属性指针
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// 创建一个纹理对象
GLuint texture;
glGenTextures(1, &texture);
// 绑定纹理对象
glBindTexture(GL_TEXTURE_2D, texture);
// 加载纹理图像
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_BGR, GL_UNSIGNED_BYTE, imageData);
// 设置纹理参数
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);
// 激活纹理单元
glActiveTexture(GL_TEXTURE0);
// 绑定纹理
glBindTexture(GL_TEXTURE_2D, texture);
// 获取 uniform 位置
GLint modelViewMatrixLocation = glGetUniformLocation(program, "modelViewMatrix");
GLint projectionMatrixLocation = glGetUniformLocation(program, "projectionMatrix");
// 创建一个模型视图矩阵
glm::mat4 modelViewMatrix = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
// 创建一个投影矩阵
glm::mat4 projectionMatrix = glm::perspective(45.0f, 800.0f / 600.0f, 0.1f, 100.0f);
// 将模型视图矩阵和投影矩阵发送到着色器程序
glUniformMatrix4fv(modelViewMatrixLocation, 1, GL_FALSE, &modelViewMatrix[0][0]);
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]);
// 启用深度测试
glEnable(GL_DEPTH_TEST);
// 设置清除颜色
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// 进入游戏循环
while (!glfwWindowShouldClose(window)) {
// 处理输入
processInput(window);
// 清除颜色缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 绘制隧道
drawTunnel();
// 交换前后缓冲区
glfwSwapBuffers(window);
// 接收事件
glfwPollEvents();
}
// 释放资源
glfwTerminate();
以上就是本节课的全部内容了。通过本节课,我们学习了如何使用 OpenGL 来创建一个简单的穿越时空隧道场景。
在下一节课中,我们将继续深入探索 OpenGL 的世界,学习如何创建更加复杂的场景。
好了,今天的课程就到这里了,感谢大家的收看,我们下节课再见!