OpenGL 基礎(chǔ)紋理

紋理坐標(biāo)

  • 紋理坐標(biāo)范圍0-1

  • 紋理坐標(biāo)表示方式(s,t,r)

  • 二維紋理坐標(biāo)如下圖


    image.png
  • 三維紋理坐標(biāo)


    image.png
  • 紋理映射


    image.png

常用的函數(shù)

  • 載入、讀取风瘦、更新、替換紋理
/**
  *參數(shù)1:GL_UNPACK_ALIGNMENT 指定OpenGL 如何從數(shù)據(jù)緩存區(qū)中解包圖像
  *參數(shù)2:GL_UNPACK_ALIGNMENT 指內(nèi)存中每個(gè)像素?起點(diǎn)的排列請(qǐng)求们何,允許設(shè)置為1 (byte排列)常遂、2(排列為偶數(shù)byte的?)、4(字word排列)、8(?從雙字節(jié)邊界開(kāi)始)
*/
//改變像素存儲(chǔ)?式
void glPixelStorei(GLenum pname,GLint param);
//恢復(fù)像素存儲(chǔ)?式
void glPixelStoref(GLenum pname,GLfloat param);
// 常設(shè)置為
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
//------------------------------------------------------
//從顏?緩存區(qū)內(nèi)容作為像素圖直接讀取
//參數(shù)1:x,矩形左下?的窗?坐標(biāo)
//參數(shù)2:y,矩形左下?的窗?坐標(biāo)
//參數(shù)3:width,矩形的寬居灯,以像素為單位
//參數(shù)4:height,矩形的?,以像素為單位
//參數(shù)5:format,OpenGL 的像素格式内狗,參考 表6-1
//參數(shù)6:type,解釋參數(shù)pixels指向的數(shù)據(jù)怪嫌,告訴OpenGL 使?緩存區(qū)中的什么
//數(shù)據(jù)類(lèi)型來(lái)存儲(chǔ)顏?分量,像素?cái)?shù)據(jù)的數(shù)據(jù)類(lèi)型柳沙,參考 表6-2
//參數(shù)7:pixels,指向圖形數(shù)據(jù)的指針
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei height, GLenum format, GLenum type,const void * pixels);
//---------------------------------------------------------
// 載?紋理
// target:`GL_TEXTURE_1D`,`GL_TEXTURE_2D`,`GL_TEXTURE_3D`
// Level:指定所加載的mip貼圖層次岩灭。?般我們都把這個(gè)參數(shù)設(shè)置為0。
// internalformat:每個(gè)紋理單元中存儲(chǔ)多少顏?成分赂鲤。
// width噪径、height柱恤、depth參數(shù):指加載紋理的寬度、?度找爱、深度梗顺。==注意!==這些值必須是2的整數(shù)次?车摄。(這是因?yàn)镺penGL 舊版本上的遺留下的?個(gè)要求寺谤。當(dāng)然現(xiàn)在已經(jīng)可以?持不是2的整數(shù)次?。但是開(kāi)發(fā)者們還是習(xí)慣使?以2的整數(shù)次?去設(shè)置這些參數(shù)吮播。)
// border參數(shù):允許為紋理貼圖指定?個(gè)邊界寬度变屁。
// format、type意狠、data參數(shù):與我們?cè)谥vglDrawPixels 函數(shù)對(duì)于的參數(shù)相同
void glTexImage1D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLint border,GLenum format,GLenum type,void *data);
void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,void * data);
void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data);
// -----------------------------------------------------
// 更新紋理
void glTexSubImage1D(GLenum target,GLint level,GLintxOffset,GLsizei width,GLenum format,GLenum type,const GLvoid *data);
void glTexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid *data);
void glTexSubImage3D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLint zOffset,GLsizei width,GLsizei height,GLsizei depth,Glenum type,const GLvoid * data);
// ------------------------------------------------------
// 替換紋理
void glCopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width);
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint x,GLint y,GLsizei width,GLsizei height);
void glCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint zOffset,GLint x,GLint y,GLsizei width,GLsizei height);
// ------------------------------------------------------
// 使?顏?緩存區(qū)加載數(shù)據(jù),形成新的紋理使?
void glCopyTexImage1D(GLenum target,GLint level,GLenum internalformt,GLint x,GLint y,GLsizei width,GLint border);
void glCopyTexImage2D(GLenum target,GLint level,GLenum internalformt,GLint x,GLint y,GLsizei width,GLsizei 
height,GLint border);
// x,y 在顏?緩存區(qū)中指定了開(kāi)始讀取紋理數(shù)據(jù)的位置粟关;緩存區(qū)?的數(shù)據(jù),是源緩存區(qū)通過(guò)glReadBuffer設(shè)置的摄职。
// 不存在glCopyTextImage3D 誊役,因?yàn)槲覀?法從2D 顏?緩存區(qū)中獲取體積數(shù)據(jù)。
  • 紋理對(duì)象
