簡單了解稍后需要用到的知識點(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;
}