SoftUI后端砖头

GL01-03:GLFW窗体

2019-07-28  本文已影响0人  杨强AT南京

OpenGL编程学习三个方面的知识:OpenGL + OpenGL扩展 + OpenGLUI载体:
  .1 OpenGL是3D的核心库,与显卡厂商关系密切,所以一般系统内置,或者系统开发工具内置,Linux一般使用开源,比如Mesa。
  2. OpenGL扩展,因为OpenGL与硬件的关系,所以调用需要考虑很多细节,这些细节被封装成OpenGL扩展,主要调用方便;同时提供一种硬件厂商使用自己独有功能的接口机制,只一点是OpenGL的特色;扩展很多,比如GLEW,GLAD等
  3. OpenGL载体,就是3D显示的GUI界面,事件交互,数据缓冲,显示性能呢等,这就是本文介绍的GLFW。当然OpenGL载体封装也有很多,比如glut,freeglut等。


本文仅仅介绍glfw的窗体相关的知识:
   1. 窗体对象与窗体创建
  2. 窗体属性
  3. 窗体的双缓冲机制与缓冲交换、
同时还在附录介绍了gamma校正的概念与使用


创建窗体

窗体对象

GLFWwindow的定义

typedef struct GLFWwindow GLFWwindow;

创建窗体

  1. 函数说明

    GLFWwindow* glfwCreateWindow    (   
        int     width,                              // 窗体宽度;
        int     height,                             // 窗体高度;
        const char *    title,                    // 窗体标题;
        GLFWmonitor *   monitor,          // 用来指定全屏显示模式的对象,NULL就是普通窗体模式;
        GLFWwindow *    share             // 需要共享窗体资源的窗体对象,NULL表示没有共享的窗体的对象;
)       

释放窗体

  1. 函数说明

    void glfwDestroyWindow  (   GLFWwindow *    window  )   

窗体创建的编程模式


    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ///////////////////////////////////////
        // 创建窗体
        GLFWwindow *window = glfwCreateWindow(
            800,
            600,
            "OpenGL的UI窗体",
            NULL,  //控制全屏;
            NULL  // 一起共享资源的窗体;
        );

        if(! window){
            printf("创建窗体失败!");
            glfwTerminate();
            exit(-1);
        }
        printf("创建窗体成功\n");   
        // 注意:创建窗体需要进入事件处理循环,防止程序结束;这里创建成功后,窗体会随着程序结束而释放。
        // 释放窗体
        glfwDestroyWindow(window);   
        printf("释放窗体!\n");

        ///////////////////////////////////////
        // 释放
        glfwTerminate();
        printf("环境释放退出!\n");
        return 0;
    }

    // 编译命令:g++ -omain  gl01_window_create_destroy.cpp  -lglfw -lglew -framework opengl

窗体的关闭

关闭操作标记获取

  1. glfwWindowShouldClose 函数定义说明
int glfwWindowShouldClose(  GLFWwindow *    window  )   

设置窗体关闭标记

  1. glfwSetWindowShouldClose函数说明
    void glfwSetWindowShouldClose   (   
        GLFWwindow *    window,
        int     value     // GLFW_TRUE或者GLFW_FALSE
    )   

通过关闭标记来阻止应用结束

    while (! glfwWindowShouldClose(window));

窗体的消息处理

  1. glfwPollEvents函数定义
    • 该函数只处理已经发生的在系统消息队列中的消息,消息处理完毕后马上返回。如果在循环中不调用该函数处理消息,所有的交互操作与事件都无法响应;
    • 所谓消息处理,就是根据不同的消息,处理对应的函数调用;
    • 有的平台在窗体移动,缩放的时候,会导致消息处理阻塞(glfwPollEvents函数需要等消息响应完毕才返回),这就需要单独处理。
    void glfwPollEvents (   void        )   

  1. glfwWaitEvents函数定义
    • 该函数释放运算资源,处于睡眠状态,直到有消息产生;与上面的不同的是,这种情况循环不是一直持续的,而是有消息发生才运行;

    void glfwWaitEvents (   void )  

  1. glfwWaitEventsTimeout函数定义
    • 这个函数是glfwWaitEvents函数的延时版本,就是在指定时间内,没有消息发生,该函数也会返回。
    • 参数是浮点数,单位是秒。
    void glfwWaitEventsTimeout  (   double  timeout )   

一个典型的消息处理与应用结束处理例子

  1. 方式一:
    • 主动处理式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <GLFW/glfw3.h>

int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        printf("初始化GLFW环境失败!\n");
        exit(-1);
    }
    ///////////////////////////////////////
    // 创建窗体
    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL,  //控制全屏;
        NULL  // 一起共享资源的窗体;
    );

    if(! window){
        printf("创建窗体失败!");
        glfwTerminate();
        exit(-1);
    }
    printf("创建窗体成功\n");   
    // 应用循环,直到用户关闭窗体
    // 方式一:
    while (! glfwWindowShouldClose(window)){
        // 这类可以处理自己的业务(比如OpenGL的3D对象绘制等)
        glfwPollEvents();  // 有消息处理消息,处理完毕直接返回,没有消息就直接返回。
    }

    // 释放窗体
    glfwDestroyWindow(window);   
    printf("释放窗体!\n");

    ///////////////////////////////////////
    // 释放
    glfwTerminate();
    printf("环境释放退出!\n");
    return 0;
}

// 编译命令:g++ -omain  gl02_window_loop.cpp  -lglfw -lglew -framework opengl


  1. 方式二:
    • 被动等待式。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <GLFW/glfw3.h>

int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        printf("初始化GLFW环境失败!\n");
        exit(-1);
    }
    ///////////////////////////////////////
    // 创建窗体
    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL,  //控制全屏;
        NULL  // 一起共享资源的窗体;
    );

    if(! window){
        printf("创建窗体失败!");
        glfwTerminate();
        exit(-1);
    }
    printf("创建窗体成功\n");   
    // 应用循环,直到用户关闭窗体
    // 方式二:
    while (! glfwWindowShouldClose(window)){
        // 这类可以处理自己的业务(比如OpenGL的3D对象绘制等)
        glfwWaitEvents();  // 释放资源,直到有消息发生,处理后返回
    }
    // 释放窗体
    glfwDestroyWindow(window);   
    printf("释放窗体!\n");

    ///////////////////////////////////////
    // 释放
    glfwTerminate();
    printf("环境释放退出!\n");
    return 0;
}

