OpenGl多重紋理的計算

Opengl  多重紋理貼圖            


    關於多重紋理:
    首先如果一個顯卡支持多重紋理,表示它可以將幾次渲染合爲一次來進行,在這個渲染過程中,你可以在不同的紋理單元分別放入第0次,第1次,第2次需要渲染的對象.當程序向屏幕繪圖時,將這些渲染結果疊加起來,將最終結果顯示到屏幕.
    每個紋理單元對應有其紋理環境,這個紋理環境指明瞭渲染的紋理圖片、渲染參數、過濾參數等等,其中有一個重要的項目指明瞭,程序在將渲染結果進行逐個疊加的過程中,當前的紋理單元內的內容如何與前面的內容進行混合.
    這個些參數中包含了:
     a . 要進行混合的紋理的來源
           這個來源要分兩步指定:
               1. 對象來自哪個紋理單元[例如GL_TEXTURE0, GL_TEXTURE1], 
              2.該單元中的什麼成分[例如:GL_SRC_COLOR,GL_ONE_MINUS_SRC_COLOR]
     b. 混合所使用的函數
           例如GL_ADD,GL_MODULATE,GL_INTERPLATE等
    通俗一點來說呢, 如果我們要進行一次多重渲染就是要把兩個紋理進行一次數學運算把得到的結果投放到屏幕。 
    當然這個數學運算是需要你自己指定的這包括運算類型,操作數來源,操作數的值, 就像下面這個簡單的代數式一樣:
            C = A + B
要算出這個結果,那麼我們首先要指定要進行什麼運算(這裏是+),然後指定這個運算的兩個操作數(這裏是a和b,對於渲染還要知道他們來自哪個紋理單元).
     這些參數的指定都是通過用不同的參數來調用glTexEnv 完成的。然後我們就可以運算了。這個C就是我們渲染的最終結果。
    具體來說:如果我們要進行一次多重渲染:
那麼首先我們要在各個紋理單元裏面放入不同的紋理圖片
例如在第0號單元 放入texture[0]所對應的圖片:
    glActiveTextureARB( GL_TEXTURE0_ARB );
    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, texture[0] );
例如在第1號單元 放入texture[1]所對應的圖片:
    glActiveTextureARB( GL_TEXTURE2_ARB );
    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, texture[1] );
然後 我們開始指定我們的代數運算:
首先告訴OpenGL 我們要把兩個單元的紋理進行混合:
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
然後告訴OpenGL我們要進行的運算:
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
這裏 INTERPOLATE 是指線性插值,它的公式是這樣的:
    C = Arg0*Arg2 + Arg1*(1-Arg2);
    翻譯成代數的是這樣:
    C = a*ω + b*(1-ω) ; 這下大家可以清楚的看到它是一個線性插值表達式了吧
 其中: Arg0 是第一個操作數,Arg1是第二個操作數,Arg2 是線性插值的係數就是那個ω了。
這些都要通過下面的函數調用來指定。當然,混合函數還可以是GL_ADD “加”,
GL_SUBTRACT “減”,GL_MODULATE “乘” 等等.
    下面來說 Arg0,Arg1,Arg2 的指定:
前面提到過:要指定一個操作數,需要指定它來自於哪個紋理單元,和來自於該紋理單元的哪個部分:
所以我們在下面可以看到,指定一個Arg用了兩句話,第一個指定了這個操作數的內容來自哪個紋理單元,第二個指定了來自於紋理單元裏的哪個部分:
    //前一個 這裏指0號單元
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
    //0號單元中的COLOR部分即RGB
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
 
    //這個GL_TEXTURE指當前活動的紋理單元也就是1號紋理單元
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
 
    //由紋理環境變量GL_PRIMARY_COLOR_ARB指定的值
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
   
有了他們 就完成了混合函數的指定了,下面要做的事就是給一個幾何圖像同時綁上不同的紋理讓它們去按上面的公式混合吧 :
        glBegin(GL_QUADS);
        glNormal3f(0.0,0.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0,0.0);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0,0.0);
        glVertex3f(0.0f,0.0f,0.0f);
 
        glNormal3f(0.0,0.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0,1.0);
 
        glVertex3f(0.0f,1.0f,0.0f);
 
        glNormal3f(0.0,0.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0,1.0);
        glVertex3f(1.0f,1.0f,0.0f);
 
        glNormal3f(0.0,0.0,1.0);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0,0.0);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0,0.0);
        glVertex3f(1.0f,0.0f,0.0f);
    glEnd();
 
   上面是我的理解,不一定準確呵呵 不要深究哦.不過我想基本的步驟是說得比較清了. 歡迎聯繫偶......
======================== 提供一些直觀的對比 =====================================
float arr0[4] = {g_T0Blend, g_T0Blend, g_T0Blend, g_T0Blend};
float arr1[4] = {g_T1Blend, g_T1Blend, g_T1Blend, g_T1Blend};
float arr2[4] = {g_T2Blend, g_T2Blend, g_T2Blend, g_T2Blend};
如果:
    g_T0Blend = 0.5f
    g_T1Blend = 0.25f
   g_T2Blend = 0.25f
rn 爲混合器n 的返回值
tn 爲第n單元的紋理值
//Texture0  
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tobjects[TO_EARTH1]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, arr0);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
以上爲紋理單元0 所作的操作,其公式是:
r0 = 0.5*t0
//Texture1
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tobjects[TO_EARTH1]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, arr1);
對應的公式是
r1 = (0.25*t1) + ((1-0.25)*r0) = 0.25*t1 + 0.375*t0
//Texture2
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tobjects[TO_EARTH2]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, arr2);
對應的公式是:
r2 = (0.25*t2) + ((1-0.25)*r1) = 0.25*t2 + 0.1875*t1 + 0.2813*t0

轉載自http://blog.csdn.net/crazyjumper/article/details/1666207?reload  寫的很明白 了, 不錯的文章!
好像我的電腦裏面多重紋理的數目爲4,也就是能用4重紋理。
發佈了39 篇原創文章 · 獲贊 9 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章