OpenGL學(xué)習(xí)之路(7.0) 隧道案例分析與源碼

簡單了解稍后需要用到的知識點(diǎn)

  • ?系列Mip貼圖圖像


    image.png

Mip貼圖: 一種紋理技巧盆色,提高渲染性能的時(shí)候玩祟,能夠改善場景的顯示質(zhì)量逃默,把貼圖分成3份昭娩,主要原理是把一張紋理圖片按照一定側(cè)尺寸縮放,生成一些列的圖片峦甩,按照圖片離照相機(jī)的距離的遠(yuǎn)近赘来,再決定使用哪張圖片。

  • 設(shè)置貼圖Mip

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

  • 經(jīng)過Mip貼圖的紋理過濾


    image.png

紋理采樣

  • 采樣分為兩種
    • 一種是各向同性采樣


      image.png
- 一種是異性采樣
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);

  • 加載壓縮紋理方法

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);
/**
    target:`GL_TEXTURE_1D`幌缝、`GL_TEXTURE_2D`、`GL_TEXTURE_3D`诫欠。
    Level:指定所加載的mip貼圖層次涵卵。?般我們都把這個(gè)參數(shù)設(shè)置為0。     
    internalformat:每個(gè)紋理單元中存儲多少顏?成分荒叼。 width轿偎、height、
    depth參數(shù):指加載紋理的寬度甩挫、高度贴硫、深度。==注意!==這些值必須是2的整數(shù)次方。(這是因?yàn)榕f版本上的遺留下的一個(gè)要求英遭。當(dāng)然現(xiàn)在已經(jīng)可以支持不是2的整數(shù)次方间护。但是開發(fā)者們還是習(xí)慣使用以2的整數(shù)次?去參數(shù)。)
    border參數(shù):允許為紋理貼圖指定一個(gè)邊界寬度挖诸。 
    format汁尺、type、data參數(shù):與我們在講glDrawPixels 函數(shù)對于的參數(shù)相同
*/
  • glGetTexLevelParameter函數(shù)提取的壓縮紋理格式


    image.png
  • GL_EXT_texture_compression_s3tc壓縮格式


    image.png

效果

image.png

分析

  • 隧道分為四個(gè)面多律,分別用三種紋面繪制而成痴突,左邊與右邊的紋理都是一樣的,并且坐標(biāo)位置也是相差無幾狼荞,那么接下來先分析四面中的地面


    image.png

floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1); //Z表示深度辽装,隧道的深度
//如果想隧道越深,把z的值改大就可以了
    for(z = 60.0f; z >= 0.0f; z -=10.0f)
    {
        floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        floorBatch.Vertex3f(-10.0f, -10.0f, z);
        floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        floorBatch.Vertex3f(10.0f, -10.0f, z);
        floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
        floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
    }
    floorBatch.End();

  • 可以從上圖看到相味,這是一個(gè)梯形的長方形拾积,由很多個(gè)三角形組成的,從上面代碼可以看出GL_TRIANGLE_STRIP 三角形扇丰涉,它會連成一個(gè)三角形拓巧,所以兩個(gè)三角形只需要四個(gè)坐標(biāo)就可以了,
    分析坐標(biāo)一死,z代表著深度肛度,越靠近里面的三角形就越小,就不斷地(z-10)一路延伸過去投慈,通過for循環(huán)不斷繪制小長方形形成一個(gè)階梯的地面
  • 天花板的設(shè)置也是和地板一樣的


    image.png

ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    for(z = 60.0f; z >= 0.0f; z -=10.0f)
    {
        ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
        ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
        ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        ceilingBatch.Vertex3f(-10.0f, 10.0f, z);
        ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        ceilingBatch.Vertex3f(10.0f, 10.0f, z);
    }
    ceilingBatch.End();

  • 左邊墻壁同上


    image.png
                
leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{

    leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    leftWallBatch.Vertex3f(-10.0f, -10.0f, z);

    leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    leftWallBatch.Vertex3f(-10.0f, 10.0f, z);

    leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);

    leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);

    leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
}
leftWallBatch.End();

  • 右面跟左面一樣


    image.png

rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
   for(z = 60.0f; z >= 0.0f; z -=10.0f)
   {
       rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
       rightWallBatch.Vertex3f(10.0f, -10.0f, z);
       rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
       rightWallBatch.Vertex3f(10.0f, 10.0f, z);
       rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
       rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
       rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
       rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
   }
   rightWallBatch.End();

