2012-01-06 4 views
2

Я пытаюсь получить 2 текстуры в 1 фрагменте шейдера.Как мне настроить текстуры, которые я могу использовать в шейдере Android OpenGL-ES 2.0?

Для этого у меня есть 2 текстуры, которые я создал с помощью следующего кода:

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glVertexPointer(2, GL_FLOAT, 0, vbuff); 
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); 

glActiveTextureARB(GL_TEXTURE0_ARB); 
glBindTexture(GL_TEXTURE_2D, texture0); 
glEnable(GL_TEXTURE_2D); 

glActiveTextureARB(GL_TEXTURE1_ARB); 
glBindTexture(GL_TEXTURE_2D, texture1); 
glEnable(GL_TEXTURE_2D); 

И я стараюсь, чтобы объединить их со следующим фрагментом шейдер:

uniform sampler2D tex0; 
uniform sampler2D tex1; 
void main() 
{ 
    vec4 texval1 = texture2D(tex0, TextureCoordOut); 
    vec4 texval2 = texture2D(tex1, TextureCoordOut); 
    gl_FragColor = 0.5*(texval1 + texval2) 
} 

Как-то это не работает и он отображает только вторую текстуру.

PS: Я разрабатываю шейдеры на Windows7, но хочу использовать код C++ и шейдеры с Android NDK на устройстве Android.

EDIT: Я получил это работает, и я разместить код здесь, чтобы другие могли извлечь из этого пользу:

вершинные шейдеры

varying vec2 TextureCoordOut; 
void main() 
{ 
    gl_Position = ftransform(); 
    TextureCoordOut = vec2(gl_MultiTexCoord0); 
} 

пиксельный шейдер

varying mediump vec2 TextureCoordOut; 
uniform sampler2D tex0; 
uniform sampler2D tex1; 
void main() 
{ 
    gl_FragColor = texture2D(tex0, TextureCoordOut) * texture2D(tex1, TextureCoordOut); 
} 

визуализации

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glVertexPointer(2, GL_FLOAT, 0, vbuff); //2 dimensional vertex buffer 
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); // 2 dimensional textures 
glColor4f(1, 1, 1, 1); 

glActiveTexture(GL_TEXTURE0);  glBindTexture(GL_TEXTURE_2D, mapid1); 
glActiveTexture(GL_TEXTURE1);  glBindTexture(GL_TEXTURE_2D, mapid2); 

glUseProgram(shader); 

glUniform1i(glGetUniformLocation(gfx.prog, "tex0"), 0); //GL_TEXTURE0 
glUniform1i(glGetUniformLocation(gfx.prog, "tex1"), 1); //GL_TEXTURE1 

render.... 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

ответ

7

Недостаточно просто связывать эти текстуры с соответствующими единицами. Вам также нужно указать шейдерам, где взять текстуры для формы sampler2D. Это делается путем установки соответствующего целое единообразного значение единицы текстуры вы хотите использовать:

//get uniform locations (either init code or render code) 
int locTex0 = glGetUniformLocation(program, "tex0"); 
int locTex1 = glGetUniformLocation(program, "tex1"); 

...  

//bind textures to texture units 
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, texture1); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, texture0); 

//bind program and specify texture units for each sampler2D uniform 
glUseProgram(program); 
glUniform1i(locTex0, 0); //use texture bound to GL_TEXTURE0 
glUniform1i(locTex1, 1); //use texture bound to GL_TEXTURE1 

... 
draw 

Конечно, это предполагает, что вы знаете, как использовать шейдеры и задать единые значения.

Некоторые дополнительные замечания:

  • При использовании фрагмента шейдер вам не нужно вызывать glEnable(GL_TEXTURE_2D), так как шейдер решает сам, если он использует текстуру или нет.
  • Не используйте эти функции и константы ARB, по крайней мере, для таких старых и установленных вещей, как мультитекстурирование, которое является ключевым с GL 1.2 или 1.3 (~ 15 лет).
  • Не ожидайте, что ваш код будет 1-к-1 переносимым в OpenGL ES 2.0, который не знает о старых встроенных атрибутах (например, glVertexPointer или glTexCoordPointer), но это другой вопрос.
+0

Спасибо большое, это действительно помогло мне заставить его работать! – HardCoder

 Смежные вопросы

  • Нет связанных вопросов^_^