OpenGL紋理案例-隧道

使用OpenGL常用的API肚邢,繪制一個簡單的隧道模型并貼圖憎妙。最終下過如下:


完成代碼:

#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個批次容器類

GLBatch? ? ? ? ? ? floorBatch;//地面

GLBatch? ? ? ? ? ? ceilingBatch;//天花板

GLBatch? ? ? ? ? ? leftWallBatch;//左墻面

GLBatch? ? ? ? ? ? rightWallBatch;//右墻面

//深度初始值霜幼,-65。

GLfloat? ? ? ? ? ? viewZ = -60.0f;

// 紋理標(biāo)識符號

#define TEXTURE_BRICK? 0 //墻面

#define TEXTURE_FLOOR? 1 //地板

#define TEXTURE_CEILING 2 //紋理天花板

#define TEXTURE_COUNT? 3 //紋理個數(shù)

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 i ;

? ? for (i = 0 ; i<TEXTURE_COUNT; i++) {


? ? ? ? glBindTexture(GL_TEXTURE_2D, textures[i]);


? ? ? ? switch(value)

? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? case 0:


? ? ? ? ? ? ? ? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 1:


? ? ? ? ? ? ? ? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 2:


? ? ? ? ? ? ? ? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 3:


? ? ? ? ? ? ? ? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 4:


? ? ? ? ? ? ? ? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 5:


? ? ? ? ? ? ? ? ? ? ? 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_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? case 7:

? ? ? ? ? ? ? ? ? ? ? //設(shè)置各向同性過濾,數(shù)量為1.0表示(各向同性采樣)

? ? ? ? ? ? ? ? ? ? ? glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);

? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? }

? ? }

? ? glutPostRedisplay();

}

//在這個函數(shù)里能夠在渲染環(huán)境中進(jìn)行任何需要的初始化,它這里的設(shè)置并初始化紋理對象

void SetupRC()

{

? ? glClearColor(0, 0, 0, 1);

? ? shaderManager.InitializeStockShaders();




? ? GLbyte * byte;


? ? GLint i, width, height, iComponent;

? ? GLenum eFormat;


? ? glGenTextures(TEXTURE_COUNT, textures);

? ? for (i = 0; i<TEXTURE_COUNT; i++) {


? ? ? ? glBindTexture(GL_TEXTURE_2D, textures[i]);


? ? ? ? byte = gltReadTGABits(szTextureFiles[i], &width, &height, &iComponent, &eFormat);

? ? ? ? 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_WRAP_S, GL_CLAMP_TO_EDGE);

? ? ? ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


? ? ? ? glTexImage2D(GL_TEXTURE_2D, 0, iComponent, width, height, 0, eFormat, GL_UNSIGNED_BYTE, byte);

? ? ? ? glGenerateMipmap(GL_TEXTURE_2D);


? ? ? ? free(byte);

? ? }


? ? GLfloat z;

? ? floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);


? ? for (z = 60.0f; z >= 0.0f; z-= 10.0f) {


? ? ? ? floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);

? ? ? ? floorBatch.Vertex3f(-10.0f, -10.0f, z);


? ? ? ? floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);

? ? ? ? floorBatch.Vertex3f(10.0f, -10.0f, z);


? ? ? ? floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);

? ? ? ? floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);


? ? ? ? floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);

? ? ? ? floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);

? ? }

? ? floorBatch.End();


? ? ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);

? ? for (z = 60.0f; z >= 0.0f; z-= 10.0f) {


? ? ? ? ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);

? ? ? ? ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);


? ? ? ? ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);

? ? ? ? ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);


? ? ? ? ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);

? ? ? ? ceilingBatch.Vertex3f(-10.0f, 10.0f, z);


? ? ? ? ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.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, 1.0f, 0.0f);

? ? ? ? leftWallBatch.Vertex3f(-10.0f, -10.0f, z);


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

? ? ? ? leftWallBatch.Vertex3f(-10.0f, 10.0f, z);


? ? ? ? leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);

? ? ? ? leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);


? ? ? ? leftWallBatch.MultiTexCoord2f(0, 0.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, 1.0f, 0.0f);

? ? ? ? rightWallBatch.Vertex3f(10.0f, -10.0f, z);


? ? ? ? rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);

? ? ? ? rightWallBatch.Vertex3f(10.0f, 10.0f, z);


? ? ? ? rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);

? ? ? ? rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);


? ? ? ? rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);

? ? ? ? rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);


? ? }

? ? rightWallBatch.End();

}

//關(guān)閉渲染環(huán)境

void ShutdownRC(void)

{

? ? glDeleteTextures(TEXTURE_COUNT, textures);

}

//前后移動視口來對方向鍵作出響應(yīng)

void SpecialKeys(int key, int x, int y)

{

? ? if (key == GLUT_KEY_UP) {

? ? ? ? viewZ += 0.5f;

? ? }

? ? if (key == GLUT_KEY_DOWN) {

? ? ? ? viewZ -= 0.5f;

? ? }

? ? glutPostRedisplay();

}

//改變視景體和視口揭鳞,在改變窗口大小或初始化窗口調(diào)用

void ChangeSize(int w, int h)

{

? ? if (h == 0) h = 1;


? ? glViewport(0, 0, w, h);


? ? viewFrustum.SetPerspective(80, float(w)/float(h), 1, 120);

? ? projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());

? ? transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);

}

//調(diào)用,繪制場景

void RenderScene(void)

{

? ? glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


? ? modelViewMatrix.PushMatrix();

? ? modelViewMatrix.Translate(0, 0, viewZ);


? ? shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,transformPipeline.GetModelViewProjectionMatrix(),0);


? ? 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;

}

紋理坐標(biāo)對應(yīng)關(guān)系如下:



總結(jié):

1.讀取的紋理可以翻轉(zhuǎn)使用,正反面都可以用來填充亩钟。

2.繪制流程:指定生成紋理ID的數(shù)量和數(shù)組 —>綁定紋理ID—>讀取.tga文件載入紋理 —>設(shè)置過濾方式和環(huán)繞 —> 設(shè)置紋理和頂點(diǎn)對應(yīng)關(guān)系 —> 綁定相應(yīng)的紋理并用對應(yīng)的批次類繪制

3.修改紋理環(huán)繞過濾方式前乓梨,也需要綁定紋理ID

參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市清酥,隨后出現(xiàn)的幾起案子扶镀,更是在濱河造成了極大的恐慌,老刑警劉巖焰轻,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件臭觉,死亡現(xiàn)場離奇詭異,居然都是意外死亡辱志,警方通過查閱死者的電腦和手機(jī)蝠筑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揩懒,“玉大人什乙,你說我怎么就攤上這事∫亚颍” “怎么了臣镣?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長智亮。 經(jīng)常有香客問我忆某,道長,這世上最難降的妖魔是什么阔蛉? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任褒繁,我火速辦了婚禮,結(jié)果婚禮上馍忽,老公的妹妹穿的比我還像新娘。我一直安慰自己燕差,他們只是感情好遭笋,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著徒探,像睡著了一般瓦呼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上测暗,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天央串,我揣著相機(jī)與錄音磨澡,去河邊找鬼。 笑死质和,一個胖子當(dāng)著我的面吹牛稳摄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饲宿,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼厦酬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瘫想?” 一聲冷哼從身側(cè)響起仗阅,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎国夜,沒想到半個月后减噪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡车吹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年筹裕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片礼搁。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡饶碘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出馒吴,到底是詐尸還是另有隱情扎运,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布饮戳,位于F島的核電站豪治,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扯罐。R本人自食惡果不足惜负拟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歹河。 院中可真熱鬧掩浙,春花似錦、人聲如沸秸歧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽键菱。三九已至谬墙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拭抬。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工部默, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人造虎。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓傅蹂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親累奈。 傳聞我的和親對象是個殘疾皇子贬派,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361