// ConsoleApplication.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
//GLEW
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "SOIL2/SOIL2.h"
#include "glm/glm.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Shader.h"
void processInput(GLFWwindow *window);
int main() {
//初始化GLFW
glfwInit();
//使用flfwWindowHint函数来配置GLFW
/*
glfwWindowHint函数的第一个参数代表选项的名称,
我们可以从很多以GLFW_开头的枚举值中选择;
第二个参数接受一个整型,
用来设置这个选项的值
*/
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwCreateWindow函数需要窗口的宽和高作为它的前两个参数
//第三个参数表示这个窗口的名称
GLFWwindow* window = glfwCreateWindow(800, 600, "B7040312", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文了
glfwMakeContextCurrent(window);
//GLEW是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLEW
//glewExperimental所做的是即使驱动程序的扩展程序字符串中不存在扩展程序,也允许加载扩展程序入口点。
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
/*
开始渲染之前还有一件重要的事情要做,我们必须告诉OpenGL渲染窗口的尺寸大小,这样OpenGL才只能知道怎样相对于窗口大小显示数据和坐标。
我们可以通过调用glViewport函数来设置窗口的维度(Dimension):
*/
/*
然而,当用户改变窗口的大小的时候,视口也应该被调整。
我们可以对窗口注册一个回调函数(Callback Function),
它会在每次窗口大小被调整的时候被调用
*/
int width, height;
glfwGetFramebufferSize(window, &width, &height);
/*
glViewport函数前两个参数控制窗口左下角的位置。
第三个和第四个参数控制渲染窗口的宽度和高度(像素),这里我们是直接从GLFW中获取的。
*/
glViewport(0, 0, width, height);
/*
我们希望程序在我们主动关闭它之前不断绘制图像并能够接受用户输入。
因此,我们需要在程序中添加一个while循环,我们可以把它称之为渲染循环(Render Loop),
它能在我们让GLFW退出前一直保持运行。
下面几行的代码就实现了一个简单的渲染循环:
*/
/*
glfwWindowShouldClose函数在我们每次循环的开始前检查一次GLFW是否被要求退出,
如果是的话该函数返回true然后渲染循环便结束了,之后为我们就可以关闭应用程序了。
*/
while (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// render
// ------
//要把所有的渲染(Rendering)操作放到渲染循环中,
//因为我们想让这些渲染指令在每次渲染循环迭代的时候都能被执行。
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
/*
glfwSwapBuffers函数会交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),
它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。
*/
/*
glfwPollEvents函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,
并调用对应的回调函数(可以通过回调方法手动设置)
*/
glfwSwapBuffers(window);
glfwPollEvents();
}
/*
当渲染循环结束后我们需要正确释放/删除之前的分配的所有资源。
我们可以在main函数的最后调用glfwTerminate函数来完成。
*/
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
//检测是否按下esc,按下则退出循环
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}