Shaders through OpenGL

In Android, OpenGL supports implementing shaders for Android 3D games. OpenGL ES 2.0 is the supporting platform in Android for shaders. It has two functional segments while manually creating the shader:

  • Shader
  • Program

The shader is converted into intermediate code to support the program to run on GPU. In the compiling stage, the shaders are converted. This is the reason why shaders need to be recompiled before the program execution.

We will work with GLSurfaceView of the android.opengl package in our example.

For 3D games, an Android developer can use this package to play with shaders on the Android SDK. This package provides the API to create and use an OpenGL shader with Java.

We will use GLSurfaceView instead of the normal Android View or SurfaceView. The implementation will look like this:

import android.opengl.GLSurfaceView;
import android.content.Context;

public class MyGLExampleView extends GLSurfaceView 
{
  private final GLRenderer mRenderer;

  public MyGLExampleView (Context context) 
  {
    super(context);

// Set OpenGL version 2.0 as we will be working with that particular library
    this.setEGLContextClientVersion(2);

// Set the Renderer for drawing on the GLSurfaceView
    MyOpenGLRendererExample = new MyOpenGLRendererExample (context);
    setRenderer(mRenderer);

// Render the view only when there is a change in the //drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
  }

  @Override
  public void onPause() 
  {
    super.onPause();
  }

  @Override
  public void onResume() 
  {
    super.onResume();
  }
}

We need to create a renderer for the view to draw objects through OpenGL:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.util.Log;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MyOpenGLRendererExample implements Renderer 
{

  // Declare matrices
  private float[] matatrixProjection = new float[32];
  private float[] matrixView = new float[32];
  private float[] matatrixProjectionOnView = new float[32];

  // Declare Co-ordinate attributes
  private float vertexList[];
  private short indicxList[];
  private FloatBuffer vertexBuffer;
  private ShortBuffer drawBuffer;

  private final String vertexShader =
          "uniform    mat4        uMVPMatrix;" +
          "attribute  vec4        vPosition;" +
          "void main() {" +
          "  gl_Position = uMVPMatrix * vPosition;" +
          "}";

  private final String pixelShader =
          "precision mediump float;" +
          "void main() {" +
          "  gl_FragColor = vec4(0.5,0,0,1);" +
          "}";

  // Declare Screen Width and Height HD display
  float ScreenWidth = 1280.0f;
  float ScreenHeight = 800.0f;

  private int programIndex = 1;

  public MyOpenGLRendererExample (Context context)
  {

  }

  @Override
  public void onDrawFrame(GL10 param) 
  {
    renderView(matatrixProjectionOnView);
  }

  @Override
  public void onSurfaceChanged(GL10 objGL, int width, 
int height) 
  {
    ScreenWidth = (float)width;
    ScreenHeight = (float)height;

    GLES20.glViewport(0, 0, (int)ScreenWidth, 
(int)ScreenHeight);

    //reset matrices
    for( int i = 0; i < 32 ; ++ i )
    {
      matatrixProjection[i] = 0.0f;
      matrixView[i] = 0.0f;
      matatrixProjectionOnView[i] = 0.0f;
    }

    Matrix.orthoM(matatrixProjection, 0, 0f, ScreenWidth, 
0.0f, ScreenHeight, 0, 50);

    Matrix.setLookAtM(matrixView, 0, 0f, 0f, 1f, 0f, 0f, 
0f, 0f, 1.0f, 0.0f);

    Matrix.multiplyMM(matatrixProjectionOnView, 0, 
matatrixProjection, 0, matrixView, 0);
  }

  @Override
  public void onSurfaceCreated(GL10 gl, EGLConfig config) 
  {
    //create any object 
    //Eg. Triangle:: simplest possible closed region

    createTriangle();

    // Set the color to black
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1);

    // Create the shaders
    int vertexShaderTmp = 
loadShader(GLES20.GL_VERTEX_SHADER, vertexShader);

    int pixelShaderTmp = 
loadShader(GLES20.GL_FRAGMENT_SHADER, pixelShader);

    int programIndexTmp = GLES20.glCreateProgram();

    GLES20.glAttachShader(programIndexTmp, 
vertexShaderTmp);
   
    GLES20.glAttachShader(programIndexTmp, 
pixelShaderTmp);
 
    GLES20.glLinkProgram(programIndexTmp);
    
    // Set shader program
    GLES20.glUseProgram(programIndexTmp);
  }

  void renderView(float[] matrixParam) 
  {
    int positionHandler = 
GLES20.glGetAttribLocation(programIndex, "vPosition");

    GLES20.glEnableVertexAttribArray(positionHandler);
    GLES20.glVertexAttribPointer(positionHandler, 3, 
GLES20.GL_FLOAT, false, 0, vertexBuffer);

    int mtrxhandle = 
GLES20.glGetUniformLocation(programIndex, "uMVPMatrix");
     
    GLES20.glUniformMatrix4fv(mtrxhandle, 1,
 false, matrixParam, 0);

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 
indicxList.length, GLES20.GL_UNSIGNED_SHORT, drawBuffer);

    GLES20.glDisableVertexAttribArray(positionHandler);  
  }

  void createTriangle()
  {
    // We have to create the vertexList of our triangle.
    vertexList = new float[]
    {
      20.0f, 200f, 0.0f,
      20.0f, 300f, 0.0f,
      200f, 150f, 0.0f,
    };
    
    //setting up the vertex list in order
    indicxList = new short[] {0, 1, 2};
    
    ByteBuffer bytebufVertex = 
ByteBuffer.allocateDirect(vertexList.length * 4);

    bytebufVertex.order(ByteOrder.nativeOrder());
    vertexBuffer = bytebufVertex.asFloatBuffer();
    vertexBuffer.put(vertexList);
    vertexBuffer.position(0);
    

    ByteBuffer bytebufindex = 
ByteBuffer.allocateDirect(indicxList.length * 2);

    bytebufindex.order(ByteOrder.nativeOrder());
    drawBuffer = bytebufindex.asShortBuffer();
    drawBuffer.put(indicxList);
    drawBuffer.position(0);

    int vertexShaderTmp = 
loadShader(GLES20.GL_VERTEX_SHADER, vertexShader);

    int pixelShaderTmp = 
loadShader(GLES20.GL_FRAGMENT_SHADER, pixelShader);
    
    int program = GLES20.glCreateProgram();
    if (program != 0) 
    {
      GLES20.glAttachShader(program, vertexShaderTmp);
      GLES20.glAttachShader(program, pixelShaderTmp);
      GLES20.glLinkProgram(program);
      
      int[] linkStatus = new int[1];
      
      GLES20.glGetProgramiv(program, 
GLES20.GL_LINK_STATUS, linkStatus, 0);
      
      if (linkStatus[0] != GLES20.GL_TRUE) 
      {
        Log.e("TAG_EXAMPLE_OPENGL", "Linking Failed !! 
Error:: " + GLES20.glGetProgramInfoLog(program));

        GLES20.glDeleteProgram(program);
        program = 0;
      }
    }
  }

// method to create shader
   int loadShader(int type, String shaderCode)
   {
        int shader = GLES20.glCreateShader(type);

        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }
}

The vertex shader code (String vs_SolidColor) has two parameters that it needs. The uMVPMatrix parameter is of the type mat4, which holds in the transformation matrix that can be used to translate the position. The uMVPMatrix parameter is a uniform matrix. The vPosition parameter is of type vec4, which holds the positions of vertex.

This system can be applied for a triangular surface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.141.219