2011-02-07 11 views
0

각면마다 서로 다른 질감의 오브젝트 (큐브)를 렌더링하는 방법을 알아 내려고하고 있습니다. 단순함을 위해서, 큐브의 3면 각각에 적용되는 2 개의 텍스처가 있습니다. 내가 사용하는 관련 텍스처를 나타내는 3 좌표와 텍스처 배열을 사용해야한다는 것을 이해합니다. 이 작업을 수행하는 방법과 조각 쉐이더를 코딩하는 방법을 잘 모르겠습니다. 내가 여기 오렌지 북 (OpenGL은 쉐이딩 언어) 예제를 제공하기 때문에하는 glActiveTextureglBindTexture 사용 약간 혼란 스러워요하지만VBO를 사용한 OpenGL 다중 텍스처

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

: 여기

init() 함수의 관련 부분입니다 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); 
} 

가 어떻게 사용되는 텍스처의 조각 쉐이더를 지시 하는가? 버텍스, 인덱스, 텍스처 버퍼 등을 채울 때라고 가정하고 각 포인트에 대해이 세 번째 텍스처 좌표를 전달하여 수행합니까? 이 세 번째 좌표의 값이 관련 텍스처 좌표의 값입니까? 제 질문이 의미가 있고 도움이 되었기를 바랍니다. 크리스

+0

내 텍스처를 생성 할 때 glTexImage3D 대신 glTexImage3D를 사용해야한다고 가정하고 위의 3 번째 좌표를 인덱스로 사용하여 액세스 할 수 있습니까? –

+0

아니요, 현재하는 일 중 상당 부분이 그대로 유지됩니다. 곧 큐브 맵 샘플을 보여 드리겠습니다. – TheBuzzSaw

답변

0

당신이 찾고있는 것은 cube map입니다. OpenGL에서는 한 번에 여섯 개의 텍스처를 정의하고 (큐브의 크기면을 나타냄) 일반적인 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); 

휴! 그것은 많은 것이었다. 나는 아무것도 남기지 않았 니?