2011-02-07 2 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 вы можете сразу определить шесть текстур (представляющих стороны размера куба) и сопоставить их с помощью трехмерных текстурных координат вместо обычных 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); 

Теперь, когда делать ваши шейдеры, вам нужно вершинный шейдер принимать и/или передавать 3D-координаты (Vec3) вместо 2D координат (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

Хорошо, я публикую обновление по вашему другому вопросу, я думаю ...? Я тоже опубликую его здесь. – TheBuzzSaw

+0

Спасибо за ответ. Теперь это уже немного больше. Тем не менее, я просто использовал пример куба для упрощения, модель, которую я пытаюсь загрузить, на самом деле имеет 30+ текстур. Не могли бы вы предложить расширение вашего решения, чтобы позволить больше текстур? –

1

Что, однако, не в том, как определить, какую текстуру я имею в виду, когда я заполнения буфера (например, когда я загрузить мои данные модели).

Вы имеете в виду какой текстуры вы последний указанный с последнего вызова ActiveTexture - это вызов не делает ничего, что Justs устанавливает скрытое состояние, которое влияет на все последующие вызовы, которые делают что-либо с текстурами.

0

Выбор текстуры на основе лица обычно затруднен для openGL (за исключением некоторых последних карт, которые могут индексировать массив текстур, например, с EXT_texture_array). Обычно проблему можно избежать, упаковывая все текстуры в один, например this.

В вашем конкретном случае, несмотря на то, что куб-карта идеальна - если вы действительно уверены, что у вас будут только кубы и ничего больше.