• OpenGL01(你好,窗口)


    //  OpenGL01(你好,窗口)
    
    
    #include <iostream>
    //这里需要注意头文件导入顺序,否则编译不能通过
    #include "glew.h"
    #include "glfw3.h"
    
    
    /*
        使用简介
     1> GLFW是在openGL里建立窗口用的。跟GLUT/freeglut类似。
     2> GLEW是用来管理OpenGL的函数指针的
     3> openGL都是跟着驱动来的。只要装了显卡驱动,就会有openGL。
     4> 一般来说假如用来开发的话,GLFW+GLEW+openGL就够用了。GLEW是用来智能载入很多openGL扩展函数(extensions)的。
     5> 编译的时候先载入openGL,然后是GLEW,最后是GLFW。假如是windows的话,也许还需要gdi32。 g++ -Wall -g main.cpp -lglfw -lglew32 -lopengl32 之类的。
     */
    
    
    
    /*! @brief The function signature for keyboard key callbacks.
     *
     *  This is the function signature for keyboard key callback functions.
     *
     *  @param[in] window The window that received the event.
     *  @param[in] key The [keyboard key](@ref keys) that was pressed or released.
     *  @param[in] scancode The system-specific scancode of the key.
     *  @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
     *  @param[in] mods Bit field describing which [modifier keys](@ref mods) were
     *  held down.
     *
     *  @sa @ref input_key
     *  @sa glfwSetKeyCallback
     *
     *  @since Added in version 1.0.
     *  @glfw3 Added window handle, scancode and modifier mask parameters.
     *
     *  @ingroup input
     */
    //GLFW会在合适的时候调用它,并不是因为glfwPollEvents 的触发
    //window:当前的窗口 key:按下的键 action:按下还是释放 mods:是否有Ctrl、Shift、Alt、Super等按钮的操做
    //这里我们监听到了 键盘 esc 被按下去了,然后将windowshouldclose 设置成TRUE,让引擎结束。
    void KeyCallback(GLFWwindow* window,int key,int scancode,int action,int mods){
        if (key==GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, GL_TRUE);
        }
    }
    
    //1>为什么需要清空屏幕?
    //每一个新的渲染开始的时候我们通常是希望清一下屏,否则我们总是能看见上一次的渲染结果。
    void clearWindow(){
        //设置一个颜色来清空屏幕
        glClearColor(1, 0.2, 0.2, 1);
        //清空函数,目前我们仅仅指向清空颜色
        //可能的缓冲位有GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT。
        glClear(GL_COLOR_BUFFER_BIT);
    }
    
    
    int main(int argc, const char * argv[]) {
        
        //1>初始化glfw并设置
        //实例化glfw
        if (glfwInit()!=GLFW_TRUE) {
            std::cout<<"初始化glfw失败"<<std::endl;
            return -1;
        }
        //配置glfw
        //主版本号设置
        //这里需要注意的是,我们的主次版本号是根据OpenGL来的,目前我们用的是2.1版本(目前大部分教程都是针对3.3以上的),所以设置主次版本应该以OpenGL版本来,而不是glfw的版本
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
        //次版本号设置
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
        //设置不可改变大小
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
        
        //2>窗口设置并设置
        //创建窗口对象
        //GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share)
        //参数依次为:窗口的宽,窗口的高,窗口的title,未知,未知。
        GLFWwindow * window = glfwCreateWindow(800, 600, "hello window", nullptr, nullptr);
        if (window==nullptr) {
            std::cout<<"初始化窗口失败"<<std::endl;
            return -1;
        }
        //通知glfw将窗口的上下文设置成当前线程的主上下文
        glfwMakeContextCurrent(window);
        
        //3>glew设置并设置
        //glew管理OpenGL的函数指针。glewExperimental设置成TRUE是为了让glew管理OpenGL函数指针的时候更多的使用现代化的技术,如果设置成FALSE可能会在使用OpenGL核心模式时出现问题。
        glewExperimental = GL_TRUE;
        if (glewInit()!=GLEW_OK) {
            std::cout<<"初始化glew失败"<<std::endl;
            return -1;
        }
        
        //4>视口设置viewport(告诉OpenGL渲染的窗口的尺寸大小,及渲染的位置。即:设置窗口的维度)
        //获取窗口大小
        int width,height;
        glfwGetFramebufferSize(window, &width, &height);
        //给视口视图设置位置及其大小
        //glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
        //x,y 表示视口视图相对于窗口的位置(0,0)表示在左下角;width,height是视口视图的宽高,这里我们从窗口获取大小而不直接用窗口的800*600 是为了让他能在高的DPI屏幕上(例如Apple的视网膜显示屏)也能正常工作
        //当然,我们也可以设置宽高小一点 这样在窗口上就会小一点显示
        //OpenGL的坐标范围是【-1,1】,对应的范围映射的坐标是【0,800】,【0,600】
        glViewport(0, 0, width, height);
        
        //5>注册我们函数回调
        glfwSetKeyCallback(window, KeyCallback);
        
        //6>准备引擎。目的是为了函数能够不断的绘制并能接收用户输入。而不是渲染了一次就程序退出关闭窗口了
        while (!glfwWindowShouldClose(window)) {
            //检查有没有什么事件被触发(键盘,鼠标等),然后调用对应的回到函数
            glfwPollEvents();
            
            
            //7>这里就是我们最终要的渲染指令了
            //这里我们写一个自定义颜色清空屏幕测试
            clearWindow();
            
            //交换颜色缓冲。
            //为什么使用交换颜色缓冲?
            //应用程序使用单缓冲绘图时可能会产生图像闪烁的问题,因为图像是从左到右,由上到下逐像素绘制而成,不是一瞬间就展示给用户。所以我们通常使用的是双缓冲渲染,前缓冲保存着最终渲染好的图像用于窗口显示,而渲染指令都会在后缓冲上绘制,当所有的渲染指令完成以后我们将前后缓冲交换(swap),这样图像就显示出来了。
            glfwSwapBuffers(window);
        }
        
        //6>当循环结束后,我们需要释放glfw的内存
        glfwTerminate();
        return 0;
    }
    从零开始学习OpenGL
    个人博客:http://www.cnblogs.com/fusheng-it/
    参考文献:https://learnopengl-cn.github.io/
    QQ群:209162510(新创建的群)
  • 相关阅读:
    Memcached
    sleep和wait的区别
    基于.net Core+EF Core项目的搭建(一)
    .net Core中使用AutoMapper
    发布.net core应用程序并部署到IIS上
    IoC原理-使用反射/Emit来实现一个最简单的IoC容器
    浅谈(IOC)依赖注入与控制反转(DI)
    使用MD5加密字符串
    C#中HttpWebRequest的用法详解
    学习memcached的一个网站
  • 原文地址:https://www.cnblogs.com/fusheng-it/p/7009066.html
Copyright © 2020-2023  润新知