Skip to content

beydeng/OpenGL

Repository files navigation

OpenGL

Learning OpenGL On the MAC

除去繁琐无用的glm,glfw,itool工具的布置,完全基于MAC上已经存在的东西来学习OpenGL。


3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线管理的。

图形渲染管线接受一组3D坐标,然后把它们转变为你屏幕上的有色2D像素输出。图形渲染管线可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。所有这些阶段都是高度专门化的(它们都有一个特定的函数),并且很容易并行执行。正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。这些小程序叫做着色器。

图形渲染包括:

顶点数据 Vertex DATA[]-》顶点着色器-》形状(图元)装配 -》几何着色器(Geomenter shader)-》光栅化-》片段着色器(Framgment Shader)-》测试和混合

注: 做图元(Primitive),任何一个绘制指令的调用都将把图元传递给OpenGL。这是其中的几个:GL_POINTS、GL_TRIANGLES、GL_LINE_STRIP。

图元渲染管线的第一部分是顶点着色器,它把一个单独的顶点作为输入。顶点着色器的主要目的是3D左边的转换,同时也允许我们对顶点属性进行一些基本处理。

图元装配阶段将顶点着色器输出的所以顶点作为输入,并对所以的点装配成指定的图元形状。

图元装配阶段的输出会传递给几何着色器。几何着色器把图元形式的顶点的几何最为输入,它可以通过产生新顶点构造出新的图元来生成其他形状。

几何着色器的输出会被传入光栅化阶段(Rasterization Stage),这里它会把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素,用来提升执行效率。

片段着色器的主要目的是生成像素的最终颜色。

最后阶段是Alpha测试和混合(Blending)阶段。这个阶段检测片段的对应的深度(和模板(Stencil))值(后面会讲),用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查alpha值(alpha值定义了一个物体的透明度)并对物体进行混合(Blend)。

可以发现,非常复杂,它包含很多可配置的部分,但是,对于大多数场合,我们只需要配置顶点和片段在色器。几何着色器可选,使用默认着色器就可以了。

开始绘制图形:

在绘制图形之前,我们先给OpenGL输入一些顶点数据。
比如我们现在,想渲染一个三角形,就需要指定三个顶点,每个顶点都有一个3D位置,如下:
        GLfloat vertices[] = {
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            0.0f,  0.5f, 0.0f
            };
定义这样的顶点数据之后,我们需要把它作为输入发送给图形渲染管线的第一个处理阶段:顶点在色器。它会在GPU上创建内存用于存储我们的顶点数据,还要配置OpenGL如何解释这些内存,并且指定其如何发送给显卡,然后顶点着色器处理这些顶点。
我们是通过顶点缓存对象VBO管理这个内存的,它会在GPU中存放大量的顶点。使用这个缓存对象是可以一次性发送大量顶点到显卡,但数据到达显卡内存中,那么顶点着色器就可以立即访问顶点。

顶点缓存对象的使用,可以询问代码中的一个-(void)setupVbo方法。

绘制第一个三角形的所有步骤可以参考OpenGLView中的重写的-(void)setupTriangle方法。
然后在重写的initWithFrame方法中调用,然后运行就可以看见一个三角形了。

每当我们绘制一个物体时,都要重复这一过程,这看起来可能不多,但是如果我们有超过5个顶点以及上百个不同物体呢?绑定正确的缓冲对象,为每个物体配置所有点点属性,就成了一件麻烦事。有没有一些方法可以使我们把所有这些状态配置储存在一个对象中,并且可以通过绑定这个对象来恢复状态呢?

就要使用顶点数组对象(VAO),可以像顶点缓冲对象那样被绑定,之后的顶点属性都会存储在这个VAO中。这样的好处是,单配置顶点属性指针时,只用姜那些调用执行一次,之后绘制物体的时候只需要绑定相应的VAO就可以了。

注:OpenGL的核心模式要求我们使用VAO,所以它知道该如何处置我们的顶点输入。如果绑定VAO失败,OpenGL会拒绝绘制任何东西。

使用过程见代码中-(void)setupVAO。

索引缓冲对象(EBO)
加入我们要绘制一个矩形,可以用两个三角形绘制一个矩形。
那么 他们的顶点集合应该是:
        GLfloat vertices[] = {
            // 第一个三角形
                0.5f, 0.5f, 0.0f,   // 右上角
                0.5f, -0.5f, 0.0f,  // 右下角
                -0.5f, 0.5f, 0.0f,  // 左上角
            // 第二个三角形
                0.5f, -0.5f, 0.0f,  // 右下角
                -0.5f, -0.5f, 0.0f, // 左下角
                -0.5f, 0.5f, 0.0f   // 左上角
                };
发现有2个点重合了,也可以想到矩形只有4个顶点,哪如何解决这个问题呢?这里就用到索引缓冲对象。EBO也是一个缓冲,它专门储存索引,OpenGL调用这些顶点的索引来决定该绘制哪个顶点。详细请查阅代码。

About

Learning OpenGL On the MAC

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published