// 编译命令:g++ -omain  gl02_window_loop.cpp  -lglfw -lglew -framework opengl

消息等待中的唤醒

  1. 函数glfwPostEmptyEvent定义

    void glfwPostEmptyEvent (void)  

监视器

监视器对象

  1. 全屏窗体是使用窗体创建函数glfwCreateWindow的时候,需要指定一个监视器对象。
    • 监视器也是一个结构体,定义如下:
      • typedef struct GLFWmonitor GLFWmonitor

获取监视器对象

  1. glfwGetPrimaryMonitor函数说明
    GLFWmonitor* glfwGetPrimaryMonitor  (void)  
  1. glfwGetMonitors函数说明
    GLFWmonitor** glfwGetMonitors   (int * count)   
  1. 获取监视器例子代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ////////////////////////////////////
        // 得到监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        if (! primary){
            printf("获取监视器失败!\n");
            glfwTerminate();
            exit(-1);
        }
        // 获取监视器可阅读的名字
        const char* name = glfwGetMonitorName(primary);
        printf("获取的监视器是:%s\n", name);


        // 获取所有的监视器(包含接入的投影仪等)
        int count;  //用来返回监视器数量
        GLFWmonitor** monitors = glfwGetMonitors(&count);
        printf("目前支持的监视器数量:%d\n",count);
        // 循环打印所有的监视器
        // -------下面代码存在问题,因为最后一个监视器对象不存在,没有提供NULL结尾的约定,监视器指针移动容易产生段错误
        // while (*monitors){
        //     printf("监视器:%s\n", glfwGetMonitorName(*monitors));
        //     monitors ++;
        // }
        // 使用下标访问比较好。
        for(int id = 0; id < count; id++){
            printf("监视器:%s\n", glfwGetMonitorName(monitors[id]));
        }
        ////////////////////////////////////
        glfwTerminate();
        return 0;
    }

    // 编译命令:g++ -omain  gl03_window_monitor.cpp  -lglfw -lglew -framework opengl

监视器配置改变监控

  1. glfwSetMonitorCallback函数说明:

    GLFWmonitorfun glfwSetMonitorCallback   (   GLFWmonitorfun  cbfun   )   

  1. 监视器回调函数的原型定义:
    - typedef void(* GLFWmonitorfun) (GLFWmonitor *, int)
    - 参数GLFWmonitor *返回变化的监视器;
    - 参数int返回监视器配置变化的事件类型:
    - GLFW_CONNECTED
    - GLFW_DISCONNECTED.

视频模式

  1. glfwGetVideoModes函数定义
    const GLFWvidmode* glfwGetVideoModes    (   
        GLFWmonitor *   monitor,
        int *   count         // 返回视频模式的数量
    )       
        
        
    // 返回视频模式对象数组

  1. glfwGetVideoMode函数定义
    const GLFWvidmode* glfwGetVideoMode (   GLFWmonitor *   monitor )   
    // 返回当前的视频模式

  1. GLFWvidmode结构体说明

    typedef struct GLFWvidmode
    {
        /*! The width, in screen coordinates, of the video mode.
         */
        int width;
        /*! The height, in screen coordinates, of the video mode.
         */
        int height;
        /*! The bit depth of the red channel of the video mode.
         */
        int redBits;
        /*! The bit depth of the green channel of the video mode.
         */
        int greenBits;
        /*! The bit depth of the blue channel of the video mode.
         */
        int blueBits;
        /*! The refresh rate, in Hz, of the video mode.
         */
        int refreshRate;
    } GLFWvidmode;

  1. 视频模式的使用例子
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ////////////////////////////////////
        // 得到监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        if (! primary){
            printf("获取监视器失败!\n");
            glfwTerminate();
            exit(-1);
        }

        // 得到监视器当前视频模式
        const GLFWvidmode* mode = glfwGetVideoMode(primary);
        printf("当前视频模式参数:\n");
        printf("\t高宽:(%d,%d)\n", mode->height, mode->width);
        printf("\t颜色位数:(R:%d,G:%d,B:%d)\n", mode->redBits, mode->greenBits, mode->blueBits);
        printf("\t刷新频率:%d\n", mode->refreshRate);

        // 得到监视器所有支持的视频模式
        int count;
        const GLFWvidmode* modes = glfwGetVideoModes(primary, &count);
        // 数组循环方式
        for (int id = 0; id < count; id++){
            printf("当前视频模式-%02d:\n", id + 1);
            printf("\t高宽:(%d,%d)\n", modes[id].height, modes[id].width);
            printf("\t颜色位数:(R:%d,G:%d,B:%d)\n", modes[id].redBits, modes[id].greenBits, modes[id].blueBits);
            printf("\t刷新频率:%d\n", modes[id].refreshRate);
        }
        printf("---------------------------------------\n");
        // 指针循环方式(注意初始位置被改变)
        for (int id = 0; id < count; id++){
            printf("当前视频模式-%02d:\n", id + 1);
            printf("\t高宽:(%d,%d)\n", modes->height, modes->width);
            printf("\t颜色位数:(R:%d,G:%d,B:%d)\n", modes->redBits, modes->greenBits, modes->blueBits);
            printf("\t刷新频率:%d\n", modes->refreshRate);
            modes++;
        }

        ////////////////////////////////////
        glfwTerminate();
        return 0;
    }

    // 编译命令:g++ -omain  gl04_window_video_mode.cpp  -lglfw -lglew -framework opengl

监视器物理大小

  1. glfwGetMonitorPhysicalSize函数定义
void glfwGetMonitorPhysicalSize (   
    GLFWmonitor *   monitor,
    int *   widthMM,     // 返回宽度
    int *   heightMM    // 返回高度
)   

内容缩放

  1. glfwGetMonitorContentScale函数定义
