这个例子是根据APIDemo 中的例子更改而来,主要是加入了我对透视投影和坐标系的理解。
1. Activity
mGLView = new GLSurfaceView(this);
mGLView.setEGLConfigChooser(false);
mGLView.setRenderer(new StaticTriangleRenderer(this));
setContentView(mGLView);
}
2. RenderView, GLSurface
private Context mContext;
private Triangle mTriangle;
private int mTextureID;
private GL11 mGL;
public StaticTriangleRenderer(Context context) {
super(context);
mContext = context;
mTriangle = new Triangle();
// We want an 8888 pixel format because that's required for
// a translucent window.
// And we want a depth buffer.
setBackgroundDrawable(null);
setFocusable(true);
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
setRenderer(this);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
// Use a surface format with an Alpha channel:
getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
//gl.glDisable(gl.GL_DITHER);
/*
* Some one-time OpenGL initialization can be made here
* probably based on features of this particular context
*/
gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT,
gl.GL_FASTEST);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(gl.GL_SMOOTH);
gl.glEnable(gl.GL_DEPTH_TEST);
gl.glEnable(GL_TEXTURE_2D);
/*
* Create our texture. This has to be done each time the
* surface is created.
*/
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
mTextureID = textures[0];
gl.glBindTexture(GL_TEXTURE_2D, mTextureID);
gl.glTexParameterf(GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER,
gl.GL_NEAREST);
gl.glTexParameterf(GL_TEXTURE_2D,
gl.GL_TEXTURE_MAG_FILTER,
gl.GL_LINEAR);
gl.glTexParameterf(GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S,
gl.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T,
gl.GL_CLAMP_TO_EDGE);
gl.glTexEnvx(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE,
GL11.GL_REPLACE);
Bitmap bmp =
BitmapFactory.decodeResource(mContext.getResources(), R.drawable.myvideo);
int width = bmp.getWidth();
int height = bmp.getHeight();
Matrix matrix = new Matrix();
float scaleWidth = ((float) 128) / width;
float scaleHeight = ((float) 128) / height;
matrix.postScale(scaleWidth, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bmp, 0, 0, width, height,
matrix, true);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, newbmp, 0);
}
public void onDrawFrame(GL10 gl) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
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().
*/
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
/*
* Now we're ready to draw some 3D objects
*/
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
//portalDrawFrame(gl);
GLU.gluLookAt(gl, 0, 0, 4, // The position of the eye
0f, 0f, 0f, // Eye to see the pointer
0f, 1.0f, 0.0f);// The direction of the see
gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);
long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
gl.glRotatef(angle, 0, 0, 1.0f);
gl.glEnable(GL_TEXTURE_2D);
gl.glBindTexture(GL11.GL_TEXTURE_2D, mTextureID);
mTriangle.draw(gl);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
/*
* Set our projection matrix. This doesn't have to be done
* each time we draw, but usually a new projection needs to
* be set when the viewport is resized.
*/
float ratio = (float) w / h;
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 90, ratio, 4, 100);
}
static class Triangle {
public Triangle() {
// 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(VERTS * 3 * 4);
vbb.order(ByteOrder.nativeOrder());
mFVertexBuffer = vbb.asFloatBuffer();
ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
tbb.order(ByteOrder.nativeOrder());
mTexBuffer = tbb.asFloatBuffer();
ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
ibb.order(ByteOrder.nativeOrder());
mIndexBuffer = ibb.asShortBuffer();
// A unit-sided equilateral triangle centered on the origin.
float[] coords = {
// X, Y, Z
-2.0f, -3.0f, -4.0f,
2.0f, -3.0f, -4.0f,
2.0f, 3.0f, -4.0f,
-2.0f, 3.0f, -4.0f};
float[] texture = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f};
mFVertexBuffer.put(coords);
mTexBuffer.put(texture);
for(int i = 0; i < VERTS; i++) {
mIndexBuffer.put((short) i);
}
mFVertexBuffer.position(0);
mTexBuffer.position(0);
mIndexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);
glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);
gl.glDrawElements(GL11.GL_TRIANGLE_FAN, VERTS, GL_UNSIGNED_SHORT, mIndexBuffer);
//gl.glDrawArrays(GL11.GL_TRIANGLE_FAN, 0, VERTS);
}
private final static int VERTS = 4;
private FloatBuffer mFVertexBuffer;
private FloatBuffer mTexBuffer;
private ShortBuffer mIndexBuffer;
}
}