2011-02-07 27 views
1

私は各面に異なるテクスチャを持つ1つのキューブを描画しようとしています。私は、glDrawElements()を呼び出す前に、display()ルーチンですべてのテクスチャユニットを有効にする必要があると述べている多くのチュートリアルに出くわしました。私はこれを私の電話にします: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つのテクスチャ(キューブのサイズ面を表す)を定義し、一般的な2Dテクスチャ座標の代わりに3Dテクスチャ座標を使用してマップすることができます。単純なキューブの場合、テクスチャの座標は頂点のそれぞれの法線と同じになります。 (この方法でプレーンキューブをテクスチャ化するだけなら、ノーマルとテクスチャ座標を頂点シェーダに統合することもできます)キューブマップは、現在行っているように6つの異なるテクスチャを同時にバインドしようとするよりはるかに簡単です。あなたのシェーダを行う際

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

は今、あなたが受け入れるおよび/または3D座標(vec3)の代わりに、2次元座標(VEC2)を渡すために頂点シェーダが必要です。この例では

// 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); 

Whew!それはたくさんあった。私は何かを残しましたか?

+0

私はもっと知りたいです。 – Mark

+0

OK、あなたの他の質問に更新を掲載しています...私もここに投稿します。 – TheBuzzSaw

+0

お返事ありがとうございます。今はもうちょっと意味が分かります。しかし、単純化のためにキューブの例を使用していましたが、実際にロードしようとしているモデルには30以上のテクスチャがあります。より多くのテクスチャを可能にするために、ソリューションの拡張を提案することはできますか? –

1

しかし、私は(例えば、私は私のモデルデータを読み込む際に)私はバッファを取り込むとき、私が言及していたテクスチャを決定する方法ではありません何。

あなたが最後に最新のActiveTexture呼び出しで指定された方のテクスチャを参照している - その呼び出しは、実際には何もしません、それはテクスチャで何かをするすべての後続の呼び出しに影響隠れ状態を設定しますjusts。

0

1面単位でテクスチャを選択するのは通常、EXT_texture_arrayなどのテクスチャの配列にインデックスを付けることができる最近のカードを除き、OpenGLでは難しいです。問題は通常、すべてのテクスチャを1つにまとめることで避けられます(thisなど)。

あなたの非常に特殊なケースでは、キューブマップは完璧です。本当にキューブだけを持っていると確信しているのであれば、他には何もありません。

関連する問題