void glfwGetMonitorContentScale (   
    GLFWmonitor *   monitor,
    float *     xscale,    // x方向缩放
    float *     yscale     // y方向缩放
)   

虚拟位置

  1. glfwGetMonitorPos函数说明
void glfwGetMonitorPos  (   
    GLFWmonitor *   monitor,
    int *   xpos,    // x-位置
    int *   ypos     // y-位置
)   
  1. 屏幕坐标系
    • 如果系统链接多个监视器,则使用虚拟屏幕的概念,如下图所示:
    • 监视器对象的屏幕管理坐标系

工作区域

  1. 函数glfwGetMonitorWorkarea定义
void glfwGetMonitorWorkarea (   
    GLFWmonitor *   monitor,
    int *   xpos,       // 区域原点
    int *   ypos,
    int *   width,      // 区域大小
    int *   height 
)       

监视器可阅读的名字

  1. 函数glfwGetMonitorName定义
    const char* glfwGetMonitorName  (   GLFWmonitor *   monitor )   

监视器用户指针

  1. 函数glfwSetMonitorUserPointer定义
    void glfwSetMonitorUserPointer  (   
        GLFWmonitor *   monitor,
        void *  pointer 
    )   
  1. 函数glfwGetMonitorUserPointer定义
    void* glfwGetMonitorUserPointer (   GLFWmonitor *   monitor )   

监视器的Gamma设置

  1. 函数glfwGetGammaRamp定义
    const GLFWgammaramp* glfwGetGammaRamp   (   GLFWmonitor *   monitor )   

  1. 函数glfwSetGammaRamp定义
    void glfwSetGammaRamp   (   
        GLFWmonitor *   monitor,
        const GLFWgammaramp *   ramp 
    )       

  1. 结构体GLFWgammaramp定义
typedef struct GLFWgammaramp
{
    /*! An array of value describing the response of the red channel.*/
    unsigned short* red;
    /*! An array of value describing the response of the green channel.*/
    unsigned short* green;
    /*! An array of value describing the response of the blue channel. */
    unsigned short* blue;
    /*! The number of elements in each array.*/
    unsigned int size;
} GLFWgammaramp;
  1. 函数glfwSetGamma定义
    • 没有对应的获取函数。
    void glfwSetGamma   (   
        GLFWmonitor *   monitor,
        float   gamma 
    )   

监视器的属性使用例子代码

  1. 属性使用例子代码-1

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ////////////////////////////////////
        // 得到监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        if (! primary){
            printf("获取监视器失败!\n");
            glfwTerminate();
            exit(-1);
        }
        // 物理大小
        int width_mm, height_mm;
        glfwGetMonitorPhysicalSize(primary, &width_mm, &height_mm);
        printf("物理大小:(%d,%d)\n", width_mm, height_mm);

        // 内容缩放
        float xscale, yscale;
        glfwGetMonitorContentScale(primary, &xscale, &yscale);
        printf("内容缩放:(%f,%f)\n", xscale, yscale);

        // 虚拟位置
        int xpos, ypos;
        glfwGetMonitorPos(primary, &xpos, &ypos);
        printf("虚拟位置:(%d,%d)\n", xpos, ypos);

        // 工作区域
        int w_xpos, w_ypos, w_width, w_height;
        glfwGetMonitorWorkarea(primary, &w_xpos, &w_ypos, &w_width, &w_height);
        printf("工作区域(%d, %d, %d, %d)\n", w_xpos, w_xpos, w_width, w_height);

        // 监视器名
        const char* name = glfwGetMonitorName(primary);
        printf("监视器:%s\n", name);

        // 用户指针(用来存放用户任意数据)
        const char* my_name = "Louis";
        // 设置用户指针
        glfwSetMonitorUserPointer(primary, (void *)my_name);    
        // 获取用户指针
        const char *data =  (const char*)glfwGetMonitorUserPointer(primary);
        printf("获取存储的数据:%s\n", data);

        ////////////////////////////////////
        glfwTerminate();
        return 0;
    }

    // 编译命令:g++ -omain  gl05_window_monitor_property.cpp  -lglfw -lglew -framework opengl

  1. 属性使用例子代码-2(gamma校正)

    • 下面代码可以自己调整gamma值,观察效果,截图截不到效果。因为gamma的值影响到监视器;图像数据本身不受影响。
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        // 创建窗体
        GLFWwindow *window = glfwCreateWindow(
            800,
            600,
            "OpenGL的UI窗体",
            NULL,  //控制全屏;
            NULL  // 一起共享资源的窗体;
        );

        if(! window){
            printf("创建窗体失败!");
            glfwTerminate();
            exit(-1);
        }
        ////////////////////////////////////////
        // 得到监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        if (! primary){
            printf("获取监视器失败!\n");
            glfwTerminate();
            exit(-1);
        }
        //设置gamma值
        glfwSetGamma(primary, 10.0);      // 调整gamma值;
        ////////////////////////////////////////
        while (! glfwWindowShouldClose(window)){
            // 这类可以处理自己的业务(比如OpenGL的3D对象绘制等)
            glfwWaitEvents();  // 释放资源,直到有消息发生,处理后返回
        }
        // 释放窗体
        glfwDestroyWindow(window);  
        // 释放
        glfwTerminate();
        printf("环境释放退出!\n");
        return 0;
    }

    // 编译命令:g++ -omain  gl06_window_monitor_gamma.cpp  -lglfw -lglew -framework opengl

  1. Gamma Ramp(Gamma斜面)的使用离子
    • 下面代码把64改成其他值试试
      • 取64的原因是,Gamma的颜色通道使用unsigned int,一共16位,表示的数值为0-65535 ;一般Ramp斜面的大小为1024,则每个值的间隔就是65536/1024,这样才能均匀填充0-65535之间的值。
    • Gamma Ramp实际是一种颜色的表示机制,类似调色板,任何绘制的图像的像素分成RGB三通道,每个通道的值在Ramp中存在一个接近的映射;
      • 如果Ramp的Red数组全部为0,则图像像素的红色通道都映射为0,图像的红色丢失。
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        // 创建窗体
        GLFWwindow *window = glfwCreateWindow(
            800,
            600,
            "OpenGL的UI窗体",
            NULL,  //控制全屏;
            NULL  // 一起共享资源的窗体;
        );

        if(! window){
            printf("创建窗体失败!");
            glfwTerminate();
            exit(-1);
        }
        ////////////////////////////////////////
        // 得到监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        if (! primary){
            printf("获取监视器失败!\n");
            glfwTerminate();
            exit(-1);
        }
        //获取Gamma Ramp值

        const GLFWgammaramp* ramp = glfwGetGammaRamp(primary);
        printf("Ramp的size:%d\n", ramp->size);

        // 获取每个值显示
        printf("Ramp的Red:\n");
        for(int i = 0; i < ramp->size; i++){
            ramp->red[i] = 64 * i;   // 修改gamma斜面的红色通道值(默认的都是64的间隔距离,效果最正常)
        }

        // 使用新的Gamma Ramp值
        glfwSetGammaRamp(primary, ramp);
        ////////////////////////////////////////
        while (! glfwWindowShouldClose(window)){
            // 这类可以处理自己的业务(比如OpenGL的3D对象绘制等)
            glfwWaitEvents();  // 释放资源,直到有消息发生,处理后返回
        }
        // 释放窗体
        glfwDestroyWindow(window);  
        // 释放
        glfwTerminate();
        printf("环境释放退出!\n");
        return 0;
    }

    // 编译命令:g++ -omain  gl07_window_monitor_gamma_ramp.cpp  -lglfw -lglew -framework opengl

