OpenGL(十)-OpenGL 基礎(chǔ)紋理

logo.jpg

一、原始圖像數(shù)據(jù)

圖像存儲空間 = 圖像的?高度 * 圖像寬度 * 每個像素的字節(jié)數(shù)

例子:RGB(8位),寬度:199像素鹉动。圖片每行需要多少存儲空間?
199 * 3 * 8 = 597字節(jié)

二轧坎、認(rèn)識函數(shù)

2.1、改變/回復(fù)像素存儲方式

改變像素存儲?方式

void glPixelStorei(GLenum pname,GLint param);

恢復(fù)像素存儲?方式

void glPixelStoref(GLenum pname,GLfloat param);

例子:
參數(shù)1:GL_UNPACK_ALIGNMENT 指定OpenGL 如何從數(shù)據(jù)緩存區(qū)中解包圖像數(shù)據(jù)
參數(shù)2:表示參數(shù)GL_UNPACK_ALIGNMENT 設(shè)置的值
GL_UNPACK_ALIGNMENT 指內(nèi)存中每個像素行起點(diǎn)的排列請求泽示,允許設(shè)置為1 (byte排列列)缸血、2(排列為偶數(shù)byte的?)蜜氨、4(字word排列)、8(?從雙字節(jié)邊界開始)
glPixelStorei(GL_UNPACK_ALIGNMENT,1);

2.2捎泻、從顏色緩存區(qū)內(nèi)容作為像素圖直接讀取
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei
height, GLenum format, GLenum type,const void * pixels);

參數(shù)1:x,矩形左下角的窗?坐標(biāo)
參數(shù)2:y,矩形左下角的窗?坐標(biāo)
參數(shù)3:width,矩形的寬记劝,以像素為單位
參數(shù)4:height,矩形的高,以像素為單位
參數(shù)5:format,OpenGL 的像素格式,參考圖1
參數(shù)6:type,解釋參數(shù)pixels指向的數(shù)據(jù)族扰,告訴OpenGL 使?緩存區(qū)中的什么數(shù)據(jù)類型來存儲顏?色分量厌丑,像素數(shù)據(jù)的數(shù)據(jù)類型,參考圖2
參數(shù)7:pixels,指向圖形數(shù)據(jù)的指針

圖1.OpenGL 像素格式.jpeg
圖2.像素數(shù)據(jù)的數(shù)據(jù)類型.jpeg
glReadBuffer(mode);

指定讀取的緩存

glWriteBuffer(mode);

指定寫?入的緩存

2.3渔呵、載?紋理
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)

*target:GL_TEXTURE_1D怒竿、GL_TEXTURE_2DGL_TEXTURE_3D扩氢。

  • Level:指定所加載的mip貼圖層次耕驰。?般我們都把這個參數(shù)設(shè)置為0。
  • internalformat:每個紋理單元中存儲多少顏色成分录豺。
  • width朦肘、height、depth參數(shù):指加載紋理理的寬度双饥、?高度媒抠、深度。這些值必須是 2的整數(shù)次?方咏花。(這是因?yàn)镺penGL 舊版本上的遺留留下的?一個要求趴生。當(dāng)然現(xiàn)在已經(jīng)可以支持不是 2的整數(shù)次?方。但是開發(fā)者們還是習(xí)慣使?用以2的整數(shù)次?方去設(shè)置這些參數(shù)昏翰。)
  • border參數(shù):允許為紋理理貼圖指定?一個邊界寬度苍匆。
  • format、type棚菊、data參數(shù):與我們在講glDrawPixels 函數(shù)對于的參數(shù)相同
2.4浸踩、更新紋理
void glTexSubImage1D(GLenum target,GLint level,GLint xOffset,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);
2.5、插入替換紋理
void glCopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsize
width);
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint x,
     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);
2.6统求、使?顏?緩存區(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ū)中指定了開始讀取紋理數(shù)據(jù)的位置; 緩存區(qū)里的數(shù)據(jù)检碗,是源緩存區(qū)通過glReadBuffer設(shè)置的。
注意:不存在glCopyTextImage3D 球订,因?yàn)槲覀?法從2D 顏?色緩存區(qū)中獲取體積數(shù)據(jù)后裸。

三、紋理對象

 void glGenTextures(GLsizei n,GLuint * textTures);

使?函數(shù)分配紋理對象
指定紋理對象的數(shù)量和指針(指針指向一個?符號整形數(shù)組冒滩,由紋理對象標(biāo)識符填充)微驶。

void glBindTexture(GLenum target,GLunit texture);

