首页
登录 | 注册

OpenGL学习笔记(1)--创建一个窗体

创建一个窗口

创建一个cpp文件

引入glew和glfw的头文件

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

接下来我们创建main函数,在这个函数中我们将会实例化GLFW窗口:

main(){
    //初始化GLFW
    glfwInit();
    //指定OpenGL主版本号为3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    //指定OpenGL次版本号为3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    //指定OpenGL使用核心模式,如果我们使用了任何老版本的api就会抛出错误
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //表明用户不能调整窗口大小
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    //在MacOS X 中,加入该设置,以上设置才能起作用,否则不能成功启动
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    //创建窗口对象,宽800,高600,窗口title为“FirstOpenGL”,后面两个参数设置为空,我现在暂时没搞懂是干嘛的,先不管
    GLFWwindow* window = glfwCreateWindow(800, 600, "FirstOpenGL", nullptr, nullptr);
    if(window == nullptr){
        std::cout << "Failed to initiaize GLEW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    //将窗口的上下文设置为当前线程的上下文
    glfwMakeContextCurrent(window);
    //初始化GLEW
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
        std::cout << "Failed to initialize GLEW" << std::endl;
        return -1;
    }
    //设置视口
    int width,height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);
    //游戏循环
    while(!glfwWindowShouldClose(window))
    {
        //设置清空屏幕的颜色
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        //清空屏幕,当调用glClear函数,清除颜色缓冲之后,整个颜色缓冲都会被填充为glClearColor里所设置的颜色
        glClear(GL_COLOR_BUFFER_BIT);
        //检查事件
        glfwPollEvents();
        //交换缓冲,将渲染好的像素输出到屏幕上
        glfwSwapBuffers(window);
    }
    //释放资源
    glfwTerminate();
    return 0;
}

请注意,我们在初始化GLEW之前设置glewExperimental变量的值为GL_TRUE,这样做能让GLEW在管理OpenGL的函数指针时更多地使用现代化的技术,如果把它设置为GL_FALSE的话可能会在使用OpenGL的核心模式时出现一些问题。

视口

视口是OpenGL的渲染窗口大小,我们必须告诉OpenGL渲染窗口的尺寸大小,这样OpenGL才只能知道怎样相对于窗口大小显示数据和坐标。我们从GLFW中获取视口的维度而不设置为800*600是为了让它在高DPI的屏幕上(比如说Apple的视网膜显示屏)也能正常工作。

坐标映射

OpenGL中的标准坐标范围是[-1, 1],它最终会映射在屏幕上,比如OpenGL学习笔记(1)--创建一个窗体

上图中,viewPort设置为400x400,如果一个OpenGL的坐标是(-0.5,0.5),那么它最终映射到屏幕的坐标就是(100,300)

游戏循环

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

最后在退出的时候释放掉glfw分配的资源

此时点击运行,不出意外,我们得到了一个黑乎乎的窗口

输入监听

glfwSetKeyCallback(window, key_callback) 方法用于窗口监听键盘事件,它有两个参数
* window,监听键盘事件的窗口
* key_callback,事件的回调函数,触发了键盘事件这个函数就会被调用,它有四个参数:
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
1. 触发事件的窗口
2. 按下的哪个键
3. 没搞明白这个参数是干嘛的,很多类似文章都没有提及
4.表示是按下动作还是释放动作
5.表示是否同时按下了Ctrl、Shift、Alt、Super等按钮的操作

我们定义一个回调函数,并在while循环之前设置好它

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    // 当用户按下ESC键,我们设置window窗口的WindowShouldClose属性为true
    // 关闭应用程序
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}    

运行程序,如果窗口变成了设置的颜色,那这个窗口就一切ok啦



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号