//使?函數(shù)分配紋理對(duì)象
//指定紋理對(duì)象的數(shù)量 和 指針(指針指向?個(gè)?符號(hào)整形數(shù)組谷市,由紋理對(duì)象標(biāo)識(shí)符填充)蛔垢。
void glGenTextures(GLsizei n,GLuint * textTures);

//綁定紋理狀態(tài)
//參數(shù)target:GL_TEXTURE_1D、GL_TEXTURE_2D迫悠、GL_TEXTURE_3D
//參數(shù)texture:需要綁定的紋理對(duì)象
void glBindTexture(GLenum target,GLunit texture);

//刪除綁定紋理對(duì)象
//紋理對(duì)象 以及 紋理對(duì)象指針(指針指向?個(gè)?符號(hào)整形數(shù)組鹏漆,由紋理對(duì)象標(biāo)識(shí)符填充)。
void glDeleteTextures(GLsizei n,GLuint *textures);

//測(cè)試紋理對(duì)象是否有效
//如果texture是?個(gè)已經(jīng)分配空間的紋理對(duì)象创泄,那么這個(gè)函數(shù)會(huì)返回GL_TRUE,否則會(huì)返回GL_FALSE艺玲。
GLboolean glIsTexture(GLuint texture);

  • 設(shè)置紋理參數(shù)
//參數(shù)1:target,指定這些參數(shù)將要應(yīng)?在那個(gè)紋理模式上,?如GL_TEXTURE_1D鞠抑、GL_TEXTURE_2D饭聚、GL_TEXTURE_3D。
//參數(shù)2:pname,指定需要設(shè)置那個(gè)紋理參數(shù)
//參數(shù)3:param,設(shè)定特定的紋理參數(shù)的值
glTexParameterf(GLenum target,GLenum pname,GLFloat param);
glTexParameteri(GLenum target,GLenum pname,GLint param);
glTexParameterfv(GLenum target,GLenum pname,GLFloat *param);
glTexParameteriv(GLenum target,GLenum pname,GLint *param);

設(shè)置過(guò)濾?式


image.png
// 一般情況紋理縮?時(shí),使?鄰近過(guò)濾搁拙,紋理放?時(shí),使?線性過(guò)濾
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST) 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) 

設(shè)置環(huán)繞方式


image.png
//參數(shù)2:GL_TEXTURE_WRAP_S秒梳、GL_TEXTURE_T、GL_TEXTURE_R,針對(duì)s,t,r坐標(biāo)
//參數(shù)3:GL_REPEAT箕速、GL_CLAMP酪碘、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER
//GL_REPEAT:OpenGL 在紋理坐標(biāo)超過(guò)1.0的?向上對(duì)紋理進(jìn)?重復(fù)盐茎;
//GL_CLAMP:所需的紋理單元取?紋理邊界或TEXTURE_BORDER_COLOR.
//GL_CLAMP_TO_EDGE環(huán)繞模式強(qiáng)制對(duì)范圍之外的紋理坐標(biāo)沿著合法的紋理單元的最后??或者最后?列來(lái)進(jìn)?采樣兴垦。
//GL_CLAMP_TO_BORDER:在紋理坐標(biāo)在0.0到1.0范圍之外的只使?邊界紋理單元。邊界紋理單元是作為圍繞基本圖像的額外的?和列,并與基本紋理圖像?起加載的探越。
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);

Mip貼圖

是一種功能強(qiáng)大的紋理技巧狡赐,它不僅可以提高渲染性能,還能提高場(chǎng)景質(zhì)量
由一些列紋理圖像組成扶关,每個(gè)圖像大小在某個(gè)軸的方向上都縮小一半阴汇,或者是原來(lái)圖像像素總數(shù)的四分之一


image.png