全屏窗体

全屏方式1

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ///////////////////////////////////////
        // 获取监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
         // 得到监视器当前视频模式
        const GLFWvidmode* mode = glfwGetVideoMode(primary);
        // 创建窗体
        GLFWwindow *window = glfwCreateWindow(
            mode->width,
            mode->height,
            "OpenGL的UI窗体",
            primary,  //控制全屏;
            NULL  // 一起共享资源的窗体;
        );

        if(! window){
            printf("创建窗体失败!");
            glfwTerminate();
            exit(-1);
        }
        printf("创建窗体成功\n");   


        while (! glfwWindowShouldClose(window)){
            glfwPollEvents();  
        }
        glfwDestroyWindow(window);   // 如果有glfwTerminate,则敢函数可以省略。
        glfwTerminate();
        return 0;
    }

    // 编译命令:g++ -omain  gl08_window_fullscreen.cpp  -lglfw -lglew -framework opengl

全屏方式2-设置窗体的监视器

  1. 函数glfwSetWindowMonitor定义

void glfwSetWindowMonitor   (   
    GLFWwindow *    window,
    GLFWmonitor *   monitor,
    int     xpos,
    int     ypos,
    int     width,
    int     height,
    int     refreshRate 
)   
  1. 设置窗体监视器的例子代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <GLFW/glfw3.h>

    int main(int argc, char const *argv[]){
        // 初始化
        int re = glfwInit();
        if(re == GLFW_FALSE){
            printf("初始化GLFW环境失败!\n");
            exit(-1);
        }
        ///////////////////////////////////////
        // 获取监视器
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
         // 得到监视器当前视频模式
        const GLFWvidmode* mode = glfwGetVideoMode(primary);
        // 创建窗体
        GLFWwindow *window = glfwCreateWindow(
            200,
            200,
            "OpenGL的UI窗体",
            NULL,  //控制全屏;
            NULL  // 一起共享资源的窗体;
        );

        if(! window){
            printf("创建窗体失败!");
            glfwTerminate();
            exit(-1);
        }

        ///////////////////////////
        // 设置窗体的监视器
        //  全屏方式
        // glfwSetWindowMonitor(window, primary, 10, 10,mode->width,mode->height,59);
        // 不全屏,改变窗体的位置与大小。
        glfwSetWindowMonitor(window, NULL, 100, 100,600,400,0);
        ////////////////////
        while (! glfwWindowShouldClose(window)){
            glfwPollEvents();  
        }
        glfwDestroyWindow(window);   // 如果有glfwTerminate,则敢函数可以省略。
        glfwTerminate();
        return 0;
    }

    // 编译命令:g++ -omain  gl09_window_fullscreen_set_monitor.cpp  -lglfw -lglew -framework opengl

  1. 获取窗体的监视器函数定义:
    GLFWmonitor* glfwGetWindowMonitor   (   GLFWwindow *    window  )   

窗体创建中的提示设置

提示设置函数

  1. glfwWindowHint函数定义

    void glfwWindowHint (   
        int     hint,
        int     value 
    )       
  1. glfwWindowHintString函数定义
void glfwWindowHintString   (   
    int     hint,
    const char *    value 
)   
  1. glfwDefaultWindowHints函数定义
    void glfwDefaultWindowHints (   void        )   

Hint的硬约束与软约束

  1. 常见的硬约束

    • GLFW_STEREO
    • GLFW_DOUBLEBUFFER
    • GLFW_CLIENT_API
    • GLFW_CONTEXT_CREATION_API
  2. 只对OpenGL的硬约束提示,对OpenGL ES无效的硬约束提示

    • GLFW_OPENGL_FORWARD_COMPAT
    • GLFW_OPENGL_PROFILE

窗体的提示分类

窗体提示的缺省值