源碼實(shí)例

  • 該源碼基于OpenGL搭建的環(huán)境

#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;       //投影矩陣
GLFrustum           viewFrustum;            //視景體
GLGeometryTransform transformPipeline;      //幾何變換管線

//4個(gè)批次容器類
GLBatch             floorBatch;//地面
GLBatch             ceilingBatch;//天花板
GLBatch             leftWallBatch;//左墻面
GLBatch             rightWallBatch;//右墻面

//深度初始值承耿,-65。
GLfloat             viewZ = -65.0f;

// 紋理標(biāo)識符號
#define TEXTURE_BRICK   0 //墻面
#define TEXTURE_FLOOR   1 //地板
#define TEXTURE_CEILING 2 //紋理天花板
#define TEXTURE_COUNT   3 //紋理個(gè)數(shù) 什么3個(gè)紋理數(shù)伪煤?因?yàn)樽筮吅陀疫吺且粯拥?GLuint  textures[TEXTURE_COUNT];//紋理標(biāo)記數(shù)組

//文件tag名字?jǐn)?shù)組
const char *szTextureFiles[TEXTURE_COUNT] = { "brick.tga", "floor.tga", "ceiling.tga" };



//菜單欄選擇
void ProcessMenu(int value)
{
    GLint iLoop;
    
    for (iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++) {
        /**綁定紋理
         參數(shù)1:GL_TEXTURE_2D
         參數(shù)2:需要綁定的紋理對象
         */
        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
        
        /**配置紋理參數(shù) glTextParameteri
         參數(shù)1:紋理模式
         參數(shù)2:紋理參數(shù)
         參數(shù)3:特定紋理參數(shù)
         */
        switch (value) {
            case 0:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器)瘩绒,GL_NEAREST(最鄰近過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                break;
            case 1:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器),GL_LINEAR(線性過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                break;
            case 2:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器)带族,GL_NEAREST_MIPMAP_NEAREST(選擇最鄰近的Mip層,并執(zhí)行最鄰近過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
                break;
            case 3:
                 //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器)蟀给,GL_NEAREST_MIPMAP_LINEAR(在Mip層之間執(zhí)行線性插補(bǔ)蝙砌,并執(zhí)行線性過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
                break;
            case 4:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器),GL_NEAREST_MIPMAP_LINEAR(在Mip層之間執(zhí)行線性插補(bǔ)跋理,并執(zhí)行最鄰近過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
                break;
            case 5:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(縮小過濾器)择克,GL_LINEAR_MIPMAP_LINEAR(在Mip層之間執(zhí)行線性插補(bǔ),并執(zhí)行線性過濾前普,又稱為三線性過濾)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                break;
            case 6: //這里簡單看一下就好了
                
               //設(shè)置各向異性過濾
                GLfloat fLargest;
                //獲取各向異性過濾的最大數(shù)量
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
                //設(shè)置紋理參數(shù)
                glTexParameterf(GL_TEXTURE_2D, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
                break;
            case 7:
                //設(shè)置各向同性過濾肚邢,數(shù)量為1.0表示各向同性過
                glTexParameterf(GL_TEXTURE_2D, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
                break;
        }
    }

    //重繪制
    glutPostRedisplay();
}


//在這個(gè)函數(shù)里能夠在渲染環(huán)境中進(jìn)行任何需要的初始化,它這里的設(shè)置并初始化紋理對象
void SetupRC()
{
    GLbyte *pBytes;
    GLint iWidth, iHeight, iComponents;
    GLenum eFormat;
    GLint iLoop;
    
    //黑色背景
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
    //初始化著色器管理器
    shaderManager.InitializeStockShaders();
    
    //加載紋理
    /** 分配紋理對象 glGenTextures
     參數(shù)1:紋理對象的數(shù)量
     參數(shù)2:紋理對象標(biāo)識數(shù)組
     */
    glGenTextures(TEXTURE_COUNT, textures);
    
    //for循環(huán)綁定、設(shè)置骡湖、載入紋理和生成Mip圖層
    for (iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++) {
        /**綁定紋理對象 glBindTexture
         參數(shù)1:紋理模式贱纠,GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D
         參數(shù)2:需要綁定的紋理對象
         */
        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
        
        /**加載tga文件
         參數(shù)1:紋理文件名稱
         參數(shù)2:文件寬度變量地址
         參數(shù)3:文件高度變量地址
         參數(shù)4:文件組件變量地址
         參數(shù)5:文件格式變量地址
         返回值:pBytes,指向圖像數(shù)據(jù)的指針
         */
        pBytes = gltReadTGABits(szTextureFiles[iLoop], &iWidth, &iHeight, &iComponents, &eFormat);
        
        
        //設(shè)置過濾器
        //GL_TEXTURE_MAG_FILTER(放大過濾器,GL_NEAREST(最鄰近過濾)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //GL_TEXTURE_MIN_FILTER(縮小過濾器),GL_NEAREST(最鄰近過濾)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        //包裝模式(環(huán)繞方式)
        //GL_TEXTURE_WRAP_S(s軸環(huán)繞),GL_CLAMP_TO_EDGE(環(huán)繞模式強(qiáng)制對范圍之外的紋理坐標(biāo)沿著合法的紋理單元的最后一行或一列進(jìn)行采樣)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        //GL_TEXTURE_WRAP_T(T軸環(huán)繞)响蕴,GL_CLAMP_TO_EDGE(環(huán)繞模式強(qiáng)制對范圍之外的紋理坐標(biāo)沿著合法的紋理單元的最后一行或一列進(jìn)行采樣)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        
        //加載紋理
        glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
        
        /**生成Mip圖層 glGenerateMipmap
         參數(shù)1:紋理維度谆焊,GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_2D
         */
        glGenerateMipmap(GL_TEXTURE_2D);
        
        //釋放原始紋理數(shù)據(jù),不在需要紋理原始數(shù)據(jù)了
        free(pBytes);
    }
    
    //建立幾何圖形
    GLfloat z;
    
    /**
     GLTools庫中的容器類浦夷,GBatch辖试,
     void GLBatch::Begin(GLenum primitive,GLuint nVerts,GLuint nTextureUnits = 0);
     參數(shù)1:圖元枚舉值,三角形扇形
     參數(shù)2:頂點(diǎn)數(shù)
     參數(shù)3:1組或者2組紋理坐標(biāo)
     */
    floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    
    //參考筆記坐標(biāo)圖的地板圖形分析
    //Z表示深度,隧道的深度
    for (z = 60.0f; z >= 0.0f; z -= 10.0f) {
        // 紋理坐標(biāo)劈狐,可以參照之前的OpenGL學(xué)習(xí)之路(6.0) 基礎(chǔ)紋理的紋理坐標(biāo)
        //注意:需要注意的是罐孝,它們繪制的順序不能交叉改變
        floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        floorBatch.Vertex3f(-10.0f, -10.0f, z);
        
        floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        floorBatch.Vertex3f(10.0f, -10.0f, z);
        
        floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
        //vFrontRight
        floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
    }
    
    floorBatch.End();
    
    //參照之前的OpenGL學(xué)習(xí)之路(6.0) 基礎(chǔ)紋理的紋理坐標(biāo)
    ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    for(z = 60.0f; z >= 0.0f; z -=10.0f)
    {
        ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
        
        ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
        
        ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        ceilingBatch.Vertex3f(-10.0f, 10.0f, z);
        
        ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        ceilingBatch.Vertex3f(10.0f, 10.0f, z);
    }
    ceilingBatch.End();
    
    //同上
    leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    for(z = 60.0f; z >= 0.0f; z -=10.0f)
    {
        leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        leftWallBatch.Vertex3f(-10.0f, -10.0f, z);
        
        leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        leftWallBatch.Vertex3f(-10.0f, 10.0f, z);
        
        leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
        
        leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
    }
    leftWallBatch.End();
    
    //同上
    rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    for(z = 60.0f; z >= 0.0f; z -=10.0f)
    {
        rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        rightWallBatch.Vertex3f(10.0f, -10.0f, z);
        
        rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        rightWallBatch.Vertex3f(10.0f, 10.0f, z);
        
        rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
        
        rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
    }
    rightWallBatch.End();
}

//關(guān)閉渲染環(huán)境
void ShutdownRC(void)
{
   //刪除紋理,有三個(gè)
    glDeleteTextures(TEXTURE_COUNT, textures);
}


//前后移動視口來對方向鍵作出響應(yīng)
void SpecialKeys(int key, int x, int y)
{
    if (key == GLUT_KEY_UP) {
        //平移的是深度值肥缔,z值
        viewZ += 0.5f;
    }
    
    if (key == GLUT_KEY_DOWN) {
        viewZ -= 0.5f;
    }
    
    //更新窗口莲兢,即可回調(diào)到RenderScene函數(shù)里
    glutPostRedisplay();
}

//改變視景體和視口,在改變窗口大小或初始化窗口調(diào)用
void ChangeSize(int w, int h)
{
    
    //將視口設(shè)置大小
    glViewport(0, 0, w, h);
    
    //生成透視投影
    viewFrustum.SetPerspective(80.0f, float(w)/float(h), 1.0f, 120.f);
    //獲取投影矩陣并加載矩陣
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}

//調(diào)用辫继,繪制場景
void RenderScene(void)
{
    // 清除顏色緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT);
    
    //模型視圖壓棧
    modelViewMatrix.PushMatrix(); //括號為空的時(shí)候怒见,表示壓棧當(dāng)前線程
    //Z軸平移ViewZ 距離
    modelViewMatrix.Translate(0.0f, 0.0f, viewZ);
    
    //紋理替換著色器管理器
    /*
     參數(shù)1:GLT_SHADER_TEXTURE_REPLACE(著色器標(biāo)簽)
     參數(shù)2:模型視圖投影矩陣
     參數(shù)3:紋理層
     */
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(),0);
    
    //綁定紋理
    /*
     參數(shù)1:紋理模式,GL_TEXTURE_1D姑宽、GL_TEXTURE_2D遣耍、GL_TEXTURE_3D
     參數(shù)2:需要綁定的紋理
     */
    glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);
    floorBatch.Draw();
    
    glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);
    ceilingBatch.Draw();
    
    glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);
    leftWallBatch.Draw();
    rightWallBatch.Draw();
    
    modelViewMatrix.PopMatrix();
    
    glutSwapBuffers();
    

}



