2011-02-07 22 views
0

私は、各面に異なるテクスチャを持つオブジェクト(立方体)をレンダリングする方法を理解しようとしています。簡単にするために、キューブの3つの面にそれぞれ2つのテクスチャが適用されています。使用する関連するテクスチャを表すために、3つの座標を持つテクスチャ配列を使用する必要があることを理解しています。私はこれをどうやって行うのか、フラグメントシェーダをどのようにコードするのか不明です。ここでVBOを使ったOpenGLの複数テクスチャ

は私init()機能の関連する部分である:

final String textureName = model.getTextures().get(i).textureName; 
final FileTexture textureGenerator = new FileTexture(this.getClass().getResourceAsStream(textureName), 
       true, context); 
textureId = textureGenerator.getTextureId(); 
width = textureGenerator.getWidth(); 
height = textureGenerator.getHeight(); 
textureMap.put(model.getTextures().get(i).matName, textureId); 
context.getGL().glActiveTexture(GL.GL_TEXTURE0 + i); 
context.getGL().glBindTexture(GL.GL_TEXTURE_2D, textureId); 

オレンジブック(OpenGLのシェーディング言語は)glActiveTextureglBindTextureが使用されている例を示しますので、私はしかし、ここで少し混乱していますが、 GLSL common mistakesはこれをしてはいけないと言います。

そこから、私のdisplay()関数は次のようになります。

gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject()); 
gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 3 * 4, getVertices(), GL.GL_STREAM_DRAW); 

gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 2 * 4, getTexCoords(), GL.GL_STREAM_DRAW); 

gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject()); 
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, getNoOfIndices() * 4, getIndices(), GL.GL_STREAM_DRAW); 

gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getColorBufferObject()); 
gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getColors(), GL.GL_STREAM_DRAW); 

layerTextureShader.use(gl); 

gl.glEnableClientState(GL.GL_VERTEX_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject()); 
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); 

gl.glEnableClientState(GL.GL_COLOR_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, mask ? getMaskColorBufferObject() : getColorBufferObject()); 
gl.glColorPointer(4, GL.GL_FLOAT, 0, 0); 

gl.glClientActiveTexture(GL.GL_TEXTURE0); 
gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
gl.glTexCoordPointer(3, GL.GL_FLOAT, 0, 0); 

gl.glClientActiveTexture(GL.GL_TEXTURE1); 
gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
gl.glTexCoordPointer(3, GL.GL_FLOAT, 0, 0); 

gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject()); 

final int count = getNoOfIndices(); 
gl.glDrawElements(GL.GL_TRIANGLES, count, GL.GL_UNSIGNED_INT, 0); 

gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); 

gl.glClientActiveTexture(GL.GL_TEXTURE0); 
gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

gl.glClientActiveTexture(GL.GL_TEXTURE1); 
gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

gl.glDisableClientState(GL.GL_VERTEX_ARRAY); 
gl.glDisableClientState(GL.GL_COLOR_ARRAY); 
gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

layerTextureShader.release(gl); 

私は私のGLSLシェーダに入れた内容が不明です。私の頂点シェーダは標準gl_TexCoord[0] = gl_MultiTexCoord0;を持っており、私のフラグメントシェーダは、次のようになります。私が使用するテクスチャのフラグメントシェーダに指示するにはどうすればよい

uniform sampler2D texture; 

void main() 
{ 
    gl_FragColor = texture2D(texture, gl_TexCoord[0].st); 
} 

?私はそれが頂点、インデックス、テクスチャバッファなどを埋めるときだと仮定し、各ポイントの3番目のテクスチャ座標を渡すことでそれを行いますか?この3番目の座標の値は、関連するテクスチャ座標の値ですか? 私の質問が意味を持ち、どんな助けでもありがとうと思います。 クリス

+0

私はテクスチャを作成するときにglTexImage2Dの代わりにglTexImage3Dを使用し、3番目の座標をインデックスとして使用してそれらにアクセスする必要があると仮定して正しいでしょうか? –

+0

いいえ、現在行っていることの多くは同じままです。まもなくキューブマップサンプルをお見せします。 – TheBuzzSaw

答えて

0

あなたが探しているのは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!それはたくさんあった。私は何かを残しましたか?