Window hint Default value Supported values
GLFW_RESIZABLE GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_VISIBLE GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_DECORATED GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_FOCUSED GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_AUTO_ICONIFY GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_FLOATING GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_MAXIMIZED GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_CENTER_CURSOR GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_TRANSPARENT_FRAMEBUFFER GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_FOCUS_ON_SHOW GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_SCALE_TO_MONITOR GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_RED_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
GLFW_GREEN_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
GLFW_BLUE_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
GLFW_ALPHA_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
GLFW_DEPTH_BITS 24 0 to INT_MAX or GLFW_DONT_CARE
GLFW_STENCIL_BITS 8 0 to INT_MAX or GLFW_DONT_CARE
GLFW_ACCUM_RED_BITS 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_ACCUM_GREEN_BITS 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_ACCUM_BLUE_BITS 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_ACCUM_ALPHA_BITS 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_AUX_BUFFERS 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_SAMPLES 0 0 to INT_MAX or GLFW_DONT_CARE
GLFW_REFRESH_RATE GLFW_DONT_CARE 0 to INT_MAX or GLFW_DONT_CARE
GLFW_STEREO GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_SRGB_CAPABLE GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_DOUBLEBUFFER GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_CLIENT_API GLFW_OPENGL_API GLFW_OPENGL_API, GLFW_OPENGL_ES_API or GLFW_NO_API
GLFW_CONTEXT_CREATION_API GLFW_NATIVE_CONTEXT_API GLFW_NATIVE_CONTEXT_API, GLFW_EGL_CONTEXT_API or GLFW_OSMESA_CONTEXT_API
GLFW_CONTEXT_VERSION_MAJOR 1 Any valid major version number of the chosen client API
GLFW_CONTEXT_VERSION_MINOR 0 Any valid minor version number of the chosen client API
GLFW_CONTEXT_ROBUSTNESS GLFW_NO_ROBUSTNESS GLFW_NO_ROBUSTNESS, GLFW_NO_RESET_NOTIFICATION or GLFW_LOSE_CONTEXT_ON_RESET
GLFW_CONTEXT_RELEASE_BEHAVIOR GLFW_ANY_RELEASE_BEHAVIOR GLFW_ANY_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH or GLFW_RELEASE_BEHAVIOR_NONE
GLFW_OPENGL_FORWARD_COMPAT GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_OPENGL_DEBUG_CONTEXT GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_OPENGL_PROFILE GLFW_OPENGL_ANY_PROFILE GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE or GLFW_OPENGL_CORE_PROFILE
GLFW_COCOA_RETINA_FRAMEBUFFER GLFW_TRUE GLFW_TRUE or GLFW_FALSE
GLFW_COCOA_FRAME_NAME "" A UTF-8 encoded frame autosave name
GLFW_COCOA_GRAPHICS_SWITCHING GLFW_FALSE GLFW_TRUE or GLFW_FALSE
GLFW_X11_CLASS_NAME "" An ASCII encoded WM_CLASS class name
GLFW_X11_INSTANCE_NAME "" An ASCII encoded WM_CLASS instance name

窗体创建的提示例子代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <png.h>
#include <GLFW/glfw3.h>

int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        printf("初始化GLFW环境失败!\n");
        exit(-1);
    }
    ///////////////////////////////////////
    //窗体创建的提示
    /*
        与监视器一样大小:此提示仅对屏幕坐标和像素始终映射为1:1(如Windows和x11)的平台有效。
        在像MacOS这样的平台上,帧缓冲区的分辨率与窗口大小无关。
     */
    glfwWindowHint(GLFW_SCALE_TO_MONITOR,GLFW_TRUE);   
    // 窗体装饰(GLFW_FALSE:表示去掉边框,标题栏,系统按钮等)
    // glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);  
    // 窗体大小变化(是否可以使用鼠标拖拽改变大小)

    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);    // 整数方式

    glfwWindowHintString(GLFW_COCOA_FRAME_NAME, "Louis");    // 字符串方式,只用于字符串数据的Hint。
      
    ///////////////////////////////////////
    // 创建窗体
    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL, 
        NULL  
    );

    if(! window){
        exit(-1);
    }
    //////////////////////////////////////
    // 恢复Window的缺省提示
    glfwDefaultWindowHints();
    ///////////////////////////////////////
    while (! glfwWindowShouldClose(window)){
        glfwWaitEvents();  
    }

    glfwDestroyWindow(window);   
    glfwTerminate();
    return 0;
}

// 编译命令:g++ -omain  gl10_window_hint.cpp  -lglfw -lglew -framework opengl

窗体属性

窗体的用户指针

  1. glfwSetWindowUserPointer函数说明
void glfwSetWindowUserPointer   (   
    GLFWwindow *    window,
    void *  pointer 
)   
  1. glfwGetWindowUserPointer函数说明
    void* glfwGetWindowUserPointer  (   GLFWwindow *    window  )   

窗体的关闭

  1. glfwWindowShouldClose函数说明
    int glfwWindowShouldClose   (   GLFWwindow *    window  )   
  1. glfwSetWindowShouldClose 函数说明
void glfwSetWindowShouldClose   (   
    GLFWwindow *    window,
    int     value     // GLFW_TRUE 或者 GLFW_FALSE
)   
  1. glfwSetWindowCloseCallback函数说明
GLFWwindowclosefun glfwSetWindowCloseCallback   (   
    GLFWwindow *    window,
    GLFWwindowclosefun  cbfun 
)   
  1. GLFWwindowclosefun回调函数原型定义
    typedef void(* GLFWwindowclosefun) (GLFWwindow *)
  1. 控制窗体关闭的例子代码
    • 下面代码使用kill -9 进程ID关闭;其他方式不能关闭并退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <png.h>
#include <GLFW/glfw3.h>

 void cb_close(GLFWwindow * win){
     // 关闭操作的回调函数
     printf("关闭操作\n");

     // 防止退出,可以在回调函数中修改关闭状态为GLFW_FALSE
     glfwSetWindowShouldClose(win, GLFW_FALSE);    
 }


int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        exit(-1);
    }
    // 创建窗体
    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL, 
        NULL  
    );

    if(! window){
        exit(-1);
    }
    // 设置窗体关闭按钮的回调操作
    GLFWwindowclosefun old_callback = glfwSetWindowCloseCallback(window, cb_close);
    // 设置窗体的关闭标记 (设置标记后,下面的循环无法进去)
    //glfwSetWindowShouldClose(window, GLFW_TRUE);    

    while (! glfwWindowShouldClose(window)){
        glfwWaitEvents();  
    }

    glfwDestroyWindow(window);   
    glfwTerminate();
    return 0;
}

// 编译命令:g++ -omain  gl11_window_close.cpp  -lglfw -lglew -framework opengl

窗体大小

  1. glfwSetWindowSize函数说明

