package com.vizit;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.microedition.khronos.egl.EGLConfig;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
/**
* Render a triangle using the simplest possible OpenGL ES 2.
*/
public class TriangleRenderer
implements GLSurfaceView.Renderer
{
/** Store our model data in a float buffer. */
private final FloatBuffer vertices;
/** How many bytes per float. */
private final int bytesPerFloat = 4;
/** Offset of the position data. */
private final int positionOffset = 0;
/** Size of each vertex. 3D coords, so 3. */
private final int positionSize = 3;
/** handle on the position attribute */
protected int positionLocation;
/**
* The TriangleRenderer class renders a simple solid color triangle to the screen.
* This constructor defines the vertices and loads them into a buffer in the
* memory of this process.
*/
public TriangleRenderer()
{
// Like any three dimensional polygon, we specify the vertices.
final float[] vertexData =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
// The OpenGL Driver expects floating point data in native byte order.
vertices = ByteBuffer.allocateDirect(vertexData.length * bytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
// Reset, so OpenGL begins reading at the beginning of the buffer.
vertices.put(vertexData).position(0);
}
/**
* Called when a surface is created. Things that need to be initialized once for each surface live here.
* For example the shaders are compiled; buffers, and the initial model-view and projection matrices are
* created.
*
* @param glUnused Archaic parameter from OpenGL 1. Unused in OpenGL 2 or higher, but it remains to keep
* the method signatures intact.
* @param config An EGLConfig representing the display configuration, including bits per pixel etc.
*/
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
{
// A Vertex shader does per vertex computations. Here we set the predefined variable
// gl_Position to the position of the vertex. We will see many uses for the vertex shader later.
// For example, vertices can be moved in the vertex shader, producing animation or motion.
// When you move through a 3D game, you are seeing the effects of a vertex shader moving the
// polygons around.
final String vertexShaderSource = "attribute vec3 position;"
+ ""
+ "void main()"
+ "{"
+ " gl_Position = vec4(position, 1);"
+ "}";
// The fragment shader can be thought of for now as doing per pixel computations. It is the
// fragment shader the colors each pixel in a 3d scene. This time we just assign an RGBA value.
final String fragmentShaderSource = "precision mediump float;"
+ ""
+ "void main()"
+ "{"
+ " gl_FragColor = vec4(0.8,0.3,0.3,1);"
+ "}";
// Create a shader - a vertex shader in this case.
int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
// Load the shader source.
GLES20.glShaderSource(vertexShader, vertexShaderSource);
// Compile the shader.
GLES20.glCompileShader(vertexShader);
// All again for the fragment shader.
int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(fragmentShader);
int program = GLES20.glCreateProgram();
// The program consists of our shaders
GLES20.glAttachShader(program, vertexShader);
// Bind the fragment shader to the program.
GLES20.glAttachShader(program, fragmentShader);
// Create a runnable program for our graphics hardware.
// Allocates and assigns memory for attributes and uniforms (explained later)
// Shaders are checked for consistency.
GLES20.glLinkProgram(program);
GLES20.glUseProgram(program);
// Get a handle on the position attribute to the vertex shader.
positionLocation = GLES20.glGetAttribLocation(program, "position");
}
/**
* Invoked when the size of a surface is changed.
* @param glUnused Archaic parameter from OpenGL 1.
* @param width An int giving the new width of the screen in pixels.
* @param height An int giving the new height of the screen in pixels.
*/
@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height)
{
// We'll show this in a later example.
}
/**
* Draw a frame. Quantities that change from frame to frame are recomputed, and the actual drawing happens here.
* Future iterations of these examples will break out these functions into separate methods and add additional
* functionality.
* @param glUnused Archaic parameter from OpenGL 1.
*/
@Override
public void onDrawFrame(GL10 glUnused)
{
// Ensure we start at the beginning of the array on each render.
vertices.position(positionOffset);
// Bind our data array to a shader attribute
// positionLocation: handle on the attribute.
// positionSize: the number of elements for each value of the attribute.
// GLES20.GL_FLOAT: the type of each element
// false: the elements are not normalized
// 0: stride = 0 => values are immediately next to each other.
// vertices: vertex data in native byte order
GLES20.glVertexAttribPointer(positionLocation, positionSize, GLES20.GL_FLOAT, false,
0, vertices);
// Setup this attribute to accept array data. Not enabled by default to conserve resources.
GLES20.glEnableVertexAttribArray(positionLocation);
// Draw a triangle from three vertices, each of which has three (positionSize) components.
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
}
}
During the presentation we walked through and explained the ESTriangle sample code.