綁定紋理理狀態(tài)
參數(shù)target:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
參數(shù)texture:需要綁定的紋理理對象

void glDeleteTextures(GLsizei n,GLuint *textures); //測試紋理理對象是否有效

刪除綁定紋理理對象
紋理對象以及紋理對象指針(指針指向一個?符號整形數(shù)組因苹,由紋理對象標(biāo)識符填充)苟耻。

GLboolean glIsTexture(GLuint texture);

如果texture是?一個已經(jīng)分配空間的紋理理對象,那么這個函數(shù)會返回GL_TRUE,否則會返回GL_FALSE扶檐。

3.1凶杖、設(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ù)1:target,指定這些參數(shù)將要應(yīng)用在哪個紋理模式上,比如GL_TEXTURE_1D款筑、GL_TEXTURE_2D智蝠、GL_TEXTURE_3D。
參數(shù)2:pname,指定需要設(shè)置那個紋理參數(shù)
參數(shù)3:param,設(shè)定特定的紋理參數(shù)的值

3.2奈梳、設(shè)置過濾?式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST) 

紋理縮?時,使?鄰近過濾

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) 

紋理放大時,使用線性過濾

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

3.2杈湾、設(shè)置環(huán)繞方式
參數(shù) 描述
GL_REPEAT 對紋理的默認(rèn)行。重復(fù)紋理圖像
GL_MIRRORED 和GL_REPEAT一樣,但每次重復(fù)圖片是鏡像放置的攘须。
GL_CLAMP_TO_EDGE 紋理坐標(biāo)會被約束在0到1之間,超出部分會重復(fù)紋理坐標(biāo)的邊緣漆撞,產(chǎn)生一種邊緣被拉伸的效果。
GL_CLAMP_TO_BORDER 超出的坐標(biāo)為用戶指定的邊緣顏色于宙。

當(dāng)紋理坐標(biāo)超出默認(rèn)范圍時,每個選項(xiàng)都有不同視覺效果輸出浮驳。我們來看看這些紋理圖像的例子:


WechatIMG22.jpeg
   glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE);
   glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);

參數(shù)1:GL_TEXTURE_1D、GL_TEXTURE_2D捞魁、GL_TEXTURE_3D
參數(shù)2:GL_TEXTURE_WRAP_S至会、GL_TEXTURE_T、GL_TEXTURE_R,針對s,t,r坐標(biāo)
參數(shù)3:GL_REPEAT署驻、GL_CLAMP奋献、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER
GL_REPEAT:OpenGL 在紋理坐標(biāo)超過1.0的?向上對紋理進(jìn)?重復(fù);
GL_CLAMP:所需的紋理單元取?紋理邊界或TEXTURE_BORDER_COLOR. GL_CLAMP_TO_EDGE環(huán)繞模式強(qiáng)制對范圍之外的紋理坐標(biāo)沿著合法的紋理單元的最后??或者最后一列來進(jìn)?采樣旺上。
GL_CLAMP_TO_BORDER:在紋理坐標(biāo)在0.0到1.0范圍之外的只使?邊界紋理單元。邊界紋理單元是作為圍繞基本圖像的額外的行和列糖埋,并與基本紋理圖像一起加載的宣吱。

四、金字塔案例

#include "GLTools.h"
#include "GLShaderManager.h"
#include "GLFrustum.h"
#include "GLBatch.h"
#include "GLFrame.h"
#include "GLMatrixStack.h"
#include "GLGeometryTransform.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

GLShaderManager     shaderManager;
GLMatrixStack       modelViewMatrix;
GLMatrixStack       projectionMatrix;
GLFrame             cameraFrame;
GLFrame             objectFrame;
GLFrustum           viewFrustum;

GLBatch             pyramidBatch;

//紋理變量瞳别,一般使用無符號整型
GLuint              textureID;

GLGeometryTransform transformPipeline;
M3DMatrix44f        shadowMatrix;

