Since I downloaded the SDK v0.9, not a single sample OpenGL code works
or even compile.
The AndroidGlobalTime example uses packages and classes that do not
exist anymore and GLView1 needs also major modifications. When I tried
to run it, it crashed and the log showed that eglCreateWindowSurface
required a SurfaceView and not just a View. I tried to modify it but
so far I cannot get the onDraw function to be called.
Could someone either give us a working sample code or correct my code
below:
package com.michel.openglapp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* Example of how to use OpenGL|ES in a custom view
*
*/
public class OpenGLView extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("test","First step");
setContentView(new GLView( getApplication() ));
Log.v("test","Going for it");
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
}
}
class GLView extends SurfaceView implements SurfaceHolder.Callback
{
private EGLContext mEGLContext;
private EGLSurface mEGLSurface;
private EGLDisplay mEGLDisplay;
private Cube mCube;
private float mAngle;
private long mNextTime;
private boolean mAnimate;
/**
* The View constructor is a good place to allocate our OpenGL
context
*/
public GLView(Context context)
{
super(context);
getHolder().addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v("test","Surface has been created");
// Get an EGL instance
EGL10 egl = (EGL10)EGLContext.getEGL();
// Get to the default display.
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
// We can now initialize EGL for that display
int[] version = new int[2];
egl.eglInitialize(dpy, version);
// Specify a configuration for our opengl session
// and grab the first configuration that matches is
int[] configSpec = {
EGL10.EGL_DEPTH_SIZE, 16,
EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
EGLConfig config = configs[0];
// Create an OpenGL ES context. This must be done only once,
an
// OpenGL context is a somewhat heavy object.
EGLContext ctx = egl.eglCreateContext(dpy, config,
EGL10.EGL_NO_CONTEXT, null);
// Create an EGL surface we can render into.
EGLSurface surface = egl.eglCreateWindowSurface(dpy, config,
this, null);
// Before we can issue GL commands, we need to make sure
// the context is current and bound to a surface.
egl.eglMakeCurrent(dpy, surface, surface, ctx);
mEGLContext = ctx;
mEGLDisplay = dpy;
mEGLSurface = surface;
// create our cube
mCube = new Cube();
/* ML Moved */
mAnimate = true;
Message msg = mHandler.obtainMessage(INVALIDATE);
mNextTime = SystemClock.uptimeMillis();
mHandler.sendMessageAtTime(msg, mNextTime);
}
/*
* Start the animation only once we're attached to a window
* @see android.view.View#onAttachedToWindow()
*/
@Override
protected void onAttachedToWindow() {
Log.v("test", "On attached to window was called");
/* mAnimate = true;
Message msg = mHandler.obtainMessage(INVALIDATE);
mNextTime = SystemClock.uptimeMillis();
mHandler.sendMessageAtTime(msg, mNextTime);*/
super.onAttachedToWindow();
}
/*
* Make sure to stop the animation when we're no longer on screen,
* failing to do so will cause most of the view hierarchy to be
* leaked until the current process dies.
* @see android.view.View#onDetachedFromWindow()
*/
@Override
protected void onDetachedFromWindow() {
mAnimate = false;
EGL10 egl = (EGL10)EGLContext.getEGL();
egl.eglMakeCurrent(mEGLDisplay,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
egl.eglDestroyContext(mEGLDisplay, mEGLContext);
egl.eglDestroySurface(mEGLDisplay, mEGLSurface);
egl.eglTerminate(mEGLDisplay);
super.onDetachedFromWindow();
}
/**
* Draw the view content
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
Log.v("test", "Draw has been called");
if (true) {
EGL10 egl = (EGL10)EGLContext.getEGL();
/*
* We need to get to the appropriate GL interface.
* This is simply done by casting the GL context to either
* GL10 or GL11.
*/
GL10 gl = (GL10)mEGLContext.getGL();
/*
* Before we can issue GL commands, we need to make sure
all
* native drawing commands are completed. Simply call
* eglWaitNative() to accomplish this. Once this is done,
no native
* calls should be issued.
*/
egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
int w = getWidth();
int h = getHeight();
/*
* Set the viewport. This doesn't have to be done each
time
* draw() is called. Typically this is called when the
view
* is resized.
*/
gl.glViewport(0, 0, w, h);
/*
* Set our projection matrix. This doesn't have to be done
* each time we draw, but usualy a new projection needs to
be set
* when the viewport is resized.
*/
float ratio = (float)w / h;
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
/*
* dithering is enabled by default in OpenGL,
unfortunattely
* it has a significant impact on performace in software
* implementation. Often, it's better to just turn it off.
*/
gl.glDisable(gl.GL_DITHER);
/*
* Usually, the first thing one might want to do is to
clear
* the screen. The most efficient way of doing this is to
use
* glClear(). However we must make sure to set the scissor
* correctly first. The scissor is always specified in
window
* coordinates:
*/
gl.glClearColor(1,1,1,1);
gl.glEnable(gl.GL_SCISSOR_TEST);
gl.glScissor(0, 0, w, h);
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
/*
* Now we're ready to draw some 3D object
*/
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
gl.glEnableClientState(gl.GL_COLOR_ARRAY);
gl.glEnable(gl.GL_CULL_FACE);
mCube.draw(gl);
mAngle += 1.2f;
/*
* Once we're done with GL, we need to flush all GL
commands and
* make sure they complete before we can issue more native
* drawing commands. This is done by calling waitGL().
*/
egl.eglWaitGL();
// more native rendering can go here...
// NOTE: if (like in this example), no more native
rendering is
// performed, it is preferable to not call eglWaitGL().
/*
* We're done, display our frame.
*/
egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
}
}
//
------------------------------------------------------------------------
private static final int INVALIDATE = 1;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// Log.v("test", "I got a message");
if (mAnimate && msg.what == INVALIDATE) {
postInvalidate();
msg = obtainMessage(INVALIDATE);
long current = SystemClock.uptimeMillis();
if (mNextTime < current) {
mNextTime = current + 20;
}
sendMessageAtTime(msg, mNextTime);
mNextTime += 20;
}
}
};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int
width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// ML Moved
Log.v("test", "Surface was destroyed");
mAnimate = false;
EGL10 egl = (EGL10)EGLContext.getEGL();
egl.eglMakeCurrent(mEGLDisplay,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
egl.eglDestroyContext(mEGLDisplay, mEGLContext);
egl.eglDestroySurface(mEGLDisplay, mEGLSurface);
egl.eglTerminate(mEGLDisplay);
}
}
class Cube
{
public Cube()
{
int one = 0x10000;
int vertices[] = {
-one, -one, -one,
one, -one, -one,
one, one, -one,
-one, one, -one,
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one,
};
int colors[] = {
0, 0, 0, one,
one, 0, 0, one,
one, one, 0, one,
0, one, 0, one,
0, 0, one, one,
one, 0, one, one,
one, one, one, one,
0, one, one, one,
};
byte indices[] = {
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
};
// Buffers to be passed to gl*Pointer() functions
// must be direct, i.e., they must be placed on the
// native heap where the garbage collector cannot
// move them.
//
// Buffers with multi-byte datatypes (e.g., short, int, float)
// must have their byte order set to native order
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
}
public void draw(GL10 gl)
{
gl.glFrontFace(gl.GL_CW);
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE,
mIndexBuffer);
}
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[EMAIL PROTECTED]
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en
-~----------~----~----~----~------~----~------~--~---