Friday, June 10, 2011

Multi-Texturing

Multi-Texturing is nothing but mixing multiple texture as per your requirement. here I’ll mix these two textures to get the resulting screen below. its up to coder to mix textures to get desired effect.
Texture1:
Texture2:
and mixing result:
Let’s look at the code below. First we will look at shaders because major change is in shaders only.
Vertex Shader:
String strVShader =
"attribute vec4 a_position;" +
"attribute vec2 a_texCoords;" +
"varying vec2 v_texCoords;" +
"void main()" +
"{" +
  "v_texCoords = a_texCoords;" +
  "gl_Position = a_position;" +
"}";
Nothing fancy here, simple shader that passes texture co-ordinates to Fragment shader and sets vertex position.
Fragment shader:
This is where we will make few changes to mix/blend textures.
String strFShader =
"precision mediump float;" +
"varying vec2 v_texCoords;" +
"uniform sampler2D u_texId1;" +
"uniform sampler2D u_texId2;" +
"void main()" +
"{" +
     "vec4 color1 = texture2D(u_texId1, v_texCoords);" +
     "vec4 color2 = texture2D(u_texId2, v_texCoords);" +
     "gl_FragColor = color2 * color1;" +
"}";
Here, get the color values from the texture at the co-ordinates and manipulate them as you like. here i just multiplied 2 color vectors.
There is no much changes in remaining renderer code. but, we will see draw function.
public void onDrawFrame(GL10 gl) {
  GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
  GLES20.glUseProgram(iProgId);
 
  GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
  GLES20.glEnableVertexAttribArray(iPosition);
 
  GLES20.glVertexAttribPointer(iTexCoords1, 2, GLES20.GL_FLOAT, false, 0, texBuffer);
  GLES20.glEnableVertexAttribArray(iTexCoords1);
 
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, iTexIds[0]);
  GLES20.glUniform1i(iTex1, 0);
 
  GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, iTexIds[1]);
  GLES20.glUniform1i(iTex2, 1);
 
//  GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
  GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, indecesBuffer);

 }

Apart from passing vertex positions and texture co-ordinates, we have activated 2 textures (GL_TEXTURE0 and GL_TEXTURE1) for passing texture ids to shaders. we can go upto 32 textures. and as usual draw triangles or triangle fan to draw quad.