美文网首页OpenGL
Learn OpenGL(一)--简介与创建窗口

Learn OpenGL(一)--简介与创建窗口

作者: 小灰灰old | 来源:发表于2019-02-23 16:54 被阅读75次
    opengl_logo.jpg

    代码Github地址

    OpenGL 简介

      OpenGL是一个由Khronos Group维护的图形绘制的规范
      OpenGL规范规定了函数的执行、输出,但是具体的实现则是由库的开发者(通常指显卡生产商)来实现的,不同的库实现可能不一样
      OpenGL本质上是一个大状态机,通过改变上下文(context)的变量告诉OpenGL怎么绘图

    创建窗口(GLFW)

    创建窗口可以使用GLUT,SDL,QT,GLFW等,这里我用的是GLFW

    GLFW

      GLFW是个开源的支持多个平台的库,支持OpenGL、Vulkan。提供创建窗口、事件接收等。

    GLFW安装

    头文件添加

    #include <GLFW\glfw3.h>
    

      gcc 在编译时需要加入-lGLEW -lglfw3 -lGL -lX11 -lpthread -lXrandr -lXi,否则可能出现未定义的引用错误

    待完成

    GLAD

      因为OpenGL只是个规范,具体是由显卡驱动开发商决定,很多函数位置不能在编译时决定,自己来取得地址的话会导致代码很复杂,所以需要使用GLAD来帮我们实现

    GLAD配置

      GLAD有一个在线服务可以根据语言、版本、模式来获取我们想要的库。打开后,语言选择C/C++,模式选择core,版本选择3.3(因为我用的是3.3版本)
      把生成的压缩文件解压,里面的glad和KHR目录放在你的项目头文件目录,glad.c也添加到工程中,并在项目引入头文件

    #include <glad/glad.h> 
    

    CMakeLists.txt

      由于我使用的CLion创建的项目,所以也就使用CMake了,CMakeLists.txt部分内容如下
    添加glad库

    add_library(glad SHARED ./src/glad/glad.c)
    

    添加stb_image(加载图片用)

    add_library(stb_image SHARED ./src/stb_image/stb_image.cpp)
    

    链接库(opengl_glfw03是项目可执行文件)

    target_link_libraries(opengl_glfw03 glad)
    target_link_libraries(opengl_glfw03 stb_image)
    target_link_libraries(opengl_glfw03 GLEW)
    target_link_libraries(opengl_glfw03 glfw3)
    target_link_libraries(opengl_glfw03 GL)
    target_link_libraries(opengl_glfw03 X11)
    target_link_libraries(opengl_glfw03 pthread)
    target_link_libraries(opengl_glfw03 Xrandr)
    target_link_libraries(opengl_glfw03 Xi)
    target_link_libraries(opengl_glfw03 Xxf86vm)
    target_link_libraries(opengl_glfw03 Xinerama)
    target_link_libraries(opengl_glfw03 Xcursor)
    target_link_libraries(opengl_glfw03 rt)
    target_link_libraries(opengl_glfw03 m)
    target_link_libraries(opengl_glfw03 dl)
    

    main.cpp

    编译没问题的话就可以创建窗口了

    #include <iostream>
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    
    int main() {
        std::cout << "Hello, World!" << std::endl;
        return 0;
    }
    

    开始创建窗口

    • 初始化GLFW
    glfwInit();
    
    • GLFW选项设置函数
      hint:需要设置的选项
      value:需要设置的值
    glfwWindowHint(int hint,int value);
    
    • 配置上下文版本为3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
    
    • 配置OpenGL模式为核心(core)模式
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
    
    • 配置多重采样实现抗锯齿
    glfwWindowHint(GLFW_SAMPLES,4);
    

    别忘了启用OpenGL的多重采样,虽然默认是启用的

    glEnable(GL_MULTISAMPLE);
    
    • 创建窗口对象
      width:窗口宽度
      height:窗口高度
      title:窗口标题
      monitor
      share
    glfwCreateWindow(int width,int height,const char *title,GLFWmonitor *monitor,GLFWwindow *share);
    
    GLFWwindow *window=glfwCreateWindow(1200,720,"OpenGL",nullptr,nullptr);
    if(window==nullptr){
        // 当窗口创建失败时中断并退出
        ...
        glfwTerminate();
        return -1;
    }
    
    • 将当前窗口设置为主线程上下文
    glfwMakeContextCurrent(window);
    
    • 初始化GLAD
    if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
        // 当GLAD初始化失败时退出
        ...
        glfwTerminate();
        return -1;
    }
    
    • 添加窗口大小改变回调
    // 声明回调函数
    void onFramebufferSizeCallback(GLFWwindow*,int,int);
    // 添加回调
    glfwSetFramebufferSizeCallback(window,onFramebufferSizeCallback);
    
    • 在回调中处理视口变换
      x:左下角x坐标
      y:左下角y坐标
      width:渲染宽度
      height:渲染高度
    glViewport(GLint x,GLint y,GLsizei width,GLsizei height);
    
    void onFramebufferSizeCallback(GLFWwindow *window,int width,int height){
        glViewport(0,0,width,height);
    }
    
    • 渲染循环
      为了避免一运行就退出
    while(!glfwWindowShouldClose(window)){
        // 交换颜色缓冲
        glfwSwapBuffers(window);
        // 检查触发事件
        glfwPollEvents();
    }
    
    • 清除窗口颜色缓冲
      red:红
      green:绿
      blue:蓝
      alpha:透明通道
    glClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);
    

    写在处理键盘事件代码之后

    // 用glClearColor设置的颜色填充
    glClearColor(0.5f,0.5f,0.6f,1.0f);
    // 清除颜色缓冲
    glClear(GL_COLOR_BUFFER_BIT);
    
    • 处理键盘事件
      声明函数
    void onKeyInput(GLFWwindow *);
    

    处理键盘事件写在循环体内部第一行

    onKeyInput(window);
    
    void onKeyInput(GLFWwindow *window){
        // 判断ESC按钮就是否触发
        if(glfwGetKey(window,GLFW_KEY_ESCAPE)==GLFW_PRESS){
            // 触发就设置close为真
            glfwSetWindowShouldClose(window,GLFW_TRUE);
        }
    }
    
    • 清理资源并退出
    glfwTerminate();
    return 0;
    

    最后

    此时运行代码应该会出现一个窗口像下面这个,按ESC即可退出,后面会在此基础上添加很多东西
    代码Github地址

    opengl_window.png

    相关文章

      网友评论

        本文标题:Learn OpenGL(一)--简介与创建窗口

        本文链接:https://www.haomeiwen.com/subject/tsppyqtx.html