Open GL工程的搭建

引子:移動(dòng)端開發(fā)經(jīng)過這么多年的開發(fā),已經(jīng)越來越成熟了,而且由于網(wǎng)頁端技術(shù)的野蠻發(fā)展,移動(dòng)端開發(fā)已經(jīng)越來越式微啦。在這個(gè)環(huán)境下深耕iOS原生和努力掌握大前端技術(shù)棧對(duì)于iOS開發(fā)者來說越發(fā)的重要?;趫D形和視頻技術(shù)的流行趨勢(shì),掌握?qǐng)D形和視頻的渲染技術(shù)棧也顯得越發(fā)重要。本篇介紹如果在Xcode搭建Open GL 工程。
該篇文章簡(jiǎn)單的搭建一個(gè)在MAC的OpenGL工程,以及對(duì)代碼進(jìn)行解釋

  • 新建macOS工程 Xcode --> File --> New --> Project
    選擇macOS ---> Application ---> App


    Mac-App Project.png
  • 添加OpenGL.framework和GLUT.framework兩個(gè)系統(tǒng)庫
    在General下的Frameworks,Libraries,and Embedded Content下,或者Build Phases下的Link Binary With Libraries下添加OpenGL.framework和GLUT.framework兩個(gè)系統(tǒng)庫


    add-framework.png
  • 導(dǎo)入GLTools、libGTools.a等文件這里已經(jīng)整理好了。直接把include、libGTools.a文件拖入工程
    文件地址:https://pan.baidu.com/s/1cM8ryabz_hfiqGCJIws5ig 提取碼:tqch

    add-libs.png

  • 刪除程序入口文件:AppDelegate.h、AppDelegate.m、Main.storyboard、main.m、viewController.h、viewController.m

  • 新建程序入口文件main.cpp
    新建c++文件main.cpp作為程序入口文件,不創(chuàng)建header file文件


    create-main-cpp.png

    no-create-header-file.png
  • 編寫main.cpp文件繪制一個(gè)圖形
    main.cpp文件如下:

#include <stdio.h>

#include "GLTools.h"
/*
 GLTool.h頭文件包含了大部分GLTool中類似C語言的獨(dú)立函數(shù)
*/
#include <GLUT/GLUT.h>
/*
 在Mac 系統(tǒng)下,`#include<glut/glut.h>`
 在Windows 和 Linux上,我們使用freeglut的靜態(tài)庫版本并且需要添加一個(gè)宏
 */
#include "GLShaderManager.h"
/*
`#include<GLShaderManager.h>` 移入了GLTool 著色器管理器(shader Mananger)類。沒有著色器,我們就不能在OpenGL(核心框架)進(jìn)行著色。著色器管理器不僅允許我們創(chuàng)建并管理著色器,還提供一組“存儲(chǔ)著色器”,他們能夠進(jìn)行一些初步?基本的渲染操作。
*/

GLBatch triangleBatch;// 簡(jiǎn)單的批次容器,是GLTools的一個(gè)簡(jiǎn)單的容器類。
GLShaderManager shaderManager;// 定義一個(gè)著色管理器

/// 窗口大小改變時(shí)接受新的寬度和高度,其中(0,0)代表窗口的左下角坐標(biāo),w、h代表像素
void changeSize(int w, int h) {
    glViewport(0, 0, w, h);
}

