2011-02-07 61 views
1

我試圖爲每個面繪製一個具有不同紋理的立方體。我遇到過很多教程,其中指出在display()例程中,您需要在調用glDrawElements()之前啓用所有紋理單元。我這樣做我的電話:OpenGL中的紋理單元和頂點數組

gl.glClientActiveTexture(GL.GL_TEXTURE0); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

gl.glClientActiveTexture(GL.GL_TEXTURE1); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+1); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

... 

gl.glClientActiveTexture(GL.GL_TEXTURE5); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+5); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

這一切都對我有意義。然而,我不知道當我填充緩衝區時(例如,當我加載模型數據時),我如何確定我所指的紋理。 感謝 克里斯

回答

2

你在找什麼是cube map。在OpenGL中,您可以一次定義6個紋理(代表立方體的大小),並使用3D紋理座標而不是通用的2D紋理座標來映射它們。對於簡單的立方體,紋理座標將與頂點各自的法線相同。 (如果您只是以這種方式對平面立方體進行紋理化處理,則還可以在頂點着色器中合併法線和紋理座標!)立方體貼圖比嘗試將六種不同紋理同時綁定到現在的方式要簡單得多。

GLuint mHandle; 
glGenTextures(1, &mHandle); // create your texture normally 

// Note the target being used instead of GL_TEXTURE_2D! 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle); 

// Now, load in your six distinct images. They need to be the same dimensions! 
// Notice the targets being specified: the six sides of the cube map. 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data1); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data2); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data3); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data4); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data5); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data6); 

glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

// And of course, after you are all done using the textures... 
glDeleteTextures(1, &mHandle); 

現在,做你的着色器時,你需要的頂點着色器接受和/或通過三維座標(VEC 3),而不是二維座標(VEC 2)。

// old GLSL style 
attribute vec3 inTextureCoordinate; 
varying vec3 vTextureCoordinate; 

// more recent GLSL 
in vec3 inTextureCoordinate; 
out vec3 vTextureCoordinate; 

在這個例子中,你的頂點着色器將只分配vTextureCoordinate = inTextureCoordinate。你的片段着色器需要接受紋理座標並對立方體貼圖進行採樣。

uniform samplerCube cubeMap; 
... 
gl_FragColor = textureCube(cubeMap, vTextureCoordinate); 

哎!這很多。我有沒有留下什麼?

+0

我想知道更多。 – Mark 2011-02-07 18:20:36

1

什麼不不過是我如何確定我指的是,當我填充緩衝其質地(例如,當我打開我的模型數據)。

你指的是哪個質感上次與最近ActiveTexture調用指定 - 該呼叫實際上並沒有做任何事情,它甫一設置影響所有後續調用是做什麼的紋理隱藏狀態。

0

基於per-face的紋理選擇通常很難在openGL上進行(除了一些最近可以對紋理數組進行索引的卡片,例如使用EXT_texture_array)。這個問題通常可以通過將所有紋理打包在一個文件中來避免,如this

然而,在您的具體情況下,立方體貼圖是完美的 - 如果您確信您只有立方體而沒有別的東西。