void glfwSetWindowSize  (   
    GLFWwindow *    window,
    int     width,
    int     height 
)   
  1. glfwGetWindowSize函数说明
void glfwGetWindowSize  (   
    GLFWwindow *    window,
    int *   width,
    int *   height 
)   
  1. glfwSetWindowSizeCallback函数说明

GLFWwindowsizefun glfwSetWindowSizeCallback (   
    GLFWwindow *    window,
    GLFWwindowsizefun   cbfun 
)   
  1. GLFWwindowsizefun回调函数说明
    typedef void(* GLFWwindowsizefun) (GLFWwindow *, int, int)
  1. glfwGetWindowFrameSize函数说明
void glfwGetWindowFrameSize (   
    GLFWwindow *    window,
    int *   left,
    int *   top,
    int *   right,
    int *   bottom 
)   
  1. 监控窗体大小改变的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <png.h>
#include <GLFW/glfw3.h>

 void cb_size(GLFWwindow * win, int width, int height){
     // 窗体大小改变操作的回调函数
     int left, top, right, bottom;
    glfwGetWindowFrameSize(win, &left, &top, &right, &bottom);
     printf("窗体大小改变:(%d,%d),Framesize(%d, %d, %d, %d)\n", width, height, left, top, right, bottom);  
 }


int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        exit(-1);
    }
    // 创建窗体
    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL, 
        NULL  
    );

    if(! window){
        exit(-1);
    }

    // 设置窗体的大小改变的回调函数
    GLFWwindowsizefun old_cb =  glfwSetWindowSizeCallback(window, cb_size);

    while (! glfwWindowShouldClose(window)){
        glfwWaitEvents();  
    }

    glfwDestroyWindow(window);   
    glfwTerminate();
    return 0;
}

// 编译命令:g++ -omain  gl12_window_size.cpp  -lglfw -lglew -framework opengl

FrameBuffer大小

  1. glfwGetFramebufferSize函数说明
void glfwGetFramebufferSize (   
    GLFWwindow *    window,
    int *   width,
    int *   height 
)   
  1. glfwSetFramebufferSizeCallback函数说明
GLFWframebuffersizefun glfwSetFramebufferSizeCallback   (   
    GLFWwindow *    window,
    GLFWframebuffersizefun  cbfun 
)   

窗体内容缩放

  1. glfwGetWindowContentScale函数说明:

void glfwGetWindowContentScale  (   
    GLFWwindow *    window,
    float *     xscale,
    float *     yscale 

  1. glfwSetWindowContentScaleCallback函数说明:

GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (   
    GLFWwindow *    window,
    GLFWwindowcontentscalefun   cbfun 
)   
  1. 回调函数GLFWwindowcontentscalefun的原型定义
    typedef void(* GLFWwindowcontentscalefun) (GLFWwindow *, float, float)

窗体大小限制

  1. glfwSetWindowSizeLimits函数说明

void glfwSetWindowSizeLimits    (   
    GLFWwindow *    window,
    int     minwidth,
    int     minheight,
    int     maxwidth,
    int     maxheight 
)   
  1. glfwSetWindowAspectRatio函数说明

void glfwSetWindowAspectRatio   (   
    GLFWwindow *    window,
    int     numer,       //所需纵横比的分子
    int     denom       //所需纵横比的分母
)   

窗体位置

  1. glfwSetWindowPos函数说明
void glfwSetWindowPos   (   
    GLFWwindow *    window,
    int     xpos,
    int     ypos 
)   
  1. glfwSetWindowPosCallback函数说明

GLFWwindowposfun glfwSetWindowPosCallback   (   
    GLFWwindow *    window,
    GLFWwindowposfun    cbfun 
)   
  1. GLFWwindowposfun原型说明
    typedef void(* GLFWwindowposfun) (GLFWwindow *, int, int)
  1. glfwGetWindowPos函数说明
void glfwGetWindowSize  (   
    GLFWwindow *    window,
    int *   width,
    int *   height 
)   

窗体标题

  1. glfwSetWindowTitle函数说明
void glfwSetWindowTitle (   
    GLFWwindow *    window,
    const char *    title 
)   

窗体图标

  1. glfwSetWindowIcon函数说明
    • 此函数设置指定窗口的图标。如果传递了一组候选图像,则会选择系统所需大小或最接近系统所需大小的图像。如果未指定图像,窗口将恢复为其默认图标。
    • MAC 系统的glfw窗口没有图标,因为它不是文档窗口,所以此函数不起任何作用。Dock图标将与应用程序包的图标相同。

void glfwSetWindowIcon  (   
    GLFWwindow *    window,
    int     count,                                  // 图像数量
    const GLFWimage *   images          // 图像数据结构
)   
  1. 图像结构体
    typedef struct GLFWimage
    {
        /*! The width, in pixels, of this image.
         */
        int width;
        /*! The height, in pixels, of this image.
         */
        int height;
        /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
         */
        unsigned char* pixels;
    } GLFWimage;
  1. 图标使用的例子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <png.h>
#include <GLFW/glfw3.h>

int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        exit(-1);
    }

    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL, 
        NULL  
    );

    if(! window){
        exit(-1);
    }

    /////////////////////////
    /*
    - RGBA格式的小端字节序。
    - 像素为32位,即每个通道8位,首先是红色通道。从左上角开始,它们按规范排列为压缩的连续行。
    - 所需的图像大小因平台和系统设置而异。所选图像将根据需要重新缩放。好尺寸包括16x16、32x32和48x48。
     */
    // 构造一个图像格式数据(黑图像)
    GLFWimage img;
    img.width = 48;
    img.height = 48;
    // 分配内存空间
    size_t buff_size = img.width * img.height * 4; // 字节
    unsigned char *buff = (unsigned char *)malloc(buff_size);
    // 初始化空间
    bzero(buff,buff_size);
    // 设置图标的数据缓存
    img.pixels = buff;
    
    // 设置图标
    printf("设置图标");
    glfwSetWindowIcon(window, 1, &img); 
    /////////////////////////

    while (! glfwWindowShouldClose(window)){
        glfwWaitEvents();  
    }

    glfwDestroyWindow(window);   
    glfwTerminate();
    return 0;
}