/// 做初始花設(shè)置
void setupRC(){
    /// 設(shè)置背景顏色
    glClearColor(1.f, 1.f, 1.f, 1.f);
    /// 初始化著色管理器
    shaderManager.InitializeStockShaders();
    /// 設(shè)置三角形,其中數(shù)組vVert包含所有3個(gè)頂點(diǎn)的x,y,笛卡爾坐標(biāo)對(duì)。
    GLfloat vVerts[] = {
        -1.f, -1.f, 0.f,
        0.5f, 0.f, 0.f,
        -0.6f, 0.5f, 0.f
    };
    /// 批次處理
    triangleBatch.Begin(GL_TRIANGLES, 3);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

/// 開始渲染
void renderScene(void) {
    /// 清除一個(gè)或一組特定的緩沖區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    /// 設(shè)置一組浮點(diǎn)數(shù)表示紅色
    GLfloat vRed[] = {1.f, 0.f, 0.f, 1.f};
    /// 傳遞到存儲(chǔ)著色器,即GLT_SHADER_IDENTITY著色器,這個(gè)著色器只是使用指定顏色以默認(rèn)笛卡爾坐標(biāo)系在屏幕上渲染集合圖形
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    /// 提交著色器
    triangleBatch.Draw();
    /// 將在后臺(tái)緩沖區(qū)進(jìn)行渲染,然后再結(jié)束時(shí)交換到前臺(tái)
    glutSwapBuffers();
}

int main(int argc, char * argv[]) {
    /// 設(shè)置當(dāng)前工作目錄,針對(duì)MAC OS X,防止在Windows上錯(cuò)誤。在Windows中是沒必要的。因?yàn)閣indows下默認(rèn)的工作目錄就是與程序可執(zhí)行目錄相同。但是在Mac OS中工作目錄被更改為應(yīng)用程序捆綁中的/Resource文件夾。
    gltSetWorkingDirectory(argv[0]);
    /// 初始化GLUT庫,GLUT庫的api在macOS 10.9 已被棄,但不影響使用
    glutInit(&argc, argv);
    /// 初始化雙緩存窗口 GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL 分別是:雙緩存窗口、RGBA顏色模式、深度測(cè)試、模板緩沖區(qū)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    /// GLUT窗口,設(shè)置窗口大小
    glutInitWindowSize(800, 800);
    /// 設(shè)置窗口標(biāo)題 
    glutCreateWindow("Triangle");
    /// 注冊(cè)回調(diào)
    glutReshapeFunc(changeSize);// 注冊(cè)重塑函數(shù)
    glutDisplayFunc(renderScene);// 注冊(cè)顯示函數(shù)
    
    /// 驅(qū)動(dòng)程序的初始化無問題,初始化GLEW庫,確保OpenGL API對(duì)程序完全可用。
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "glew error: %s\n",glewGetErrorString(err));
        return 1;
    }
    /// 調(diào)用setupRC,設(shè)置渲染環(huán)境
    setupRC();
    /// 進(jìn)入GLUT事件處理循環(huán),讓所有的與“事件”有關(guān)的函數(shù)調(diào)用無限循環(huán),這里讓整個(gè)繪圖循環(huán)進(jìn)行。它將調(diào)用必要的任何已注冊(cè)的回調(diào)
    glutMainLoop();
    return 0;
}
OpenGL-triangle.png

程序入口main函數(shù)代碼解讀:
  • gltSetWorkingDirectory(argv[0])
    設(shè)置當(dāng)前工作目錄,針對(duì)MAC OS X,防止在Windows上錯(cuò)誤。在Windows中是沒必要的。因?yàn)閣indows下默認(rèn)的工作目錄就是與程序可執(zhí)行目錄相同。但是在Mac OS中工作目錄被更改為應(yīng)用程序捆綁中的/Resource文件夾。
  • glutInit(&argc, argv)
    初始化\color{red} {GLUT庫}(OpenGL Utility Toolkit),GLUT是一個(gè)很方便的輔助庫,而且與平臺(tái)無關(guān)。GLUT的功能包括窗口和菜單的創(chuàng)建和管理,事件處理以及提供了很多繪制3D圖形的方法等等。雖然GLUT庫的api在macOS 10.9 已被棄用但是作為窗口工具在學(xué)習(xí)OpenGL卻是比較方便的
  • glutInitDisplayMode(unsigned int mode)
    設(shè)置顯示模式的類型mode的類型值可指定單個(gè)或多個(gè)值的組合,在本程序我們選擇GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL
對(duì)應(yīng)宏定義 意義
GLUT_RGB 0x0000 指定RGB顏色模式的窗口
GLUT_RGBA 0x0000 指定RGBA顏色模式的窗口
GLUT_INDEX 0x0001 指定顏色索引模式的窗口
GLUT_SINGLE 0x0000 指定單緩存窗口
GLUT_DOUBLE 0x0002 指定雙緩存窗口
GLUT_ACCUM 0x0004 窗口使用累加緩存
GLUT_ALPHA 0x0008 窗口的顏色分量包含 alpha 值
GLUT_DEPTH 0x0010 窗口使用深度緩存
GLUT_STENCIL 0x0020 窗口使用模板緩存
GLUT_MULTISAMPLE 0x0080 指定支持多樣本功能的窗口
GLUT_STEREO 0x0100 指定立體窗口
GLUT_LUMINANCE 0x0200 窗口使用亮度顏色模型
  • 窗口參數(shù)設(shè)置:
    glutInitWindowSize(800, 800)用來設(shè)置窗口大小
    glutCreateWindow("Triangle")設(shè)置窗口的名字
  • 注冊(cè)回調(diào)函數(shù):
    glutReshapeFunc(void (func)(int width, int height));// glutReshapeFunc函數(shù)在調(diào)整窗口大小時(shí)被調(diào)用
    glutDisplayFunc(void (
    func)(void));// glut調(diào)用glutDisplayFunc函數(shù)進(jìn)行渲染
  • glewInit()初始化GLEW
    \color{red}{GLEW}(OpenGL Extension Wrangler Library)是用來管理OpenGL的函數(shù)指針的,所以在調(diào)用任何OpenGL的函數(shù)之前我們需要初始化GLEW。初始化失敗就退出程序。
  • setupRC()
    在該函數(shù)中進(jìn)行預(yù)加載紋理,建立幾何圖形,渲染器等工作
  • glutMainLoop()
    進(jìn)入GLUT事件處理循環(huán),讓所有的與“事件”有關(guān)的函數(shù)調(diào)用無限循環(huán),這里讓整個(gè)繪圖循環(huán)進(jìn)行。它將調(diào)用必要的任何已注冊(cè)的回調(diào)