int main(int argc, char *argv[])
{
    gltSetWorkingDirectory(argv[0]);
    
    // 標(biāo)準(zhǔn)初始化
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Tunnel");
    glutReshapeFunc(ChangeSize);
    glutSpecialFunc(SpecialKeys);
    glutDisplayFunc(RenderScene);
    
    // 添加菜單入口,改變過濾器
    glutCreateMenu(ProcessMenu);
    glutAddMenuEntry("GL_NEAREST",0);
    glutAddMenuEntry("GL_LINEAR",1);
    glutAddMenuEntry("GL_NEAREST_MIPMAP_NEAREST",2);
    glutAddMenuEntry("GL_NEAREST_MIPMAP_LINEAR", 3);
    glutAddMenuEntry("GL_LINEAR_MIPMAP_NEAREST", 4);
    glutAddMenuEntry("GL_LINEAR_MIPMAP_LINEAR", 5);
    glutAddMenuEntry("Anisotropic Filter", 6);
    glutAddMenuEntry("Anisotropic Off", 7);
    
    
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    
    
    // 啟動循環(huán)炮车,關(guān)閉紋理
    SetupRC();
    glutMainLoop();
    ShutdownRC();
    
    return 0;
}


源碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舵变,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瘦穆,更是在濱河造成了極大的恐慌纪隙,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扛或,死亡現(xiàn)場離奇詭異绵咱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)熙兔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門悲伶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人住涉,你說我怎么就攤上這事麸锉。” “怎么了舆声?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵花沉,是天一觀的道長柳爽。 經(jīng)常有香客問我,道長碱屁,這世上最難降的妖魔是什么磷脯? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮忽媒,結(jié)果婚禮上争拐,老公的妹妹穿的比我還像新娘。我一直安慰自己晦雨,他們只是感情好架曹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闹瞧,像睡著了一般绑雄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奥邮,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天万牺,我揣著相機(jī)與錄音,去河邊找鬼洽腺。 笑死脚粟,一個(gè)胖子當(dāng)著我的面吹牛努潘,可吹牛的內(nèi)容都是我干的遥缕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼款违,長吁一口氣:“原來是場噩夢啊……” “哼藕坯!你這毒婦竟也來了团南?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤炼彪,失蹤者是張志新(化名)和其女友劉穎吐根,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辐马,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拷橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喜爷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膜楷。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贞奋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穷绵,我是刑警寧澤轿塔,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響勾缭,放射性物質(zhì)發(fā)生泄漏揍障。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一俩由、第九天 我趴在偏房一處隱蔽的房頂上張望毒嫡。 院中可真熱鬧,春花似錦幻梯、人聲如沸兜畸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咬摇。三九已至,卻和暖如春煞躬,著一層夾襖步出監(jiān)牢的瞬間肛鹏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工恩沛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留在扰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓雷客,卻偏偏與公主長得像芒珠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子佛纫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

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