opengl 入门之创建窗口

学了一个月的opengl,从入门到窒息。

如果觉得本文写的看不懂,具体可以参考LearnOpengl

1 opengl基础知识

   opengl ,并不是一个API,而是一个组织规范,由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者自行决定(注:这里开发者是指编写OpenGL库的人)。因为OpenGL规范并没有规定实现的细节,具体的OpenGL库允许使用不同的实现,只要其功能和结果与规范相匹配(亦即,作为用户不会感受到功能上的差异)。

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

   使用OpenGL时,建议使用OpenGL定义的基元类型。比如使用float时我们加上前缀GL(因此写作GLfloat)。int、uint、char、bool等等也类似。OpenGL定义的这些GL基元类型的内存布局是与平台无关的,而int等基元类型在不同操作系统上可能有不同的内存布局。使用GL基元类型可以保证你的程序在不同的平台上工作一致。

C++基元类型opengl基元类型
intGLint
floatGLfloat
unitGLuint
charGLchar
boolGLbool

2 opengl的安装配置

2.1依赖安装

sudo apt-get install build-essential
sudo apt-get install libgl1-mesa-dev
sudo apt-get install libglu1-mesa-dev
sudo apt-get install freeglut3-dev

2.2GLFW安装配置

    GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,这正是我们需要的。

sudo apt-get install cmake xorg-dev libglu1-mesa-dev

(1)下载GLFW的source package

(2)编译

cd glfw-3.2.1
mkdir build
cd build
cmake ..
make
sudo make install

2.3GLEW安装

GLEW是OpenGL Extension Wrangler Library的缩写

(1)下载GLEW并解压

(2)编译

cd glew-2.1.0
make
sudo make install

2.3makefile配置

CC=g++
ELF=main
SRC=$(shell find -name '*.cpp')
OBJ=$(SRC:.cpp=.o)
LIBS=-lGLEW -lglfw3 -lGL -lX11 -lXrandr -lXi -ldl -lpthread -lm -lrt -lXxf86vm -lXcursor -lXinerama
$(ELF):$(OBJ)
	$(CC) $(SRC) $(LIBS) -o $(ELF)
$(OBJ):
clean:
	rm -f $(OBJ) $(ELF)

3窗口

3.1GLFW

GLFW用来创建窗口

使用前需要包含头文件

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

在包含GLFW的头文件之前需要先包含GLEW的头文件,否则会报错

3.2GLEW

GLEW是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLEW。

glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
    std::cout << "Failed to initialize GLEW" << std::endl;
    return -1;
}

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

3.3视口

在我们开始渲染之前还有一件重要的事情要做,我们必须告诉OpenGL渲染窗口的尺寸大小,这样OpenGL才只能知道怎样相对于窗口大小显示数据和坐标。我们可以通过调用glViewport函数来设置窗口的维度(Dimension):

GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
}
glfwMakeContextCurrent(window);

int width, height;
glfwGetFramebufferSize(window, &width, &height);

glViewport(0, 0, width, height);

3.4游戏循环(Game Loop)

在程序中添加一个while循环,在我们让GLFW退出前一直保持运行

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

3.5释放资源

当游戏循环结束后我们需要正确释放/删除之前的分配的所有资源。我们可以在main函数的最后调用glfwTerminate函数来释放GLFW分配的内存。

glfwTerminate(); 
return 0;

3.6渲染

    我们要把所有的渲染(Rendering)操作放到游戏循环中,因为我们想让这些渲染指令在每次游戏循环迭代的时候都能被执行。在每个新的渲染迭代开始的时候我们总是希望清屏,否则我们仍能看见上一次迭代的渲染结果。

glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //设置清空屏幕所用的颜色 
glClear(GL_COLOR_BUFFER_BIT);//清空颜色缓冲区GL_COLOR_BUFFER_BIT 
//当调用glClear函数,清除颜色缓冲之后,整个颜色缓冲都会被填充为glClearColor里所设置的颜色

调用glClear函数来清空屏幕的颜色缓冲,它接受一个缓冲位(Buffer Bit)来指定要清空的缓冲,可能的缓冲位有GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT。

glClearColor函数是一个状态设置函数,而glClear函数则是一个状态应用的函数。

3.7窗口代码

/ GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
int main()
{
    //初始化GLFW
    glfwInit();  //成功返回GLFW_TRUE(1);失败返回GLFW_FALSE(0)
    
    //配置GLFW窗口的hint(选项)。参数一是配置的hint名称,使用GLFW常量(以GLFW_开头)指定;第二个是我们要把该hint设置成的值,该值随要设置的hint而异。
    //在本PC机中配置的opengl为4.6.0 因此设定主版本号为4,副版本号为6,设置opengl模式为核心模式,且无法改变窗口大小
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);                 //GLFW_CONTEXT_VERSION_MAJOR 主版本号
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5;                 //GLFW_CONTEXT_VERSION_MINOR 副版本号
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //GLFW_OPENGL_PROFILE OpenGL模式
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);                      //GLFW_RESIZABLE 窗口是否可调整大小
    
    //创建窗口对象,第一个参数为窗口的宽;第二个参数为窗口的高;第三个为窗口的名称
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    //通知GLFW将窗口的上下文设置为当前线程的主上下文。
    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);
    
    //Game loop
    while (!glfwWindowShouldClose(window))//检查一次GLFW是否被要求退出
    {
        //检查是否触发什么事件,有的话调用对应的回调函数
        glfwPollEvents();
        //clear
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        // 渲染指令
         ...
        // 交换颜色缓冲
        glfwSwapBuffers(window);
    }

    return 0;
}

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值