参考学习:https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%20Window/
OpenGL入门:
目标:创建一个窗口,按下按键可以改变颜色,退出窗口
流程:
首先调用glfwInit()函数初始化GLFW。
初始化完成后使用glfwWindowHint()为接下来要创建的窗口设置好属性(hint为暗示的意思),这些属性将在设置后保持不变。(这一步实际上是对glfwCreateWindow()的上下文(context)环境进行配置,在我的理解里,设置上下文的意思就是设置属性)。以后更改窗口属性可以调用以下函数进行更改glfwWindowHint、glfwDefaultWindowHints或者glfwTerminate。
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置副版本号
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//使用核心模式
如果使用的是mac系统的话还要再加入下面的代码
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
要创建窗口的属性(即上下文)设置好之后,使用glfwCreateWindow()函数创建一个窗口对象。前两个参数分别为窗口的宽高,第三个为窗口的标题。如果窗口创建失败,该函数会返回NULL。
GLFWwindow* glWindow = glfwCreateWindow(800, 600, "Hello OPENGL", NULL, NULL);
if (!glWindow)
{
std::cout << "Create GLFWWindow Failed" << std::endl;
glfwTerminate();//终止GLFW库
return -1;
}
窗口设置完成后,调用glfwMakeContextCurrent()把创建好的窗口设置为当前线程的上下文
glfwMakeContextCurrent(glWindow);
接下来初始化glew
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
std::cout << "GLEW Init failed" << std::endl;
glfwTerminate();
return -1;
}
调用 glViewport()设置渲染窗口的大小,前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度。
glViewport(0, 0, 800, 600);
如果这时运行,创建的窗口会一闪而过。所以我们要添加一个while循环,称之为渲染循环,它能让窗口退出前一直保持运行。
glfwWindowShouldClose函数用来检查窗口是否需要退出
glfwSwapBuffers交换颜色缓冲
glfwPollEvents检查有没有触发什么事件,比如键盘输入,窗口大小改变,调用相关的回调函数
while (!glfwWindowShouldClose(glWindow))
{
glfwSwapBuffers(glWindow);
glfwPollEvents();
}
此时,在运行,窗口就不会消失。
接下来写一个函数,用于读取键盘输入,并根据输入进行输出
当按下ESC键时,窗口关闭,循环终止,程序运行结束。
当按下E键时,颜色发生变化。glClear用来清除缓冲,它可以接受一个参数,用来指定清楚的缓冲,这里我们清除掉颜色缓冲。glClearColor可以用来设置用来清楚缓冲的颜色。
void ProcessInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
{
glClearColor(0.2, 0.6, 0.8, 8);
glClear(GL_COLOR_BUFFER_BIT);
}
}
在while循环中调用该函数
while (!glfwWindowShouldClose(glWindow))
{
ProcessInput(glWindow);
glfwSwapBuffers(glWindow);
glfwPollEvents();
}
最后被忘记调用glfwTerminate()函数,在程序运行结束前关闭glfw。
运行结果
完整代码
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void ProcessInput(GLFWwindow* window);
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置副版本号
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* glWindow = glfwCreateWindow(800, 600, "Hello OPENGL", NULL, NULL);
if (!glWindow)
{
std::cout << "Create GLFWWindow Failed" << std::endl;
glfwTerminate();
return -1;
}
//把该窗口设置为当前的上下文
glfwMakeContextCurrent(glWindow);
//初始化glew
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
std::cout << "GLEW Init failed" << std::endl;
glfwTerminate();
return -1;
}
//设置渲染窗口的大小
glViewport(0, 0, 800, 600);
while (!glfwWindowShouldClose(glWindow))
{
ProcessInput(glWindow);
glfwSwapBuffers(glWindow);//交换双缓存区的颜色缓冲
glfwPollEvents();//检查有无触发事件
}
glfwTerminate();
return 0;
}
void ProcessInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
{
glClearColor(0.2, 0.6, 0.8, 8);
glClear(GL_COLOR_BUFFER_BIT);
}
}