mipmap有多少個(gè)層級(jí)是有g(shù)lTexImage1D、glTexImage2D載入紋理的第二個(gè)參數(shù)level決定的节槐。 層級(jí)從0開(kāi)始搀庶,0,1铜异,2哥倔,3這樣遞增,如果沒(méi)有使用mipmap技術(shù)揍庄,只有第0層的紋理會(huì)被加載咆蒿。在默認(rèn)情況下, 為了使用mipmap蚂子,所有層級(jí)都會(huì)被加載沃测,但是我們可以用紋理參數(shù)來(lái)控制要加載的層級(jí)范圍

//GL_TEXTURE_BASE_LEVEL設(shè)置mip貼圖基層level
//GL_TEXTURE_MAX_LEVEL設(shè)置mip貼圖最?層level
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 

Mip貼圖的紋理過(guò)濾


image.png

紋理壓縮

  • 壓縮格式


    image.png
  • 壓縮

//判斷紋理是否被成功壓縮
GLint comFlag;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);
//根據(jù)選擇的壓縮紋理格式,選擇最快食茎、最優(yōu)蒂破、??選擇的算法?式選擇壓縮格式。
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE);
  • 加載壓縮紋理
// target:`GL_TEXTURE_1D``GL_TEXTURE_2D``GL_TEXTURE_3D` //Level:指定所加載的mip貼圖層次别渔。?般我們都把這個(gè)參數(shù)設(shè)置為0附迷。
// internalformat:每個(gè)紋理單元中存儲(chǔ)多少顏?成分。
// width哎媚、height喇伯、depth參數(shù):指加載紋理的寬度、?度拨与、深度稻据。==注意
//border參數(shù):允許為紋理貼圖指定?個(gè)邊界寬度。
//format买喧、type攀甚、data參數(shù):與我們?cè)谥vglDrawPixels 函數(shù)對(duì)于的參數(shù)相同
void glCompressedTexImage1D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,void *data);
void glCompressedTexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint heigth,GLint border,GLsizei imageSize,void *data);
void glCompressedTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei heigth,GLsizei depth,GLint border,GLsizei imageSize,void *data);

紋理使用案例

  • 加載紋理
void SetupRC() {
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
    
    shaderManager.InitializeStockShaders();
    
    glEnable(GL_DEPTH_TEST);
    
    //分配紋理對(duì)象 參數(shù)1:紋理對(duì)象個(gè)數(shù),參數(shù)2:紋理對(duì)象指針
    glGenTextures(1, &textureID);
    //綁定紋理狀態(tài) 參數(shù)1:紋理狀態(tài)2D 參數(shù)2:紋理對(duì)象
    glBindTexture(GL_TEXTURE_2D, textureID);
    //將TGA文件加載為2D紋理岗喉。
    //參數(shù)1:紋理文件名稱(chēng)
    //參數(shù)2&參數(shù)3:需要縮小&放大的過(guò)濾器
    //參數(shù)4:紋理坐標(biāo)環(huán)繞模式
    LoadTGATexture("stone.tga", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, GL_CLAMP_TO_EDGE);
    
    //創(chuàng)造金字塔pyramidBatch
    MakePyramid(pyramidBatch);
    
    /**相機(jī)frame MoveForward(平移)
    參數(shù)1:Z,深度(屏幕到圖形的Z軸距離)
     */
    cameraFrame.MoveForward(-10);
}

