你好,窗口

  • 头文件

#include   
#include 
  • 选择版本

int main() 
{ 
    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);  return  0; 
}
  • 创建窗口对象

GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); 
if (window == NULL) 
{ 
    std::cout << "Failed to create GLFW window" << std::endl; 
    glfwTerminate(); 
    return -1; 
} 
glfwMakeContextCurrent(window);
  • GLAD

GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD。

//传入了用来加载系统相关的OpenGL函数指针地址的函数
//GLFW给我们的是 glfwGetProcAddress
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl; 
    return -1; 
}
  • 视口

我们必须告诉OpenGL渲染窗口的尺寸大小,即视口(Viewport),这样OpenGL才只能知道怎样根据窗口大小显示数据和坐标。

//前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)
glViewport(0, 0, 800, 600);

2D坐标的转换
将OpenGL中的位置坐标转换为你的屏幕坐标。处理过的OpenGL坐标范围只为-1到1,因此我们事实上将(-1~1)范围内的坐标映射到(0, 800)和(0, 600)。

当用户改变窗口的大小的时候,视口也应该被调整。我们可以对窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用。

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
//这个帧缓冲大小函数需要一个GLFWwindow作为它的第一个参数
//两个整数表示窗口的新维度
//每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理
void framebuffer_size_callback(GLFWwindow* window, int width, int height) 
{ 
    glViewport(0, 0, width, height); 
}

我们还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数:

glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

我们还可以将我们的函数注册到其它很多的回调函数中。比如说,我们可以创建一个回调函数来处理手柄输入变化,处理错误消息等。我们会在创建窗口之后,渲染循环初始化之前注册这些回调函数。

  • 渲染

渲染循环(Render Loop),它能在我们让GLFW退出前一直保持运行。

//我们每次循环的开始前检查一次GLFW是否被要求退出
//如果是的话该函数返回`true`然后渲染循环便结束了
//之后为我们就可以关闭应用程序了
while(!glfwWindowShouldClose(window)) 
{ 
    //交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲)
    //它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上
    glfwSwapBuffers(window);
    //检查有没有触发什么事件(比如键盘输入、鼠标移动等)
    //更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)
    glfwPollEvents(); 
}

双缓冲(Double Buffer)
应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。 这是因为生成的图像不是一下子被绘制出来的,而是按照从左到右,由上而下逐像素地绘制而成的。最终图像不是在瞬间显示给用户,而是通过一步一步生成的,这会导致渲染的结果很不真实。为了规避这些问题,我们应用双缓冲渲染窗口应用程序。缓冲保存着最终输出的图像,它会在屏幕上显示;而所有的的渲染指令都会在缓冲上绘制。当所有的渲染指令执行完毕后,我们交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来,之前提到的不真实感就消除了。

  • 释放资源

glfwTerminate(); 
return  0;
  • 输入

使用GLFW的glfwGetKey函数,它需要一个窗口以及一个按键作为输入。这个函数将会返回这个按键是否正在被按下。
我们将创建一个processInput函数来让所有的输入代码保持整洁。

void processInput(GLFWwindow *window) 
{ 
    //这里我们检查用户是否按下了返回键(Esc)
    //如果没按,返回GLFW_RELEASE,如果按了,属性设置为 `true`,关闭GLFW
    //下一次while循环的条件检测将会失败,程序将会关闭
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true); 
}

渲染循环的每一个迭代中调用processInput

while (!glfwWindowShouldClose(window))
{
    processInput(window); 
    //...
    //...渲染指令
    //...
    glfwSwapBuffers(window); 
    glfwPollEvents(); 
}
  • 自定义颜色清空屏幕

在每个新的渲染迭代开始的时候我们总是希望清屏,否则我们仍能看见上一次迭代的渲染结果(这可能是你想要的效果,但通常这不是)。
我们可以通过调用glClear函数清空颜色缓冲,它接受一个缓冲位(Buffer Bit)来指定要清空的缓冲,可能的缓冲位有GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT,GL_STEBCIL_BUFFER_BIT

//设置清空屏幕所用的颜色
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT);

你可能感兴趣的:(你好,窗口)