//繪制金字塔
void MakePyramid(GLBatch& pyramidBatch)
{
    /*1征候、通過pyramidBatch組建三角形批次
      參數(shù)1:類型
      參數(shù)2:頂點(diǎn)數(shù)
      參數(shù)3:這個批次中將會應(yīng)用1個紋理
      注意:如果不寫這個參數(shù),默認(rèn)為0祟敛。
     */
    pyramidBatch.Begin(GL_TRIANGLES, 18, 1);
    
    /***前情導(dǎo)入
     
     1)設(shè)置法線
     void Normal3f(GLfloat x, GLfloat y, GLfloat z);
     Normal3f:添加一個表面法線(法線坐標(biāo) 與 Vertex頂點(diǎn)坐標(biāo)中的Y軸一致)
     表面法線是有方向的向量疤坝,代表表面或者頂點(diǎn)面對的方向(相反的方向)。在多數(shù)的關(guān)照模式下是必須使用馆铁。后面的課程會詳細(xì)來講法線的應(yīng)用
     
     pyramidBatch.Normal3f(X,Y,Z);
     
     2)設(shè)置紋理坐標(biāo)
     void MultiTexCoord2f(GLuint texture, GLclampf s, GLclampf t);
     參數(shù)1:texture跑揉,紋理層次,對于使用存儲著色器來進(jìn)行渲染,設(shè)置為0
     參數(shù)2:s:對應(yīng)頂點(diǎn)坐標(biāo)中的x坐標(biāo)
     參數(shù)3:t:對應(yīng)頂點(diǎn)坐標(biāo)中的y
     (s,t,r,q對應(yīng)頂點(diǎn)坐標(biāo)的x,y,z,w)
     
     pyramidBatch.MultiTexCoord2f(0,s,t);
     
     3)void Vertex3f(GLfloat x, GLfloat y, GLfloat z);
      void Vertex3fv(M3DVector3f vVertex);
     向三角形批次類添加頂點(diǎn)數(shù)據(jù)(x,y,z);
      pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f);
     
     
     4)獲取從三點(diǎn)找到一個法線坐標(biāo)(三點(diǎn)確定一個面)
     void m3dFindNormal(result,point1, point2,point3);
     參數(shù)1:結(jié)果
     參數(shù)2-4:3個頂點(diǎn)數(shù)據(jù)
     */
    
    //塔頂
    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;
    
    //金字塔底部
    //底部的四邊形 = 三角形X + 三角形Y
    //三角形X = (vBackLeft,vBackRight,vFrontRight)
    
    //1.找到三角形X 法線
    m3dFindNormal(n, vBackLeft, vBackRight, vFrontRight);
   
    //vBackLeft
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackLeft);
    
    //vBackRight
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackRight);
    
    //vFrontRight
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    pyramidBatch.Vertex3fv(vFrontRight);
    
    
    //三角形Y =(vFrontLeft,vBackLeft,vFrontRight)
   
    //1.找到三角形X 法線
    m3dFindNormal(n, vFrontLeft, vBackLeft, vFrontRight);
    
    //vFrontLeft
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    pyramidBatch.Vertex3fv(vFrontLeft);
    
    //vBackLeft
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    pyramidBatch.Vertex3fv(vBackLeft);
    
    //vFrontRight
    pyramidBatch.Normal3fv(n);
    pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    pyramidBatch.Vertex3fv(vFrontRight);

    
    // 金字塔前面
    //三角形:(Apex历谍,vFrontLeft现拒,vFrontRight)
    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();
}

// 將TGA文件加載為2D紋理。
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
    GLbyte *pBits;
    int nWidth, nHeight, nComponents;
    GLenum eFormat;
    
    //1望侈、讀紋理位印蔬,讀取像素
    //參數(shù)1:紋理文件名稱
    //參數(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:線性過濾
    //參數(shù)3:wrapMode,環(huán)繞模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    

    //3.載入紋理
    //參數(shù)1:紋理維度
    //參數(shù)2:mip貼圖層次
    //參數(shù)3:紋理單元存儲的顏色成分(從讀取像素圖是獲得)
    //參數(shù)4:加載紋理寬
    //參數(shù)5:加載紋理高
    //參數(shù)6:加載紋理的深度
    //參數(shù)7:像素數(shù)據(jù)的數(shù)據(jù)類型(GL_UNSIGNED_BYTE脱衙,每個顏色分量都是一個8位無符號整數(shù))
    //參數(shù)8:指向紋理圖像數(shù)據(jù)的指針
    
    glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
                 eFormat, GL_UNSIGNED_BYTE, pBits);
    
    //使用完畢釋放pBits
    free(pBits);
    
    
    //4.加載Mip,紋理生成所有的Mip層
    //參數(shù):GL_TEXTURE_1D侥猬、GL_TEXTURE_2D、GL_TEXTURE_3D
    glGenerateMipmap(GL_TEXTURE_2D);
 
    return true;
}




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



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