// 將TGA文件加載為2D紋理炸庞。
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) {
    GLbyte *pBits;
    int nWidth, nHeight, nComponents;
    GLenum eFormat;
    
    //1钱床、讀紋理位,讀取像素
    //參數(shù)1:紋理文件名稱(chēng)
    //參數(shù)2:文件寬度地址
    //參數(shù)3:文件高度地址
    //參數(shù)4:文件組件地址
    //參數(shù)5:文件格式地址
    //返回值:pBits,指向圖像數(shù)據(jù)的指針
    
    pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
    if(pBits == NULL)
        return false;
    
    //2埠居、設(shè)置紋理參數(shù)
    //參數(shù)1:紋理維度
    //參數(shù)2:為S/T坐標(biāo)設(shè)置模式
    //參數(shù)3:wrapMode,環(huán)繞模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
    
    //參數(shù)1:紋理維度
    //參數(shù)2:線性過(guò)濾
    //參數(shù)3:wrapMode,環(huán)繞模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    
    //3查牌、精密包裝像素?cái)?shù)據(jù)
    //參數(shù)1:GL_UNPACK_ALIGNMENT,指定OpenGL如何從數(shù)據(jù)緩存區(qū)中解包圖像數(shù)據(jù)
    //參數(shù)2:針對(duì)GL_UNPACK_ALIGNMENT 設(shè)置的值
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
    //載入紋理
    //參數(shù)1:紋理維度
    //參數(shù)2:mip貼圖層次
    //參數(shù)3:紋理單元存儲(chǔ)的顏色成分(從讀取像素圖是獲得)
    //參數(shù)4:加載紋理寬
    //參數(shù)5:加載紋理高
    //參數(shù)6:加載紋理的深度
    //參數(shù)7:像素?cái)?shù)據(jù)的數(shù)據(jù)類(lèi)型(GL_UNSIGNED_BYTE事期,每個(gè)顏色分量都是一個(gè)8位無(wú)符號(hào)整數(shù))
    //參數(shù)8:指向紋理圖像數(shù)據(jù)的指針
    
    glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
                 eFormat, GL_UNSIGNED_BYTE, pBits);
    
    //使用完畢釋放pBits
    free(pBits);
    
    
    //只有minFilter 等于以下四種模式,才可以生成Mip貼圖
    //GL_NEAREST_MIPMAP_NEAREST具有非常好的性能纸颜,并且閃爍現(xiàn)象非常弱
    //GL_LINEAR_MIPMAP_NEAREST常常用于對(duì)游戲進(jìn)行加速兽泣,它使用了高質(zhì)量的線性過(guò)濾器
    //GL_LINEAR_MIPMAP_LINEAR 和GL_NEAREST_MIPMAP_LINEAR 過(guò)濾器在Mip層之間執(zhí)行了一些額外的插值,以消除他們之間的過(guò)濾痕跡胁孙。
    //GL_LINEAR_MIPMAP_LINEAR 三線性Mip貼圖唠倦。紋理過(guò)濾的黃金準(zhǔn)則,具有最高的精度涮较。
    if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
       minFilter == GL_LINEAR_MIPMAP_NEAREST ||
       minFilter == GL_NEAREST_MIPMAP_LINEAR ||
       minFilter == GL_NEAREST_MIPMAP_NEAREST)
        
        //加載Mip,紋理生成所有的Mip層
        //參數(shù):GL_TEXTURE_1D稠鼻、GL_TEXTURE_2D、GL_TEXTURE_3D
        glGenerateMipmap(GL_TEXTURE_2D);
    
    return true;
}


  • 紋理使用
