學習書籍: OpenGL 超級寶典(中文第五版) 密碼:fu4w
書籍原始碼:OpenGL 超級寶典第五版原始碼 密碼:oyb4
環境搭建:OpenGL 學習 01 - Mac 搭建 OpenGL 環境
基本概念
GLUT
全名 OpenGL utility toolkit,一種跨平臺(Windows/Mac/Linux)的 GUI 程式設計框架,用於輔助 OpenGL 顯示 GUI 介面
GLEW
一種維護最好的開源 OpenGL 擴充套件載入庫(自動初始化所有函式指標幷包含所需型別定義、常量和列舉值),GLEW 被預先封裝在了 GLTools 庫中。
GLTools
OpenGL 快捷開發工具,包含一個用於操作矩陣和向量的 3D 數學庫,一些產生和渲染簡單的 3D 物件的函式,以及對視覺平截頭體、相機類和變換矩陣進行管理的函式的充分支援
OpenGL 資料型別
為了 OpenGL 的移植性,OpenGL 定義了各種資料型別,這些資料型別可以對映到所有平臺上的特定最小格式。
原始碼解析
一、GLUT 構建視窗
要使用 GLUT 框架,需要匯入標頭檔案#include <glut/glut.h>
1. 設定當前目錄(只針對 Mac)
// 程式入口
int main(int argc, char* argv[])
{
//設定當前工作目錄,針對MAC OS X
gltSetWorkingDirectory(argv[0]);
複製程式碼
2. 初始化 GLUT 庫
glutInit(&argc, argv);
複製程式碼
3. 初始化視窗渲染模式
/*
* 初始化渲染模式
* GLUT_DOUBLE - 雙緩衝模式
* GLUT_RGBA - RGBA顏色模式
* GLUT_DEPTH - 深度測試模式
* GLUT_STENCIL - 模板快取模式
*/
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
複製程式碼
4.建立視窗並命名
//初始化視窗大小(width=800, height=600)
glutInitWindowSize(800, 600);
//建立視窗
glutCreateWindow("Triangle");
複製程式碼
5. 註冊不同的回撥函式,攔截適當訊息
//註冊回撥函式,攔截視窗大小變化訊息,ChangeSize 是自定義方法名
glutReshapeFunc(ChangeSize);
//註冊回撥函式,攔截視窗渲染訊息,RenderScene 是自定義方法名
glutDisplayFunc(RenderScene);
複製程式碼
6. 初始化 GLEW 庫
//確保驅動程式的初始化中沒有出現任何問題。
GLenum err = glewInit();
if(GLEW_OK != err) {
return -1;
}
複製程式碼
7. 初始化渲染環境
//自定義函式,方法名隨意,這裡用 SetupRC
SetupRC();
複製程式碼
8. 主訊息迴圈,類似 OC 中 RunLoop
glutMainLoop();
複製程式碼
二、第一個三角形
1. 設定視口
//設定視口,(x, y, width, height),其中 (x, y) 代表視窗中視口的左下角座標,
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
複製程式碼
2. 設定視窗背景顏色
//設定視窗背景顏色(RGBA),CGclampf 是浮點型,RGBA 每種分量在 0.0~1.0 之間
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
複製程式碼
3. 著色器管理器初始化
//定義著色器管理器,OpenGL 沒有著色器是無法渲染的
GLShaderManager shaderManager;
//初始化著色管理器
shaderManager.InitializeStockShaders();
複製程式碼
4. 批次初始化
//構建三角形頂點陣列,vVert包含3個頂點的(x, y, z)笛卡爾座標
//視窗大小預設-1.0到1.0
GLfloat vVerts[] = {
-0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
};
//建立批次,GLTools 容器類,方便我們儲存資料和渲染圖形
GLBatch triangleBatch;
//開始構建批次,GL_TRIANGLES 表示三角形,後面引數是頂點數
triangleBatch.Begin(GL_TRIANGLES, 3);
/*
* 批次增加儲存屬性
* CopyVertexData3f(XYZ頂點資料)
* CopyNormalDataf(表面法線)
* CopyColorData4f(RGBA顏色)
* CopyTexCoordData2f(紋理座標)
*/
triangleBatch.CopyVertexData3f(vVerts);
//結束批次屬性設定,表明完成資料複製操作,不能再新增新屬性
triangleBatch.End();
複製程式碼
5. 清除快取區組
//清除一個或一組特定的緩衝區,對應前面設定的視窗渲染模式
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
複製程式碼
6. 著色器設定顏色
//設定一組浮點數來表示紅色(RGBA)
GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
//GLT_SHADER_IDENTITY 單位著色器,這個著色器只是使用指定顏色為頂點上色
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
複製程式碼
7. 批次資料渲染
//根據批次裡的頂點資料利用當前設定的著色器進行畫圖
triangleBatch.Draw();
複製程式碼
8. 緩衝區交換(渲染模式包含 GLUT_DOUBLE,其他就可略過)
/*
* 當 glutInitDisplayMode 有傳入雙緩衝模式時,
* 將在後臺緩衝區進行渲染,然後在結束時交換到前臺
* 為了防止觀察者看到可能隨著動畫幀和動畫幀之間閃爍的渲染過程
*/
glutSwapBuffers();
複製程式碼
三、全部原始碼如下:
#include <iostream>
#include <GLShaderManager.h>
#include <GLTools.h>
#include <glut/glut.h>
GLBatch triangleBatch;
GLShaderManager shaderManager;
//視窗大小改變時接受新的寬度和高度
void ChangeSize(int width, int height) {
// 設定視口,(x, y, width, height),其中 (x, y) 代表視窗中視口的左下角座標
glViewport(0, 0, width, height);
}
//為程式作一次性的設定
void SetupRC() {
//設定背影顏色
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
//初始化著色管理器
shaderManager.InitializeStockShaders();
//構建三角形頂點陣列,vVert包含3個頂點的(x, y, z)笛卡爾座標
GLfloat vVerts[] = {
-0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
};
//開始構建批次,GL_TRIANGLES 表示三角形,後面引數是頂點數
triangleBatch.Begin(GL_TRIANGLES, 3);
/*
* 批次增加儲存屬性
* CopyVertexData3f(XYZ頂點資料)
* CopyNormalDataf(表面法線)
* CopyColorData4f(RGBA顏色)
* CopyTexCoordData2f(紋理座標)
*/
triangleBatch.CopyVertexData3f(vVerts);
//結束批次屬性設定,表明完成資料複製操作,不能再新增新屬性
triangleBatch.End();
}
//開始渲染
void RenderScene(void) {
//清除一個或一組特定的緩衝區
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//設定一組浮點數來表示紅色
GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
//傳遞到儲存著色器,即GLT_SHADER_IDENTITY著色器,這個著色器只是使用指定顏色以預設笛卡爾座標第在螢幕上渲染幾何圖形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
//根據批次裡的頂點資料利用當前設定的著色器進行畫圖
triangleBatch.Draw();
/*
* 當 glutInitDisplayMode 有傳入雙緩衝模式時,
* 將在後臺緩衝區進行渲染,然後在結束時交換到前臺
* 為了防止觀察者看到可能隨著動畫幀和動畫幀之間閃爍的渲染過程
*/
glutSwapBuffers();
}
//程式入口
int main(int argc, char* argv[]) {
//設定當前工作目錄,針對MAC OS X
gltSetWorkingDirectory(argv[0]);
//初始化GLUT庫
glutInit(&argc, argv);
/*初始化渲染模式,其中標誌GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分別指
雙緩衝視窗、RGBA顏色模式、深度測試、模板緩衝區*/
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
//初始化視窗大小
glutInitWindowSize(800, 600);
//建立視窗
glutCreateWindow("Triangle");
//註冊回撥函式,攔截視窗大小變化訊息,ChangeSize 是自定義方法名
glutReshapeFunc(ChangeSize);
//註冊回撥函式,攔截視窗渲染訊息,RenderScene 是自定義方法名
glutDisplayFunc(RenderScene);
//確保驅動程式的初始化中沒有出現任何問題。
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr, "glew error:%s\n", glewGetErrorString(err));
return 1;
}
//初始化設定
SetupRC();
//進入呼叫迴圈
glutMainLoop();
return 0;
}
複製程式碼
這裡是 Demo 地址:github->openGLDemo->01-environment