前言:
opengl 的配置这里就不说了,上一篇有转载的一篇配置方法。
GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,这正是我们需要的
初始化 GLFW 窗口
glfwInit() 就是初始化GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
是设置opengl的主版本(major)和次版本(minor)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
这一句告诉GLFW 使用的是核心模式,明确告诉GLFW我们需要使用核心模式意味着我们只能使用OpenGL功能的一个子集
创建窗口对象
创建了一个 800*600 标题名字为 learnOpengl的窗口
GLAD
glad是管理 opengl 函数指针的,所以在调用任何的opengl函数之前我们要初始化GLAD
视口
我们已经设置了窗口的大小为800*600 现在我们要渲染的区域的大小是多少我们还没有设置,那就是视口(viewport)
设置视口
glViewport(0,0,800,600);
第一个第二个参数是起点 也就是左下角
第二个第三个参数是宽度和高度 是单位像素
现在的话当你窗口尺寸放大缩小时,视口的大小是不会变的,所以
我们要写视口随着窗口的大小变化而变化
给窗口注册一个回调函数就可以,当窗口变化时 视口也变化
ok 这个时候就可以了
渲染引擎
我们不想这个渲染的东西渲染一次就退出了,所以我们要while 一直渲染,直到我们关闭
glfwWindowShouldClose(window) 是判断GLFW 是否关闭,如果窗口关闭了也就不渲染了退出while了
glfwSwapBuffers(window); 交换颜色缓冲,双缓冲
双缓冲(Double Buffer)
应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。
这是因为生成的图像不是一下子被绘制出来的,而是按
照从左到右,由上而下逐像素地绘制而成的。最终图像
不是在瞬间显示给用户,而是通过一步一步生成的,这
会导致渲染的结果很不真实。为了规避这些问题,我们
应用双缓冲渲染窗口应用程序。前缓冲保存着最终输出
的图像,它会在屏幕上显示;而所有的的渲染指令都会
在后缓冲上绘制。当所有的渲染指令执行完毕后,我们
交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来
,之前提到的不真实感就消除了。
glfwPollEvents(); 是事件的检测,比如是否触发了键盘事件,鼠标事件等等 更新窗口状态
清空资源
整个循环渲染之后,释放所有占用的资源.
这个黑色的窗口 就是我们的GLFW
opengl 确实学起来有点费劲,比较难理解,慢慢来吧
完整code:
#include <glad/glad.h>
#include <iostream>
#include "openGL/include/GLFW/glfw3.h"
inline void frameBuffer_size_callback(GLFWwindow* w, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
std::cout << "Hello opengl!\n";
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, "learnOpengl", NULL, NULL);
if (window == NULL)
{
std::cout << "opengl window failed" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, frameBuffer_size_callback);
/*glad:load all opengl function pointer */
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initalize glad"<<std::endl;
return -1;
}
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
system("pause");
}