void RenderScene(void)
{
    //1.顏色值&光源位置
    static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f };
    static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f };
    
    //2.清理緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    //3.當(dāng)前模型視頻壓棧
    modelViewMatrix.PushMatrix();
    
    //添加照相機(jī)矩陣
    M3DMatrix44f mCamera;
    //從camraFrame中獲取一個4*4的矩陣
    cameraFrame.GetCameraMatrix(mCamera);
    //矩陣乘以矩陣堆棧頂部矩陣奥帘,相乘結(jié)果存儲到堆棧的頂部 將照相機(jī)矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
    modelViewMatrix.MultMatrix(mCamera);
    
    //創(chuàng)建mObjectFrame矩陣
    M3DMatrix44f mObjectFrame;
    //從objectFrame中獲取矩陣铜邮,objectFrame保存的是特殊鍵位的變換矩陣
    objectFrame.GetMatrix(mObjectFrame);
    //矩陣乘以矩陣堆棧頂部矩陣,相乘結(jié)果存儲到堆棧的頂部 將世界變換矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
    modelViewMatrix.MultMatrix(mObjectFrame);
    
    //4.綁定紋理寨蹋,因?yàn)槲覀兊捻?xiàng)目中只有一個紋理松蒜。如果有多個紋理。綁定紋理很重要
    glBindTexture(GL_TEXTURE_2D, textureID);
    
    /*5.點(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();
    
    //6.交換緩存區(qū)
    glutSwapBuffers();
}



void SpecialKeys(int key, int x, int y)
{
    if(key == GLUT_KEY_UP)
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
    
    if(key == GLUT_KEY_DOWN)
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);
    
    if(key == GLUT_KEY_LEFT)
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);
    
    if(key == GLUT_KEY_RIGHT)
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);
    
    glutPostRedisplay();
}





void ChangeSize(int w, int h)
{
    //1.設(shè)置視口
    glViewport(0, 0, w, h);
    
    //2.創(chuàng)建投影矩陣
    viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
  
    //viewFrustum.GetProjectionMatrix()  獲取viewFrustum投影矩陣
    //并將其加載到投影矩陣堆棧上
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    
    //3.設(shè)置變換管道以使用兩個矩陣堆棧(變換矩陣modelViewMatrix ,投影矩陣projectionMatrix)
    //初始化GLGeometryTransform 的實(shí)例transformPipeline.通過將它的內(nèi)部指針設(shè)置為模型視圖矩陣堆棧 和 投影矩陣堆棧實(shí)例运褪,來完成初始化
    //當(dāng)然這個操作也可以在SetupRC 函數(shù)中完成惊楼,但是在窗口大小改變時或者窗口創(chuàng)建時設(shè)置它們并沒有壞處。而且這樣可以一次性完成矩陣和管線的設(shè)置秸讹。
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}


int main(int argc, char* argv[])
{
    gltSetWorkingDirectory(argv[0]);
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Pyramid");
    glutReshapeFunc(ChangeSize);
    glutSpecialFunc(SpecialKeys);
    glutDisplayFunc(RenderScene);
    
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    

    SetupRC();
    
    glutMainLoop();
    
    ShutdownRC();
    
    return 0;
}

001--紋理(金字塔案例).png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末檀咙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子璃诀,更是在濱河造成了極大的恐慌弧可,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣欢,死亡現(xiàn)場離奇詭異棕诵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凿将,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門校套,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人牧抵,你說我怎么就攤上這事笛匙。” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵膳算,是天一觀的道長座硕。 經(jīng)常有香客問我,道長涕蜂,這世上最難降的妖魔是什么华匾? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮机隙,結(jié)果婚禮上蜘拉,老公的妹妹穿的比我還像新娘。我一直安慰自己有鹿,他們只是感情好旭旭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葱跋,像睡著了一般持寄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娱俺,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天稍味,我揣著相機(jī)與錄音,去河邊找鬼荠卷。 笑死模庐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的油宜。 我是一名探鬼主播掂碱,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼慎冤!你這毒婦竟也來了疼燥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤粪薛,失蹤者是張志新(化名)和其女友劉穎悴了,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體违寿,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年熟空,在試婚紗的時候發(fā)現(xiàn)自己被綠了藤巢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡息罗,死狀恐怖掂咒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤绍刮,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布温圆,位于F島的核電站,受9級特大地震影響孩革,放射性物質(zhì)發(fā)生泄漏岁歉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一膝蜈、第九天 我趴在偏房一處隱蔽的房頂上張望锅移。 院中可真熱鬧莺匠,春花似錦梨州、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽备绽。三九已至,卻和暖如春鬓催,著一層夾襖步出監(jiān)牢的瞬間肺素,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工深浮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留压怠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓飞苇,卻偏偏與公主長得像菌瘫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子布卡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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