OpenGL环境配置及HelloWorld程序

学习OpenGL建议从32位学起,因为64位有些细节可能需要特殊处理,因此初学者可以暂不考虑这些特殊情况,从简单开始入手,减少不必要的麻烦。

1.渲染模式:立即渲染模式和核心模式

立即渲染模式(Immediate mode,也就是固定渲染管线),这个模式下绘制图形很方便。立即渲染模式确实容易使用和理解,但是效率太低,现在已经废弃。
核心模式迫使我们使用现代的函数,现代函数的优势是更高的灵活性和效率,然而也更难于学习。

2.状态机

OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行。OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文来渲染。

3.对象

OpenGL开发的时候引入了一些抽象层。“对象(Object)”就是其中一个。在OpenGL中一个对象是指一些选项的集合,它代表OpenGL状态的一个子集。在我们想绘制其中任何一个模型的时候,只需绑定一个包含对应模型数据的对象就可以了(当然,我们需要先创建并设置对象的选项)。

4.使用vs2015搭建opengl+glfw3+glad环境

4.1 opengl

opengl库在vs2015的SDK中自带,不需要安装

4.2 glfw3

glfw3的项目地址:https://www.glfw.org/download.html
该网址有现成的库文件,作为初学者,我建议自己编译。
怎么编译?答:使用CMake(不会的找几篇文章看看就会了,用不了10分钟肯定能学会)
(1)下载源码,并解压
(2)打开cmd,进入源码目录,执行:cmake .
(3)上一步执行成功后,会生成visual studio工程(具体是vs2015还是2017,cmake根据你的开发环境帮你自动配置),进入源码目录,打开FLFW.sln,如果学习的话,编译32位的Release版本就够了。
(4)把include和glfw3.lib(静态库)拷贝出来,备用。

4.3 glad

这个最简单,直接配置就可以,配置地址:https://glad.dav1d.de/
只填一个gl版本就行(根据自己显卡确认,如果确定不了,就选3.3版本,其他新版本都是基于3.3扩展而来的,核心未变,可以兼容),最后点GENERATE,然后直接下载glad.zip,里面一个include一个glad.c,include加载到vs2015工程,glad.c直接作为源码加入你的opengl工程。

5.第一个opengl+glfw3+glad工程

新建一个控制台空项目,控制台可以用printf或cout打印,便于自己调试。
先把glad.c加入到工程
把glfw3和glad的include添加到工程的附加目录
在依赖库里面新增2个新的:opengl32.lib和glfw3.lib
新建一个文件HelloWorld.cpp文件,copy下面源码进去编译,然后运行程序即可。代码来自opengl学习网站,我自己加了一点点注释。


#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

#define GL_PRINT(S) (printf("%s\n",#S),S)

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);//将该窗口作为当前线程的主上下文
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//注册回调函数,这里是窗口大小改变时候调用framebuffer_size_callback,该函数还可以注册其他相关硬件的回调函数

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//初始化glad库,只要用glad库都这么写,没什么可说的,glfwGetProcAddress这个函数返回指定的OpenGL或OpenGL ES核心或扩展函数的地址,如果它被当前上下文所支持的话。
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))//不阻塞,循环会一直执行
    {
        // input
        // -----
        processInput(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);//交换缓冲区,这里用了双缓冲技术,用两个内存区域来保存数据,分为前缓冲区和后缓冲区,前缓冲区用于展示屏幕上的内容,而后缓冲区就用来绘制,然后每一帧开始的时候,将两个缓冲区交换,这样后缓冲区又可以画新的内容
        glfwPollEvents();//轮询事件(如: 鼠标键盘事件)
    }

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
    GL_PRINT("Window Resize!");
}

猜你喜欢

转载自blog.51cto.com/14207158/2536415