setupRC函數(shù)解讀:
  • glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)在顏色緩沖被清空后調(diào)用設(shè)置色值和透明度。
  • GLShaderManager:
    存儲(chǔ)著色器由GLTools的C++類GLShaderManager管理。
    GLShaderManager shaderManager;
    shaderManager.InitializeStockShaders();初始化存儲(chǔ)著色管理器
  • vVerts:
    vVerts中存儲(chǔ)頂點(diǎn)坐標(biāo),因?yàn)椴捎玫氖堑芽栕鴺?biāo)系,所以是三個(gè)參數(shù)表示為一個(gè)點(diǎn),三個(gè)三處依次為(x,y,z)
  • GLBatch:
    GLBatch是GL的一個(gè)批次類,可以簡(jiǎn)單的理解為GL的批次處理腳本類。
    GLBatch的Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0);函數(shù)三個(gè)參數(shù)分別為幾何圖元類型,頂點(diǎn)坐標(biāo)個(gè)數(shù)和紋理參數(shù)。其中紋理參數(shù)可為空。該工程我們選擇GL_TRIANGLES。調(diào)用GLBatch的Begin函數(shù)開始預(yù)處理,調(diào)用CopyVertexData3f函數(shù)復(fù)制頂點(diǎn)數(shù)據(jù),最后調(diào)用End函數(shù)結(jié)束
    幾何圖元的參數(shù)一共有十種,分別為:
    GL_POINTS:點(diǎn)
    GL_LINES:線段,二個(gè)點(diǎn)確定線段
    GL_LINE_STRIP:第一個(gè)點(diǎn)依次連接的線段
    GL_LINE_LOOP:和GL_LINE_STRIP相同,但首尾連接,形成環(huán)狀
    GL_POLYGON:多邊形
    GL_QUADS:由四個(gè)點(diǎn)組成一個(gè)四邊形
    GL_QUADS_STRIP:四邊形帶
    GL_TRIANGLES:三角形,三個(gè)點(diǎn)確定
    GL_TRIANGLE_STRIP:共用一個(gè)條帶上的頂點(diǎn)的一組三角形
    GL_TRIANGLE_FAN:以一個(gè)原點(diǎn)為中心呈扇形排列,公共相鄰頂點(diǎn)的一組三角形


    geometric-primitive.png
renderScene函數(shù)解讀
  • glClear (GLbitfield mask)清除viewport的緩沖區(qū),可以清空單個(gè)或多個(gè)緩沖區(qū)標(biāo)志為:
    GL_COLOR_BUFFER_BIT: 當(dāng)前可寫的顏色緩沖
    GL_DEPTH_BUFFER_BIT: 深度緩沖
    GL_ACCUM_BUFFER_BIT: 累積緩沖
    GL_STENCIL_BUFFER_BIT: 模板緩沖
  • UseStockShader(GLT_STOCK_SHADER nShaderID, ...)存儲(chǔ)著色器的種類有很多種,在該程序我們使用單位著色器GLT_SHADER_IDENTITY。存儲(chǔ)著色器的種類有:
    單位(Identity)著色器---GLT_SHADER_IDENTITY
    平面著色器---GLT_SHADER_FLAT
    上色(Shaded)著色器---GLT_SHADER_SHADED
    默認(rèn)光源著色器---GLT_SHADER_DEFAULT_LIGHT
    點(diǎn)光源著色器---GLT_SHADER_DEFAULT_LIGHT
    紋理替換矩陣著色器---GLT_SHADER_TEXTURE_REPLACE
    紋理調(diào)整著色器---GLT_SHADER_TEXTURE_MODULATE
    紋理光源著色器---GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF等
  • GLBatch 的 Draw()函數(shù)。提交批次類進(jìn)行繪制
  • glutSwapBuffers()。函數(shù)表示雙緩存的后臺(tái)渲染完成后可以交換兩個(gè)緩沖區(qū)指針,這樣緩存區(qū)已經(jīng)渲染好的位圖就可以交替的出現(xiàn)在屏幕上了
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容