//繪制金字塔
void MakePyramid(GLBatch& pyramidBatch) {
    /*1狂票、通過(guò)pyramidBatch組建三角形批次
      參數(shù)1:類(lèi)型
      參數(shù)2:頂點(diǎn)數(shù)
      參數(shù)3:這個(gè)批次中將會(huì)應(yīng)用1個(gè)紋理
      注意:如果不寫(xiě)這個(gè)參數(shù)候齿,默認(rèn)為0。
     */
    pyramidBatch.Begin(GL_TRIANGLES, 18, 1);
    
    //金字塔底部
    //底部的四邊形 = 三角形X + 三角形Y
    //三角形X
    
    /*設(shè)置法線
     Normal3f:添加一個(gè)表面法線(法線坐標(biāo) 與 Vertex頂點(diǎn)坐標(biāo)中的Y軸一致)
     表面法線是有方向的向量闺属,代表表面或者頂點(diǎn)面對(duì)的方向(相反的方向)慌盯。在多數(shù)的關(guān)照模式下是必須使用。后面的課程會(huì)詳細(xì)來(lái)講法線的應(yīng)用
     */
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    /**設(shè)置紋理坐標(biāo)
     MultiTexCoord2f(GLuint texture,GLclampf s,GLclamp t);
     參數(shù)1:texture掂器,紋理層次亚皂,對(duì)于使用存儲(chǔ)著色器來(lái)進(jìn)行渲染,設(shè)置為0
     參數(shù)2:(s,t,r,q對(duì)應(yīng)頂點(diǎn)坐標(biāo)的x,y,z,w)s:對(duì)應(yīng)頂點(diǎn)坐標(biāo)中的x坐標(biāo)
     參數(shù)3:t:對(duì)應(yīng)頂點(diǎn)坐標(biāo)中的y
     */
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    //vBlackLeft點(diǎn)
    pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f);
   
    
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    //vBlackRight點(diǎn)
    pyramidBatch.Vertex3f(1.0f, -1.0f, -1.0f);
    
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    //vFrontRight點(diǎn)
    pyramidBatch.Vertex3f(1.0f, -1.0f, 1.0f);
    
    
    //三角形B
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    pyramidBatch.Vertex3f(-1.0f, -1.0f, 1.0f);
    
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f);
    
    pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    pyramidBatch.Vertex3f(1.0f, -1.0f, 1.0f);
    
    //塔頂
    M3DVector3f vApex = { 0.0f, 1.0f, 0.0f };
    M3DVector3f vFrontLeft = { -1.0f, -1.0f, 1.0f };
    M3DVector3f vFrontRight = { 1.0f, -1.0f, 1.0f };
    M3DVector3f vBackLeft = { -1.0f, -1.0f, -1.0f };
    M3DVector3f vBackRight = { 1.0f, -1.0f, -1.0f };
    M3DVector3f n;
    
    
    // 金字塔前面
    //三角形:(Apex唉匾,vFrontLeft孕讳,vFrontRight)
    //紋理坐標(biāo)設(shè)置,參考PPT圖6-4圖
    /** 獲取從三點(diǎn)找到一個(gè)法線坐標(biāo)(三點(diǎn)確定一個(gè)面)
     void m3dFindNormal(result,point1, point2,point3);
     參數(shù)1:結(jié)果
     參數(shù)2-4:3個(gè)頂點(diǎn)數(shù)據(jù)
     */
    m3dFindNormal(n, vApex, vFrontLeft, vFrontRight);
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
    pyramidBatch.Vertex3fv(vApex);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vFrontLeft);

    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    pyramidBatch.Vertex3fv(vFrontRight);
    
    //金字塔左邊
    //三角形:(vApex, vBackLeft, vFrontLeft)
    m3dFindNormal(n, vApex, vBackLeft, vFrontLeft);
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
    pyramidBatch.Vertex3fv(vApex);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackLeft);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vFrontLeft);
    
    //金字塔右邊
    //三角形:(vApex, vFrontRight, vBackRight)
    m3dFindNormal(n, vApex, vFrontRight, vBackRight);
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
    pyramidBatch.Vertex3fv(vApex);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    pyramidBatch.Vertex3fv(vFrontRight);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackRight);
    
    //金字塔后邊
    //三角形:(vApex, vBackRight, vBackLeft)
    m3dFindNormal(n, vApex, vBackRight, vBackLeft);
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
    pyramidBatch.Vertex3fv(vApex);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackRight);
    
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackLeft);
    
    //結(jié)束批次設(shè)置
    pyramidBatch.End();
}

void RenderScene(void) {
    //顏色值
    static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f };
    static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f };
    
    //清理緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    //當(dāng)前模型視圖壓棧
    modelViewMatrix.PushMatrix();
    //添加照相機(jī)矩陣
    M3DMatrix44f mCamera;
    //從camraFrame中獲取一個(gè)4*4的矩陣
    cameraFrame.GetCameraMatrix(mCamera);
    //矩陣乘以矩陣堆棧頂部矩陣巍膘,相乘結(jié)果存儲(chǔ)到堆棧的頂部 將照相機(jī)矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
    modelViewMatrix.MultMatrix(mCamera);
    
    //創(chuàng)建mObjectFrame矩陣
    M3DMatrix44f mObjectFrame;
    //從objectFrame中獲取矩陣厂财,objectFrame保存的是特殊鍵位的變換矩陣
    objectFrame.GetMatrix(mObjectFrame);
    //矩陣乘以矩陣堆棧頂部矩陣,相乘結(jié)果存儲(chǔ)到堆棧的頂部 將世界變換矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
    modelViewMatrix.MultMatrix(mObjectFrame);
    
    //綁定紋理峡懈,因?yàn)槲覀兊捻?xiàng)目中只有一個(gè)紋理璃饱。如果有多個(gè)紋理。綁定紋理很重要
    glBindTexture(GL_TEXTURE_2D, textureID);
    
    /**點(diǎn)光源著色器
     參數(shù)1:GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF(著色器標(biāo)簽)
     參數(shù)2:模型視圖矩陣
     參數(shù)3:投影矩陣
     參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
     參數(shù)5:基本漫反射顏色
     參數(shù)6:圖形顏色(用紋理就不需要設(shè)置顏色肪康。設(shè)置為0)
     */
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
                                 transformPipeline.GetModelViewMatrix(),
                                 transformPipeline.GetProjectionMatrix(),
                                 vLightPos, vWhite, 0);
    
    //pyramidBatch 繪制
    pyramidBatch.Draw();
    
    //模型視圖出棧荚恶,恢復(fù)矩陣(push一次就要pop一次)
    modelViewMatrix.PopMatrix();
    
    //交換緩存區(qū)
    glutSwapBuffers();
}

  • 刪除紋理