// 编译命令:g++ -omain  gl13_window_icon.cpp  -lglfw -lglew -framework opengl

窗体监视器

  1. glfwGetWindowMonitor函数说明

GLFWmonitor* glfwGetWindowMonitor(GLFWwindow *  window  )   

  1. glfwSetWindowMonitor函数说明
void glfwSetWindowMonitor(GLFWwindow *  window,
    GLFWmonitor *   monitor,
    int     xpos,
    int     ypos,
    int     width,
    int     height,
    int     refreshRate 
)   

窗体图标化

  1. glfwIconifyWindow函数说明

void glfwIconifyWindow  (   GLFWwindow *    window  )   

  1. glfwRestoreWindow函数说明
void glfwRestoreWindow  (   GLFWwindow *    window  )   

  1. glfwSetWindowIconifyCallback函数说明
GLFWwindowiconifyfun glfwSetWindowIconifyCallback   (   
    GLFWwindow *    window,
    GLFWwindowiconifyfun    cbfun 
)   
  1. 回调函数GLFWwindowiconifyfun原型说明

typedef void(* GLFWwindowiconifyfun) (GLFWwindow *, int)

  1. glfwGetWindowAttrib函数说明
int glfwGetWindowAttrib (   
    GLFWwindow *    window,
    int     attrib 
)   
  1. 窗体特性
    • 与窗体有关的特性包含:
      • GLFW_FOCUSED
      • GLFW_ICONIFIED
      • GLFW_MAXIMIZED
      • GLFW_HOVERED
      • GLFW_VISIBLE
      • GLFW_RESIZABLE
      • GLFW_DECORATED
      • GLFW_AUTO_ICONIFY
      • GLFW_FLOATING
      • GLFW_TRANSPARENT_FRAMEBUFFER
      • GLFW_FOCUS_ON_SHOW
    • 与上下文有关的特性;(参考官方文档)
    • 与FrameBuffer有关的特性;(参考官方文档)

窗体最大化

  1. glfwMaximizeWindow函数说明
void glfwMaximizeWindow (   GLFWwindow *    window  )   

  1. glfwSetWindowMaximizeCallback函数说明
GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (   
    GLFWwindow *    window,
    GLFWwindowmaximizefun   cbfun 
)   
  1. GLFWwindowmaximizefun回调函数原型说明

typedef void(* GLFWwindowmaximizefun) (GLFWwindow *, int)  
    // 参数是逻辑值,GLFW_TRUE 与 GLFW_FALSE

窗体可见

  1. 函数说明
void glfwHideWindow (   GLFWwindow *    window  )   
  1. 函数说明
void glfwShowWindow (   GLFWwindow *    window  )   

窗体输入焦点

  1. 函数说明
void glfwFocusWindow    (   GLFWwindow *    window  )   

  1. 函数说明
GLFWwindowfocusfun glfwSetWindowFocusCallback   (   
    GLFWwindow *    window,
    GLFWwindowfocusfun  cbfun 
)   
  1. GLFWwindowfocusfun回调函数原型说明

typedef void(* GLFWwindowfocusfun) (GLFWwindow *, int)
        // 第二个参数:焦点状态:GLFW_TRUE 或 GLFW_FALSE

窗体关注

  1. glfwRequestWindowAttention函数说明
    void glfwRequestWindowAttention (   GLFWwindow *    window  )

窗体刷新

  1. glfwSetWindowRefreshCallback函数说明
GLFWwindowrefreshfun glfwSetWindowRefreshCallback   (   
    GLFWwindow *    window,
    GLFWwindowrefreshfun    cbfun 
)   
  1. 回调函数GLFWwindowrefreshfun原型说明
typedef void(* GLFWwindowrefreshfun) (GLFWwindow *)

窗体透明

  1. glfwSetWindowOpacity函数说明:

void glfwSetWindowOpacity   (   
    GLFWwindow *    window,
    float   opacity 
)   
  1. glfwGetWindowOpacity函数说明:

float glfwGetWindowOpacity  (   GLFWwindow *    window  )   

窗体特性

  1. glfwGetWindowAttrib函数说明

int glfwGetWindowAttrib (   
    GLFWwindow *    window,
    int     attrib 
)   
  1. glfwSetWindowAttrib函数说明
void glfwSetWindowAttrib(   
    GLFWwindow *    window,
    int     attrib,
    int     value 
)       

双缓冲与交换

  1. glfwSwapBuffers函数说明
    void glfwSwapBuffers(GLFWwindow *   window) 

  1. glfwSwapInterval函数说明
    void glfwSwapInterval(int interval) 

  1. 经典的绘制刷新模式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <png.h>
#include <GLFW/glfw3.h>

int main(int argc, char const *argv[]){
    // 初始化
    int re = glfwInit();
    if(re == GLFW_FALSE){
        exit(-1);
    }

    GLFWwindow *window = glfwCreateWindow(
        800,
        600,
        "OpenGL的UI窗体",
        NULL, 
        NULL  
    );

    if(! window){
        exit(-1);
    }

    while (! glfwWindowShouldClose(window)){
        // 完成图形绘制
        // ......
        // 设置监视器的最低刷新数
        glfwSwapInterval(2);
        // 交换缓冲区
        glfwSwapBuffers(window);
        
        glfwWaitEvents();  
    }

    glfwDestroyWindow(window);   
    glfwTerminate();
    return 0;
}

// 编译命令:g++ -omain  gl13_window_icon.cpp  -lglfw -lglew -framework opengl

  1. 提示:
    • 还可以通过刷新回调来实现图形绘制。

附录

宏定义

#define GLFW_FOCUSED 0x00020001

#define GLFW_ICONIFIED 0x00020002

#define GLFW_RESIZABLE 0x00020003

#define GLFW_VISIBLE 0x00020004

#define GLFW_DECORATED 0x00020005

#define GLFW_AUTO_ICONIFY 0x00020006

#define GLFW_FLOATING 0x00020007

#define GLFW_MAXIMIZED 0x00020008

