OpenGL ES 學(xué)習(xí)日志。
本文將學(xué)習(xí)OpenGL ES (超級(jí)寶典)記錄下的日志,將同步到簡(jiǎn)書上,歡迎大家批評(píng),順便說一句,這本書 是第五版,俗稱,藍(lán)寶書
總結(jié)的幾個(gè)名詞,僅供個(gè)人參考。
- 渲染 : 將數(shù)學(xué)和圖形數(shù)據(jù)轉(zhuǎn)換成3D空間圖像的操作叫做渲染。
- Transformation(變換) -- 通過變換,或者說旋轉(zhuǎn) 這些點(diǎn),并在他們之間繪制線段,我們就能在一個(gè)2D屏幕上創(chuàng)造出一個(gè)3D的世界錯(cuò)覺。
- 光柵化(Rasterization)實(shí)際繪制或填充每個(gè)點(diǎn)之間的像素,形成的線段就叫光刪化。
- 紋理貼圖(個(gè)人理解就是圖片 貼合在繪制的2D圖形上)
- 混合(個(gè)人理解就是將兩個(gè)不同顏色的圖片疊在一起,然后重疊的那個(gè)顏色 (當(dāng)然了透明度肯定不是100%))
- 3D幾何圖形無非是將頂點(diǎn)間的點(diǎn)連接起來,然后對(duì)三角形進(jìn)行光刪化。而使得對(duì)對(duì)象變得有實(shí)體。變換,著色,紋理與混合。
- 還有一個(gè)很重要的概念就是(三維笛卡爾坐標(biāo)系)--- 因?yàn)樽x書的時(shí)候并沒有好好學(xué)習(xí),所以,在理解笛卡爾三維坐標(biāo)系上有很大的難度,但是網(wǎng)上有篇文章寫的非常的清楚 網(wǎng)址在 "http://www.360doc.com/content/14/0302/15/13998280_357087559.shtml" 利用 太極,兩儀,四象,八卦 來分析笛卡爾三維坐標(biāo)系。其實(shí)把二維笛卡爾坐標(biāo)系作為一個(gè)面,然后再加上一個(gè)坐標(biāo)系,Z 使其成為一個(gè)立體的圖形。
支持陣容
GLUT :框架,OpenGL 的主要的編程框架。
GLEW :開源庫(kù)
GLTools:包含了一個(gè)用語(yǔ)言操作矩陣向向量的3D 數(shù)學(xué)庫(kù)。
變量類型 和 字節(jié)長(zhǎng)度。
| OepnGL數(shù)據(jù)類型 | 最小位寬 | 描述 |
|---|---|---|
| GLBoolean | 1 | 真 or 假 |
| GLbyte | 8 | 有符號(hào)的八位整數(shù) |
| GLubyte | 8 | 無符號(hào)的八位整數(shù) |
| GLChar | 8 | 字符串 |
| GLShort | 16 | 有符號(hào)16位整數(shù) |
| GLuShort | 16 | 無符號(hào)16位整數(shù) |
| GLhalf | 16 | 半精度浮點(diǎn)數(shù) |
| GLint | 32 | 有符號(hào)的32位整數(shù) |
| GLuint | 32 | 無符號(hào)的32位整數(shù) |
| GLSizei | 32 | 無符號(hào)的32位整數(shù) |
| GLunem | 32 | 無符號(hào)的32位整數(shù) |
| GLFloat | 32 | 32位浮點(diǎn)數(shù) |
| GLclampf | 32 | 【0 - 1】范圍內(nèi)的32位浮點(diǎn)數(shù) |
| GLbitfield | 32 | 32位 |
| GLdouble | 64 | 64位雙精度 |
| GLclampd | 64 | 【0 - 1】64位雙精度 |
| GLint64 | 64 | 有符號(hào)64位整數(shù) |
| GLuint64 | 64 | 無符號(hào)64位整數(shù) |
| GLSizeiptr | 本地操作系統(tǒng)指針大小 | 無符號(hào)整數(shù) |
| GLinptr | 本地操作系統(tǒng)指針大小 | 有符號(hào)整數(shù) |
| GLSync | 本地操作系統(tǒng)指針大小 | 同步對(duì)象句柄 |
openGL 并沒有對(duì)指針和數(shù)組做特殊的考慮。我們可參考C語(yǔ)言聲明一個(gè)100個(gè)GLshort變量的數(shù)組
GLShort shorts[100];
聲明一個(gè)長(zhǎng)度為100的指向 GLDouble 類型變量的指針數(shù)組
GLdouble *doubles[10];
OpenGL 錯(cuò)誤
openGL 在內(nèi)部保留了一組錯(cuò)誤標(biāo)志(共4個(gè))其中每個(gè)標(biāo)志代表著一種不同的數(shù)據(jù)類型的錯(cuò)誤,當(dāng)一個(gè)錯(cuò)誤發(fā)生時(shí),與這個(gè)錯(cuò)誤相對(duì)應(yīng)的標(biāo)志就會(huì)被設(shè)置,可以調(diào)用 glGetError 這個(gè)函數(shù)
GLunem glGetError(void);
通常情況下,我們需要在循環(huán)中調(diào)用 上面的函數(shù),直到返回 GL_NO_ERROR 為止
| 錯(cuò)誤代碼 | 描述 |
|---|---|
| GL_INVALID_ENUM | 枚舉參數(shù)超出范圍 |
| GL_INVALID_VALUE | 數(shù)值參數(shù)超出范圍 |
| GL_INVALID_OPERATION | 在當(dāng)前狀態(tài)中操作非法 |
| GL_OUT_OF_MEMORY | 沒有足夠的內(nèi)存來執(zhí)行這條命令 |
| GL_NO_ERROR | 沒有錯(cuò)誤出現(xiàn) |
OpenGL查詢版本號(hào) 和 生產(chǎn)商有關(guān)的特定的信息
const GLubyte *glGetString(GLEnum name)
上面的的函數(shù)返回一個(gè)靜態(tài)的字符串,描述GL 函數(shù)庫(kù)中所請(qǐng)求的信息。
OpenGL 實(shí)用glHint獲取線索
glHint函數(shù)允許我們制定片中于視覺質(zhì)量還是速度,以適應(yīng)各種不同類型的操作,簡(jiǎn)而言之 就是(速度 和 質(zhì)量的 選擇)
void glHint (GLenum target.GLEnum mode)
繪制第一個(gè)三角形
// Created by 張孝江 on 2020/10/8.
//
#define GL_SILENCE_DEPRECATION //為了解除警告的宏。
#include <GLShaderManager.h>
#include <GLUT/GLUT.h>
#include <GLTools.h>
//批處理
GLBatch batch;
//渲染
GLShaderManager shaderManager;
#pragma mark - 定義視口的大小 /窗口里面包含視口/。改變視口并不會(huì)改變坐標(biāo)系,
void changeWindowsSize(GLint width , GLint height){
glViewport(0, 0, width, height);
printf("改變后的寬是%d\n,改變后的高是%d",width,height);
}
#pragma mark - 設(shè)置程序的一些屬性
void setupRC(){
///設(shè)置程序窗口的顏色,
glClearColor(0, 0, 1, 1);
///初始化著色器
shaderManager.InitializeStockShaders();
///設(shè)置三角形的頂點(diǎn)數(shù)據(jù) //從左到右。 因?yàn)?我們渲染的是一個(gè)三角形,所以 Y 軸的 點(diǎn)都為0.
//坐標(biāo)是以屏幕的中心為原點(diǎn)的。左邊- 右邊+ 上+ 下- ,這樣子就會(huì)有八個(gè)象限 立體來說。中國(guó)古人對(duì)于空間的理解是 混沌(點(diǎn)) -> 太極(線)->四象 -(平面 (笛卡爾 2D坐標(biāo)系))-> 八卦(笛卡爾3D 坐標(biāo)系。)
//此外,還有 左手坐標(biāo)系,和 右手坐標(biāo)系。
GLfloat vVters[] = {
//三角形第一個(gè)點(diǎn)在三維笛卡爾坐標(biāo)系的位置
-0.5,-0.0f,-0.0f,
//三角形第二個(gè)點(diǎn)在三維笛卡爾坐標(biāo)系的位置
0.0f,0.5f,0.0f,
//三角形第三個(gè)點(diǎn)在三維笛卡爾坐標(biāo)系的位置
0.5f,0.0f,0.0f,
};
//處理數(shù)據(jù)
batch.Begin(GL_TRIANGLES, 3);
batch.CopyVertexData3f(vVters);
batch.End();
}
#pragma mark //畫屏幕
void RenderScene (void){
//清除緩沖區(qū)的內(nèi)容
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//設(shè)置三角形的填充顏色。
GLfloat vred[] = {1.0f,0.0f,0.0f,1.0f};
//傳遞到存儲(chǔ)著色器,即GLT_SHADER_IDENITY 著色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vred);
//提交著色器
batch.Draw();
//將在后臺(tái)緩沖區(qū)進(jìn)行渲染 然后交換到前臺(tái)
glutSwapBuffers();
}
//按鍵使視圖進(jìn)行變化
void specilalkeys(int key,int x,int y){
GLfloat c = 0.25f;
GLfloat vVters[] = {
-0.5,0.0f,0.0f,
0.0f,0.5f,0.0f,
0.5f,0.0f,0.0f,
};
if (key == GLUT_KEY_UP) {
vVters[4] +=c;
}
if (key == GLUT_KEY_DOWN) {
vVters[4] -=c;
}
if (key == GLUT_KEY_LEFT) {
vVters[0]-=c;
}
if (key == GLUT_KEY_RIGHT) {
vVters[0]+=c;
}
batch.CopyVertexData3f(vVters);
glutPostRedisplay();
}
///main 函數(shù)
int main(int argc,char * argv[])
{
/*設(shè)置當(dāng)前的工作目錄 (針對(duì)macOS)*/
gltSetWorkingDirectory(argv[0]);
/*初始化GLUT*/
glutInit(&argc, argv);
/*初始化雙緩沖窗口,其中標(biāo)志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分別指
雙緩沖窗口、RGBA顏色模式、深度測(cè)試、模板緩沖區(qū)*/
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
/*設(shè)置初始值窗口大小*/
glutInitWindowSize(313,218);
/*設(shè)置窗口的標(biāo)題*/
glutCreateWindow("我的第一個(gè)三角形");
/*注冊(cè)回調(diào)函數(shù) 此函數(shù)可監(jiān)聽窗口大小的改變 切 glView*/
glutReshapeFunc(changeWindowsSize);
/*注冊(cè)函數(shù)回調(diào) 繪制屏幕 上面函數(shù)一旦發(fā)生改變,下面的函數(shù)就立刻執(zhí)行繪制。*/
glutDisplayFunc(RenderScene);
/*為了讓其移動(dòng)注冊(cè)回調(diào)函數(shù)*/
glutSpecialFunc(specilalkeys);
/*驅(qū)動(dòng)程序初始化過程中可能遇到的問題。說上有說名*/
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
/*繪制三角形*/
setupRC();
glutMainLoop();
return 0;
}