How to draw 3D graphics?
This is a sample application which shows how to create 3D graphics using OpenGL in android.
Underlying Algorithm:
Basic description of algorithm in step by step form:
1.) Create a Project Graphics3d.
2.) Put an image in res/drawable.
3.) Create a custom view MyGLView.java ,which will look like this:
1.) Create a Project Graphics3d.
2.) Put an image in res/drawable.
3.) Create a custom view MyGLView.java ,which will look like this:
package com.app.Graphics3d;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView;
class MyGLView extends GLSurfaceView {
private final MyGLRenderer renderer;
MyGLView(Context context) {
super(context);
renderer = new MyGLRenderer(context);
setRenderer(renderer);
}
}
private final MyGLRenderer renderer;
MyGLView(Context context) {
super(context);
renderer = new MyGLRenderer(context);
setRenderer(renderer);
}
}
4.) In OpenGL ES on Android, drawing is separated out into a rendering class which is responsible for initializing and drawing the entire screen.
5.) Create MyGLRenderer.java ,which will look like this:
5.) Create MyGLRenderer.java ,which will look like this:
package com.app.Graphics3d;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.util.Log;
class MyGLRenderer implements GLSurfaceView.Renderer {
private static final String TAG = "GLRenderer";
private final Context context;
private final MyCube cube = new MyCube();
private long startTime;
private long fpsStartTime;
private long numFrames;
MyGLRenderer(Context context) {
this.context = context;
}
private static final String TAG = "GLRenderer";
private final Context context;
private final MyCube cube = new MyCube();
private long startTime;
private long fpsStartTime;
private long numFrames;
MyGLRenderer(Context context) {
this.context = context;
}
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
boolean SEE_THRU = true;
{
boolean SEE_THRU = true;
startTime = System.currentTimeMillis();
fpsStartTime = startTime;
numFrames = 0;
// Define the lighting
float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1 };
float lightDiffuse[] = new float[] { 1, 1, 1, 1 };
float[] lightPos = new float[] { 1, 1, 1, 1 };
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
// What is the cube made of?
float matAmbient[] = new float[] { 1, 1, 1, 1 };
float matDiffuse[] = new float[] { 1, 1, 1, 1 };
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,
matAmbient, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,
matDiffuse, 0);
// Set up any OpenGL options we need
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
fpsStartTime = startTime;
numFrames = 0;
// Define the lighting
float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1 };
float lightDiffuse[] = new float[] { 1, 1, 1, 1 };
float[] lightPos = new float[] { 1, 1, 1, 1 };
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
// What is the cube made of?
float matAmbient[] = new float[] { 1, 1, 1, 1 };
float matDiffuse[] = new float[] { 1, 1, 1, 1 };
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,
matAmbient, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,
matDiffuse, 0);
// Set up any OpenGL options we need
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
if (SEE_THRU) {
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
}
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
}
// Enable textures
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL10.GL_TEXTURE_2D);
// Load the cube’s texture from a bitmap
MyCube.loadTexture(gl, context, R.drawable.one);
}
MyCube.loadTexture(gl, context, R.drawable.one);
}
public void onSurfaceChanged(GL10 gl, int width, int height)
{
{
// Define the view frustum
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio = (float) width / height;
GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio = (float) width / height;
GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);
}
public void onDrawFrame(GL10 gl) {
// Clear the screen to black
gl.glClear(GL10.GL_COLOR_BUFFER_BIT
| GL10.GL_DEPTH_BUFFER_BIT);
public void onDrawFrame(GL10 gl) {
// Clear the screen to black
gl.glClear(GL10.GL_COLOR_BUFFER_BIT
| GL10.GL_DEPTH_BUFFER_BIT);
// Position model so we can see it
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
// Set rotation angle based on the time
long elapsed = System.currentTimeMillis() - startTime;
gl.glRotatef(elapsed * (30f / 1000f), 0, 1, 0);
gl.glRotatef(elapsed * (15f / 1000f), 1, 0, 0);
long elapsed = System.currentTimeMillis() - startTime;
gl.glRotatef(elapsed * (30f / 1000f), 0, 1, 0);
gl.glRotatef(elapsed * (15f / 1000f), 1, 0, 0);
// Draw the model
cube.draw(gl);
cube.draw(gl);
// Keep track of number of frames drawn
numFrames++;
long fpsElapsed = System.currentTimeMillis() - fpsStartTime;
if (fpsElapsed > 5 * 1000) { // every 5 seconds
float fps = (numFrames * 1000.0F) / fpsElapsed;
Log.d(TAG, "Frames per second: " + fps + " (" + numFrames
+ " frames in " + fpsElapsed + " ms)");
fpsStartTime = System.currentTimeMillis();
numFrames = 0;
}
numFrames++;
long fpsElapsed = System.currentTimeMillis() - fpsStartTime;
if (fpsElapsed > 5 * 1000) { // every 5 seconds
float fps = (numFrames * 1000.0F) / fpsElapsed;
Log.d(TAG, "Frames per second: " + fps + " (" + numFrames
+ " frames in " + fpsElapsed + " ms)");
fpsStartTime = System.currentTimeMillis();
numFrames = 0;
}
}
}
}
6.) Create MyCube.java, which will look like this:
package com.app.Graphics3d;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
class MyCube {
private final IntBuffer mVertexBuffer;
private final IntBuffer mTextureBuffer;
public MyCube() {
int one = 65536;
int half = one / 2;
int vertices[] = {
// FRONT
-half, -half, half, half, -half, half,
-half, half, half, half, half, half,
// BACK
-half, -half, -half, -half, half, -half,
half, -half, -half, half, half, -half,
// LEFT
-half, -half, half, -half, half, half,
-half, -half, -half, -half, half, -half,
// RIGHT
half, -half, -half, half, half, -half,
half, -half, half, half, half, half,
// TOP
-half, half, half, half, half, half,
-half, half, -half, half, half, -half,
// BOTTOM
-half, -half, half, -half, -half, -half,
half, -half, half, half, -half, -half, };
private final IntBuffer mVertexBuffer;
private final IntBuffer mTextureBuffer;
public MyCube() {
int one = 65536;
int half = one / 2;
int vertices[] = {
// FRONT
-half, -half, half, half, -half, half,
-half, half, half, half, half, half,
// BACK
-half, -half, -half, -half, half, -half,
half, -half, -half, half, half, -half,
// LEFT
-half, -half, half, -half, half, half,
-half, -half, -half, -half, half, -half,
// RIGHT
half, -half, -half, half, half, -half,
half, -half, half, half, half, half,
// TOP
-half, half, half, half, half, half,
-half, half, -half, half, half, -half,
// BOTTOM
-half, -half, half, -half, -half, -half,
half, -half, half, half, -half, -half, };
int texCoords[] = {
// FRONT
0, one, one, one, 0, 0, one, 0,
// BACK
one, one, one, 0, 0, one, 0, 0,
// LEFT
one, one, one, 0, 0, one, 0, 0,
// RIGHT
one, one, one, 0, 0, one, 0, 0,
// TOP
one, 0, 0, 0, one, one, 0, one,
// BOTTOM
0, 0, 0, one, one, 0, one, one, };
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
// FRONT
0, one, one, one, 0, 0, one, 0,
// BACK
one, one, one, 0, 0, one, 0, 0,
// LEFT
one, one, one, 0, 0, one, 0, 0,
// RIGHT
one, one, one, 0, 0, one, 0, 0,
// TOP
one, 0, 0, 0, one, one, 0, one,
// BOTTOM
0, 0, 0, one, one, 0, one, one, };
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
// …
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
mTextureBuffer = tbb.asIntBuffer();
mTextureBuffer.put(texCoords);
mTextureBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
mTextureBuffer = tbb.asIntBuffer();
mTextureBuffer.put(texCoords);
mTextureBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D); // workaround bug 3623
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTextureBuffer);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTextureBuffer);
gl.glColor4f(1, 1, 1, 1);
gl.glNormal3f(0, 0, 1);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glNormal3f(0, 0, -1);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
gl.glNormal3f(0, 0, 1);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glNormal3f(0, 0, -1);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
gl.glColor4f(1, 1, 1, 1);
gl.glNormal3f(-1, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
gl.glNormal3f(1, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
gl.glNormal3f(-1, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
gl.glNormal3f(1, 0, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
gl.glColor4f(1, 1, 1, 1);
gl.glNormal3f(0, 1, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
gl.glNormal3f(0, -1, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
}
gl.glNormal3f(0, 1, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
gl.glNormal3f(0, -1, 0);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
}
static void loadTexture(GL10 gl, Context context, int resource) {
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), resource);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
bmp.recycle();
}
}
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), resource);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
bmp.recycle();
}
}
7.) Run the Application.
Steps to Create:
1.) Open Eclipse. Use the New Project Wizard and select Android Project Give the respective project name i.e. Graphics3d. Enter following information:
Project name: Graphics3d
Build Target: Google APIs
Application name: Graphics3d
Package name: app. Com.app.Graphics3d
Create Activity: Graphics3d
Project name: Graphics3d
Build Target: Google APIs
Application name: Graphics3d
Package name: app. Com.app.Graphics3d
Create Activity: Graphics3d
On Clicking Finish Graphics3d code structure is generated with the necessary Android Packages being imported along with Graphics3d.java. Graphics3d class will look like following:
package com.app.Graphics3d;
import android.app.Activity;
import android.os.Bundle;
public class Graphics3d extends Activity {
MyGLView view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new MyGLView(this);
setContentView(view);
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
@Override
protected void onResume() {
super.onResume();
view.onResume();
}
}
import android.os.Bundle;
public class Graphics3d extends Activity {
MyGLView view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new MyGLView(this);
setContentView(view);
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
@Override
protected void onResume() {
super.onResume();
view.onResume();
}
}
Output –The final output:
No comments:
Post a Comment