// 清理…例如刪除紋理對(duì)象
void ShutdownRC(void) {
    glDeleteTextures(1, &textureID);
}

(本文為學(xué)習(xí)筆記,資料來(lái)自CC老師)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末磷支,一起剝皮案震驚了整個(gè)濱河市谒撼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雾狈,老刑警劉巖廓潜,帶你破解...
    沈念sama閱讀 223,207評(píng)論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辩蛋,警方通過(guò)查閱死者的電腦和手機(jī)呻畸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)悼院,“玉大人伤为,你說(shuō)我怎么就攤上這事【萃荆” “怎么了绞愚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 170,031評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)昨凡。 經(jīng)常有香客問(wèn)我爽醋,道長(zhǎng),這世上最難降的妖魔是什么便脊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,334評(píng)論 1 300
  • 正文 為了忘掉前任蚂四,我火速辦了婚禮,結(jié)果婚禮上哪痰,老公的妹妹穿的比我還像新娘遂赠。我一直安慰自己,他們只是感情好晌杰,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,322評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布跷睦。 她就那樣靜靜地躺著,像睡著了一般肋演。 火紅的嫁衣襯著肌膚如雪抑诸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,895評(píng)論 1 314
  • 那天爹殊,我揣著相機(jī)與錄音蜕乡,去河邊找鬼。 笑死梗夸,一個(gè)胖子當(dāng)著我的面吹牛层玲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播反症,決...
    沈念sama閱讀 41,300評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辛块,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了铅碍?” 一聲冷哼從身側(cè)響起润绵,我...
    開(kāi)封第一講書(shū)人閱讀 40,264評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胞谈,沒(méi)想到半個(gè)月后授药,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體士嚎,經(jīng)...
    沈念sama閱讀 46,784評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,870評(píng)論 3 343
  • 正文 我和宋清朗相戀三年悔叽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爵嗅。...
    茶點(diǎn)故事閱讀 40,989評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娇澎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睹晒,到底是詐尸還是另有隱情趟庄,我是刑警寧澤,帶...
    沈念sama閱讀 36,649評(píng)論 5 351
  • 正文 年R本政府宣布伪很,位于F島的核電站戚啥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锉试。R本人自食惡果不足惜猫十,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,331評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呆盖。 院中可真熱鬧拖云,春花似錦、人聲如沸应又。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,814評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)株扛。三九已至尤筐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洞就,已是汗流浹背盆繁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,940評(píng)論 1 275
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奖磁,地道東北人改基。 一個(gè)月前我還...
    沈念sama閱讀 49,452評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咖为,于是被迫代替她去往敵國(guó)和親秕狰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,995評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 第五章 OpenGL基礎(chǔ)紋理 本章內(nèi)容: 一躁染、常用函數(shù) 像素存儲(chǔ)方式 從顏色緩存區(qū)內(nèi)容作為像素圖直接讀取 載入紋理...
    沙克阿拉卡閱讀 236評(píng)論 0 0
  • 圖像數(shù)據(jù)的存儲(chǔ)空間 我們都知道圖片展示在屏幕上吞彤,都是以位圖來(lái)顯示的 紋理其實(shí)就位圖我衬,只是在OpenGL中我們通常稱(chēng)...
    恍然如夢(mèng)_b700閱讀 262評(píng)論 0 1
  • 一叹放、紋理綜述 物理世界中,視域內(nèi)的顏色會(huì)發(fā)生快速的變化挠羔。你可以看到很多物體表面都會(huì)呈現(xiàn)出豐富的顏色井仰,并且在狹小的面...
    凡幾多閱讀 1,040評(píng)論 1 5
  • 一、原始圖像數(shù)據(jù) 1.像素包裝 圖像存儲(chǔ)空間 = 圖像的高度 * 圖像寬度 * 每個(gè)像素的字節(jié)數(shù) 二破加、函數(shù) (注意...
    a浮生若夢(mèng)a閱讀 640評(píng)論 0 0
  • 前言:如果你沒(méi)有 OpenGL ES 2 的基礎(chǔ)知識(shí)俱恶,請(qǐng)先移步《OpenGL ES 2.0 (iOS) 筆記大綱》...
    半紙淵閱讀 2,110評(píng)論 6 10