#define GLFW_CENTER_CURSOR 0x00020009

#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A

#define GLFW_HOVERED 0x0002000B

#define GLFW_FOCUS_ON_SHOW 0x0002000C

#define GLFW_RED_BITS 0x00021001

#define GLFW_GREEN_BITS 0x00021002

#define GLFW_BLUE_BITS 0x00021003

#define GLFW_ALPHA_BITS 0x00021004

#define GLFW_DEPTH_BITS 0x00021005

#define GLFW_STENCIL_BITS 0x00021006

#define GLFW_ACCUM_RED_BITS 0x00021007

#define GLFW_ACCUM_GREEN_BITS 0x00021008

#define GLFW_ACCUM_BLUE_BITS 0x00021009

#define GLFW_ACCUM_ALPHA_BITS 0x0002100A

#define GLFW_AUX_BUFFERS 0x0002100B

#define GLFW_STEREO 0x0002100C

#define GLFW_SAMPLES 0x0002100D

#define GLFW_SRGB_CAPABLE 0x0002100E

#define GLFW_REFRESH_RATE 0x0002100F

#define GLFW_DOUBLEBUFFER 0x00021010

#define GLFW_CLIENT_API 0x00022001

#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002

#define GLFW_CONTEXT_VERSION_MINOR 0x00022003

#define GLFW_CONTEXT_REVISION 0x00022004

#define GLFW_CONTEXT_ROBUSTNESS 0x00022005

#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006

#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007

#define GLFW_OPENGL_PROFILE 0x00022008

#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009

#define GLFW_CONTEXT_NO_ERROR 0x0002200A

#define GLFW_CONTEXT_CREATION_API 0x0002200B

#define GLFW_SCALE_TO_MONITOR 0x0002200C

#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001

#define GLFW_COCOA_FRAME_NAME 0x00023002

#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003

#define GLFW_X11_CLASS_NAME 0x00024001

#define GLFW_X11_INSTANCE_NAME 0x00024002

类型定义

typedef struct GLFWwindow GLFWwindow

typedef void(* GLFWwindowposfun) (GLFWwindow *, int, int)

typedef void(* GLFWwindowsizefun) (GLFWwindow *, int, int)

typedef void(* GLFWwindowclosefun) (GLFWwindow *)

typedef void(* GLFWwindowrefreshfun) (GLFWwindow *)

typedef void(* GLFWwindowfocusfun) (GLFWwindow *, int)

typedef void(* GLFWwindowiconifyfun) (GLFWwindow *, int)

typedef void(* GLFWwindowmaximizefun) (GLFWwindow *, int)

typedef void(* GLFWframebuffersizefun) (GLFWwindow *, int, int)

typedef void(* GLFWwindowcontentscalefun) (GLFWwindow *, float, float)

typedef struct GLFWimage GLFWimage

函数定义

void glfwDefaultWindowHints (void)

void glfwWindowHint (int hint, int value)

void glfwWindowHintString (int hint, const char *value)

GLFWwindow * glfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)

void glfwDestroyWindow (GLFWwindow *window)

int glfwWindowShouldClose (GLFWwindow *window)

void glfwSetWindowShouldClose (GLFWwindow *window, int value)

void glfwSetWindowTitle (GLFWwindow *window, const char *title)

void glfwSetWindowIcon (GLFWwindow *window, int count, const GLFWimage *images)

void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)

void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)

void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)

void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)

void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)

void glfwSetWindowSize (GLFWwindow *window, int width, int height)

void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)

void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)

void glfwGetWindowContentScale (GLFWwindow *window, float *xscale, float *yscale)

float glfwGetWindowOpacity (GLFWwindow *window)

void glfwSetWindowOpacity (GLFWwindow *window, float opacity)

void glfwIconifyWindow (GLFWwindow *window)

void glfwRestoreWindow (GLFWwindow *window)

void glfwMaximizeWindow (GLFWwindow *window)

void glfwShowWindow (GLFWwindow *window)

void glfwHideWindow (GLFWwindow *window)

void glfwFocusWindow (GLFWwindow *window)

void glfwRequestWindowAttention (GLFWwindow *window)

GLFWmonitor * glfwGetWindowMonitor (GLFWwindow *window)

void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)

int glfwGetWindowAttrib (GLFWwindow *window, int attrib)

void glfwSetWindowAttrib (GLFWwindow *window, int attrib, int value)

void glfwSetWindowUserPointer (GLFWwindow *window, void *pointer)

void * glfwGetWindowUserPointer (GLFWwindow *window)

GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun cbfun)

GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun cbfun)

GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun cbfun)

GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun cbfun)

GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun cbfun)

GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun cbfun)

GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun cbfun)

GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun cbfun)

GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun cbfun)

void glfwPollEvents (void)

void glfwWaitEvents (void)

void glfwWaitEventsTimeout (double timeout)

void glfwPostEmptyEvent (void)

void glfwSwapBuffers (GLFWwindow *window)

关于Gamma校正

比较两幅图像

图一:没有gamma校正


没有gamma校正

图二:gamma校正


gamma校正

说明

  1. 在场景中放置一个球,使用默认的Diffuse材质,打一个平行光;

  2. 在真实场景中看到的与在电脑上看见的是不一样的。

  3. 假设球上有一点B,它的法线和光线方向成60°,还有一点A,它的法线和光线方向成90°,计算输出的时候,会得出B的输出是(0.5, 0.5, 0.5),A的输出的(1.0, 1.0, 1.0)。

    • 法向量就是垂直切面的向量(球面上的点到圆心直线的向量),按照sin求输出;
  4. 在第一张图中,没有进行伽马校正。因此,在把像素值转换到屏幕亮度时并不是线性关系,也就是说B点的亮度其实并不是A亮度的一半,在Mac显示器上,这个亮度只有A亮度的1/1.8呗,约为四分之一。在第二张图中,进行了伽马校正,此时的亮度才是真正跟像素值成正比的。

Gamma校正公式

gamma校正公式与原理示意图

gamma校正的效果

不同gamma值得校正效果比较

gamma校正算法


上一篇下一篇

猜你喜欢

热点阅读