I got mine working today e.g. bitmap applied to a quad. It works very nicely although I have problems animating it.
I will copy below. You need two main pieces: A quad with a texture applied to it (in my case R.drawable.smurf). Remember that the image dimensions MUST be a power of four for things to work.
Below I have copied most of what you need to get this working: A "Run" activity that launches things, a "Quad" claass that textures a quad and a class to do all the fun rendering things (this is based on the NeHe 6 tutorial).
- Code: Select all
package com.nea.nehe.lesson06;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
/**
* The initial Android Activity, setting and initiating
* the OpenGL ES Renderer Class @see Lesson06.java
*
* @author Savas Ziplies (nea/INsanityDesign)
*/
public class Run extends Activity {
/** The OpenGL View */
private GLSurfaceView glSurface;
/**
* Initiate the OpenGL View and set our own
* Renderer (@see Lesson06.java)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer and hand the renderer this Activity Context
glSurface.setRenderer(new Lesson06(this));
//Set the GLSurface as View to this Activity
setContentView(glSurface);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurface.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurface.onPause();
}
}
- Code: Select all
package com.nea.nehe.lesson06;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
/**
* This is a port of the {@link http://nehe.gamedev.net} OpenGL
* tutorials to the Android 1.5 OpenGL ES platform. Thanks to
* NeHe and all contributors for their great tutorials and great
* documentation. This source should be used together with the
* textual explanations made at {@link http://nehe.gamedev.net}.
* The code is based on the original Visual C++ code with all
* comments made. It has been altered and extended to meet the
* Android requirements. The Java code has according comments.
*
* If you use this code or find it helpful, please visit and send
* a shout to the author under {@link http://www.insanitydesign.com/}
*
* @DISCLAIMER
* This source and the whole package comes without warranty. It may or may
* not harm your computer or cell phone. Please use with care. Any damage
* cannot be related back to the author. The source has been tested on a
* virtual environment and scanned for viruses and has passed all tests.
*
*
* This is an interpretation of "Lesson 06: Texture Mapping"
* for the Google Android platform.
*
* @author Savas Ziplies (nea/INsanityDesign)
*/
public class Lesson06 implements Renderer {
/** Cube instance */
private Cube cube;
private Quad quad;
/* Rotation values for all axis */
private float xrot; //X Rotation ( NEW )
private float yrot; //Y Rotation ( NEW )
private float zrot; //Z Rotation ( NEW )
/** The Activity Context ( NEW ) */
private Context context;
/**
* Instance the Cube object and set
* the Activity Context handed over
*/
public Lesson06(Context context) {
this.context = context;
quad = new Quad();
}
/**
* The Surface is created/init()
*/
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//Load the texture for the cube once during Surface creation
quad.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(1.0f, 1.0f, 0.0f, 0.0f); //Yellow Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); //enable transparency
gl.glEnable(GL10.GL_BLEND); //enable transparency blending
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
/**
* Here we do our drawing
*/
public void onDrawFrame(GL10 gl) {
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); //Reset The Current Modelview Matrix
//Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); //Move 5 units into the screen
gl.glScalef(0.8f, 0.8f, 0.8f); //Scale the Cube to 80 percent, otherwise it would be too large for the screen
//Rotate around the axis based on the rotation matrix (rotation, x, y, z)
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); //X
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); //Y
gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f); //Z
quad.draw(gl); //Draw the Cube
//Change rotation factors (nice rotation)
xrot += 0.3f;
yrot += 0.2f;
zrot += 0.4f;
}
/**
* If the surface changes, reset the view
*/
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
}
- Code: Select all
package com.nea.nehe.lesson06;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/**
* This class is an object representation of
* a Cube containing the vertex information,
* texture coordinates, the vertex indices
* and drawing functionality, which is called
* by the renderer.
*
* @author Savas Ziplies (nea/INsanityDesign)
*/
public class Quad {
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
/** The buffer holding the indices */
private ByteBuffer indexBuffer;
/** Our texture pointer */
private int[] textures = new int[1];
/**
* The initial vertex definitio
*
* Note that each face is defined, even
* if indices are available, because
* of the texturing we want to achieve
*/
private float vertices[] = {
//Vertices according to faces
-1.0f, -1.0f, 1.0f, //Vertex 0
1.0f, -1.0f, 1.0f, //v1
-1.0f, 1.0f, 1.0f, //v2
1.0f, 1.0f, 1.0f, //v3
};
/** The initial texture coordinates (u, v) */
private float texture[] = {
//Mapping coordinates for the vertices
0.0f, 0.0f,
0.0f, .25f,
.25f, 0.0f,
.25f, .25f,
};
/** The initial indices definition */
private byte indices[] = {
//Faces definition
0,1,3, 0,3,2, //Face front
};
/**
* The Quad constructor.
*
* Initiate the buffers.
*/
public Quad() {
//
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
//
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
//
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
/**
* The object own drawing function.
* Called from the renderer to redraw this instance
* with possible changes in values.
*
* @param gl - The GL Context
*/
public void draw(GL10 gl) {
//Bind our only previously generated texture in this case
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
//Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
//Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangles, based on the Index Buffer information
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/**
* Load the textures
*
* @param gl - The GL Context
* @param context - The Activity context
*/
public void loadGLTexture(GL10 gl, Context context) {
//Get the texture from the Android resource directory
InputStream is = context.getResources().openRawResource(R.drawable.smurf_sprite);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
//Generate one texture pointer...
gl.glGenTextures(1, textures, 0);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
//Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//Clean up
bitmap.recycle();
}
}