This repository has been archived on 2024-01-06. You can view files and clone it, but cannot push or open issues or pull requests.
justhomework/OpenGL/hello/src/main.cpp

177 lines
5.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "source.h"
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
int main() {
// 设置 glfw
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// 创建窗口
GLFWwindow *window =
glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// 加载glad
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// 设置视口
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
// 创建着色器程序
Shader shader = Shader("src/cube.vs", "src/cube.fs");
Shader lightShader = Shader("src/light.vs", "src/light.fs");
unsigned int VAO, VBO, EBO;
// 创建顶点数组对象
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// 创建顶点缓冲对象
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, 6 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
// 法向量属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),
(void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 设置光源
unsigned int lightVAO;
glGenVertexArrays(1, &lightVAO);
glBindVertexArray(lightVAO);
// 只需要绑定VBO不用再次设置VBO的数据因为箱子的VBO数据中已经包含了正确的立方体顶点数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 设置灯立方体的顶点属性(对我们的灯来说仅仅只有位置数据)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
// 激活着色器
shader.use();
// 绑定纹理
shader.setInt("texture1", 0);
shader.setInt("texture2", 1);
shader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
shader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
lightShader.use();
lightShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
lightShader.setVec3("lightPos", lightPos);
// 开启深度测试
glEnable(GL_DEPTH_TEST);
// 循环渲染
while (!glfwWindowShouldClose(window)) {
// 计算帧时间差
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// 处理输入
processInput(window);
// 设置为白色
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection =
glm::perspective(glm::radians(camera.Zoom),
(float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
// 绘制三角形
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
// 设置变换矩阵
glm::mat4 trans(1.0f);
trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0, 0.25, 0.0));
shader.setMat4("trans", trans);
glBindVertexArray(VAO);
for (unsigned int i = 0; i < 10; i++) {
glm::mat4 model(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i + 50.0f;
model =
glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
lightShader.use();
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
glBindVertexArray(lightVAO);
lightShader.setMat4("projection", projection);
lightShader.setMat4("view", view);
lightShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
// 检查并调用事件,交换缓冲
glfwSwapBuffers(window);
glfwPollEvents();
}
// 释放资源
glfwTerminate();
return 0;
}
// 处理输入
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
}
// 窗口大小改变时回调该函数
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height);
}
void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
camera.ProcessMouseMovement(xpos, ypos);
}
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
camera.ProcessMouseScroll(yoffset);
}