auto import from //depot/cupcake/@135843
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class AlphaBitmap extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Bitmap mBitmap;
|
||||
private Bitmap mBitmap2;
|
||||
private Bitmap mBitmap3;
|
||||
private Shader mShader;
|
||||
|
||||
private static void drawIntoBitmap(Bitmap bm) {
|
||||
float x = bm.getWidth();
|
||||
float y = bm.getHeight();
|
||||
Canvas c = new Canvas(bm);
|
||||
Paint p = new Paint();
|
||||
p.setAntiAlias(true);
|
||||
|
||||
p.setAlpha(0x80);
|
||||
c.drawCircle(x/2, y/2, x/2, p);
|
||||
|
||||
p.setAlpha(0x30);
|
||||
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
|
||||
p.setTextSize(60);
|
||||
p.setTextAlign(Paint.Align.CENTER);
|
||||
Paint.FontMetrics fm = p.getFontMetrics();
|
||||
c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
InputStream is = context.getResources().openRawResource(R.drawable.app_sample_code);
|
||||
mBitmap = BitmapFactory.decodeStream(is);
|
||||
mBitmap2 = mBitmap.extractAlpha();
|
||||
mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8);
|
||||
drawIntoBitmap(mBitmap3);
|
||||
|
||||
mShader = new LinearGradient(0, 0, 100, 70, new int[] {
|
||||
Color.RED, Color.GREEN, Color.BLUE },
|
||||
null, Shader.TileMode.MIRROR);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
Paint p = new Paint();
|
||||
float y = 10;
|
||||
|
||||
p.setColor(Color.RED);
|
||||
canvas.drawBitmap(mBitmap, 10, y, p);
|
||||
y += mBitmap.getHeight() + 10;
|
||||
canvas.drawBitmap(mBitmap2, 10, y, p);
|
||||
y += mBitmap2.getHeight() + 10;
|
||||
p.setShader(mShader);
|
||||
canvas.drawBitmap(mBitmap3, 10, y, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Transformation;
|
||||
|
||||
public class AnimateDrawable extends ProxyDrawable {
|
||||
|
||||
private Animation mAnimation;
|
||||
private Transformation mTransformation = new Transformation();
|
||||
|
||||
public AnimateDrawable(Drawable target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
public AnimateDrawable(Drawable target, Animation animation) {
|
||||
super(target);
|
||||
mAnimation = animation;
|
||||
}
|
||||
|
||||
public Animation getAnimation() {
|
||||
return mAnimation;
|
||||
}
|
||||
|
||||
public void setAnimation(Animation anim) {
|
||||
mAnimation = anim;
|
||||
}
|
||||
|
||||
public boolean hasStarted() {
|
||||
return mAnimation != null && mAnimation.hasStarted();
|
||||
}
|
||||
|
||||
public boolean hasEnded() {
|
||||
return mAnimation == null || mAnimation.hasEnded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
Drawable dr = getProxy();
|
||||
if (dr != null) {
|
||||
int sc = canvas.save();
|
||||
Animation anim = mAnimation;
|
||||
if (anim != null) {
|
||||
anim.getTransformation(
|
||||
AnimationUtils.currentAnimationTimeMillis(),
|
||||
mTransformation);
|
||||
canvas.concat(mTransformation.getMatrix());
|
||||
}
|
||||
dr.draw(canvas);
|
||||
canvas.restoreToCount(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.view.animation.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class AnimateDrawables extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private AnimateDrawable mDrawable;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
Drawable dr = context.getResources().getDrawable(R.drawable.beach);
|
||||
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
|
||||
|
||||
Animation an = new TranslateAnimation(0, 100, 0, 200);
|
||||
an.setDuration(2000);
|
||||
an.setRepeatCount(-1);
|
||||
an.initialize(10, 10, 10, 10);
|
||||
|
||||
mDrawable = new AnimateDrawable(dr, an);
|
||||
an.startNow();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
mDrawable.draw(canvas);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
119
samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
Normal file
119
samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
// Need the following import to get access to the app resources, since this
|
||||
// class is in a sub-package.
|
||||
//import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class Arcs extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint[] mPaints;
|
||||
private Paint mFramePaint;
|
||||
private boolean[] mUseCenters;
|
||||
private RectF[] mOvals;
|
||||
private RectF mBigOval;
|
||||
private float mStart;
|
||||
private float mSweep;
|
||||
private int mBigIndex;
|
||||
|
||||
private static final float SWEEP_INC = 2;
|
||||
private static final float START_INC = 15;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
mPaints = new Paint[4];
|
||||
mUseCenters = new boolean[4];
|
||||
mOvals = new RectF[4];
|
||||
|
||||
mPaints[0] = new Paint();
|
||||
mPaints[0].setAntiAlias(true);
|
||||
mPaints[0].setStyle(Paint.Style.FILL);
|
||||
mPaints[0].setColor(0x88FF0000);
|
||||
mUseCenters[0] = false;
|
||||
|
||||
mPaints[1] = new Paint(mPaints[0]);
|
||||
mPaints[1].setColor(0x8800FF00);
|
||||
mUseCenters[1] = true;
|
||||
|
||||
mPaints[2] = new Paint(mPaints[0]);
|
||||
mPaints[2].setStyle(Paint.Style.STROKE);
|
||||
mPaints[2].setStrokeWidth(4);
|
||||
mPaints[2].setColor(0x880000FF);
|
||||
mUseCenters[2] = false;
|
||||
|
||||
mPaints[3] = new Paint(mPaints[2]);
|
||||
mPaints[3].setColor(0x88888888);
|
||||
mUseCenters[3] = true;
|
||||
|
||||
mBigOval = new RectF(40, 10, 280, 250);
|
||||
|
||||
mOvals[0] = new RectF( 10, 270, 70, 330);
|
||||
mOvals[1] = new RectF( 90, 270, 150, 330);
|
||||
mOvals[2] = new RectF(170, 270, 230, 330);
|
||||
mOvals[3] = new RectF(250, 270, 310, 330);
|
||||
|
||||
mFramePaint = new Paint();
|
||||
mFramePaint.setAntiAlias(true);
|
||||
mFramePaint.setStyle(Paint.Style.STROKE);
|
||||
mFramePaint.setStrokeWidth(0);
|
||||
}
|
||||
|
||||
private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
|
||||
Paint paint) {
|
||||
canvas.drawRect(oval, mFramePaint);
|
||||
canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
drawArcs(canvas, mBigOval, mUseCenters[mBigIndex],
|
||||
mPaints[mBigIndex]);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
drawArcs(canvas, mOvals[i], mUseCenters[i], mPaints[i]);
|
||||
}
|
||||
|
||||
mSweep += SWEEP_INC;
|
||||
if (mSweep > 360) {
|
||||
mSweep -= 360;
|
||||
mStart += START_INC;
|
||||
if (mStart >= 360) {
|
||||
mStart -= 360;
|
||||
}
|
||||
mBigIndex = (mBigIndex + 1) % mOvals.length;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class BitmapDecode extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Bitmap mBitmap;
|
||||
private Bitmap mBitmap2;
|
||||
private Bitmap mBitmap3;
|
||||
private Bitmap mBitmap4;
|
||||
private Drawable mDrawable;
|
||||
|
||||
private Movie mMovie;
|
||||
private long mMovieStart;
|
||||
|
||||
private static byte[] streamToBytes(InputStream is) {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
try {
|
||||
while ((len = is.read(buffer)) >= 0) {
|
||||
os.write(buffer, 0, len);
|
||||
}
|
||||
} catch (java.io.IOException e) {
|
||||
}
|
||||
return os.toByteArray();
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
java.io.InputStream is;
|
||||
is = context.getResources().openRawResource(R.drawable.beach);
|
||||
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
Bitmap bm;
|
||||
|
||||
opts.inJustDecodeBounds = true;
|
||||
bm = BitmapFactory.decodeStream(is, null, opts);
|
||||
|
||||
// now opts.outWidth and opts.outHeight are the dimension of the
|
||||
// bitmap, even though bm is null
|
||||
|
||||
opts.inJustDecodeBounds = false; // this will request the bm
|
||||
opts.inSampleSize = 4; // scaled down by 4
|
||||
bm = BitmapFactory.decodeStream(is, null, opts);
|
||||
|
||||
mBitmap = bm;
|
||||
|
||||
// decode an image with transparency
|
||||
is = context.getResources().openRawResource(R.drawable.frog);
|
||||
mBitmap2 = BitmapFactory.decodeStream(is);
|
||||
|
||||
// create a deep copy of it using getPixels() into different configs
|
||||
int w = mBitmap2.getWidth();
|
||||
int h = mBitmap2.getHeight();
|
||||
int[] pixels = new int[w*h];
|
||||
mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
|
||||
mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
|
||||
Bitmap.Config.ARGB_4444);
|
||||
|
||||
mDrawable = context.getResources().getDrawable(R.drawable.button);
|
||||
mDrawable.setBounds(150, 20, 300, 100);
|
||||
|
||||
is = context.getResources().openRawResource(R.drawable.animated_gif);
|
||||
if (true) {
|
||||
mMovie = Movie.decodeStream(is);
|
||||
} else {
|
||||
byte[] array = streamToBytes(is);
|
||||
mMovie = Movie.decodeByteArray(array, 0, array.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(0xFFCCCCCC);
|
||||
|
||||
Paint p = new Paint();
|
||||
p.setAntiAlias(true);
|
||||
|
||||
canvas.drawBitmap(mBitmap, 10, 10, null);
|
||||
canvas.drawBitmap(mBitmap2, 10, 170, null);
|
||||
canvas.drawBitmap(mBitmap3, 110, 170, null);
|
||||
canvas.drawBitmap(mBitmap4, 210, 170, null);
|
||||
|
||||
mDrawable.draw(canvas);
|
||||
|
||||
long now = android.os.SystemClock.uptimeMillis();
|
||||
if (mMovieStart == 0) { // first time
|
||||
mMovieStart = now;
|
||||
}
|
||||
if (mMovie != null) {
|
||||
int dur = mMovie.duration();
|
||||
if (dur == 0) {
|
||||
dur = 1000;
|
||||
}
|
||||
int relTime = (int)((now - mMovieStart) % dur);
|
||||
mMovie.setTime(relTime);
|
||||
mMovie.draw(canvas, getWidth() - mMovie.width(),
|
||||
getHeight() - mMovie.height());
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.*;
|
||||
import android.util.FloatMath;
|
||||
|
||||
public class BitmapMesh extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private static final int WIDTH = 20;
|
||||
private static final int HEIGHT = 20;
|
||||
private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
|
||||
|
||||
private final Bitmap mBitmap;
|
||||
private final float[] mVerts = new float[COUNT*2];
|
||||
private final float[] mOrig = new float[COUNT*2];
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private final Matrix mInverse = new Matrix();
|
||||
|
||||
private static void setXY(float[] array, int index, float x, float y) {
|
||||
array[index*2 + 0] = x;
|
||||
array[index*2 + 1] = y;
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mBitmap = BitmapFactory.decodeResource(getResources(),
|
||||
R.drawable.beach);
|
||||
|
||||
float w = mBitmap.getWidth();
|
||||
float h = mBitmap.getHeight();
|
||||
// construct our mesh
|
||||
int index = 0;
|
||||
for (int y = 0; y <= HEIGHT; y++) {
|
||||
float fy = h * y / HEIGHT;
|
||||
for (int x = 0; x <= WIDTH; x++) {
|
||||
float fx = w * x / WIDTH;
|
||||
setXY(mVerts, index, fx, fy);
|
||||
setXY(mOrig, index, fx, fy);
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
mMatrix.setTranslate(10, 10);
|
||||
mMatrix.invert(mInverse);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(0xFFCCCCCC);
|
||||
|
||||
canvas.concat(mMatrix);
|
||||
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0,
|
||||
null, 0, null);
|
||||
}
|
||||
|
||||
private void warp(float cx, float cy) {
|
||||
final float K = 10000;
|
||||
float[] src = mOrig;
|
||||
float[] dst = mVerts;
|
||||
for (int i = 0; i < COUNT*2; i += 2) {
|
||||
float x = src[i+0];
|
||||
float y = src[i+1];
|
||||
float dx = cx - x;
|
||||
float dy = cy - y;
|
||||
float dd = dx*dx + dy*dy;
|
||||
float d = FloatMath.sqrt(dd);
|
||||
float pull = K / (dd + 0.000001f);
|
||||
|
||||
pull /= (d + 0.000001f);
|
||||
// android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull);
|
||||
|
||||
if (pull >= 1) {
|
||||
dst[i+0] = cx;
|
||||
dst[i+1] = cy;
|
||||
} else {
|
||||
dst[i+0] = x + dx * pull;
|
||||
dst[i+1] = y + dy * pull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int mLastWarpX = -9999; // don't match a touch coordinate
|
||||
private int mLastWarpY;
|
||||
|
||||
@Override public boolean onTouchEvent(MotionEvent event) {
|
||||
float[] pt = { event.getX(), event.getY() };
|
||||
mInverse.mapPoints(pt);
|
||||
|
||||
int x = (int)pt[0];
|
||||
int y = (int)pt[1];
|
||||
if (mLastWarpX != x || mLastWarpY != y) {
|
||||
mLastWarpX = x;
|
||||
mLastWarpY = y;
|
||||
warp(pt[0], pt[1]);
|
||||
invalidate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
public class BitmapPixels extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Bitmap mBitmap1;
|
||||
private Bitmap mBitmap2;
|
||||
private Bitmap mBitmap3;
|
||||
private Bitmap mBitmap4;
|
||||
|
||||
// access the red component from a premultiplied color
|
||||
private static int getR32(int c) { return (c >> 0) & 0xFF; }
|
||||
// access the red component from a premultiplied color
|
||||
private static int getG32(int c) { return (c >> 8) & 0xFF; }
|
||||
// access the red component from a premultiplied color
|
||||
private static int getB32(int c) { return (c >> 16) & 0xFF; }
|
||||
// access the red component from a premultiplied color
|
||||
private static int getA32(int c) { return (c >> 24) & 0xFF; }
|
||||
|
||||
/**
|
||||
* This takes components that are already in premultiplied form, and
|
||||
* packs them into an int in the correct device order.
|
||||
*/
|
||||
private static int pack8888(int r, int g, int b, int a) {
|
||||
return (r << 0) | ( g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
private static short pack565(int r, int g, int b) {
|
||||
return (short)((r << 11) | ( g << 5) | (b << 0));
|
||||
}
|
||||
|
||||
private static short pack4444(int r, int g, int b, int a) {
|
||||
return (short)((a << 0) | ( b << 4) | (g << 8) | (r << 12));
|
||||
}
|
||||
|
||||
private static int mul255(int c, int a) {
|
||||
int prod = c * a + 128;
|
||||
return (prod + (prod >> 8)) >> 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a color int into a premultiplied device color
|
||||
*/
|
||||
private static int premultiplyColor(int c) {
|
||||
int r = Color.red(c);
|
||||
int g = Color.green(c);
|
||||
int b = Color.blue(c);
|
||||
int a = Color.alpha(c);
|
||||
// now apply the alpha to r, g, b
|
||||
r = mul255(r, a);
|
||||
g = mul255(g, a);
|
||||
b = mul255(b, a);
|
||||
// now pack it in the correct order
|
||||
return pack8888(r, g, b, a);
|
||||
}
|
||||
|
||||
private static void makeRamp(int from, int to, int n,
|
||||
int[] ramp8888, short[] ramp565,
|
||||
short[] ramp4444) {
|
||||
int r = getR32(from) << 23;
|
||||
int g = getG32(from) << 23;
|
||||
int b = getB32(from) << 23;
|
||||
int a = getA32(from) << 23;
|
||||
// now compute our step amounts per componenet (biased by 23 bits)
|
||||
int dr = ((getR32(to) << 23) - r) / (n - 1);
|
||||
int dg = ((getG32(to) << 23) - g) / (n - 1);
|
||||
int db = ((getB32(to) << 23) - b) / (n - 1);
|
||||
int da = ((getA32(to) << 23) - a) / (n - 1);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
ramp8888[i] = pack8888(r >> 23, g >> 23, b >> 23, a >> 23);
|
||||
ramp565[i] = pack565(r >> (23+3), g >> (23+2), b >> (23+3));
|
||||
ramp4444[i] = pack4444(r >> (23+4), g >> (23+4), b >> (23+4),
|
||||
a >> (23+4));
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
a += da;
|
||||
}
|
||||
}
|
||||
|
||||
private static IntBuffer makeBuffer(int[] src, int n) {
|
||||
IntBuffer dst = IntBuffer.allocate(n*n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
dst.put(src);
|
||||
}
|
||||
dst.rewind();
|
||||
return dst;
|
||||
}
|
||||
|
||||
private static ShortBuffer makeBuffer(short[] src, int n) {
|
||||
ShortBuffer dst = ShortBuffer.allocate(n*n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
dst.put(src);
|
||||
}
|
||||
dst.rewind();
|
||||
return dst;
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
final int N = 100;
|
||||
int[] data8888 = new int[N];
|
||||
short[] data565 = new short[N];
|
||||
short[] data4444 = new short[N];
|
||||
|
||||
makeRamp(premultiplyColor(Color.RED), premultiplyColor(Color.GREEN),
|
||||
N, data8888, data565, data4444);
|
||||
|
||||
mBitmap1 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_8888);
|
||||
mBitmap2 = Bitmap.createBitmap(N, N, Bitmap.Config.RGB_565);
|
||||
mBitmap3 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_4444);
|
||||
|
||||
mBitmap1.copyPixelsFromBuffer(makeBuffer(data8888, N));
|
||||
mBitmap2.copyPixelsFromBuffer(makeBuffer(data565, N));
|
||||
mBitmap3.copyPixelsFromBuffer(makeBuffer(data4444, N));
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(0xFFCCCCCC);
|
||||
|
||||
int y = 10;
|
||||
canvas.drawBitmap(mBitmap1, 10, y, null);
|
||||
y += mBitmap1.getHeight() + 10;
|
||||
canvas.drawBitmap(mBitmap2, 10, y, null);
|
||||
y += mBitmap2.getHeight() + 10;
|
||||
canvas.drawBitmap(mBitmap3, 10, y, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Bundle;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.Window;
|
||||
import java.io.IOException;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public class CameraPreview extends Activity {
|
||||
private Preview mPreview;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Hide the window title.
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
// Create our Preview view and set it as the content of our activity.
|
||||
mPreview = new Preview(this);
|
||||
setContentView(mPreview);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class Preview extends SurfaceView implements SurfaceHolder.Callback {
|
||||
SurfaceHolder mHolder;
|
||||
Camera mCamera;
|
||||
|
||||
Preview(Context context) {
|
||||
super(context);
|
||||
|
||||
// Install a SurfaceHolder.Callback so we get notified when the
|
||||
// underlying surface is created and destroyed.
|
||||
mHolder = getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
// The Surface has been created, acquire the camera and tell it where
|
||||
// to draw.
|
||||
mCamera = Camera.open();
|
||||
try {
|
||||
mCamera.setPreviewDisplay(holder);
|
||||
} catch (IOException exception) {
|
||||
mCamera.release();
|
||||
mCamera = null;
|
||||
// TODO: add more exception handling logic here
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
// Surface will be destroyed when we return, so stop the preview.
|
||||
// Because the CameraDevice object is not a shared resource, it's very
|
||||
// important to release it when the activity is paused.
|
||||
mCamera.stopPreview();
|
||||
mCamera = null;
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
// Now that the size is known, set up the camera parameters and begin
|
||||
// the preview.
|
||||
Camera.Parameters parameters = mCamera.getParameters();
|
||||
parameters.setPreviewSize(w, h);
|
||||
mCamera.setParameters(parameters);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class Clipping extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint;
|
||||
private Path mPath;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setStrokeWidth(6);
|
||||
mPaint.setTextSize(16);
|
||||
mPaint.setTextAlign(Paint.Align.RIGHT);
|
||||
|
||||
mPath = new Path();
|
||||
}
|
||||
|
||||
private void drawScene(Canvas canvas) {
|
||||
canvas.clipRect(0, 0, 100, 100);
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
mPaint.setColor(Color.RED);
|
||||
canvas.drawLine(0, 0, 100, 100, mPaint);
|
||||
|
||||
mPaint.setColor(Color.GREEN);
|
||||
canvas.drawCircle(30, 70, 30, mPaint);
|
||||
|
||||
mPaint.setColor(Color.BLUE);
|
||||
canvas.drawText("Clipping", 100, 30, mPaint);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.GRAY);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 10);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 10);
|
||||
canvas.clipRect(10, 10, 90, 90);
|
||||
canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 160);
|
||||
mPath.reset();
|
||||
canvas.clipPath(mPath); // makes the clip empty
|
||||
mPath.addCircle(50, 50, 50, Path.Direction.CCW);
|
||||
canvas.clipPath(mPath, Region.Op.REPLACE);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 160);
|
||||
canvas.clipRect(0, 0, 60, 60);
|
||||
canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 310);
|
||||
canvas.clipRect(0, 0, 60, 60);
|
||||
canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 310);
|
||||
canvas.clipRect(0, 0, 60, 60);
|
||||
canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);
|
||||
drawScene(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class ColorMatrixSample extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private ColorMatrix mCM = new ColorMatrix();
|
||||
private Bitmap mBitmap;
|
||||
private float mSaturation;
|
||||
private float mAngle;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
mBitmap = BitmapFactory.decodeResource(context.getResources(),
|
||||
R.drawable.balloons);
|
||||
}
|
||||
|
||||
private static void setTranslate(ColorMatrix cm, float dr, float dg,
|
||||
float db, float da) {
|
||||
cm.set(new float[] {
|
||||
2, 0, 0, 0, dr,
|
||||
0, 2, 0, 0, dg,
|
||||
0, 0, 2, 0, db,
|
||||
0, 0, 0, 1, da });
|
||||
}
|
||||
|
||||
private static void setContrast(ColorMatrix cm, float contrast) {
|
||||
float scale = contrast + 1.f;
|
||||
float translate = (-.5f * scale + .5f) * 255.f;
|
||||
cm.set(new float[] {
|
||||
scale, 0, 0, 0, translate,
|
||||
0, scale, 0, 0, translate,
|
||||
0, 0, scale, 0, translate,
|
||||
0, 0, 0, 1, 0 });
|
||||
}
|
||||
|
||||
private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) {
|
||||
float scale = contrast + 1.f;
|
||||
float translate = (-.5f * scale + .5f) * 255.f;
|
||||
cm.set(new float[] {
|
||||
1, 0, 0, 0, translate,
|
||||
0, 1, 0, 0, translate,
|
||||
0, 0, 1, 0, translate,
|
||||
0, 0, 0, 1, 0 });
|
||||
}
|
||||
|
||||
private static void setContrastScaleOnly(ColorMatrix cm, float contrast) {
|
||||
float scale = contrast + 1.f;
|
||||
float translate = (-.5f * scale + .5f) * 255.f;
|
||||
cm.set(new float[] {
|
||||
scale, 0, 0, 0, 0,
|
||||
0, scale, 0, 0, 0,
|
||||
0, 0, scale, 0, 0,
|
||||
0, 0, 0, 1, 0 });
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
float x = 20;
|
||||
float y = 20;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
paint.setColorFilter(null);
|
||||
canvas.drawBitmap(mBitmap, x, y, paint);
|
||||
|
||||
ColorMatrix cm = new ColorMatrix();
|
||||
|
||||
mAngle += 2;
|
||||
if (mAngle > 180) {
|
||||
mAngle = 0;
|
||||
}
|
||||
|
||||
//convert our animated angle [-180...180] to a contrast value of [-1..1]
|
||||
float contrast = mAngle / 180.f;
|
||||
|
||||
setContrast(cm, contrast);
|
||||
paint.setColorFilter(new ColorMatrixColorFilter(cm));
|
||||
canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint);
|
||||
|
||||
setContrastScaleOnly(cm, contrast);
|
||||
paint.setColorFilter(new ColorMatrixColorFilter(cm));
|
||||
canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint);
|
||||
|
||||
setContrastTranslateOnly(cm, contrast);
|
||||
paint.setColorFilter(new ColorMatrixColorFilter(cm));
|
||||
canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10),
|
||||
paint);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.R;
|
||||
import android.os.Bundle;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class ColorPickerDialog extends Dialog {
|
||||
|
||||
public interface OnColorChangedListener {
|
||||
void colorChanged(int color);
|
||||
}
|
||||
|
||||
private OnColorChangedListener mListener;
|
||||
private int mInitialColor;
|
||||
|
||||
private static class ColorPickerView extends View {
|
||||
private Paint mPaint;
|
||||
private Paint mCenterPaint;
|
||||
private final int[] mColors;
|
||||
private OnColorChangedListener mListener;
|
||||
|
||||
ColorPickerView(Context c, OnColorChangedListener l, int color) {
|
||||
super(c);
|
||||
mListener = l;
|
||||
mColors = new int[] {
|
||||
0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
|
||||
0xFFFFFF00, 0xFFFF0000
|
||||
};
|
||||
Shader s = new SweepGradient(0, 0, mColors, null);
|
||||
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setShader(s);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setStrokeWidth(32);
|
||||
|
||||
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCenterPaint.setColor(color);
|
||||
mCenterPaint.setStrokeWidth(5);
|
||||
}
|
||||
|
||||
private boolean mTrackingCenter;
|
||||
private boolean mHighlightCenter;
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
|
||||
|
||||
canvas.translate(CENTER_X, CENTER_X);
|
||||
|
||||
canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
|
||||
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
|
||||
|
||||
if (mTrackingCenter) {
|
||||
int c = mCenterPaint.getColor();
|
||||
mCenterPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
if (mHighlightCenter) {
|
||||
mCenterPaint.setAlpha(0xFF);
|
||||
} else {
|
||||
mCenterPaint.setAlpha(0x80);
|
||||
}
|
||||
canvas.drawCircle(0, 0,
|
||||
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
|
||||
mCenterPaint);
|
||||
|
||||
mCenterPaint.setStyle(Paint.Style.FILL);
|
||||
mCenterPaint.setColor(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
|
||||
}
|
||||
|
||||
private static final int CENTER_X = 100;
|
||||
private static final int CENTER_Y = 100;
|
||||
private static final int CENTER_RADIUS = 32;
|
||||
|
||||
private int floatToByte(float x) {
|
||||
int n = java.lang.Math.round(x);
|
||||
return n;
|
||||
}
|
||||
private int pinToByte(int n) {
|
||||
if (n < 0) {
|
||||
n = 0;
|
||||
} else if (n > 255) {
|
||||
n = 255;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private int ave(int s, int d, float p) {
|
||||
return s + java.lang.Math.round(p * (d - s));
|
||||
}
|
||||
|
||||
private int interpColor(int colors[], float unit) {
|
||||
if (unit <= 0) {
|
||||
return colors[0];
|
||||
}
|
||||
if (unit >= 1) {
|
||||
return colors[colors.length - 1];
|
||||
}
|
||||
|
||||
float p = unit * (colors.length - 1);
|
||||
int i = (int)p;
|
||||
p -= i;
|
||||
|
||||
// now p is just the fractional part [0...1) and i is the index
|
||||
int c0 = colors[i];
|
||||
int c1 = colors[i+1];
|
||||
int a = ave(Color.alpha(c0), Color.alpha(c1), p);
|
||||
int r = ave(Color.red(c0), Color.red(c1), p);
|
||||
int g = ave(Color.green(c0), Color.green(c1), p);
|
||||
int b = ave(Color.blue(c0), Color.blue(c1), p);
|
||||
|
||||
return Color.argb(a, r, g, b);
|
||||
}
|
||||
|
||||
private int rotateColor(int color, float rad) {
|
||||
float deg = rad * 180 / 3.1415927f;
|
||||
int r = Color.red(color);
|
||||
int g = Color.green(color);
|
||||
int b = Color.blue(color);
|
||||
|
||||
ColorMatrix cm = new ColorMatrix();
|
||||
ColorMatrix tmp = new ColorMatrix();
|
||||
|
||||
cm.setRGB2YUV();
|
||||
tmp.setRotate(0, deg);
|
||||
cm.postConcat(tmp);
|
||||
tmp.setYUV2RGB();
|
||||
cm.postConcat(tmp);
|
||||
|
||||
final float[] a = cm.getArray();
|
||||
|
||||
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
|
||||
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
|
||||
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
|
||||
|
||||
return Color.argb(Color.alpha(color), pinToByte(ir),
|
||||
pinToByte(ig), pinToByte(ib));
|
||||
}
|
||||
|
||||
private static final float PI = 3.1415926f;
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX() - CENTER_X;
|
||||
float y = event.getY() - CENTER_Y;
|
||||
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mTrackingCenter = inCenter;
|
||||
if (inCenter) {
|
||||
mHighlightCenter = true;
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mTrackingCenter) {
|
||||
if (mHighlightCenter != inCenter) {
|
||||
mHighlightCenter = inCenter;
|
||||
invalidate();
|
||||
}
|
||||
} else {
|
||||
float angle = (float)java.lang.Math.atan2(y, x);
|
||||
// need to turn angle [-PI ... PI] into unit [0....1]
|
||||
float unit = angle/(2*PI);
|
||||
if (unit < 0) {
|
||||
unit += 1;
|
||||
}
|
||||
mCenterPaint.setColor(interpColor(mColors, unit));
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mTrackingCenter) {
|
||||
if (inCenter) {
|
||||
mListener.colorChanged(mCenterPaint.getColor());
|
||||
}
|
||||
mTrackingCenter = false; // so we draw w/o halo
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public ColorPickerDialog(Context context,
|
||||
OnColorChangedListener listener,
|
||||
int initialColor) {
|
||||
super(context);
|
||||
|
||||
mListener = listener;
|
||||
mInitialColor = initialColor;
|
||||
}
|
||||
|
||||
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
OnColorChangedListener l = new OnColorChangedListener() {
|
||||
public void colorChanged(int color) {
|
||||
mListener.colorChanged(color);
|
||||
dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
setContentView(new ColorPickerView(getContext(), l, mInitialColor));
|
||||
setTitle("Pick a Color");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.hardware.SensorListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
public class Compass extends GraphicsActivity {
|
||||
|
||||
private static final String TAG = "Compass";
|
||||
|
||||
private SensorManager mSensorManager;
|
||||
private SampleView mView;
|
||||
private float[] mValues;
|
||||
|
||||
private final SensorListener mListener = new SensorListener() {
|
||||
|
||||
public void onSensorChanged(int sensor, float[] values) {
|
||||
if (Config.LOGD) Log.d(TAG, "sensorChanged (" + values[0] + ", " + values[1] + ", " + values[2] + ")");
|
||||
mValues = values;
|
||||
if (mView != null) {
|
||||
mView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void onAccuracyChanged(int sensor, int accuracy) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
|
||||
mView = new SampleView(this);
|
||||
setContentView(mView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
if (Config.LOGD) Log.d(TAG, "onResume");
|
||||
super.onResume();
|
||||
mSensorManager.registerListener(mListener,
|
||||
SensorManager.SENSOR_ORIENTATION,
|
||||
SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
if (Config.LOGD) Log.d(TAG, "onStop");
|
||||
mSensorManager.unregisterListener(mListener);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
private class SampleView extends View {
|
||||
private Paint mPaint = new Paint();
|
||||
private Path mPath = new Path();
|
||||
private boolean mAnimate;
|
||||
private long mNextTime;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
// Construct a wedge-shaped path
|
||||
mPath.moveTo(0, -50);
|
||||
mPath.lineTo(-20, 60);
|
||||
mPath.lineTo(0, 50);
|
||||
mPath.lineTo(20, 60);
|
||||
mPath.close();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
|
||||
int w = canvas.getWidth();
|
||||
int h = canvas.getHeight();
|
||||
int cx = w / 2;
|
||||
int cy = h / 2;
|
||||
|
||||
canvas.translate(cx, cy);
|
||||
if (mValues != null) {
|
||||
canvas.rotate(-mValues[0]);
|
||||
}
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
mAnimate = true;
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
mAnimate = false;
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class CreateBitmap extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static final int WIDTH = 50;
|
||||
private static final int HEIGHT = 50;
|
||||
private static final int STRIDE = 64; // must be >= WIDTH
|
||||
|
||||
private static int[] createColors() {
|
||||
int[] colors = new int[STRIDE * HEIGHT];
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
int r = x * 255 / (WIDTH - 1);
|
||||
int g = y * 255 / (HEIGHT - 1);
|
||||
int b = 255 - Math.min(r, g);
|
||||
int a = Math.max(r, g);
|
||||
colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Bitmap[] mBitmaps;
|
||||
private Bitmap[] mJPEG;
|
||||
private Bitmap[] mPNG;
|
||||
private int[] mColors;
|
||||
private Paint mPaint;
|
||||
|
||||
private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format,
|
||||
int quality) {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
src.compress(format, quality, os);
|
||||
|
||||
byte[] array = os.toByteArray();
|
||||
return BitmapFactory.decodeByteArray(array, 0, array.length);
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mColors = createColors();
|
||||
int[] colors = mColors;
|
||||
|
||||
mBitmaps = new Bitmap[6];
|
||||
// these three are initialized with colors[]
|
||||
mBitmaps[0] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
mBitmaps[1] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
|
||||
Bitmap.Config.RGB_565);
|
||||
mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
|
||||
Bitmap.Config.ARGB_4444);
|
||||
|
||||
// these three will have their colors set later
|
||||
mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
mBitmaps[4] = Bitmap.createBitmap(WIDTH, HEIGHT,
|
||||
Bitmap.Config.RGB_565);
|
||||
mBitmaps[5] = Bitmap.createBitmap(WIDTH, HEIGHT,
|
||||
Bitmap.Config.ARGB_4444);
|
||||
for (int i = 3; i <= 5; i++) {
|
||||
mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setDither(true);
|
||||
|
||||
// now encode/decode using JPEG and PNG
|
||||
mJPEG = new Bitmap[mBitmaps.length];
|
||||
mPNG = new Bitmap[mBitmaps.length];
|
||||
for (int i = 0; i < mBitmaps.length; i++) {
|
||||
mJPEG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.JPEG, 80);
|
||||
mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
for (int i = 0; i < mBitmaps.length; i++) {
|
||||
canvas.drawBitmap(mBitmaps[i], 0, 0, null);
|
||||
canvas.drawBitmap(mJPEG[i], 80, 0, null);
|
||||
canvas.drawBitmap(mPNG[i], 160, 0, null);
|
||||
canvas.translate(0, mBitmaps[i].getHeight());
|
||||
}
|
||||
|
||||
// draw the color array directly, w/o craeting a bitmap object
|
||||
canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
|
||||
true, null);
|
||||
canvas.translate(0, HEIGHT);
|
||||
canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
|
||||
false, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100
samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
Normal file
100
samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A vertex shaded cube.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
/**
|
||||
* Render a pair of tumbling cubes.
|
||||
*/
|
||||
|
||||
class CubeRenderer implements GLSurfaceView.Renderer {
|
||||
public CubeRenderer(boolean useTranslucentBackground) {
|
||||
mTranslucentBackground = useTranslucentBackground;
|
||||
mCube = new Cube();
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
/*
|
||||
* 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(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D objects
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
gl.glRotatef(mAngle, 0, 1, 0);
|
||||
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
|
||||
gl.glTranslatef(0.5f, 0.5f, 0.5f);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
mAngle += 1.2f;
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
if (mTranslucentBackground) {
|
||||
// We want a depth buffer and an alpha buffer
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_RED_SIZE, 8,
|
||||
EGL10.EGL_GREEN_SIZE, 8,
|
||||
EGL10.EGL_BLUE_SIZE, 8,
|
||||
EGL10.EGL_ALPHA_SIZE, 8,
|
||||
EGL10.EGL_DEPTH_SIZE, 16,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
} else {
|
||||
// We want a depth buffer, don't care about the
|
||||
// details of the color buffer.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_DEPTH_SIZE, 16,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
}
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
* 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) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
/*
|
||||
* Some one-time OpenGL initialization can be made here
|
||||
* probably based on features of this particular context
|
||||
*/
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
GL10.GL_FASTEST);
|
||||
|
||||
if (mTranslucentBackground) {
|
||||
gl.glClearColor(0,0,0,0);
|
||||
} else {
|
||||
gl.glClearColor(1,1,1,1);
|
||||
}
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
}
|
||||
private boolean mTranslucentBackground;
|
||||
private Cube mCube;
|
||||
private float mAngle;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class DrawPoints extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint();
|
||||
private float[] mPts;
|
||||
|
||||
private static final float SIZE = 300;
|
||||
private static final int SEGS = 32;
|
||||
private static final int X = 0;
|
||||
private static final int Y = 1;
|
||||
|
||||
private void buildPoints() {
|
||||
final int ptCount = (SEGS + 1) * 2;
|
||||
mPts = new float[ptCount * 2];
|
||||
|
||||
float value = 0;
|
||||
final float delta = SIZE / SEGS;
|
||||
for (int i = 0; i <= SEGS; i++) {
|
||||
mPts[i*4 + X] = SIZE - value;
|
||||
mPts[i*4 + Y] = 0;
|
||||
mPts[i*4 + X + 2] = 0;
|
||||
mPts[i*4 + Y + 2] = value;
|
||||
value += delta;
|
||||
}
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
buildPoints();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.translate(10, 10);
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
paint.setColor(Color.RED);
|
||||
paint.setStrokeWidth(0);
|
||||
canvas.drawLines(mPts, paint);
|
||||
|
||||
paint.setColor(Color.BLUE);
|
||||
paint.setStrokeWidth(3);
|
||||
canvas.drawPoints(mPts, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class FingerPaint extends GraphicsActivity
|
||||
implements ColorPickerDialog.OnColorChangedListener {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new MyView(this));
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setDither(true);
|
||||
mPaint.setColor(0xFFFF0000);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||
mPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
mPaint.setStrokeWidth(12);
|
||||
|
||||
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
|
||||
0.4f, 6, 3.5f);
|
||||
|
||||
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
|
||||
}
|
||||
|
||||
private Paint mPaint;
|
||||
private MaskFilter mEmboss;
|
||||
private MaskFilter mBlur;
|
||||
|
||||
public void colorChanged(int color) {
|
||||
mPaint.setColor(color);
|
||||
}
|
||||
|
||||
public class MyView extends View {
|
||||
|
||||
private static final float MINP = 0.25f;
|
||||
private static final float MAXP = 0.75f;
|
||||
|
||||
private Bitmap mBitmap;
|
||||
private Canvas mCanvas;
|
||||
private Path mPath;
|
||||
private Paint mBitmapPaint;
|
||||
|
||||
public MyView(Context c) {
|
||||
super(c);
|
||||
|
||||
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
mPath = new Path();
|
||||
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(0xFFAAAAAA);
|
||||
|
||||
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
|
||||
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
private float mX, mY;
|
||||
private static final float TOUCH_TOLERANCE = 4;
|
||||
|
||||
private void touch_start(float x, float y) {
|
||||
mPath.reset();
|
||||
mPath.moveTo(x, y);
|
||||
mX = x;
|
||||
mY = y;
|
||||
}
|
||||
private void touch_move(float x, float y) {
|
||||
float dx = Math.abs(x - mX);
|
||||
float dy = Math.abs(y - mY);
|
||||
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
|
||||
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
|
||||
mX = x;
|
||||
mY = y;
|
||||
}
|
||||
}
|
||||
private void touch_up() {
|
||||
mPath.lineTo(mX, mY);
|
||||
// commit the path to our offscreen
|
||||
mCanvas.drawPath(mPath, mPaint);
|
||||
// kill this so we don't double draw
|
||||
mPath.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touch_start(x, y);
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
touch_move(x, y);
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
touch_up();
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int COLOR_MENU_ID = Menu.FIRST;
|
||||
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
|
||||
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
|
||||
private static final int ERASE_MENU_ID = Menu.FIRST + 3;
|
||||
private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
|
||||
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
|
||||
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
|
||||
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
|
||||
menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
|
||||
menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
|
||||
|
||||
/**** Is this the mechanism to extend with filter effects?
|
||||
Intent intent = new Intent(null, getIntent().getData());
|
||||
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
|
||||
menu.addIntentOptions(
|
||||
Menu.ALTERNATIVE, 0,
|
||||
new ComponentName(this, NotesList.class),
|
||||
null, intent, 0, null);
|
||||
*****/
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
mPaint.setXfermode(null);
|
||||
mPaint.setAlpha(0xFF);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case COLOR_MENU_ID:
|
||||
new ColorPickerDialog(this, this, mPaint.getColor()).show();
|
||||
return true;
|
||||
case EMBOSS_MENU_ID:
|
||||
if (mPaint.getMaskFilter() != mEmboss) {
|
||||
mPaint.setMaskFilter(mEmboss);
|
||||
} else {
|
||||
mPaint.setMaskFilter(null);
|
||||
}
|
||||
return true;
|
||||
case BLUR_MENU_ID:
|
||||
if (mPaint.getMaskFilter() != mBlur) {
|
||||
mPaint.setMaskFilter(mBlur);
|
||||
} else {
|
||||
mPaint.setMaskFilter(null);
|
||||
}
|
||||
return true;
|
||||
case ERASE_MENU_ID:
|
||||
mPaint.setXfermode(new PorterDuffXfermode(
|
||||
PorterDuff.Mode.CLEAR));
|
||||
return true;
|
||||
case SRCATOP_MENU_ID:
|
||||
mPaint.setXfermode(new PorterDuffXfermode(
|
||||
PorterDuff.Mode.SRC_ATOP));
|
||||
mPaint.setAlpha(0x80);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view
|
||||
* that uses OpenGL drawing into a dedicated surface.
|
||||
*/
|
||||
public class GLSurfaceViewActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create our Preview view and set it as the content of our
|
||||
// Activity
|
||||
mGLSurfaceView = new GLSurfaceView(this);
|
||||
mGLSurfaceView.setRenderer(new CubeRenderer(false));
|
||||
setContentView(mGLSurfaceView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
// Need the following import to get access to the app resources, since this
|
||||
// class is in a sub-package.
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class GradientDrawable1 extends GraphicsActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.shape_drawable_1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
|
||||
class GraphicsActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(View view) {
|
||||
if (false) { // set to true to test Picture
|
||||
ViewGroup vg = new PictureLayout(this);
|
||||
vg.addView(view);
|
||||
view = vg;
|
||||
}
|
||||
|
||||
super.setContentView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.*;
|
||||
|
||||
public class Layers extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG |
|
||||
Canvas.CLIP_SAVE_FLAG |
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
|
||||
Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
|
||||
Canvas.CLIP_TO_LAYER_SAVE_FLAG;
|
||||
|
||||
private Paint mPaint;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.translate(10, 10);
|
||||
|
||||
canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
|
||||
|
||||
mPaint.setColor(Color.RED);
|
||||
canvas.drawCircle(75, 75, 75, mPaint);
|
||||
mPaint.setColor(Color.BLUE);
|
||||
canvas.drawCircle(125, 125, 75, mPaint);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
public class MeasureText extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static final int WIDTH = 50;
|
||||
private static final int HEIGHT = 50;
|
||||
private static final int STRIDE = 64; // must be >= WIDTH
|
||||
|
||||
private static int[] createColors() {
|
||||
int[] colors = new int[STRIDE * HEIGHT];
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
int r = x * 255 / (WIDTH - 1);
|
||||
int g = y * 255 / (HEIGHT - 1);
|
||||
int b = 255 - Math.min(r, g);
|
||||
int a = Math.max(r, g);
|
||||
colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint;
|
||||
private float mOriginX = 10;
|
||||
private float mOriginY = 80;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setStrokeWidth(5);
|
||||
mPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
mPaint.setTextSize(64);
|
||||
mPaint.setTypeface(Typeface.create(Typeface.SERIF,
|
||||
Typeface.ITALIC));
|
||||
}
|
||||
|
||||
private void showText(Canvas canvas, String text, Paint.Align align) {
|
||||
// mPaint.setTextAlign(align);
|
||||
|
||||
Rect bounds = new Rect();
|
||||
float[] widths = new float[text.length()];
|
||||
|
||||
int count = mPaint.getTextWidths(text, 0, text.length(), widths);
|
||||
float w = mPaint.measureText(text, 0, text.length());
|
||||
mPaint.getTextBounds(text, 0, text.length(), bounds);
|
||||
|
||||
mPaint.setColor(0xFF88FF88);
|
||||
canvas.drawRect(bounds, mPaint);
|
||||
mPaint.setColor(Color.BLACK);
|
||||
canvas.drawText(text, 0, 0, mPaint);
|
||||
|
||||
float[] pts = new float[2 + count*2];
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
pts[0] = x;
|
||||
pts[1] = y;
|
||||
for (int i = 0; i < count; i++) {
|
||||
x += widths[i];
|
||||
pts[2 + i*2] = x;
|
||||
pts[2 + i*2 + 1] = y;
|
||||
}
|
||||
mPaint.setColor(Color.RED);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawLine(0, 0, w, 0, mPaint);
|
||||
mPaint.setStrokeWidth(5);
|
||||
canvas.drawPoints(pts, 0, (count + 1) << 1, mPaint);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.translate(mOriginX, mOriginY);
|
||||
|
||||
showText(canvas, "Measure", Paint.Align.LEFT);
|
||||
canvas.translate(0, 80);
|
||||
showText(canvas, "wiggy!", Paint.Align.CENTER);
|
||||
canvas.translate(0, 80);
|
||||
showText(canvas, "Text", Paint.Align.RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class PathEffects extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint;
|
||||
private Path mPath;
|
||||
private PathEffect[] mEffects;
|
||||
private int[] mColors;
|
||||
private float mPhase;
|
||||
|
||||
private static PathEffect makeDash(float phase) {
|
||||
return new DashPathEffect(new float[] { 15, 5, 8, 5 }, phase);
|
||||
}
|
||||
|
||||
private static void makeEffects(PathEffect[] e, float phase) {
|
||||
e[0] = null; // no effect
|
||||
e[1] = new CornerPathEffect(10);
|
||||
e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
|
||||
e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
|
||||
PathDashPathEffect.Style.ROTATE);
|
||||
e[4] = new ComposePathEffect(e[2], e[1]);
|
||||
e[5] = new ComposePathEffect(e[3], e[1]);
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setStrokeWidth(6);
|
||||
|
||||
mPath = makeFollowPath();
|
||||
|
||||
mEffects = new PathEffect[6];
|
||||
|
||||
mColors = new int[] { Color.BLACK, Color.RED, Color.BLUE,
|
||||
Color.GREEN, Color.MAGENTA, Color.BLACK
|
||||
};
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
RectF bounds = new RectF();
|
||||
mPath.computeBounds(bounds, false);
|
||||
canvas.translate(10 - bounds.left, 10 - bounds.top);
|
||||
|
||||
makeEffects(mEffects, mPhase);
|
||||
mPhase += 1;
|
||||
invalidate();
|
||||
|
||||
for (int i = 0; i < mEffects.length; i++) {
|
||||
mPaint.setPathEffect(mEffects[i]);
|
||||
mPaint.setColor(mColors[i]);
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
canvas.translate(0, 28);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
mPath = makeFollowPath();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
private static Path makeFollowPath() {
|
||||
Path p = new Path();
|
||||
p.moveTo(0, 0);
|
||||
for (int i = 1; i <= 15; i++) {
|
||||
p.lineTo(i*20, (float)Math.random() * 35);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private static Path makePathDash() {
|
||||
Path p = new Path();
|
||||
p.moveTo(4, 0);
|
||||
p.lineTo(0, -4);
|
||||
p.lineTo(8, -4);
|
||||
p.lineTo(12, 0);
|
||||
p.lineTo(8, 4);
|
||||
p.lineTo(0, 4);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
// Need the following import to get access to the app resources, since this
|
||||
// class is in a sub-package.
|
||||
//import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class PathFillTypes extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private Path mPath;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mPath = new Path();
|
||||
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
|
||||
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
|
||||
}
|
||||
|
||||
private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
|
||||
Paint paint) {
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
canvas.clipRect(0, 0, 120, 120);
|
||||
canvas.drawColor(Color.WHITE);
|
||||
mPath.setFillType(ft);
|
||||
canvas.drawPath(mPath, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.drawColor(0xFFCCCCCC);
|
||||
|
||||
canvas.translate(20, 20);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
|
||||
showPath(canvas, 160, 0, Path.FillType.EVEN_ODD, paint);
|
||||
showPath(canvas, 0, 160, Path.FillType.INVERSE_WINDING, paint);
|
||||
showPath(canvas, 160, 160, Path.FillType.INVERSE_EVEN_ODD, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.*;
|
||||
|
||||
public class Patterns extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static Bitmap makeBitmap1() {
|
||||
Bitmap bm = Bitmap.createBitmap(40, 40, Bitmap.Config.RGB_565);
|
||||
Canvas c = new Canvas(bm);
|
||||
c.drawColor(Color.RED);
|
||||
Paint p = new Paint();
|
||||
p.setColor(Color.BLUE);
|
||||
c.drawRect(5, 5, 35, 35, p);
|
||||
return bm;
|
||||
}
|
||||
|
||||
private static Bitmap makeBitmap2() {
|
||||
Bitmap bm = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(bm);
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
p.setColor(Color.GREEN);
|
||||
p.setAlpha(0xCC);
|
||||
c.drawCircle(32, 32, 27, p);
|
||||
return bm;
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private final Shader mShader1;
|
||||
private final Shader mShader2;
|
||||
private final Paint mPaint;
|
||||
private final DrawFilter mFastDF;
|
||||
|
||||
private float mTouchStartX;
|
||||
private float mTouchStartY;
|
||||
private float mTouchCurrX;
|
||||
private float mTouchCurrY;
|
||||
private DrawFilter mDF;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mFastDF = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG |
|
||||
Paint.DITHER_FLAG,
|
||||
0);
|
||||
|
||||
mShader1 = new BitmapShader(makeBitmap1(), Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
mShader2 = new BitmapShader(makeBitmap2(), Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
|
||||
Matrix m = new Matrix();
|
||||
m.setRotate(30);
|
||||
mShader2.setLocalMatrix(m);
|
||||
|
||||
mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.setDrawFilter(mDF);
|
||||
|
||||
mPaint.setShader(mShader1);
|
||||
canvas.drawPaint(mPaint);
|
||||
|
||||
canvas.translate(mTouchCurrX - mTouchStartX,
|
||||
mTouchCurrY - mTouchStartY);
|
||||
|
||||
mPaint.setShader(mShader2);
|
||||
canvas.drawPaint(mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mTouchStartX = mTouchCurrX = x;
|
||||
mTouchStartY = mTouchCurrY = y;
|
||||
mDF = mFastDF;
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mTouchCurrX = x;
|
||||
mTouchCurrY = y;
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
mDF = null;
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
|
||||
|
||||
public class PictureLayout extends ViewGroup {
|
||||
private final Picture mPicture = new Picture();
|
||||
|
||||
public PictureLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PictureLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child) {
|
||||
if (getChildCount() > 1) {
|
||||
throw new IllegalStateException("PictureLayout can host only one direct child");
|
||||
}
|
||||
|
||||
super.addView(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index) {
|
||||
if (getChildCount() > 1) {
|
||||
throw new IllegalStateException("PictureLayout can host only one direct child");
|
||||
}
|
||||
|
||||
super.addView(child, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, LayoutParams params) {
|
||||
if (getChildCount() > 1) {
|
||||
throw new IllegalStateException("PictureLayout can host only one direct child");
|
||||
}
|
||||
|
||||
super.addView(child, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, LayoutParams params) {
|
||||
if (getChildCount() > 1) {
|
||||
throw new IllegalStateException("PictureLayout can host only one direct child");
|
||||
}
|
||||
|
||||
super.addView(child, index, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateDefaultLayoutParams() {
|
||||
return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int count = getChildCount();
|
||||
|
||||
int maxHeight = 0;
|
||||
int maxWidth = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
measureChild(child, widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
maxWidth += getPaddingLeft() + getPaddingRight();
|
||||
maxHeight += getPaddingTop() + getPaddingBottom();
|
||||
|
||||
Drawable drawable = getBackground();
|
||||
if (drawable != null) {
|
||||
maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
|
||||
maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
|
||||
}
|
||||
|
||||
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
|
||||
resolveSize(maxHeight, heightMeasureSpec));
|
||||
}
|
||||
|
||||
private void drawPict(Canvas canvas, int x, int y, int w, int h,
|
||||
float sx, float sy) {
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
canvas.clipRect(0, 0, w, h);
|
||||
canvas.scale(0.5f, 0.5f);
|
||||
canvas.scale(sx, sy, w, h);
|
||||
canvas.drawPicture(mPicture);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
|
||||
mPicture.endRecording();
|
||||
|
||||
int x = getWidth()/2;
|
||||
int y = getHeight()/2;
|
||||
|
||||
if (false) {
|
||||
canvas.drawPicture(mPicture);
|
||||
} else {
|
||||
drawPict(canvas, 0, 0, x, y, 1, 1);
|
||||
drawPict(canvas, x, 0, x, y, -1, 1);
|
||||
drawPict(canvas, 0, y, x, y, 1, -1);
|
||||
drawPict(canvas, x, y, x, y, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
|
||||
location[0] = getLeft();
|
||||
location[1] = getTop();
|
||||
dirty.set(0, 0, getWidth(), getHeight());
|
||||
return getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
final int count = super.getChildCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
final int childLeft = getPaddingLeft();
|
||||
final int childTop = getPaddingTop();
|
||||
child.layout(childLeft, childTop,
|
||||
childLeft + child.getMeasuredWidth(),
|
||||
childTop + child.getMeasuredHeight());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class Pictures extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Picture mPicture;
|
||||
private Drawable mDrawable;
|
||||
|
||||
static void drawSomething(Canvas canvas) {
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
p.setColor(0x88FF0000);
|
||||
canvas.drawCircle(50, 50, 40, p);
|
||||
|
||||
p.setColor(Color.GREEN);
|
||||
p.setTextSize(30);
|
||||
canvas.drawText("Pictures", 60, 60, p);
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mPicture = new Picture();
|
||||
drawSomething(mPicture.beginRecording(200, 100));
|
||||
mPicture.endRecording();
|
||||
|
||||
mDrawable = new PictureDrawable(mPicture);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.drawPicture(mPicture);
|
||||
|
||||
canvas.drawPicture(mPicture, new RectF(0, 100, getWidth(), 200));
|
||||
|
||||
mDrawable.setBounds(0, 200, getWidth(), 300);
|
||||
mDrawable.draw(canvas);
|
||||
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
mPicture.writeToStream(os);
|
||||
InputStream is = new ByteArrayInputStream(os.toByteArray());
|
||||
canvas.translate(0, 300);
|
||||
canvas.drawPicture(Picture.createFromStream(is));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
// Need the following import to get access to the app resources, since this
|
||||
// class is in a sub-package.
|
||||
//import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class PolyToPoly extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private Matrix mMatrix = new Matrix();
|
||||
private Paint.FontMetrics mFontMetrics;
|
||||
|
||||
private void doDraw(Canvas canvas, float src[], float dst[]) {
|
||||
canvas.save();
|
||||
mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
|
||||
canvas.concat(mMatrix);
|
||||
|
||||
mPaint.setColor(Color.GRAY);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
canvas.drawRect(0, 0, 64, 64, mPaint);
|
||||
canvas.drawLine(0, 0, 64, 64, mPaint);
|
||||
canvas.drawLine(0, 64, 64, 0, mPaint);
|
||||
|
||||
mPaint.setColor(Color.RED);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
// how to draw the text center on our square
|
||||
// centering in X is easy... use alignment (and X at midpoint)
|
||||
float x = 64/2;
|
||||
// centering in Y, we need to measure ascent/descent first
|
||||
float y = 64/2 - (mFontMetrics.ascent + mFontMetrics.descent)/2;
|
||||
canvas.drawText(src.length/2 + "", x, y, mPaint);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
// for when the style is STROKE
|
||||
mPaint.setStrokeWidth(4);
|
||||
// for when we draw text
|
||||
mPaint.setTextSize(40);
|
||||
mPaint.setTextAlign(Paint.Align.CENTER);
|
||||
mFontMetrics = mPaint.getFontMetrics();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 10);
|
||||
// translate (1 point)
|
||||
doDraw(canvas, new float[] { 0, 0 }, new float[] { 5, 5 });
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 10);
|
||||
// rotate/uniform-scale (2 points)
|
||||
doDraw(canvas, new float[] { 32, 32, 64, 32 },
|
||||
new float[] { 32, 32, 64, 48 });
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 110);
|
||||
// rotate/skew (3 points)
|
||||
doDraw(canvas, new float[] { 0, 0, 64, 0, 0, 64 },
|
||||
new float[] { 0, 0, 96, 0, 24, 64 });
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 110);
|
||||
// perspective (4 points)
|
||||
doDraw(canvas, new float[] { 0, 0, 64, 0, 64, 64, 0, 64 },
|
||||
new float[] { 0, 0, 96, 0, 64, 96, 0, 64 });
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class ProxyDrawable extends Drawable {
|
||||
|
||||
private Drawable mProxy;
|
||||
private boolean mMutated;
|
||||
|
||||
public ProxyDrawable(Drawable target) {
|
||||
mProxy = target;
|
||||
}
|
||||
|
||||
public Drawable getProxy() {
|
||||
return mProxy;
|
||||
}
|
||||
|
||||
public void setProxy(Drawable proxy) {
|
||||
if (proxy != this) {
|
||||
mProxy = proxy;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mProxy != null) {
|
||||
mProxy.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mProxy != null ? mProxy.getIntrinsicWidth() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mProxy != null ? mProxy.getIntrinsicHeight() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return mProxy != null ? mProxy.getOpacity() : PixelFormat.TRANSPARENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterBitmap(boolean filter) {
|
||||
if (mProxy != null) {
|
||||
mProxy.setFilterBitmap(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDither(boolean dither) {
|
||||
if (mProxy != null) {
|
||||
mProxy.setDither(dither);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
if (mProxy != null) {
|
||||
mProxy.setColorFilter(colorFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
if (mProxy != null) {
|
||||
mProxy.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable mutate() {
|
||||
if (mProxy != null && !mMutated && super.mutate() == this) {
|
||||
mProxy.mutate();
|
||||
mMutated = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class Regions extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private final Paint mPaint = new Paint();
|
||||
private final Rect mRect1 = new Rect();
|
||||
private final Rect mRect2 = new Rect();
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setTextSize(16);
|
||||
mPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
mRect1.set(10, 10, 100, 80);
|
||||
mRect2.set(50, 50, 130, 110);
|
||||
}
|
||||
|
||||
private void drawOriginalRects(Canvas canvas, int alpha) {
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setColor(Color.RED);
|
||||
mPaint.setAlpha(alpha);
|
||||
drawCentered(canvas, mRect1, mPaint);
|
||||
mPaint.setColor(Color.BLUE);
|
||||
mPaint.setAlpha(alpha);
|
||||
drawCentered(canvas, mRect2, mPaint);
|
||||
|
||||
// restore style
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
private void drawRgn(Canvas canvas, int color, String str, Region.Op op) {
|
||||
if (str != null) {
|
||||
mPaint.setColor(Color.BLACK);
|
||||
canvas.drawText(str, 80, 24, mPaint);
|
||||
}
|
||||
|
||||
Region rgn = new Region();
|
||||
rgn.set(mRect1);
|
||||
rgn.op(mRect2, op);
|
||||
|
||||
mPaint.setColor(color);
|
||||
RegionIterator iter = new RegionIterator(rgn);
|
||||
Rect r = new Rect();
|
||||
|
||||
canvas.translate(0, 30);
|
||||
mPaint.setColor(color);
|
||||
while (iter.next(r)) {
|
||||
canvas.drawRect(r, mPaint);
|
||||
}
|
||||
drawOriginalRects(canvas, 0x80);
|
||||
}
|
||||
|
||||
private static void drawCentered(Canvas c, Rect r, Paint p) {
|
||||
float inset = p.getStrokeWidth() * 0.5f;
|
||||
if (inset == 0) { // catch hairlines
|
||||
inset = 0.5f;
|
||||
}
|
||||
c.drawRect(r.left + inset, r.top + inset,
|
||||
r.right - inset, r.bottom - inset, p);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.GRAY);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(80, 5);
|
||||
drawOriginalRects(canvas, 0xFF);
|
||||
canvas.restore();
|
||||
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(0, 140);
|
||||
drawRgn(canvas, Color.RED, "Union", Region.Op.UNION);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(0, 280);
|
||||
drawRgn(canvas, Color.BLUE, "Xor", Region.Op.XOR);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 140);
|
||||
drawRgn(canvas, Color.GREEN, "Difference", Region.Op.DIFFERENCE);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(160, 280);
|
||||
drawRgn(canvas, Color.WHITE, "Intersect", Region.Op.INTERSECT);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
public class RoundRects extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Path mPath;
|
||||
private Paint mPaint;
|
||||
private Rect mRect;
|
||||
private GradientDrawable mDrawable;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPath = new Path();
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mRect = new Rect(0, 0, 120, 120);
|
||||
|
||||
mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR,
|
||||
new int[] { 0xFFFF0000, 0xFF00FF00,
|
||||
0xFF0000FF });
|
||||
mDrawable.setShape(GradientDrawable.RECTANGLE);
|
||||
mDrawable.setGradientRadius((float)(Math.sqrt(2) * 60));
|
||||
}
|
||||
|
||||
static void setCornerRadii(GradientDrawable drawable, float r0,
|
||||
float r1, float r2, float r3) {
|
||||
drawable.setCornerRadii(new float[] { r0, r0, r1, r1,
|
||||
r2, r2, r3, r3 });
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
|
||||
mDrawable.setBounds(mRect);
|
||||
|
||||
float r = 16;
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
|
||||
setCornerRadii(mDrawable, r, r, 0, 0);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10 + mRect.width() + 10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
|
||||
setCornerRadii(mDrawable, 0, 0, r, r);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.translate(0, mRect.height() + 10);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
|
||||
setCornerRadii(mDrawable, 0, r, r, 0);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10 + mRect.width() + 10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
|
||||
setCornerRadii(mDrawable, r, 0, 0, r);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.translate(0, mRect.height() + 10);
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
|
||||
setCornerRadii(mDrawable, r, 0, r, 0);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(10 + mRect.width() + 10, 10);
|
||||
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
|
||||
setCornerRadii(mDrawable, 0, r, 0, r);
|
||||
mDrawable.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class ScaleToFit extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mHairPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private final RectF mSrcR = new RectF();
|
||||
|
||||
private static final Matrix.ScaleToFit[] sFits =
|
||||
new Matrix.ScaleToFit[] {
|
||||
Matrix.ScaleToFit.FILL,
|
||||
Matrix.ScaleToFit.START,
|
||||
Matrix.ScaleToFit.CENTER,
|
||||
Matrix.ScaleToFit.END
|
||||
};
|
||||
|
||||
private static final String[] sFitLabels = new String[] {
|
||||
"FILL", "START", "CENTER", "END"
|
||||
};
|
||||
|
||||
private static final int[] sSrcData = new int[] {
|
||||
80, 40, Color.RED,
|
||||
40, 80, Color.GREEN,
|
||||
30, 30, Color.BLUE,
|
||||
80, 80, Color.BLACK
|
||||
};
|
||||
private static final int N = 4;
|
||||
|
||||
private static final int WIDTH = 52;
|
||||
private static final int HEIGHT = 52;
|
||||
private final RectF mDstR = new RectF(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
mHairPaint.setStyle(Paint.Style.STROKE);
|
||||
mLabelPaint.setTextSize(16);
|
||||
}
|
||||
|
||||
private void setSrcR(int index) {
|
||||
int w = sSrcData[index*3 + 0];
|
||||
int h = sSrcData[index*3 + 1];
|
||||
mSrcR.set(0, 0, w, h);
|
||||
}
|
||||
|
||||
private void drawSrcR(Canvas canvas, int index) {
|
||||
mPaint.setColor(sSrcData[index*3 + 2]);
|
||||
canvas.drawOval(mSrcR, mPaint);
|
||||
}
|
||||
|
||||
private void drawFit(Canvas canvas, int index, Matrix.ScaleToFit stf) {
|
||||
canvas.save();
|
||||
|
||||
setSrcR(index);
|
||||
mMatrix.setRectToRect(mSrcR, mDstR, stf);
|
||||
canvas.concat(mMatrix);
|
||||
drawSrcR(canvas, index);
|
||||
|
||||
canvas.restore();
|
||||
|
||||
canvas.drawRect(mDstR, mHairPaint);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.translate(10, 10);
|
||||
|
||||
canvas.save();
|
||||
for (int i = 0; i < N; i++) {
|
||||
setSrcR(i);
|
||||
drawSrcR(canvas, i);
|
||||
canvas.translate(mSrcR.width() + 15, 0);
|
||||
}
|
||||
canvas.restore();
|
||||
|
||||
canvas.translate(0, 100);
|
||||
for (int j = 0; j < sFits.length; j++) {
|
||||
canvas.save();
|
||||
for (int i = 0; i < N; i++) {
|
||||
drawFit(canvas, i, sFits[j]);
|
||||
canvas.translate(mDstR.width() + 8, 0);
|
||||
}
|
||||
canvas.drawText(sFitLabels[j], 0, HEIGHT*2/3, mLabelPaint);
|
||||
canvas.restore();
|
||||
canvas.translate(0, 80);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.hardware.SensorListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
public class SensorTest extends GraphicsActivity {
|
||||
|
||||
private SensorManager mSensorManager;
|
||||
private SampleView mView;
|
||||
private float[] mValues;
|
||||
|
||||
private static class RunAve {
|
||||
private final float[] mWeights;
|
||||
private final float mWeightScale;
|
||||
private final float[] mSamples;
|
||||
private final int mDepth;
|
||||
private int mCurr;
|
||||
|
||||
public RunAve(float[] weights) {
|
||||
mWeights = weights;
|
||||
|
||||
float sum = 0;
|
||||
for (int i = 0; i < weights.length; i++) {
|
||||
sum += weights[i];
|
||||
}
|
||||
mWeightScale = 1 / sum;
|
||||
|
||||
mDepth = weights.length;
|
||||
mSamples = new float[mDepth];
|
||||
mCurr = 0;
|
||||
}
|
||||
|
||||
public void addSample(float value) {
|
||||
mSamples[mCurr] = value;
|
||||
mCurr = (mCurr + 1) % mDepth;
|
||||
}
|
||||
|
||||
public float computeAve() {
|
||||
final int depth = mDepth;
|
||||
int index = mCurr;
|
||||
float sum = 0;
|
||||
for (int i = 0; i < depth; i++) {
|
||||
sum += mWeights[i] * mSamples[index];
|
||||
index -= 1;
|
||||
if (index < 0) {
|
||||
index = depth - 1;
|
||||
}
|
||||
}
|
||||
return sum * mWeightScale;
|
||||
}
|
||||
};
|
||||
|
||||
private final SensorListener mListener = new SensorListener() {
|
||||
|
||||
private final float[] mScale = new float[] { 2, 2.5f, 0.5f }; // accel
|
||||
|
||||
private float[] mPrev = new float[3];
|
||||
|
||||
public void onSensorChanged(int sensor, float[] values) {
|
||||
boolean show = false;
|
||||
float[] diff = new float[3];
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
diff[i] = Math.round(mScale[i] * (values[i] - mPrev[i]) * 0.45f);
|
||||
if (Math.abs(diff[i]) > 0) {
|
||||
show = true;
|
||||
}
|
||||
mPrev[i] = values[i];
|
||||
}
|
||||
|
||||
if (show) {
|
||||
// only shows if we think the delta is big enough, in an attempt
|
||||
// to detect "serious" moves left/right or up/down
|
||||
android.util.Log.e("test", "sensorChanged " + sensor + " (" + values[0] + ", " + values[1] + ", " + values[2] + ")"
|
||||
+ " diff(" + diff[0] + " " + diff[1] + " " + diff[2] + ")");
|
||||
}
|
||||
|
||||
long now = android.os.SystemClock.uptimeMillis();
|
||||
if (now - mLastGestureTime > 1000) {
|
||||
mLastGestureTime = 0;
|
||||
|
||||
float x = diff[0];
|
||||
float y = diff[1];
|
||||
boolean gestX = Math.abs(x) > 3;
|
||||
boolean gestY = Math.abs(y) > 3;
|
||||
|
||||
if ((gestX || gestY) && !(gestX && gestY)) {
|
||||
if (gestX) {
|
||||
if (x < 0) {
|
||||
android.util.Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
|
||||
} else {
|
||||
android.util.Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
|
||||
}
|
||||
} else {
|
||||
if (y < -2) {
|
||||
android.util.Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
|
||||
} else {
|
||||
android.util.Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
|
||||
}
|
||||
}
|
||||
mLastGestureTime = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long mLastGestureTime;
|
||||
|
||||
public void onAccuracyChanged(int sensor, int accuracy) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
|
||||
mView = new SampleView(this);
|
||||
setContentView(mView);
|
||||
// android.util.Log.d("skia", "create " + mSensorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
int mask = 0;
|
||||
// mask |= SensorManager.SENSOR_ORIENTATION;
|
||||
mask |= SensorManager.SENSOR_ACCELEROMETER;
|
||||
|
||||
mSensorManager.registerListener(mListener, mask, SensorManager.SENSOR_DELAY_FASTEST);
|
||||
// android.util.Log.d("skia", "resume " + mSensorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
mSensorManager.unregisterListener(mListener);
|
||||
super.onStop();
|
||||
// android.util.Log.d("skia", "stop " + mSensorManager);
|
||||
}
|
||||
|
||||
private class SampleView extends View {
|
||||
private Paint mPaint = new Paint();
|
||||
private Path mPath = new Path();
|
||||
private boolean mAnimate;
|
||||
private long mNextTime;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
// Construct a wedge-shaped path
|
||||
mPath.moveTo(0, -50);
|
||||
mPath.lineTo(-20, 60);
|
||||
mPath.lineTo(0, 50);
|
||||
mPath.lineTo(20, 60);
|
||||
mPath.close();
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
|
||||
int w = canvas.getWidth();
|
||||
int h = canvas.getHeight();
|
||||
int cx = w / 2;
|
||||
int cy = h / 2;
|
||||
|
||||
canvas.translate(cx, cy);
|
||||
if (mValues != null) {
|
||||
canvas.rotate(-mValues[0]);
|
||||
}
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
mAnimate = true;
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
mAnimate = false;
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
public class ShapeDrawable1 extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private ShapeDrawable[] mDrawables;
|
||||
|
||||
private static Shader makeSweep() {
|
||||
return new SweepGradient(150, 25,
|
||||
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
|
||||
null);
|
||||
}
|
||||
|
||||
private static Shader makeLinear() {
|
||||
return new LinearGradient(0, 0, 50, 50,
|
||||
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
|
||||
null, Shader.TileMode.MIRROR);
|
||||
}
|
||||
|
||||
private static Shader makeTiling() {
|
||||
int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
|
||||
Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
|
||||
return new BitmapShader(bm, Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
}
|
||||
|
||||
private static class MyShapeDrawable extends ShapeDrawable {
|
||||
private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
public MyShapeDrawable(Shape s) {
|
||||
super(s);
|
||||
mStrokePaint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
|
||||
public Paint getStrokePaint() {
|
||||
return mStrokePaint;
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Shape s, Canvas c, Paint p) {
|
||||
s.draw(c, p);
|
||||
s.draw(c, mStrokePaint);
|
||||
}
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
|
||||
RectF inset = new RectF(6, 6, 6, 6);
|
||||
float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
|
||||
|
||||
Path path = new Path();
|
||||
path.moveTo(50, 0);
|
||||
path.lineTo(0, 50);
|
||||
path.lineTo(50, 100);
|
||||
path.lineTo(100, 50);
|
||||
path.close();
|
||||
|
||||
mDrawables = new ShapeDrawable[7];
|
||||
mDrawables[0] = new ShapeDrawable(new RectShape());
|
||||
mDrawables[1] = new ShapeDrawable(new OvalShape());
|
||||
mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
|
||||
null));
|
||||
mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
|
||||
null));
|
||||
mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
|
||||
innerR));
|
||||
mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
|
||||
mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
|
||||
|
||||
mDrawables[0].getPaint().setColor(0xFFFF0000);
|
||||
mDrawables[1].getPaint().setColor(0xFF00FF00);
|
||||
mDrawables[2].getPaint().setColor(0xFF0000FF);
|
||||
mDrawables[3].getPaint().setShader(makeSweep());
|
||||
mDrawables[4].getPaint().setShader(makeLinear());
|
||||
mDrawables[5].getPaint().setShader(makeTiling());
|
||||
mDrawables[6].getPaint().setColor(0x88FF8844);
|
||||
|
||||
PathEffect pe = new DiscretePathEffect(10, 4);
|
||||
PathEffect pe2 = new CornerPathEffect(4);
|
||||
mDrawables[3].getPaint().setPathEffect(
|
||||
new ComposePathEffect(pe2, pe));
|
||||
|
||||
MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
|
||||
msd.getStrokePaint().setStrokeWidth(4);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
|
||||
int x = 10;
|
||||
int y = 10;
|
||||
int width = 300;
|
||||
int height = 50;
|
||||
|
||||
for (Drawable dr : mDrawables) {
|
||||
dr.setBounds(x, y, x + width, y + height);
|
||||
dr.draw(canvas);
|
||||
y += height + 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
|
||||
//Need the following import to get access to the app resources, since this
|
||||
//class is in a sub-package.
|
||||
import com.example.android.apis.R;
|
||||
|
||||
/**
|
||||
* Demonstration of overlays placed on top of a SurfaceView.
|
||||
*/
|
||||
public class SurfaceViewOverlay extends Activity {
|
||||
View mVictimContainer;
|
||||
View mVictim1;
|
||||
View mVictim2;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.surface_view_overlay);
|
||||
|
||||
GLSurfaceView glSurfaceView =
|
||||
(GLSurfaceView) findViewById(R.id.glsurfaceview);
|
||||
glSurfaceView.setRenderer(new CubeRenderer(false));
|
||||
|
||||
// Find the views whose visibility will change
|
||||
mVictimContainer = findViewById(R.id.hidecontainer);
|
||||
mVictim1 = findViewById(R.id.hideme1);
|
||||
mVictim1.setOnClickListener(new HideMeListener(mVictim1));
|
||||
mVictim2 = findViewById(R.id.hideme2);
|
||||
mVictim2.setOnClickListener(new HideMeListener(mVictim2));
|
||||
|
||||
// Find our buttons
|
||||
Button visibleButton = (Button) findViewById(R.id.vis);
|
||||
Button invisibleButton = (Button) findViewById(R.id.invis);
|
||||
Button goneButton = (Button) findViewById(R.id.gone);
|
||||
|
||||
// Wire each button to a click listener
|
||||
visibleButton.setOnClickListener(mVisibleListener);
|
||||
invisibleButton.setOnClickListener(mInvisibleListener);
|
||||
goneButton.setOnClickListener(mGoneListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
class HideMeListener implements OnClickListener {
|
||||
final View mTarget;
|
||||
|
||||
HideMeListener(View target) {
|
||||
mTarget = target;
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
mTarget.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OnClickListener mVisibleListener = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mVictim1.setVisibility(View.VISIBLE);
|
||||
mVictim2.setVisibility(View.VISIBLE);
|
||||
mVictimContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
OnClickListener mInvisibleListener = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mVictim1.setVisibility(View.INVISIBLE);
|
||||
mVictim2.setVisibility(View.INVISIBLE);
|
||||
mVictimContainer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
OnClickListener mGoneListener = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mVictim1.setVisibility(View.GONE);
|
||||
mVictim2.setVisibility(View.GONE);
|
||||
mVictimContainer.setVisibility(View.GONE);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
// Need the following import to get access to the app resources, since this
|
||||
// class is in a sub-package.
|
||||
//import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class Sweep extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private float mRotate;
|
||||
private Matrix mMatrix = new Matrix();
|
||||
private Shader mShader;
|
||||
private boolean mDoTiming;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
float x = 160;
|
||||
float y = 100;
|
||||
mShader = new SweepGradient(x, y, new int[] { Color.GREEN,
|
||||
Color.RED,
|
||||
Color.BLUE,
|
||||
Color.GREEN }, null);
|
||||
mPaint.setShader(mShader);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
Paint paint = mPaint;
|
||||
float x = 160;
|
||||
float y = 100;
|
||||
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
mMatrix.setRotate(mRotate, x, y);
|
||||
mShader.setLocalMatrix(mMatrix);
|
||||
mRotate += 3;
|
||||
if (mRotate >= 360) {
|
||||
mRotate = 0;
|
||||
}
|
||||
invalidate();
|
||||
|
||||
if (mDoTiming) {
|
||||
long now = System.currentTimeMillis();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
canvas.drawCircle(x, y, 80, paint);
|
||||
}
|
||||
now = System.currentTimeMillis() - now;
|
||||
android.util.Log.d("skia", "sweep ms = " + (now/20.));
|
||||
}
|
||||
else {
|
||||
canvas.drawCircle(x, y, 80, paint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_D:
|
||||
mPaint.setDither(!mPaint.isDither());
|
||||
invalidate();
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_T:
|
||||
mDoTiming = !mDoTiming;
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
public class TextAlign extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint;
|
||||
private float mX;
|
||||
private float[] mPos;
|
||||
|
||||
private Path mPath;
|
||||
private Paint mPathPaint;
|
||||
|
||||
private static final int DY = 30;
|
||||
private static final String TEXT_L = "Left";
|
||||
private static final String TEXT_C = "Center";
|
||||
private static final String TEXT_R = "Right";
|
||||
private static final String POSTEXT = "Positioned";
|
||||
private static final String TEXTONPATH = "Along a path";
|
||||
|
||||
private static void makePath(Path p) {
|
||||
p.moveTo(10, 0);
|
||||
p.cubicTo(100, -50, 200, 50, 300, 0);
|
||||
}
|
||||
|
||||
private float[] buildTextPositions(String text, float y, Paint paint) {
|
||||
float[] widths = new float[text.length()];
|
||||
// initially get the widths for each char
|
||||
int n = paint.getTextWidths(text, widths);
|
||||
// now popuplate the array, interleaving spaces for the Y values
|
||||
float[] pos = new float[n * 2];
|
||||
float accumulatedX = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
pos[i*2 + 0] = accumulatedX;
|
||||
pos[i*2 + 1] = y;
|
||||
accumulatedX += widths[i];
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setTextSize(30);
|
||||
mPaint.setTypeface(Typeface.SERIF);
|
||||
|
||||
mPos = buildTextPositions(POSTEXT, 0, mPaint);
|
||||
|
||||
mPath = new Path();
|
||||
makePath(mPath);
|
||||
|
||||
mPathPaint = new Paint();
|
||||
mPathPaint.setAntiAlias(true);
|
||||
mPathPaint.setColor(0x800000FF);
|
||||
mPathPaint.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
Paint p = mPaint;
|
||||
float x = mX;
|
||||
float y = 0;
|
||||
float[] pos = mPos;
|
||||
|
||||
// draw the normal strings
|
||||
|
||||
p.setColor(0x80FF0000);
|
||||
canvas.drawLine(x, y, x, y+DY*3, p);
|
||||
p.setColor(Color.BLACK);
|
||||
|
||||
canvas.translate(0, DY);
|
||||
p.setTextAlign(Paint.Align.LEFT);
|
||||
canvas.drawText(TEXT_L, x, y, p);
|
||||
|
||||
canvas.translate(0, DY);
|
||||
p.setTextAlign(Paint.Align.CENTER);
|
||||
canvas.drawText(TEXT_C, x, y, p);
|
||||
|
||||
canvas.translate(0, DY);
|
||||
p.setTextAlign(Paint.Align.RIGHT);
|
||||
canvas.drawText(TEXT_R, x, y, p);
|
||||
|
||||
canvas.translate(100, DY*2);
|
||||
|
||||
// now draw the positioned strings
|
||||
|
||||
p.setColor(0xBB00FF00);
|
||||
for (int i = 0; i < pos.length/2; i++) {
|
||||
canvas.drawLine(pos[i*2+0], pos[i*2+1]-DY,
|
||||
pos[i*2+0], pos[i*2+1]+DY*2, p);
|
||||
}
|
||||
p.setColor(Color.BLACK);
|
||||
|
||||
p.setTextAlign(Paint.Align.LEFT);
|
||||
canvas.drawPosText(POSTEXT, pos, p);
|
||||
|
||||
canvas.translate(0, DY);
|
||||
p.setTextAlign(Paint.Align.CENTER);
|
||||
canvas.drawPosText(POSTEXT, pos, p);
|
||||
|
||||
canvas.translate(0, DY);
|
||||
p.setTextAlign(Paint.Align.RIGHT);
|
||||
canvas.drawPosText(POSTEXT, pos, p);
|
||||
|
||||
// now draw the text on path
|
||||
|
||||
canvas.translate(-100, DY*2);
|
||||
|
||||
canvas.drawPath(mPath, mPathPaint);
|
||||
p.setTextAlign(Paint.Align.LEFT);
|
||||
canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
|
||||
|
||||
canvas.translate(0, DY*1.5f);
|
||||
canvas.drawPath(mPath, mPathPaint);
|
||||
p.setTextAlign(Paint.Align.CENTER);
|
||||
canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
|
||||
|
||||
canvas.translate(0, DY*1.5f);
|
||||
canvas.drawPath(mPath, mPathPaint);
|
||||
p.setTextAlign(Paint.Align.RIGHT);
|
||||
canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int ow, int oh) {
|
||||
super.onSizeChanged(w, h, ow, oh);
|
||||
mX = w * 0.5f; // remember the center of the screen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
//Need the following import to get access to the app resources, since this
|
||||
//class is in a sub-package.
|
||||
|
||||
|
||||
/**
|
||||
* Demonstrates the handling of touch screen and trackball events to
|
||||
* implement a simple painting app.
|
||||
*/
|
||||
public class TouchPaint extends GraphicsActivity {
|
||||
/** Used as a pulse to gradually fade the contents of the window. */
|
||||
private static final int FADE_MSG = 1;
|
||||
|
||||
/** Menu ID for the command to clear the window. */
|
||||
private static final int CLEAR_ID = Menu.FIRST;
|
||||
/** Menu ID for the command to toggle fading. */
|
||||
private static final int FADE_ID = Menu.FIRST+1;
|
||||
|
||||
/** How often to fade the contents of the window (in ms). */
|
||||
private static final int FADE_DELAY = 100;
|
||||
|
||||
/** The view responsible for drawing the window. */
|
||||
MyView mView;
|
||||
/** Is fading mode enabled? */
|
||||
boolean mFading;
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create and attach the view that is responsible for painting.
|
||||
mView = new MyView(this);
|
||||
setContentView(mView);
|
||||
mView.requestFocus();
|
||||
|
||||
// Restore the fading option if we are being thawed from a
|
||||
// previously saved state. Note that we are not currently remembering
|
||||
// the contents of the bitmap.
|
||||
mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true;
|
||||
}
|
||||
|
||||
@Override public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.add(0, CLEAR_ID, 0, "Clear");
|
||||
menu.add(0, FADE_ID, 0, "Fade").setCheckable(true);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(FADE_ID).setChecked(mFading);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case CLEAR_ID:
|
||||
mView.clear();
|
||||
return true;
|
||||
case FADE_ID:
|
||||
mFading = !mFading;
|
||||
if (mFading) {
|
||||
startFading();
|
||||
} else {
|
||||
stopFading();
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
// If fading mode is enabled, then as long as we are resumed we want
|
||||
// to run pulse to fade the contents.
|
||||
if (mFading) {
|
||||
startFading();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
// Save away the fading state to restore if needed later. Note that
|
||||
// we do not currently save the contents of the display.
|
||||
outState.putBoolean("fading", mFading);
|
||||
}
|
||||
|
||||
@Override protected void onPause() {
|
||||
super.onPause();
|
||||
// Make sure to never run the fading pulse while we are paused or
|
||||
// stopped.
|
||||
stopFading();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start up the pulse to fade the screen, clearing any existing pulse to
|
||||
* ensure that we don't have multiple pulses running at a time.
|
||||
*/
|
||||
void startFading() {
|
||||
mHandler.removeMessages(FADE_MSG);
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the pulse to fade the screen.
|
||||
*/
|
||||
void stopFading() {
|
||||
mHandler.removeMessages(FADE_MSG);
|
||||
}
|
||||
|
||||
private Handler mHandler = new Handler() {
|
||||
@Override public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
// Upon receiving the fade pulse, we have the view perform a
|
||||
// fade and then enqueue a new message to pulse at the desired
|
||||
// next time.
|
||||
case FADE_MSG: {
|
||||
mView.fade();
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public class MyView extends View {
|
||||
private static final int FADE_ALPHA = 0x06;
|
||||
private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4;
|
||||
private Bitmap mBitmap;
|
||||
private Canvas mCanvas;
|
||||
private final Rect mRect = new Rect();
|
||||
private final Paint mPaint;
|
||||
private final Paint mFadePaint;
|
||||
private boolean mCurDown;
|
||||
private int mCurX;
|
||||
private int mCurY;
|
||||
private float mCurPressure;
|
||||
private float mCurSize;
|
||||
private int mCurWidth;
|
||||
private int mFadeSteps = MAX_FADE_STEPS;
|
||||
|
||||
public MyView(Context c) {
|
||||
super(c);
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setARGB(255, 255, 255, 255);
|
||||
mFadePaint = new Paint();
|
||||
mFadePaint.setDither(true);
|
||||
mFadePaint.setARGB(FADE_ALPHA, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (mCanvas != null) {
|
||||
mPaint.setARGB(0xff, 0, 0, 0);
|
||||
mCanvas.drawPaint(mPaint);
|
||||
invalidate();
|
||||
mFadeSteps = MAX_FADE_STEPS;
|
||||
}
|
||||
}
|
||||
|
||||
public void fade() {
|
||||
if (mCanvas != null && mFadeSteps < MAX_FADE_STEPS) {
|
||||
mCanvas.drawPaint(mFadePaint);
|
||||
invalidate();
|
||||
mFadeSteps++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onSizeChanged(int w, int h, int oldw,
|
||||
int oldh) {
|
||||
int curW = mBitmap != null ? mBitmap.getWidth() : 0;
|
||||
int curH = mBitmap != null ? mBitmap.getHeight() : 0;
|
||||
if (curW >= w && curH >= h) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (curW < w) curW = w;
|
||||
if (curH < h) curH = h;
|
||||
|
||||
Bitmap newBitmap = Bitmap.createBitmap(curW, curH,
|
||||
Bitmap.Config.RGB_565);
|
||||
Canvas newCanvas = new Canvas();
|
||||
newCanvas.setBitmap(newBitmap);
|
||||
if (mBitmap != null) {
|
||||
newCanvas.drawBitmap(mBitmap, 0, 0, null);
|
||||
}
|
||||
mBitmap = newBitmap;
|
||||
mCanvas = newCanvas;
|
||||
mFadeSteps = MAX_FADE_STEPS;
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
if (mBitmap != null) {
|
||||
canvas.drawBitmap(mBitmap, 0, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean onTrackballEvent(MotionEvent event) {
|
||||
boolean oldDown = mCurDown;
|
||||
mCurDown = true;
|
||||
int N = event.getHistorySize();
|
||||
int baseX = mCurX;
|
||||
int baseY = mCurY;
|
||||
final float scaleX = event.getXPrecision();
|
||||
final float scaleY = event.getYPrecision();
|
||||
for (int i=0; i<N; i++) {
|
||||
//Log.i("TouchPaint", "Intermediate trackball #" + i
|
||||
// + ": x=" + event.getHistoricalX(i)
|
||||
// + ", y=" + event.getHistoricalY(i));
|
||||
drawPoint(baseX+event.getHistoricalX(i)*scaleX,
|
||||
baseY+event.getHistoricalY(i)*scaleY,
|
||||
event.getHistoricalPressure(i),
|
||||
event.getHistoricalSize(i));
|
||||
}
|
||||
//Log.i("TouchPaint", "Trackball: x=" + event.getX()
|
||||
// + ", y=" + event.getY());
|
||||
drawPoint(baseX+event.getX()*scaleX, baseY+event.getY()*scaleY,
|
||||
event.getPressure(), event.getSize());
|
||||
mCurDown = oldDown;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public boolean onTouchEvent(MotionEvent event) {
|
||||
int action = event.getAction();
|
||||
mCurDown = action == MotionEvent.ACTION_DOWN
|
||||
|| action == MotionEvent.ACTION_MOVE;
|
||||
int N = event.getHistorySize();
|
||||
for (int i=0; i<N; i++) {
|
||||
//Log.i("TouchPaint", "Intermediate pointer #" + i);
|
||||
drawPoint(event.getHistoricalX(i), event.getHistoricalY(i),
|
||||
event.getHistoricalPressure(i),
|
||||
event.getHistoricalSize(i));
|
||||
}
|
||||
drawPoint(event.getX(), event.getY(), event.getPressure(),
|
||||
event.getSize());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void drawPoint(float x, float y, float pressure, float size) {
|
||||
//Log.i("TouchPaint", "Drawing: " + x + "x" + y + " p="
|
||||
// + pressure + " s=" + size);
|
||||
mCurX = (int)x;
|
||||
mCurY = (int)y;
|
||||
mCurPressure = pressure;
|
||||
mCurSize = size;
|
||||
mCurWidth = (int)(mCurSize*(getWidth()/3));
|
||||
if (mCurWidth < 1) mCurWidth = 1;
|
||||
if (mCurDown && mBitmap != null) {
|
||||
int pressureLevel = (int)(mCurPressure*255);
|
||||
mPaint.setARGB(pressureLevel, 255, 255, 255);
|
||||
mCanvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
|
||||
mRect.set(mCurX-mCurWidth-2, mCurY-mCurWidth-2,
|
||||
mCurX+mCurWidth+2, mCurY+mCurWidth+2);
|
||||
invalidate(mRect);
|
||||
}
|
||||
mFadeSteps = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view
|
||||
* that uses OpenGL drawing into a dedicated surface.
|
||||
*
|
||||
* Shows:
|
||||
* + How to redraw in response to user input.
|
||||
*/
|
||||
public class TouchRotateActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create our Preview view and set it as the content of our
|
||||
// Activity
|
||||
mGLSurfaceView = new TouchSurfaceView(this);
|
||||
setContentView(mGLSurfaceView);
|
||||
mGLSurfaceView.requestFocus();
|
||||
mGLSurfaceView.setFocusableInTouchMode(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement a simple rotation control.
|
||||
*
|
||||
*/
|
||||
class TouchSurfaceView extends GLSurfaceView {
|
||||
|
||||
public TouchSurfaceView(Context context) {
|
||||
super(context);
|
||||
mRenderer = new CubeRenderer();
|
||||
setRenderer(mRenderer);
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
}
|
||||
|
||||
@Override public boolean onTrackballEvent(MotionEvent e) {
|
||||
mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
|
||||
mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
|
||||
requestRender();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public boolean onTouchEvent(MotionEvent e) {
|
||||
float x = e.getX();
|
||||
float y = e.getY();
|
||||
switch (e.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dx = x - mPreviousX;
|
||||
float dy = y - mPreviousY;
|
||||
mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR;
|
||||
mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR;
|
||||
requestRender();
|
||||
}
|
||||
mPreviousX = x;
|
||||
mPreviousY = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a cube.
|
||||
*/
|
||||
private class CubeRenderer implements GLSurfaceView.Renderer {
|
||||
public CubeRenderer() {
|
||||
mCube = new Cube();
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
/*
|
||||
* 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(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D objects
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
gl.glRotatef(mAngleX, 0, 1, 0);
|
||||
gl.glRotatef(mAngleY, 1, 0, 0);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
// We want a depth buffer, don't care about the
|
||||
// details of the color buffer.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_DEPTH_SIZE, 16,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
* 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) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
/*
|
||||
* Some one-time OpenGL initialization can be made here
|
||||
* probably based on features of this particular context
|
||||
*/
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
GL10.GL_FASTEST);
|
||||
|
||||
|
||||
gl.glClearColor(1,1,1,1);
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
}
|
||||
private Cube mCube;
|
||||
public float mAngleX;
|
||||
public float mAngleY;
|
||||
}
|
||||
|
||||
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
|
||||
private final float TRACKBALL_SCALE_FACTOR = 36.0f;
|
||||
private CubeRenderer mRenderer;
|
||||
private float mPreviousX;
|
||||
private float mPreviousY;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper activity demonstrating the use of {@link GLSurfaceView} to
|
||||
* display translucent 3D graphics.
|
||||
*/
|
||||
public class TranslucentGLSurfaceViewActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create our Preview view and set it as the content of our
|
||||
// Activity
|
||||
mGLSurfaceView = new GLSurfaceView(this);
|
||||
// Tell the cube renderer that we want to render a translucent version
|
||||
// of the cube:
|
||||
mGLSurfaceView.setRenderer(new CubeRenderer(true));
|
||||
// Use a surface format with an Alpha channel:
|
||||
mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
|
||||
setContentView(mGLSurfaceView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class TriangleActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mGLView = new GLSurfaceView(this);
|
||||
mGLView.setRenderer(new TriangleRenderer(this));
|
||||
setContentView(mGLView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLView.onResume();
|
||||
}
|
||||
|
||||
private GLSurfaceView mGLView;
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLU;
|
||||
import android.opengl.GLUtils;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
public class TriangleRenderer implements GLSurfaceView.Renderer{
|
||||
|
||||
public TriangleRenderer(Context context) {
|
||||
mContext = context;
|
||||
mTriangle = new Triangle();
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
// We don't need a depth buffer, and don't care about our
|
||||
// color depth.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_DEPTH_SIZE, 0,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
/*
|
||||
* Some one-time OpenGL initialization can be made here
|
||||
* probably based on features of this particular context
|
||||
*/
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
GL10.GL_FASTEST);
|
||||
|
||||
gl.glClearColor(.5f, .5f, .5f, 1);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
gl.glEnable(GL10.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(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
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);
|
||||
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
|
||||
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_REPLACE);
|
||||
|
||||
InputStream is = mContext.getResources()
|
||||
.openRawResource(R.drawable.robot);
|
||||
Bitmap bitmap;
|
||||
try {
|
||||
bitmap = BitmapFactory.decodeStream(is);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch(IOException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
bitmap.recycle();
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_MODULATE);
|
||||
|
||||
/*
|
||||
* 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(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D objects
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
gl.glActiveTexture(GL10.GL_TEXTURE0);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_REPEAT);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_REPEAT);
|
||||
|
||||
long time = SystemClock.uptimeMillis() % 4000L;
|
||||
float angle = 0.090f * ((int) time);
|
||||
|
||||
gl.glRotatef(angle, 0, 0, 1.0f);
|
||||
|
||||
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(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
|
||||
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private Triangle mTriangle;
|
||||
private int mTextureID;
|
||||
}
|
||||
|
||||
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 equalateral triangle centered on the origin.
|
||||
float[] coords = {
|
||||
// X, Y, Z
|
||||
-0.5f, -0.25f, 0,
|
||||
0.5f, -0.25f, 0,
|
||||
0.0f, 0.559016994f, 0
|
||||
};
|
||||
|
||||
for (int i = 0; i < VERTS; i++) {
|
||||
for(int j = 0; j < 3; j++) {
|
||||
mFVertexBuffer.put(coords[i*3+j] * 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < VERTS; i++) {
|
||||
for(int j = 0; j < 2; j++) {
|
||||
mTexBuffer.put(coords[i*3+j] * 2.0f + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
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.glFrontFace(GL10.GL_CCW);
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
|
||||
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS,
|
||||
GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
|
||||
}
|
||||
|
||||
private final static int VERTS = 3;
|
||||
|
||||
private FloatBuffer mFVertexBuffer;
|
||||
private FloatBuffer mTexBuffer;
|
||||
private ShortBuffer mIndexBuffer;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class Typefaces extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private Typeface mFace;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
mFace = Typeface.createFromAsset(getContext().getAssets(),
|
||||
"fonts/samplefont.ttf");
|
||||
|
||||
mPaint.setTextSize(64);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
mPaint.setTypeface(null);
|
||||
canvas.drawText("Default", 10, 100, mPaint);
|
||||
mPaint.setTypeface(mFace);
|
||||
canvas.drawText("Custom", 10, 200, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
|
||||
public class UnicodeChart extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private Paint mBigCharPaint;
|
||||
private Paint mLabelPaint;
|
||||
private final char[] mChars = new char[256];
|
||||
private final float[] mPos = new float[512];
|
||||
|
||||
private int mBase;
|
||||
|
||||
private static final int XMUL = 20;
|
||||
private static final int YMUL = 28;
|
||||
private static final int YBASE = 18;
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mBigCharPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mBigCharPaint.setTextSize(15);
|
||||
mBigCharPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mLabelPaint.setTextSize(8);
|
||||
mLabelPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
// the position array is the same for all charts
|
||||
float[] pos = mPos;
|
||||
int index = 0;
|
||||
for (int col = 0; col < 16; col++) {
|
||||
final float x = col * 20 + 10;
|
||||
for (int row = 0; row < 16; row++) {
|
||||
pos[index++] = x;
|
||||
pos[index++] = row * YMUL + YBASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float computeX(int index) {
|
||||
return (index >> 4) * 20 + 10;
|
||||
}
|
||||
|
||||
private float computeY(int index) {
|
||||
return (index & 0xF) * YMUL + YMUL;
|
||||
}
|
||||
|
||||
private void drawChart(Canvas canvas, int base) {
|
||||
char[] chars = mChars;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int unichar = base + i;
|
||||
chars[i] = (char)unichar;
|
||||
|
||||
canvas.drawText(Integer.toHexString(unichar),
|
||||
computeX(i), computeY(i), mLabelPaint);
|
||||
}
|
||||
canvas.drawPosText(chars, 0, 256, mPos, mBigCharPaint);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
canvas.translate(0, 1);
|
||||
drawChart(canvas, mBase * 256);
|
||||
}
|
||||
|
||||
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
if (mBase > 0) {
|
||||
mBase -= 1;
|
||||
invalidate();
|
||||
}
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
mBase += 1;
|
||||
invalidate();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class Vertices extends GraphicsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private final Paint mPaint = new Paint();
|
||||
private final float[] mVerts = new float[10];
|
||||
private final float[] mTexs = new float[10];
|
||||
private final int[] mColors = new int[10];
|
||||
private final short[] mIndices = { 0, 1, 2, 3, 4, 1 };
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private final Matrix mInverse = new Matrix();
|
||||
|
||||
private static void setXY(float[] array, int index, float x, float y) {
|
||||
array[index*2 + 0] = x;
|
||||
array[index*2 + 1] = y;
|
||||
}
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
setFocusable(true);
|
||||
|
||||
Bitmap bm = BitmapFactory.decodeResource(getResources(),
|
||||
R.drawable.beach);
|
||||
Shader s = new BitmapShader(bm, Shader.TileMode.CLAMP,
|
||||
Shader.TileMode.CLAMP);
|
||||
mPaint.setShader(s);
|
||||
|
||||
float w = bm.getWidth();
|
||||
float h = bm.getHeight();
|
||||
// construct our mesh
|
||||
setXY(mTexs, 0, w/2, h/2);
|
||||
setXY(mTexs, 1, 0, 0);
|
||||
setXY(mTexs, 2, w, 0);
|
||||
setXY(mTexs, 3, w, h);
|
||||
setXY(mTexs, 4, 0, h);
|
||||
|
||||
setXY(mVerts, 0, w/2, h/2);
|
||||
setXY(mVerts, 1, 0, 0);
|
||||
setXY(mVerts, 2, w, 0);
|
||||
setXY(mVerts, 3, w, h);
|
||||
setXY(mVerts, 4, 0, h);
|
||||
|
||||
mMatrix.setScale(0.8f, 0.8f);
|
||||
mMatrix.preTranslate(20, 20);
|
||||
mMatrix.invert(mInverse);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(0xFFCCCCCC);
|
||||
canvas.save();
|
||||
canvas.concat(mMatrix);
|
||||
|
||||
canvas.drawVertices(Canvas.VertexMode.TRIANGLE_FAN, 10, mVerts, 0,
|
||||
mTexs, 0, null, 0, null, 0, 0, mPaint);
|
||||
|
||||
canvas.translate(0, 240);
|
||||
canvas.drawVertices(Canvas.VertexMode.TRIANGLE_FAN, 10, mVerts, 0,
|
||||
mTexs, 0, null, 0, mIndices, 0, 6, mPaint);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override public boolean onTouchEvent(MotionEvent event) {
|
||||
float[] pt = { event.getX(), event.getY() };
|
||||
mInverse.mapPoints(pt);
|
||||
setXY(mVerts, 0, pt[0], pt[1]);
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.Xfermode;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class Xfermodes extends GraphicsActivity {
|
||||
|
||||
// create a bitmap with a circle, used for the "dst" image
|
||||
static Bitmap makeDst(int w, int h) {
|
||||
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(bm);
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
p.setColor(0xFFFFCC44);
|
||||
c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
|
||||
return bm;
|
||||
}
|
||||
|
||||
// create a bitmap with a rect, used for the "src" image
|
||||
static Bitmap makeSrc(int w, int h) {
|
||||
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(bm);
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
p.setColor(0xFF66AAFF);
|
||||
c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
|
||||
return bm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(new SampleView(this));
|
||||
}
|
||||
|
||||
private static class SampleView extends View {
|
||||
private static final int W = 64;
|
||||
private static final int H = 64;
|
||||
private static final int ROW_MAX = 4; // number of samples per row
|
||||
|
||||
private Bitmap mSrcB;
|
||||
private Bitmap mDstB;
|
||||
private Shader mBG; // background checker-board pattern
|
||||
|
||||
private static final Xfermode[] sModes = {
|
||||
new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SRC),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DST),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.XOR),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
|
||||
new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
|
||||
};
|
||||
|
||||
private static final String[] sLabels = {
|
||||
"Clear", "Src", "Dst", "SrcOver",
|
||||
"DstOver", "SrcIn", "DstIn", "SrcOut",
|
||||
"DstOut", "SrcATop", "DstATop", "Xor",
|
||||
"Darken", "Lighten", "Multiply", "Screen"
|
||||
};
|
||||
|
||||
public SampleView(Context context) {
|
||||
super(context);
|
||||
|
||||
mSrcB = makeSrc(W, H);
|
||||
mDstB = makeDst(W, H);
|
||||
|
||||
// make a ckeckerboard pattern
|
||||
Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
|
||||
0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,
|
||||
Bitmap.Config.RGB_565);
|
||||
mBG = new BitmapShader(bm,
|
||||
Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
Matrix m = new Matrix();
|
||||
m.setScale(6, 6);
|
||||
mBG.setLocalMatrix(m);
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Color.WHITE);
|
||||
|
||||
Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
labelP.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setFilterBitmap(false);
|
||||
|
||||
canvas.translate(15, 35);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (int i = 0; i < sModes.length; i++) {
|
||||
// draw the border
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setShader(null);
|
||||
canvas.drawRect(x - 0.5f, y - 0.5f,
|
||||
x + W + 0.5f, y + H + 0.5f, paint);
|
||||
|
||||
// draw the checker-board pattern
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setShader(mBG);
|
||||
canvas.drawRect(x, y, x + W, y + H, paint);
|
||||
|
||||
// draw the src/dst example into our offscreen bitmap
|
||||
int sc = canvas.saveLayer(x, y, x + W, y + H, null,
|
||||
Canvas.MATRIX_SAVE_FLAG |
|
||||
Canvas.CLIP_SAVE_FLAG |
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
|
||||
Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
|
||||
Canvas.CLIP_TO_LAYER_SAVE_FLAG);
|
||||
canvas.translate(x, y);
|
||||
canvas.drawBitmap(mDstB, 0, 0, paint);
|
||||
paint.setXfermode(sModes[i]);
|
||||
canvas.drawBitmap(mSrcB, 0, 0, paint);
|
||||
paint.setXfermode(null);
|
||||
canvas.restoreToCount(sc);
|
||||
|
||||
// draw the label
|
||||
canvas.drawText(sLabels[i],
|
||||
x + W/2, y - labelP.getTextSize()/2, labelP);
|
||||
|
||||
x += W + 10;
|
||||
|
||||
// wrap around when we've drawn enough for one row
|
||||
if ((i % ROW_MAX) == ROW_MAX - 1) {
|
||||
x = 0;
|
||||
y += H + 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
<h3>Drawable</h3>
|
||||
<dl>
|
||||
<dt><a href="ShapeDrawable1.html">ShapeDrawable</a></dt>
|
||||
<dd>Demonstrates creating Drawables in XML.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>OpenGL|ES</h3>
|
||||
<dl>
|
||||
<dt><a href="CameraPreview.html">CameraPreview</a></dt>
|
||||
<dd> Demonstrates capturing the image stream from the camera, drawing to a surface (extending SurfaceView) on a separate thread (extending Thread).</dd>
|
||||
|
||||
<dt><a href="GLSurfaceViewActivity.html">GL SurfaceView</a></dt>
|
||||
<dd>Demonstrates how to perform OpenGL rendering in to a SurfaceView.
|
||||
<dl>
|
||||
<dt>Code:
|
||||
<dd> <a href="GLSurfaceViewActivity.html">GLSurfaceViewActivity.java</a>,
|
||||
<a href="GLSurfaceView.html">GLSurfaceView.java</a>
|
||||
<dt>Layout:
|
||||
<dd> <a href="{@docRoot}samples/ApiDemos/res/layout/hello_world.html">
|
||||
hello_world.xml</a>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="PolyToPoly.html">PolyToPoly</a></dt>
|
||||
<dd>Demonstrates calling the <a href="@{docRoot}reference/android/graphics/Matrix.html#setPolyToPoly(float[],%20int,%20float[],%20int,%20int)">Matrix.setPolyToPoly()</a> method to translate coordinates on a canvas to a new perspective (used to simulate perspective). </dd>
|
||||
|
||||
<dt><a href="DrawPoints.html">DrawPoints</a></dt>
|
||||
<dd>Demonstrates using the <a href="android.graphics.Paint">Paint</a> and <a href="android.graphics.Canvas">Canvas</a> objects to draw random points on the screen, with different colors and strokes. </dd>
|
||||
|
||||
<dt><a href="PathEffects.html">PathEffects</a></dt>
|
||||
<dd> Demonstrates the use of <a href="android.graphics.Path">Path</a> and various <a href="android.graphics.PathEffect">PathEffect</a> subclasses. </dd>
|
||||
|
||||
<dt><a href="SurfaceViewOverlay.html">SurfaceView Overlay</a></dt>
|
||||
<dd>Shows how you can place overlays on top of a SurfaceView.
|
||||
<dl>
|
||||
<dt>Code:
|
||||
<dd> <a href="SurfaceViewOverlay.html">SurfaceViewOverlay.java</a>,
|
||||
<a href="GLSurfaceView.html">GLSurfaceView.java</a>
|
||||
<dt>Layout:
|
||||
<dd> <a href="{@docRoot}samples/ApiDemos/res/layout/surface_view_overlay.html">
|
||||
surface_view_overlay.xml</a>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="TouchPaint.html">TouchPaint</a></dt>
|
||||
<dd> Demonstrates the handling of touch screen events to implement a simple painting app. </dd>
|
||||
</dl>
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
|
||||
public class Cube extends GLShape {
|
||||
|
||||
public Cube(GLWorld world, float left, float bottom, float back, float right, float top, float front) {
|
||||
super(world);
|
||||
GLVertex leftBottomBack = addVertex(left, bottom, back);
|
||||
GLVertex rightBottomBack = addVertex(right, bottom, back);
|
||||
GLVertex leftTopBack = addVertex(left, top, back);
|
||||
GLVertex rightTopBack = addVertex(right, top, back);
|
||||
GLVertex leftBottomFront = addVertex(left, bottom, front);
|
||||
GLVertex rightBottomFront = addVertex(right, bottom, front);
|
||||
GLVertex leftTopFront = addVertex(left, top, front);
|
||||
GLVertex rightTopFront = addVertex(right, top, front);
|
||||
|
||||
// vertices are added in a clockwise orientation (when viewed from the outside)
|
||||
// bottom
|
||||
addFace(new GLFace(leftBottomBack, leftBottomFront, rightBottomFront, rightBottomBack));
|
||||
// front
|
||||
addFace(new GLFace(leftBottomFront, leftTopFront, rightTopFront, rightBottomFront));
|
||||
// left
|
||||
addFace(new GLFace(leftBottomBack, leftTopBack, leftTopFront, leftBottomFront));
|
||||
// right
|
||||
addFace(new GLFace(rightBottomBack, rightBottomFront, rightTopFront, rightTopBack));
|
||||
// back
|
||||
addFace(new GLFace(leftBottomBack, rightBottomBack, rightTopBack, leftTopBack));
|
||||
// top
|
||||
addFace(new GLFace(leftTopBack, rightTopBack, rightTopFront, leftTopFront));
|
||||
|
||||
}
|
||||
|
||||
public static final int kBottom = 0;
|
||||
public static final int kFront = 1;
|
||||
public static final int kLeft = 2;
|
||||
public static final int kRight = 3;
|
||||
public static final int kBack = 4;
|
||||
public static final int kTop = 5;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
public class GLColor {
|
||||
|
||||
public final int red;
|
||||
public final int green;
|
||||
public final int blue;
|
||||
public final int alpha;
|
||||
|
||||
public GLColor(int red, int green, int blue, int alpha) {
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
public GLColor(int red, int green, int blue) {
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
this.alpha = 0x10000;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof GLColor) {
|
||||
GLColor color = (GLColor)other;
|
||||
return (red == color.red && green == color.green &&
|
||||
blue == color.blue && alpha == color.alpha);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GLFace {
|
||||
|
||||
public GLFace() {
|
||||
|
||||
}
|
||||
|
||||
// for triangles
|
||||
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3) {
|
||||
addVertex(v1);
|
||||
addVertex(v2);
|
||||
addVertex(v3);
|
||||
}
|
||||
// for quadrilaterals
|
||||
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3, GLVertex v4) {
|
||||
addVertex(v1);
|
||||
addVertex(v2);
|
||||
addVertex(v3);
|
||||
addVertex(v4);
|
||||
}
|
||||
|
||||
public void addVertex(GLVertex v) {
|
||||
mVertexList.add(v);
|
||||
}
|
||||
|
||||
// must be called after all vertices are added
|
||||
public void setColor(GLColor c) {
|
||||
|
||||
int last = mVertexList.size() - 1;
|
||||
if (last < 2) {
|
||||
Log.e("GLFace", "not enough vertices in setColor()");
|
||||
} else {
|
||||
GLVertex vertex = mVertexList.get(last);
|
||||
|
||||
// only need to do this if the color has never been set
|
||||
if (mColor == null) {
|
||||
while (vertex.color != null) {
|
||||
mVertexList.add(0, vertex);
|
||||
mVertexList.remove(last + 1);
|
||||
vertex = mVertexList.get(last);
|
||||
}
|
||||
}
|
||||
|
||||
vertex.color = c;
|
||||
}
|
||||
|
||||
mColor = c;
|
||||
}
|
||||
|
||||
public int getIndexCount() {
|
||||
return (mVertexList.size() - 2) * 3;
|
||||
}
|
||||
|
||||
public void putIndices(ShortBuffer buffer) {
|
||||
int last = mVertexList.size() - 1;
|
||||
|
||||
GLVertex v0 = mVertexList.get(0);
|
||||
GLVertex vn = mVertexList.get(last);
|
||||
|
||||
// push triangles into the buffer
|
||||
for (int i = 1; i < last; i++) {
|
||||
GLVertex v1 = mVertexList.get(i);
|
||||
buffer.put(v0.index);
|
||||
buffer.put(v1.index);
|
||||
buffer.put(vn.index);
|
||||
v0 = v1;
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
|
||||
private GLColor mColor;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GLShape {
|
||||
|
||||
public GLShape(GLWorld world) {
|
||||
mWorld = world;
|
||||
}
|
||||
|
||||
public void addFace(GLFace face) {
|
||||
mFaceList.add(face);
|
||||
}
|
||||
|
||||
public void setFaceColor(int face, GLColor color) {
|
||||
mFaceList.get(face).setColor(color);
|
||||
}
|
||||
|
||||
public void putIndices(ShortBuffer buffer) {
|
||||
Iterator<GLFace> iter = mFaceList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
GLFace face = iter.next();
|
||||
face.putIndices(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndexCount() {
|
||||
int count = 0;
|
||||
Iterator<GLFace> iter = mFaceList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
GLFace face = iter.next();
|
||||
count += face.getIndexCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public GLVertex addVertex(float x, float y, float z) {
|
||||
|
||||
// look for an existing GLVertex first
|
||||
Iterator<GLVertex> iter = mVertexList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
GLVertex vertex = iter.next();
|
||||
if (vertex.x == x && vertex.y == y && vertex.z == z) {
|
||||
return vertex;
|
||||
}
|
||||
}
|
||||
|
||||
// doesn't exist, so create new vertex
|
||||
GLVertex vertex = mWorld.addVertex(x, y, z);
|
||||
mVertexList.add(vertex);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
public void animateTransform(M4 transform) {
|
||||
mAnimateTransform = transform;
|
||||
|
||||
if (mTransform != null)
|
||||
transform = mTransform.multiply(transform);
|
||||
|
||||
Iterator<GLVertex> iter = mVertexList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
GLVertex vertex = iter.next();
|
||||
mWorld.transformVertex(vertex, transform);
|
||||
}
|
||||
}
|
||||
|
||||
public void startAnimation() {
|
||||
}
|
||||
|
||||
public void endAnimation() {
|
||||
if (mTransform == null) {
|
||||
mTransform = new M4(mAnimateTransform);
|
||||
} else {
|
||||
mTransform = mTransform.multiply(mAnimateTransform);
|
||||
}
|
||||
}
|
||||
|
||||
public M4 mTransform;
|
||||
public M4 mAnimateTransform;
|
||||
protected ArrayList<GLFace> mFaceList = new ArrayList<GLFace>();
|
||||
protected ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
|
||||
protected ArrayList<Integer> mIndexList = new ArrayList<Integer>(); // make more efficient?
|
||||
protected GLWorld mWorld;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
public class GLVertex {
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
final short index; // index in vertex table
|
||||
GLColor color;
|
||||
|
||||
GLVertex() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
GLVertex(float x, float y, float z, int index) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.index = (short)index;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof GLVertex) {
|
||||
GLVertex v = (GLVertex)other;
|
||||
return (x == v.x && y == v.y && z == v.z);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public int toFixed(float x) {
|
||||
return (int)(x*65536.0f);
|
||||
}
|
||||
|
||||
public void put(IntBuffer vertexBuffer, IntBuffer colorBuffer) {
|
||||
vertexBuffer.put(toFixed(x));
|
||||
vertexBuffer.put(toFixed(y));
|
||||
vertexBuffer.put(toFixed(z));
|
||||
if (color == null) {
|
||||
colorBuffer.put(0);
|
||||
colorBuffer.put(0);
|
||||
colorBuffer.put(0);
|
||||
colorBuffer.put(0);
|
||||
} else {
|
||||
colorBuffer.put(color.red);
|
||||
colorBuffer.put(color.green);
|
||||
colorBuffer.put(color.blue);
|
||||
colorBuffer.put(color.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
public void update(IntBuffer vertexBuffer, M4 transform) {
|
||||
// skip to location of vertex in mVertex buffer
|
||||
vertexBuffer.position(index * 3);
|
||||
|
||||
if (transform == null) {
|
||||
vertexBuffer.put(toFixed(x));
|
||||
vertexBuffer.put(toFixed(y));
|
||||
vertexBuffer.put(toFixed(z));
|
||||
} else {
|
||||
GLVertex temp = new GLVertex();
|
||||
transform.multiply(this, temp);
|
||||
vertexBuffer.put(toFixed(temp.x));
|
||||
vertexBuffer.put(toFixed(temp.y));
|
||||
vertexBuffer.put(toFixed(temp.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class GLWorld {
|
||||
|
||||
public void addShape(GLShape shape) {
|
||||
mShapeList.add(shape);
|
||||
mIndexCount += shape.getIndexCount();
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(mVertexList.size()*4*4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
mColorBuffer = bb.asIntBuffer();
|
||||
|
||||
bb = ByteBuffer.allocateDirect(mVertexList.size()*4*3);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
mVertexBuffer = bb.asIntBuffer();
|
||||
|
||||
bb = ByteBuffer.allocateDirect(mIndexCount*2);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
mIndexBuffer = bb.asShortBuffer();
|
||||
|
||||
Iterator<GLVertex> iter2 = mVertexList.iterator();
|
||||
while (iter2.hasNext()) {
|
||||
GLVertex vertex = iter2.next();
|
||||
vertex.put(mVertexBuffer, mColorBuffer);
|
||||
}
|
||||
|
||||
Iterator<GLShape> iter3 = mShapeList.iterator();
|
||||
while (iter3.hasNext()) {
|
||||
GLShape shape = iter3.next();
|
||||
shape.putIndices(mIndexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public GLVertex addVertex(float x, float y, float z) {
|
||||
GLVertex vertex = new GLVertex(x, y, z, mVertexList.size());
|
||||
mVertexList.add(vertex);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
public void transformVertex(GLVertex vertex, M4 transform) {
|
||||
vertex.update(mVertexBuffer, transform);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
public void draw(GL10 gl)
|
||||
{
|
||||
mColorBuffer.position(0);
|
||||
mVertexBuffer.position(0);
|
||||
mIndexBuffer.position(0);
|
||||
|
||||
gl.glFrontFace(GL10.GL_CW);
|
||||
gl.glShadeModel(GL10.GL_FLAT);
|
||||
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
|
||||
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
|
||||
gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
|
||||
count++;
|
||||
}
|
||||
|
||||
static public float toFloat(int x) {
|
||||
return x/65536.0f;
|
||||
}
|
||||
|
||||
private ArrayList<GLShape> mShapeList = new ArrayList<GLShape>();
|
||||
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
|
||||
|
||||
private int mIndexCount = 0;
|
||||
|
||||
private IntBuffer mVertexBuffer;
|
||||
private IntBuffer mColorBuffer;
|
||||
private ShortBuffer mIndexBuffer;
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Kube extends Activity implements KubeRenderer.AnimationCallback {
|
||||
|
||||
private GLWorld makeGLWorld()
|
||||
{
|
||||
GLWorld world = new GLWorld();
|
||||
|
||||
int one = 0x10000;
|
||||
int half = 0x08000;
|
||||
GLColor red = new GLColor(one, 0, 0);
|
||||
GLColor green = new GLColor(0, one, 0);
|
||||
GLColor blue = new GLColor(0, 0, one);
|
||||
GLColor yellow = new GLColor(one, one, 0);
|
||||
GLColor orange = new GLColor(one, half, 0);
|
||||
GLColor white = new GLColor(one, one, one);
|
||||
GLColor black = new GLColor(0, 0, 0);
|
||||
|
||||
// coordinates for our cubes
|
||||
float c0 = -1.0f;
|
||||
float c1 = -0.38f;
|
||||
float c2 = -0.32f;
|
||||
float c3 = 0.32f;
|
||||
float c4 = 0.38f;
|
||||
float c5 = 1.0f;
|
||||
|
||||
// top back, left to right
|
||||
mCubes[0] = new Cube(world, c0, c4, c0, c1, c5, c1);
|
||||
mCubes[1] = new Cube(world, c2, c4, c0, c3, c5, c1);
|
||||
mCubes[2] = new Cube(world, c4, c4, c0, c5, c5, c1);
|
||||
// top middle, left to right
|
||||
mCubes[3] = new Cube(world, c0, c4, c2, c1, c5, c3);
|
||||
mCubes[4] = new Cube(world, c2, c4, c2, c3, c5, c3);
|
||||
mCubes[5] = new Cube(world, c4, c4, c2, c5, c5, c3);
|
||||
// top front, left to right
|
||||
mCubes[6] = new Cube(world, c0, c4, c4, c1, c5, c5);
|
||||
mCubes[7] = new Cube(world, c2, c4, c4, c3, c5, c5);
|
||||
mCubes[8] = new Cube(world, c4, c4, c4, c5, c5, c5);
|
||||
// middle back, left to right
|
||||
mCubes[9] = new Cube(world, c0, c2, c0, c1, c3, c1);
|
||||
mCubes[10] = new Cube(world, c2, c2, c0, c3, c3, c1);
|
||||
mCubes[11] = new Cube(world, c4, c2, c0, c5, c3, c1);
|
||||
// middle middle, left to right
|
||||
mCubes[12] = new Cube(world, c0, c2, c2, c1, c3, c3);
|
||||
mCubes[13] = null;
|
||||
mCubes[14] = new Cube(world, c4, c2, c2, c5, c3, c3);
|
||||
// middle front, left to right
|
||||
mCubes[15] = new Cube(world, c0, c2, c4, c1, c3, c5);
|
||||
mCubes[16] = new Cube(world, c2, c2, c4, c3, c3, c5);
|
||||
mCubes[17] = new Cube(world, c4, c2, c4, c5, c3, c5);
|
||||
// bottom back, left to right
|
||||
mCubes[18] = new Cube(world, c0, c0, c0, c1, c1, c1);
|
||||
mCubes[19] = new Cube(world, c2, c0, c0, c3, c1, c1);
|
||||
mCubes[20] = new Cube(world, c4, c0, c0, c5, c1, c1);
|
||||
// bottom middle, left to right
|
||||
mCubes[21] = new Cube(world, c0, c0, c2, c1, c1, c3);
|
||||
mCubes[22] = new Cube(world, c2, c0, c2, c3, c1, c3);
|
||||
mCubes[23] = new Cube(world, c4, c0, c2, c5, c1, c3);
|
||||
// bottom front, left to right
|
||||
mCubes[24] = new Cube(world, c0, c0, c4, c1, c1, c5);
|
||||
mCubes[25] = new Cube(world, c2, c0, c4, c3, c1, c5);
|
||||
mCubes[26] = new Cube(world, c4, c0, c4, c5, c1, c5);
|
||||
|
||||
// paint the sides
|
||||
int i, j;
|
||||
// set all faces black by default
|
||||
for (i = 0; i < 27; i++) {
|
||||
Cube cube = mCubes[i];
|
||||
if (cube != null) {
|
||||
for (j = 0; j < 6; j++)
|
||||
cube.setFaceColor(j, black);
|
||||
}
|
||||
}
|
||||
|
||||
// paint top
|
||||
for (i = 0; i < 9; i++)
|
||||
mCubes[i].setFaceColor(Cube.kTop, orange);
|
||||
// paint bottom
|
||||
for (i = 18; i < 27; i++)
|
||||
mCubes[i].setFaceColor(Cube.kBottom, red);
|
||||
// paint left
|
||||
for (i = 0; i < 27; i += 3)
|
||||
mCubes[i].setFaceColor(Cube.kLeft, yellow);
|
||||
// paint right
|
||||
for (i = 2; i < 27; i += 3)
|
||||
mCubes[i].setFaceColor(Cube.kRight, white);
|
||||
// paint back
|
||||
for (i = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 3; j++)
|
||||
mCubes[i + j].setFaceColor(Cube.kBack, blue);
|
||||
// paint front
|
||||
for (i = 6; i < 27; i += 9)
|
||||
for (j = 0; j < 3; j++)
|
||||
mCubes[i + j].setFaceColor(Cube.kFront, green);
|
||||
|
||||
for (i = 0; i < 27; i++)
|
||||
if (mCubes[i] != null)
|
||||
world.addShape(mCubes[i]);
|
||||
|
||||
// initialize our permutation to solved position
|
||||
mPermutation = new int[27];
|
||||
for (i = 0; i < mPermutation.length; i++)
|
||||
mPermutation[i] = i;
|
||||
|
||||
createLayers();
|
||||
updateLayers();
|
||||
|
||||
world.generate();
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
private void createLayers() {
|
||||
mLayers[kUp] = new Layer(Layer.kAxisY);
|
||||
mLayers[kDown] = new Layer(Layer.kAxisY);
|
||||
mLayers[kLeft] = new Layer(Layer.kAxisX);
|
||||
mLayers[kRight] = new Layer(Layer.kAxisX);
|
||||
mLayers[kFront] = new Layer(Layer.kAxisZ);
|
||||
mLayers[kBack] = new Layer(Layer.kAxisZ);
|
||||
mLayers[kMiddle] = new Layer(Layer.kAxisX);
|
||||
mLayers[kEquator] = new Layer(Layer.kAxisY);
|
||||
mLayers[kSide] = new Layer(Layer.kAxisZ);
|
||||
}
|
||||
|
||||
private void updateLayers() {
|
||||
Layer layer;
|
||||
GLShape[] shapes;
|
||||
int i, j, k;
|
||||
|
||||
// up layer
|
||||
layer = mLayers[kUp];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 0; i < 9; i++)
|
||||
shapes[i] = mCubes[mPermutation[i]];
|
||||
|
||||
// down layer
|
||||
layer = mLayers[kDown];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 18, k = 0; i < 27; i++)
|
||||
shapes[k++] = mCubes[mPermutation[i]];
|
||||
|
||||
// left layer
|
||||
layer = mLayers[kLeft];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 0, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 9; j += 3)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
|
||||
// right layer
|
||||
layer = mLayers[kRight];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 2, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 9; j += 3)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
|
||||
// front layer
|
||||
layer = mLayers[kFront];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 6, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 3; j++)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
|
||||
// back layer
|
||||
layer = mLayers[kBack];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 0, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 3; j++)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
|
||||
// middle layer
|
||||
layer = mLayers[kMiddle];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 1, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 9; j += 3)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
|
||||
// equator layer
|
||||
layer = mLayers[kEquator];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 9, k = 0; i < 18; i++)
|
||||
shapes[k++] = mCubes[mPermutation[i]];
|
||||
|
||||
// side layer
|
||||
layer = mLayers[kSide];
|
||||
shapes = layer.mShapes;
|
||||
for (i = 3, k = 0; i < 27; i += 9)
|
||||
for (j = 0; j < 3; j++)
|
||||
shapes[k++] = mCubes[mPermutation[i + j]];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// We don't need a title either.
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
mView = new GLSurfaceView(getApplication());
|
||||
mRenderer = new KubeRenderer(makeGLWorld(), this);
|
||||
mView.setRenderer(mRenderer);
|
||||
setContentView(mView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
mView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
mView.onPause();
|
||||
}
|
||||
|
||||
public void animate() {
|
||||
// change our angle of view
|
||||
mRenderer.setAngle(mRenderer.getAngle() + 1.2f);
|
||||
|
||||
if (mCurrentLayer == null) {
|
||||
int layerID = mRandom.nextInt(9);
|
||||
mCurrentLayer = mLayers[layerID];
|
||||
mCurrentLayerPermutation = mLayerPermutations[layerID];
|
||||
mCurrentLayer.startAnimation();
|
||||
boolean direction = mRandom.nextBoolean();
|
||||
int count = mRandom.nextInt(3) + 1;
|
||||
|
||||
count = 1;
|
||||
direction = false;
|
||||
mCurrentAngle = 0;
|
||||
if (direction) {
|
||||
mAngleIncrement = (float)Math.PI / 50;
|
||||
mEndAngle = mCurrentAngle + ((float)Math.PI * count) / 2f;
|
||||
} else {
|
||||
mAngleIncrement = -(float)Math.PI / 50;
|
||||
mEndAngle = mCurrentAngle - ((float)Math.PI * count) / 2f;
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentAngle += mAngleIncrement;
|
||||
|
||||
if ((mAngleIncrement > 0f && mCurrentAngle >= mEndAngle) ||
|
||||
(mAngleIncrement < 0f && mCurrentAngle <= mEndAngle)) {
|
||||
mCurrentLayer.setAngle(mEndAngle);
|
||||
mCurrentLayer.endAnimation();
|
||||
mCurrentLayer = null;
|
||||
|
||||
// adjust mPermutation based on the completed layer rotation
|
||||
int[] newPermutation = new int[27];
|
||||
for (int i = 0; i < 27; i++) {
|
||||
newPermutation[i] = mPermutation[mCurrentLayerPermutation[i]];
|
||||
// newPermutation[i] = mCurrentLayerPermutation[mPermutation[i]];
|
||||
}
|
||||
mPermutation = newPermutation;
|
||||
updateLayers();
|
||||
|
||||
} else {
|
||||
mCurrentLayer.setAngle(mCurrentAngle);
|
||||
}
|
||||
}
|
||||
|
||||
GLSurfaceView mView;
|
||||
KubeRenderer mRenderer;
|
||||
Cube[] mCubes = new Cube[27];
|
||||
// a Layer for each possible move
|
||||
Layer[] mLayers = new Layer[9];
|
||||
// permutations corresponding to a pi/2 rotation of each layer about its axis
|
||||
static int[][] mLayerPermutations = {
|
||||
// permutation for UP layer
|
||||
{ 2, 5, 8, 1, 4, 7, 0, 3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
|
||||
// permutation for DOWN layer
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 23, 26, 19, 22, 25, 18, 21, 24 },
|
||||
// permutation for LEFT layer
|
||||
{ 6, 1, 2, 15, 4, 5, 24, 7, 8, 3, 10, 11, 12, 13, 14, 21, 16, 17, 0, 19, 20, 9, 22, 23, 18, 25, 26 },
|
||||
// permutation for RIGHT layer
|
||||
{ 0, 1, 8, 3, 4, 17, 6, 7, 26, 9, 10, 5, 12, 13, 14, 15, 16, 23, 18, 19, 2, 21, 22, 11, 24, 25, 20 },
|
||||
// permutation for FRONT layer
|
||||
{ 0, 1, 2, 3, 4, 5, 24, 15, 6, 9, 10, 11, 12, 13, 14, 25, 16, 7, 18, 19, 20, 21, 22, 23, 26, 17, 8 },
|
||||
// permutation for BACK layer
|
||||
{ 18, 9, 0, 3, 4, 5, 6, 7, 8, 19, 10, 1, 12, 13, 14, 15, 16, 17, 20, 11, 2, 21, 22, 23, 24, 25, 26 },
|
||||
// permutation for MIDDLE layer
|
||||
{ 0, 7, 2, 3, 16, 5, 6, 25, 8, 9, 4, 11, 12, 13, 14, 15, 22, 17, 18, 1, 20, 21, 10, 23, 24, 19, 26 },
|
||||
// permutation for EQUATOR layer
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 17, 10, 13, 16, 9, 12, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
|
||||
// permutation for SIDE layer
|
||||
{ 0, 1, 2, 21, 12, 3, 6, 7, 8, 9, 10, 11, 22, 13, 4, 15, 16, 17, 18, 19, 20, 23, 14, 5, 24, 25, 26 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// current permutation of starting position
|
||||
int[] mPermutation;
|
||||
|
||||
// for random cube movements
|
||||
Random mRandom = new Random(System.currentTimeMillis());
|
||||
// currently turning layer
|
||||
Layer mCurrentLayer = null;
|
||||
// current and final angle for current Layer animation
|
||||
float mCurrentAngle, mEndAngle;
|
||||
// amount to increment angle
|
||||
float mAngleIncrement;
|
||||
int[] mCurrentLayerPermutation;
|
||||
|
||||
// names for our 9 layers (based on notation from http://www.cubefreak.net/notation.html)
|
||||
static final int kUp = 0;
|
||||
static final int kDown = 1;
|
||||
static final int kLeft = 2;
|
||||
static final int kRight = 3;
|
||||
static final int kFront = 4;
|
||||
static final int kBack = 5;
|
||||
static final int kMiddle = 6;
|
||||
static final int kEquator = 7;
|
||||
static final int kSide = 8;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
|
||||
/**
|
||||
* Example of how to use OpenGL|ES in a custom view
|
||||
*
|
||||
*/
|
||||
class KubeRenderer implements GLSurfaceView.Renderer {
|
||||
public interface AnimationCallback {
|
||||
void animate();
|
||||
}
|
||||
|
||||
public KubeRenderer(GLWorld world, AnimationCallback callback) {
|
||||
mWorld = world;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
if (mCallback != null) {
|
||||
mCallback.animate();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(0.5f,0.5f,0.5f,1);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D object
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.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(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
|
||||
mWorld.draw(gl);
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
// Need a depth buffer, don't care about color depth.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_DEPTH_SIZE, 16,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
* 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)width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
|
||||
|
||||
/*
|
||||
* By default, OpenGL enables features that improve quality
|
||||
* but reduce performance. One might want to tweak that
|
||||
* especially on software renderer.
|
||||
*/
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
gl.glActiveTexture(GL10.GL_TEXTURE0);
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// Nothing special, don't have any textures we need to recreate.
|
||||
}
|
||||
|
||||
public void setAngle(float angle) {
|
||||
mAngle = angle;
|
||||
}
|
||||
|
||||
public float getAngle() {
|
||||
return mAngle;
|
||||
}
|
||||
|
||||
private GLWorld mWorld;
|
||||
private AnimationCallback mCallback;
|
||||
private float mAngle;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
public class Layer {
|
||||
|
||||
public Layer(int axis) {
|
||||
// start with identity matrix for transformation
|
||||
mAxis = axis;
|
||||
mTransform.setIdentity();
|
||||
}
|
||||
|
||||
public void startAnimation() {
|
||||
for (int i = 0; i < mShapes.length; i++) {
|
||||
GLShape shape = mShapes[i];
|
||||
if (shape != null) {
|
||||
shape.startAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void endAnimation() {
|
||||
for (int i = 0; i < mShapes.length; i++) {
|
||||
GLShape shape = mShapes[i];
|
||||
if (shape != null) {
|
||||
shape.endAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setAngle(float angle) {
|
||||
// normalize the angle
|
||||
float twopi = (float)Math.PI *2f;
|
||||
while (angle >= twopi) angle -= twopi;
|
||||
while (angle < 0f) angle += twopi;
|
||||
// mAngle = angle;
|
||||
|
||||
float sin = (float)Math.sin(angle);
|
||||
float cos = (float)Math.cos(angle);
|
||||
|
||||
float[][] m = mTransform.m;
|
||||
switch (mAxis) {
|
||||
case kAxisX:
|
||||
m[1][1] = cos;
|
||||
m[1][2] = sin;
|
||||
m[2][1] = -sin;
|
||||
m[2][2] = cos;
|
||||
m[0][0] = 1f;
|
||||
m[0][1] = m[0][2] = m[1][0] = m[2][0] = 0f;
|
||||
break;
|
||||
case kAxisY:
|
||||
m[0][0] = cos;
|
||||
m[0][2] = sin;
|
||||
m[2][0] = -sin;
|
||||
m[2][2] = cos;
|
||||
m[1][1] = 1f;
|
||||
m[0][1] = m[1][0] = m[1][2] = m[2][1] = 0f;
|
||||
break;
|
||||
case kAxisZ:
|
||||
m[0][0] = cos;
|
||||
m[0][1] = sin;
|
||||
m[1][0] = -sin;
|
||||
m[1][1] = cos;
|
||||
m[2][2] = 1f;
|
||||
m[2][0] = m[2][1] = m[0][2] = m[1][2] = 0f;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mShapes.length; i++) {
|
||||
GLShape shape = mShapes[i];
|
||||
if (shape != null) {
|
||||
shape.animateTransform(mTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLShape[] mShapes = new GLShape[9];
|
||||
M4 mTransform = new M4();
|
||||
// float mAngle;
|
||||
|
||||
// which axis do we rotate around?
|
||||
// 0 for X, 1 for Y, 2 for Z
|
||||
int mAxis;
|
||||
static public final int kAxisX = 0;
|
||||
static public final int kAxisY = 1;
|
||||
static public final int kAxisZ = 2;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.kube;
|
||||
|
||||
/**
|
||||
*
|
||||
* A 4x4 float matrix
|
||||
*
|
||||
*/
|
||||
public class M4 {
|
||||
public float[][] m = new float[4][4];
|
||||
|
||||
public M4() {
|
||||
}
|
||||
|
||||
public M4(M4 other) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
m[i][j] = other.m[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void multiply(GLVertex src, GLVertex dest) {
|
||||
dest.x = src.x * m[0][0] + src.y * m[1][0] + src.z * m[2][0] + m[3][0];
|
||||
dest.y = src.x * m[0][1] + src.y * m[1][1] + src.z * m[2][1] + m[3][1];
|
||||
dest.z = src.x * m[0][2] + src.y * m[1][2] + src.z * m[2][2] + m[3][2];
|
||||
}
|
||||
|
||||
public M4 multiply(M4 other) {
|
||||
M4 result = new M4();
|
||||
float[][] m1 = m;
|
||||
float[][] m2 = other.m;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
result.m[i][j] = m1[i][0]*m2[0][j] + m1[i][1]*m2[1][j] + m1[i][2]*m2[2][j] + m1[i][3]*m2[3][j];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setIdentity() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
m[i][j] = (i == j ? 1f : 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder("[ ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
builder.append(m[i][j]);
|
||||
builder.append(" ");
|
||||
}
|
||||
if (i < 2)
|
||||
builder.append("\n ");
|
||||
}
|
||||
builder.append(" ]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A 2D rectangular mesh. Can be drawn textured or untextured.
|
||||
*
|
||||
*/
|
||||
class Grid {
|
||||
|
||||
public Grid(int w, int h) {
|
||||
if (w < 0 || w >= 65536) {
|
||||
throw new IllegalArgumentException("w");
|
||||
}
|
||||
if (h < 0 || h >= 65536) {
|
||||
throw new IllegalArgumentException("h");
|
||||
}
|
||||
if (w * h >= 65536) {
|
||||
throw new IllegalArgumentException("w * h >= 65536");
|
||||
}
|
||||
|
||||
mW = w;
|
||||
mH = h;
|
||||
int size = w * h;
|
||||
mVertexArray = new float[size * 3];
|
||||
mVertexBuffer = FloatBuffer.wrap(mVertexArray);
|
||||
|
||||
mTexCoordArray = new float[size * 2];
|
||||
mTexCoordBuffer = FloatBuffer.wrap(mTexCoordArray);
|
||||
|
||||
int quadW = mW - 1;
|
||||
int quadH = mH - 1;
|
||||
int quadCount = quadW * quadH;
|
||||
int indexCount = quadCount * 6;
|
||||
mIndexCount = indexCount;
|
||||
char[] indexArray = new char[indexCount];
|
||||
|
||||
/*
|
||||
* Initialize triangle list mesh.
|
||||
*
|
||||
* [0]-----[ 1] ...
|
||||
* | / |
|
||||
* | / |
|
||||
* | / |
|
||||
* [w]-----[w+1] ...
|
||||
* | |
|
||||
*
|
||||
*/
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
for (int y = 0; y < quadH; y++) {
|
||||
for (int x = 0; x < quadW; x++) {
|
||||
char a = (char) (y * mW + x);
|
||||
char b = (char) (y * mW + x + 1);
|
||||
char c = (char) ((y + 1) * mW + x);
|
||||
char d = (char) ((y + 1) * mW + x + 1);
|
||||
|
||||
indexArray[i++] = a;
|
||||
indexArray[i++] = b;
|
||||
indexArray[i++] = c;
|
||||
|
||||
indexArray[i++] = b;
|
||||
indexArray[i++] = c;
|
||||
indexArray[i++] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mIndexBuffer = CharBuffer.wrap(indexArray);
|
||||
}
|
||||
|
||||
void set(int i, int j, float x, float y, float z, float u, float v) {
|
||||
if (i < 0 || i >= mW) {
|
||||
throw new IllegalArgumentException("i");
|
||||
}
|
||||
if (j < 0 || j >= mH) {
|
||||
throw new IllegalArgumentException("j");
|
||||
}
|
||||
|
||||
int index = mW * j + i;
|
||||
|
||||
int posIndex = index * 3;
|
||||
mVertexArray[posIndex] = x;
|
||||
mVertexArray[posIndex + 1] = y;
|
||||
mVertexArray[posIndex + 2] = z;
|
||||
|
||||
int texIndex = index * 2;
|
||||
mTexCoordArray[texIndex] = u;
|
||||
mTexCoordArray[texIndex + 1] = v;
|
||||
}
|
||||
|
||||
public void draw(GL10 gl, boolean useTexture) {
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
|
||||
|
||||
if (useTexture) {
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordBuffer);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount,
|
||||
GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
|
||||
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
private FloatBuffer mVertexBuffer;
|
||||
private float[] mVertexArray;
|
||||
|
||||
private FloatBuffer mTexCoordBuffer;
|
||||
private float[] mTexCoordArray;
|
||||
|
||||
private CharBuffer mIndexBuffer;
|
||||
|
||||
private int mW;
|
||||
private int mH;
|
||||
private int mIndexCount;
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.opengl.GLUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL11;
|
||||
import javax.microedition.khronos.opengles.GL11Ext;
|
||||
|
||||
/**
|
||||
* An OpenGL text label maker.
|
||||
*
|
||||
*
|
||||
* OpenGL labels are implemented by creating a Bitmap, drawing all the labels
|
||||
* into the Bitmap, converting the Bitmap into an Alpha texture, and creating a
|
||||
* mesh for each label
|
||||
*
|
||||
* The benefits of this approach are that the labels are drawn using the high
|
||||
* quality anti-aliased font rasterizer, full character set support, and all the
|
||||
* text labels are stored on a single texture, which makes it faster to use.
|
||||
*
|
||||
* The drawbacks are that you can only have as many labels as will fit onto one
|
||||
* texture, and you have to recreate the whole texture if any label text
|
||||
* changes.
|
||||
*
|
||||
*/
|
||||
public class LabelMaker {
|
||||
/**
|
||||
* Create a label maker
|
||||
* or maximum compatibility with various OpenGL ES implementations,
|
||||
* the strike width and height must be powers of two,
|
||||
* We want the strike width to be at least as wide as the widest window.
|
||||
*
|
||||
* @param fullColor true if we want a full color backing store (4444),
|
||||
* otherwise we generate a grey L8 backing store.
|
||||
* @param strikeWidth width of strike
|
||||
* @param strikeHeight height of strike
|
||||
*/
|
||||
public LabelMaker(boolean fullColor, int strikeWidth, int strikeHeight) {
|
||||
mFullColor = fullColor;
|
||||
mStrikeWidth = strikeWidth;
|
||||
mStrikeHeight = strikeHeight;
|
||||
mTexelWidth = (float) (1.0 / mStrikeWidth);
|
||||
mTexelHeight = (float) (1.0 / mStrikeHeight);
|
||||
mClearPaint = new Paint();
|
||||
mClearPaint.setARGB(0, 0, 0, 0);
|
||||
mClearPaint.setStyle(Style.FILL);
|
||||
mState = STATE_NEW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to initialize the class.
|
||||
* Call whenever the surface has been created.
|
||||
*
|
||||
* @param gl
|
||||
*/
|
||||
public void initialize(GL10 gl) {
|
||||
mState = STATE_INITIALIZED;
|
||||
int[] textures = new int[1];
|
||||
gl.glGenTextures(1, textures, 0);
|
||||
mTextureID = textures[0];
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
// Use Nearest for performance.
|
||||
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_NEAREST);
|
||||
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
|
||||
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_REPLACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when the surface has been destroyed
|
||||
*/
|
||||
public void shutdown(GL10 gl) {
|
||||
if ( gl != null) {
|
||||
if (mState > STATE_NEW) {
|
||||
int[] textures = new int[1];
|
||||
textures[0] = mTextureID;
|
||||
gl.glDeleteTextures(1, textures, 0);
|
||||
mState = STATE_NEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call before adding labels. Clears out any existing labels.
|
||||
*
|
||||
* @param gl
|
||||
*/
|
||||
public void beginAdding(GL10 gl) {
|
||||
checkState(STATE_INITIALIZED, STATE_ADDING);
|
||||
mLabels.clear();
|
||||
mU = 0;
|
||||
mV = 0;
|
||||
mLineHeight = 0;
|
||||
Bitmap.Config config = mFullColor ?
|
||||
Bitmap.Config.ARGB_4444 : Bitmap.Config.ALPHA_8;
|
||||
mBitmap = Bitmap.createBitmap(mStrikeWidth, mStrikeHeight, config);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
mBitmap.eraseColor(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to add a label
|
||||
*
|
||||
* @param gl
|
||||
* @param text the text of the label
|
||||
* @param textPaint the paint of the label
|
||||
* @return the id of the label, used to measure and draw the label
|
||||
*/
|
||||
public int add(GL10 gl, String text, Paint textPaint) {
|
||||
return add(gl, null, text, textPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to add a label
|
||||
*
|
||||
* @param gl
|
||||
* @param text the text of the label
|
||||
* @param textPaint the paint of the label
|
||||
* @return the id of the label, used to measure and draw the label
|
||||
*/
|
||||
public int add(GL10 gl, Drawable background, String text, Paint textPaint) {
|
||||
return add(gl, background, text, textPaint, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to add a label
|
||||
* @return the id of the label, used to measure and draw the label
|
||||
*/
|
||||
public int add(GL10 gl, Drawable drawable, int minWidth, int minHeight) {
|
||||
return add(gl, drawable, null, null, minWidth, minHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to add a label
|
||||
*
|
||||
* @param gl
|
||||
* @param text the text of the label
|
||||
* @param textPaint the paint of the label
|
||||
* @return the id of the label, used to measure and draw the label
|
||||
*/
|
||||
public int add(GL10 gl, Drawable background, String text, Paint textPaint,
|
||||
int minWidth, int minHeight) {
|
||||
checkState(STATE_ADDING, STATE_ADDING);
|
||||
boolean drawBackground = background != null;
|
||||
boolean drawText = (text != null) && (textPaint != null);
|
||||
|
||||
Rect padding = new Rect();
|
||||
if (drawBackground) {
|
||||
background.getPadding(padding);
|
||||
minWidth = Math.max(minWidth, background.getMinimumWidth());
|
||||
minHeight = Math.max(minHeight, background.getMinimumHeight());
|
||||
}
|
||||
|
||||
int ascent = 0;
|
||||
int descent = 0;
|
||||
int measuredTextWidth = 0;
|
||||
if (drawText) {
|
||||
// Paint.ascent is negative, so negate it.
|
||||
ascent = (int) Math.ceil(-textPaint.ascent());
|
||||
descent = (int) Math.ceil(textPaint.descent());
|
||||
measuredTextWidth = (int) Math.ceil(textPaint.measureText(text));
|
||||
}
|
||||
int textHeight = ascent + descent;
|
||||
int textWidth = Math.min(mStrikeWidth,measuredTextWidth);
|
||||
|
||||
int padHeight = padding.top + padding.bottom;
|
||||
int padWidth = padding.left + padding.right;
|
||||
int height = Math.max(minHeight, textHeight + padHeight);
|
||||
int width = Math.max(minWidth, textWidth + padWidth);
|
||||
int effectiveTextHeight = height - padHeight;
|
||||
int effectiveTextWidth = width - padWidth;
|
||||
|
||||
int centerOffsetHeight = (effectiveTextHeight - textHeight) / 2;
|
||||
int centerOffsetWidth = (effectiveTextWidth - textWidth) / 2;
|
||||
|
||||
// Make changes to the local variables, only commit them
|
||||
// to the member variables after we've decided not to throw
|
||||
// any exceptions.
|
||||
|
||||
int u = mU;
|
||||
int v = mV;
|
||||
int lineHeight = mLineHeight;
|
||||
|
||||
if (width > mStrikeWidth) {
|
||||
width = mStrikeWidth;
|
||||
}
|
||||
|
||||
// Is there room for this string on the current line?
|
||||
if (u + width > mStrikeWidth) {
|
||||
// No room, go to the next line:
|
||||
u = 0;
|
||||
v += lineHeight;
|
||||
lineHeight = 0;
|
||||
}
|
||||
lineHeight = Math.max(lineHeight, height);
|
||||
if (v + lineHeight > mStrikeHeight) {
|
||||
throw new IllegalArgumentException("Out of texture space.");
|
||||
}
|
||||
|
||||
int u2 = u + width;
|
||||
int vBase = v + ascent;
|
||||
int v2 = v + height;
|
||||
|
||||
if (drawBackground) {
|
||||
background.setBounds(u, v, u + width, v + height);
|
||||
background.draw(mCanvas);
|
||||
}
|
||||
|
||||
if (drawText) {
|
||||
mCanvas.drawText(text,
|
||||
u + padding.left + centerOffsetWidth,
|
||||
vBase + padding.top + centerOffsetHeight,
|
||||
textPaint);
|
||||
}
|
||||
|
||||
Grid grid = new Grid(2, 2);
|
||||
// Grid.set arguments: i, j, x, y, z, u, v
|
||||
|
||||
float texU = u * mTexelWidth;
|
||||
float texU2 = u2 * mTexelWidth;
|
||||
float texV = 1.0f - v * mTexelHeight;
|
||||
float texV2 = 1.0f - v2 * mTexelHeight;
|
||||
|
||||
grid.set(0, 0, 0.0f, 0.0f, 0.0f, texU , texV2);
|
||||
grid.set(1, 0, width, 0.0f, 0.0f, texU2, texV2);
|
||||
grid.set(0, 1, 0.0f, height, 0.0f, texU , texV );
|
||||
grid.set(1, 1, width, height, 0.0f, texU2, texV );
|
||||
|
||||
// We know there's enough space, so update the member variables
|
||||
mU = u + width;
|
||||
mV = v;
|
||||
mLineHeight = lineHeight;
|
||||
mLabels.add(new Label(grid, width, height, ascent,
|
||||
u, v + height, width, -height));
|
||||
return mLabels.size() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to end adding labels. Must be called before drawing starts.
|
||||
*
|
||||
* @param gl
|
||||
*/
|
||||
public void endAdding(GL10 gl) {
|
||||
checkState(STATE_ADDING, STATE_INITIALIZED);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
|
||||
// Reclaim storage used by bitmap and canvas.
|
||||
mBitmap.recycle();
|
||||
mBitmap = null;
|
||||
mCanvas = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width in pixels of a given label.
|
||||
*
|
||||
* @param labelID
|
||||
* @return the width in pixels
|
||||
*/
|
||||
public float getWidth(int labelID) {
|
||||
return mLabels.get(labelID).width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height in pixels of a given label.
|
||||
*
|
||||
* @param labelID
|
||||
* @return the height in pixels
|
||||
*/
|
||||
public float getHeight(int labelID) {
|
||||
return mLabels.get(labelID).height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the baseline of a given label. That's how many pixels from the top of
|
||||
* the label to the text baseline. (This is equivalent to the negative of
|
||||
* the label's paint's ascent.)
|
||||
*
|
||||
* @param labelID
|
||||
* @return the baseline in pixels.
|
||||
*/
|
||||
public float getBaseline(int labelID) {
|
||||
return mLabels.get(labelID).baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin drawing labels. Sets the OpenGL state for rapid drawing.
|
||||
*
|
||||
* @param gl
|
||||
* @param viewWidth
|
||||
* @param viewHeight
|
||||
*/
|
||||
public void beginDrawing(GL10 gl, float viewWidth, float viewHeight) {
|
||||
checkState(STATE_INITIALIZED, STATE_DRAWING);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
gl.glShadeModel(GL10.GL_FLAT);
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glPushMatrix();
|
||||
gl.glLoadIdentity();
|
||||
gl.glOrthof(0.0f, viewWidth, 0.0f, viewHeight, 0.0f, 1.0f);
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glPushMatrix();
|
||||
gl.glLoadIdentity();
|
||||
// Magic offsets to promote consistent rasterization.
|
||||
gl.glTranslatef(0.375f, 0.375f, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a given label at a given x,y position, expressed in pixels, with the
|
||||
* lower-left-hand-corner of the view being (0,0).
|
||||
*
|
||||
* @param gl
|
||||
* @param x
|
||||
* @param y
|
||||
* @param labelID
|
||||
*/
|
||||
public void draw(GL10 gl, float x, float y, int labelID) {
|
||||
checkState(STATE_DRAWING, STATE_DRAWING);
|
||||
gl.glPushMatrix();
|
||||
float snappedX = (float) Math.floor(x);
|
||||
float snappedY = (float) Math.floor(y);
|
||||
gl.glTranslatef(snappedX, snappedY, 0.0f);
|
||||
Label label = mLabels.get(labelID);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
|
||||
GL11Ext.GL_TEXTURE_CROP_RECT_OES, label.mCrop, 0);
|
||||
((GL11Ext)gl).glDrawTexiOES((int) snappedX, (int) snappedY, 0,
|
||||
(int) label.width, (int) label.height);
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the drawing and restores the OpenGL state.
|
||||
*
|
||||
* @param gl
|
||||
*/
|
||||
public void endDrawing(GL10 gl) {
|
||||
checkState(STATE_DRAWING, STATE_INITIALIZED);
|
||||
gl.glDisable(GL10.GL_BLEND);
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glPopMatrix();
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
private void checkState(int oldState, int newState) {
|
||||
if (mState != oldState) {
|
||||
throw new IllegalArgumentException("Can't call this method now.");
|
||||
}
|
||||
mState = newState;
|
||||
}
|
||||
|
||||
private static class Label {
|
||||
public Label(Grid grid, float width, float height, float baseLine,
|
||||
int cropU, int cropV, int cropW, int cropH) {
|
||||
this.grid = grid;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.baseline = baseLine;
|
||||
int[] crop = new int[4];
|
||||
crop[0] = cropU;
|
||||
crop[1] = cropV;
|
||||
crop[2] = cropW;
|
||||
crop[3] = cropH;
|
||||
mCrop = crop;
|
||||
}
|
||||
|
||||
public Grid grid;
|
||||
public float width;
|
||||
public float height;
|
||||
public float baseline;
|
||||
public int[] mCrop;
|
||||
}
|
||||
|
||||
private int mStrikeWidth;
|
||||
private int mStrikeHeight;
|
||||
private boolean mFullColor;
|
||||
private Bitmap mBitmap;
|
||||
private Canvas mCanvas;
|
||||
private Paint mClearPaint;
|
||||
|
||||
private int mTextureID;
|
||||
|
||||
private float mTexelWidth; // Convert texel to U
|
||||
private float mTexelHeight; // Convert texel to V
|
||||
private int mU;
|
||||
private int mV;
|
||||
private int mLineHeight;
|
||||
private ArrayList<Label> mLabels = new ArrayList<Label>();
|
||||
|
||||
private static final int STATE_NEW = 0;
|
||||
private static final int STATE_INITIALIZED = 1;
|
||||
private static final int STATE_ADDING = 2;
|
||||
private static final int STATE_DRAWING = 3;
|
||||
private int mState;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
class MatrixGrabber {
|
||||
public MatrixGrabber() {
|
||||
mModelView = new float[16];
|
||||
mProjection = new float[16];
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the current modelView and projection matrix state.
|
||||
* Has the side effect of setting the current matrix state to GL_MODELVIEW
|
||||
* @param gl
|
||||
*/
|
||||
public void getCurrentState(GL10 gl) {
|
||||
getCurrentProjection(gl);
|
||||
getCurrentModelView(gl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the current modelView matrix state. Has the side effect of
|
||||
* setting the current matrix state to GL_MODELVIEW
|
||||
* @param gl
|
||||
*/
|
||||
public void getCurrentModelView(GL10 gl) {
|
||||
getMatrix(gl, GL10.GL_MODELVIEW, mModelView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the current projection matrix state. Has the side effect of
|
||||
* setting the current matrix state to GL_PROJECTION
|
||||
* @param gl
|
||||
*/
|
||||
public void getCurrentProjection(GL10 gl) {
|
||||
getMatrix(gl, GL10.GL_PROJECTION, mProjection);
|
||||
}
|
||||
|
||||
private void getMatrix(GL10 gl, int mode, float[] mat) {
|
||||
MatrixTrackingGL gl2 = (MatrixTrackingGL) gl;
|
||||
gl2.glMatrixMode(mode);
|
||||
gl2.getMatrix(mat, 0);
|
||||
}
|
||||
|
||||
public float[] mModelView;
|
||||
public float[] mProjection;
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import android.opengl.Matrix;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
/**
|
||||
* A matrix stack, similar to OpenGL ES's internal matrix stack.
|
||||
*/
|
||||
public class MatrixStack {
|
||||
public MatrixStack() {
|
||||
commonInit(DEFAULT_MAX_DEPTH);
|
||||
}
|
||||
|
||||
public MatrixStack(int maxDepth) {
|
||||
commonInit(maxDepth);
|
||||
}
|
||||
|
||||
private void commonInit(int maxDepth) {
|
||||
mMatrix = new float[maxDepth * MATRIX_SIZE];
|
||||
mTemp = new float[MATRIX_SIZE * 2];
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
public void glFrustumf(float left, float right, float bottom, float top,
|
||||
float near, float far) {
|
||||
Matrix.frustumM(mMatrix, mTop, left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
public void glFrustumx(int left, int right, int bottom, int top, int near,
|
||||
int far) {
|
||||
glFrustumf(fixedToFloat(left),fixedToFloat(right),
|
||||
fixedToFloat(bottom), fixedToFloat(top),
|
||||
fixedToFloat(near), fixedToFloat(far));
|
||||
}
|
||||
|
||||
public void glLoadIdentity() {
|
||||
Matrix.setIdentityM(mMatrix, mTop);
|
||||
}
|
||||
|
||||
public void glLoadMatrixf(float[] m, int offset) {
|
||||
System.arraycopy(m, offset, mMatrix, mTop, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
public void glLoadMatrixf(FloatBuffer m) {
|
||||
m.get(mMatrix, mTop, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
public void glLoadMatrixx(int[] m, int offset) {
|
||||
for(int i = 0; i < MATRIX_SIZE; i++) {
|
||||
mMatrix[mTop + i] = fixedToFloat(m[offset + i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void glLoadMatrixx(IntBuffer m) {
|
||||
for(int i = 0; i < MATRIX_SIZE; i++) {
|
||||
mMatrix[mTop + i] = fixedToFloat(m.get());
|
||||
}
|
||||
}
|
||||
|
||||
public void glMultMatrixf(float[] m, int offset) {
|
||||
System.arraycopy(mMatrix, mTop, mTemp, 0, MATRIX_SIZE);
|
||||
Matrix.multiplyMM(mMatrix, mTop, mTemp, 0, m, offset);
|
||||
}
|
||||
|
||||
public void glMultMatrixf(FloatBuffer m) {
|
||||
m.get(mTemp, MATRIX_SIZE, MATRIX_SIZE);
|
||||
glMultMatrixf(mTemp, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
public void glMultMatrixx(int[] m, int offset) {
|
||||
for(int i = 0; i < MATRIX_SIZE; i++) {
|
||||
mTemp[MATRIX_SIZE + i] = fixedToFloat(m[offset + i]);
|
||||
}
|
||||
glMultMatrixf(mTemp, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
public void glMultMatrixx(IntBuffer m) {
|
||||
for(int i = 0; i < MATRIX_SIZE; i++) {
|
||||
mTemp[MATRIX_SIZE + i] = fixedToFloat(m.get());
|
||||
}
|
||||
glMultMatrixf(mTemp, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
public void glOrthof(float left, float right, float bottom, float top,
|
||||
float near, float far) {
|
||||
Matrix.orthoM(mMatrix, mTop, left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
public void glOrthox(int left, int right, int bottom, int top, int near,
|
||||
int far) {
|
||||
glOrthof(fixedToFloat(left), fixedToFloat(right),
|
||||
fixedToFloat(bottom), fixedToFloat(top),
|
||||
fixedToFloat(near), fixedToFloat(far));
|
||||
}
|
||||
|
||||
public void glPopMatrix() {
|
||||
preflight_adjust(-1);
|
||||
adjust(-1);
|
||||
}
|
||||
|
||||
public void glPushMatrix() {
|
||||
preflight_adjust(1);
|
||||
System.arraycopy(mMatrix, mTop, mMatrix, mTop + MATRIX_SIZE,
|
||||
MATRIX_SIZE);
|
||||
adjust(1);
|
||||
}
|
||||
|
||||
public void glRotatef(float angle, float x, float y, float z) {
|
||||
Matrix.setRotateM(mTemp, 0, angle, x, y, z);
|
||||
System.arraycopy(mMatrix, mTop, mTemp, MATRIX_SIZE, MATRIX_SIZE);
|
||||
Matrix.multiplyMM(mMatrix, mTop, mTemp, MATRIX_SIZE, mTemp, 0);
|
||||
}
|
||||
|
||||
public void glRotatex(int angle, int x, int y, int z) {
|
||||
glRotatef(angle, fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
|
||||
}
|
||||
|
||||
public void glScalef(float x, float y, float z) {
|
||||
Matrix.scaleM(mMatrix, mTop, x, y, z);
|
||||
}
|
||||
|
||||
public void glScalex(int x, int y, int z) {
|
||||
glScalef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
|
||||
}
|
||||
|
||||
public void glTranslatef(float x, float y, float z) {
|
||||
Matrix.translateM(mMatrix, mTop, x, y, z);
|
||||
}
|
||||
|
||||
public void glTranslatex(int x, int y, int z) {
|
||||
glTranslatef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
|
||||
}
|
||||
|
||||
public void getMatrix(float[] dest, int offset) {
|
||||
System.arraycopy(mMatrix, mTop, dest, offset, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
private float fixedToFloat(int x) {
|
||||
return x * (1.0f / 65536.0f);
|
||||
}
|
||||
|
||||
private void preflight_adjust(int dir) {
|
||||
int newTop = mTop + dir * MATRIX_SIZE;
|
||||
if (newTop < 0) {
|
||||
throw new IllegalArgumentException("stack underflow");
|
||||
}
|
||||
if (newTop + MATRIX_SIZE > mMatrix.length) {
|
||||
throw new IllegalArgumentException("stack overflow");
|
||||
}
|
||||
}
|
||||
|
||||
private void adjust(int dir) {
|
||||
mTop += dir * MATRIX_SIZE;
|
||||
}
|
||||
|
||||
private final static int DEFAULT_MAX_DEPTH = 32;
|
||||
private final static int MATRIX_SIZE = 16;
|
||||
private float[] mMatrix;
|
||||
private int mTop;
|
||||
private float[] mTemp;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.graphics.Paint;
|
||||
|
||||
public class NumericSprite {
|
||||
public NumericSprite() {
|
||||
mText = "";
|
||||
mLabelMaker = null;
|
||||
}
|
||||
|
||||
public void initialize(GL10 gl, Paint paint) {
|
||||
int height = roundUpPower2((int) paint.getFontSpacing());
|
||||
final float interDigitGaps = 9 * 1.0f;
|
||||
int width = roundUpPower2((int) (interDigitGaps + paint.measureText(sStrike)));
|
||||
mLabelMaker = new LabelMaker(true, width, height);
|
||||
mLabelMaker.initialize(gl);
|
||||
mLabelMaker.beginAdding(gl);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String digit = sStrike.substring(i, i+1);
|
||||
mLabelId[i] = mLabelMaker.add(gl, digit, paint);
|
||||
mWidth[i] = (int) Math.ceil(mLabelMaker.getWidth(i));
|
||||
}
|
||||
mLabelMaker.endAdding(gl);
|
||||
}
|
||||
|
||||
public void shutdown(GL10 gl) {
|
||||
mLabelMaker.shutdown(gl);
|
||||
mLabelMaker = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the smallest power of two >= the input value.
|
||||
* (Doesn't work for negative numbers.)
|
||||
*/
|
||||
private int roundUpPower2(int x) {
|
||||
x = x - 1;
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >>16);
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
mText = format(value);
|
||||
}
|
||||
|
||||
public void draw(GL10 gl, float x, float y,
|
||||
float viewWidth, float viewHeight) {
|
||||
int length = mText.length();
|
||||
mLabelMaker.beginDrawing(gl, viewWidth, viewHeight);
|
||||
for(int i = 0; i < length; i++) {
|
||||
char c = mText.charAt(i);
|
||||
int digit = c - '0';
|
||||
mLabelMaker.draw(gl, x, y, mLabelId[digit]);
|
||||
x += mWidth[digit];
|
||||
}
|
||||
mLabelMaker.endDrawing(gl);
|
||||
}
|
||||
|
||||
public float width() {
|
||||
float width = 0.0f;
|
||||
int length = mText.length();
|
||||
for(int i = 0; i < length; i++) {
|
||||
char c = mText.charAt(i);
|
||||
width += mWidth[c - '0'];
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
private String format(int value) {
|
||||
return Integer.toString(value);
|
||||
}
|
||||
|
||||
private LabelMaker mLabelMaker;
|
||||
private String mText;
|
||||
private int[] mWidth = new int[10];
|
||||
private int[] mLabelId = new int[10];
|
||||
private final static String sStrike = "0123456789";
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import android.opengl.Matrix;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A utility that projects
|
||||
*
|
||||
*/
|
||||
class Projector {
|
||||
public Projector() {
|
||||
mMVP = new float[16];
|
||||
mV = new float[4];
|
||||
mGrabber = new MatrixGrabber();
|
||||
}
|
||||
|
||||
public void setCurrentView(int x, int y, int width, int height) {
|
||||
mX = x;
|
||||
mY = y;
|
||||
mViewWidth = width;
|
||||
mViewHeight = height;
|
||||
}
|
||||
|
||||
public void project(float[] obj, int objOffset, float[] win, int winOffset) {
|
||||
if (!mMVPComputed) {
|
||||
Matrix.multiplyMM(mMVP, 0, mGrabber.mProjection, 0, mGrabber.mModelView, 0);
|
||||
mMVPComputed = true;
|
||||
}
|
||||
|
||||
Matrix.multiplyMV(mV, 0, mMVP, 0, obj, objOffset);
|
||||
|
||||
float rw = 1.0f / mV[3];
|
||||
|
||||
win[winOffset] = mX + mViewWidth * (mV[0] * rw + 1.0f) * 0.5f;
|
||||
win[winOffset + 1] = mY + mViewHeight * (mV[1] * rw + 1.0f) * 0.5f;
|
||||
win[winOffset + 2] = (mV[2] * rw + 1.0f) * 0.5f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current projection matrix. Has the side-effect of
|
||||
* setting current matrix mode to GL_PROJECTION
|
||||
* @param gl
|
||||
*/
|
||||
public void getCurrentProjection(GL10 gl) {
|
||||
mGrabber.getCurrentProjection(gl);
|
||||
mMVPComputed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current model view matrix. Has the side-effect of
|
||||
* setting current matrix mode to GL_MODELVIEW
|
||||
* @param gl
|
||||
*/
|
||||
public void getCurrentModelView(GL10 gl) {
|
||||
mGrabber.getCurrentModelView(gl);
|
||||
mMVPComputed = false;
|
||||
}
|
||||
|
||||
private MatrixGrabber mGrabber;
|
||||
private boolean mMVPComputed;
|
||||
private float[] mMVP;
|
||||
private float[] mV;
|
||||
private int mX;
|
||||
private int mY;
|
||||
private int mViewWidth;
|
||||
private int mViewHeight;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class SpriteTextActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mGLSurfaceView = new GLSurfaceView(this);
|
||||
mGLSurfaceView.setGLWrapper(new GLSurfaceView.GLWrapper() {
|
||||
public GL wrap(GL gl) {
|
||||
return new MatrixTrackingGL(gl);
|
||||
}});
|
||||
mGLSurfaceView.setRenderer(new SpriteTextRenderer(this));
|
||||
setContentView(mGLSurfaceView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.apis.graphics.spritetext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Paint;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLU;
|
||||
import android.opengl.GLUtils;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
public class SpriteTextRenderer implements GLSurfaceView.Renderer{
|
||||
|
||||
public SpriteTextRenderer(Context context) {
|
||||
mContext = context;
|
||||
mTriangle = new Triangle();
|
||||
mProjector = new Projector();
|
||||
mLabelPaint = new Paint();
|
||||
mLabelPaint.setTextSize(32);
|
||||
mLabelPaint.setAntiAlias(true);
|
||||
mLabelPaint.setARGB(0xff, 0x00, 0x00, 0x00);
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
// We don't need a depth buffer, and don't care about our
|
||||
// color depth.
|
||||
int[] configSpec = {
|
||||
EGL10.EGL_DEPTH_SIZE, 0,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
return configSpec;
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
/*
|
||||
* Some one-time OpenGL initialization can be made here
|
||||
* probably based on features of this particular context
|
||||
*/
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
GL10.GL_FASTEST);
|
||||
|
||||
gl.glClearColor(.5f, .5f, .5f, 1);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
gl.glEnable(GL10.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(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
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);
|
||||
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_CLAMP_TO_EDGE);
|
||||
|
||||
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_REPLACE);
|
||||
|
||||
InputStream is = mContext.getResources()
|
||||
.openRawResource(R.drawable.robot);
|
||||
Bitmap bitmap;
|
||||
try {
|
||||
bitmap = BitmapFactory.decodeStream(is);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch(IOException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
bitmap.recycle();
|
||||
|
||||
if (mLabels != null) {
|
||||
mLabels.shutdown(gl);
|
||||
} else {
|
||||
mLabels = new LabelMaker(true, 256, 64);
|
||||
}
|
||||
mLabels.initialize(gl);
|
||||
mLabels.beginAdding(gl);
|
||||
mLabelA = mLabels.add(gl, "A", mLabelPaint);
|
||||
mLabelB = mLabels.add(gl, "B", mLabelPaint);
|
||||
mLabelC = mLabels.add(gl, "C", mLabelPaint);
|
||||
mLabelMsPF = mLabels.add(gl, "ms/f", mLabelPaint);
|
||||
mLabels.endAdding(gl);
|
||||
|
||||
if (mNumericSprite != null) {
|
||||
mNumericSprite.shutdown(gl);
|
||||
} else {
|
||||
mNumericSprite = new NumericSprite();
|
||||
}
|
||||
mNumericSprite.initialize(gl, mLabelPaint);
|
||||
}
|
||||
|
||||
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(GL10.GL_DITHER);
|
||||
|
||||
gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_MODULATE);
|
||||
|
||||
/*
|
||||
* 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(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D objects
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
GLU.gluLookAt(gl, 0.0f, 0.0f, -2.5f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
gl.glActiveTexture(GL10.GL_TEXTURE0);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_REPEAT);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_REPEAT);
|
||||
|
||||
long time = SystemClock.uptimeMillis() % 4000L;
|
||||
float angle = 0.090f * ((int) time);
|
||||
|
||||
gl.glRotatef(angle, 0, 0, 1.0f);
|
||||
gl.glScalef(2.0f, 2.0f, 2.0f);
|
||||
|
||||
mTriangle.draw(gl);
|
||||
|
||||
mProjector.getCurrentModelView(gl);
|
||||
mLabels.beginDrawing(gl, mWidth, mHeight);
|
||||
drawLabel(gl, 0, mLabelA);
|
||||
drawLabel(gl, 1, mLabelB);
|
||||
drawLabel(gl, 2, mLabelC);
|
||||
float msPFX = mWidth - mLabels.getWidth(mLabelMsPF) - 1;
|
||||
mLabels.draw(gl, msPFX, 0, mLabelMsPF);
|
||||
mLabels.endDrawing(gl);
|
||||
|
||||
drawMsPF(gl, msPFX);
|
||||
}
|
||||
|
||||
private void drawMsPF(GL10 gl, float rightMargin) {
|
||||
long time = SystemClock.uptimeMillis();
|
||||
if (mStartTime == 0) {
|
||||
mStartTime = time;
|
||||
}
|
||||
if (mFrames++ == SAMPLE_PERIOD_FRAMES) {
|
||||
mFrames = 0;
|
||||
long delta = time - mStartTime;
|
||||
mStartTime = time;
|
||||
mMsPerFrame = (int) (delta * SAMPLE_FACTOR);
|
||||
}
|
||||
if (mMsPerFrame > 0) {
|
||||
mNumericSprite.setValue(mMsPerFrame);
|
||||
float numWidth = mNumericSprite.width();
|
||||
float x = rightMargin - numWidth;
|
||||
mNumericSprite.draw(gl, x, 0, mWidth, mHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawLabel(GL10 gl, int triangleVertex, int labelId) {
|
||||
float x = mTriangle.getX(triangleVertex);
|
||||
float y = mTriangle.getY(triangleVertex);
|
||||
mScratch[0] = x;
|
||||
mScratch[1] = y;
|
||||
mScratch[2] = 0.0f;
|
||||
mScratch[3] = 1.0f;
|
||||
mProjector.project(mScratch, 0, mScratch, 4);
|
||||
float sx = mScratch[4];
|
||||
float sy = mScratch[5];
|
||||
float height = mLabels.getHeight(labelId);
|
||||
float width = mLabels.getWidth(labelId);
|
||||
float tx = sx - width * 0.5f;
|
||||
float ty = sy - height * 0.5f;
|
||||
mLabels.draw(gl, tx, ty, labelId);
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int w, int h) {
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
gl.glViewport(0, 0, w, h);
|
||||
mProjector.setCurrentView(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(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
mProjector.getCurrentProjection(gl);
|
||||
}
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private Context mContext;
|
||||
private Triangle mTriangle;
|
||||
private int mTextureID;
|
||||
private int mFrames;
|
||||
private int mMsPerFrame;
|
||||
private final static int SAMPLE_PERIOD_FRAMES = 12;
|
||||
private final static float SAMPLE_FACTOR = 1.0f / SAMPLE_PERIOD_FRAMES;
|
||||
private long mStartTime;
|
||||
private LabelMaker mLabels;
|
||||
private Paint mLabelPaint;
|
||||
private int mLabelA;
|
||||
private int mLabelB;
|
||||
private int mLabelC;
|
||||
private int mLabelMsPF;
|
||||
private Projector mProjector;
|
||||
private NumericSprite mNumericSprite;
|
||||
private float[] mScratch = new float[8];
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
for (int i = 0; i < VERTS; i++) {
|
||||
for(int j = 0; j < 3; j++) {
|
||||
mFVertexBuffer.put(sCoords[i*3+j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < VERTS; i++) {
|
||||
for(int j = 0; j < 2; j++) {
|
||||
mTexBuffer.put(sCoords[i*3+j] * 2.0f + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
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.glFrontFace(GL10.GL_CCW);
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
|
||||
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS,
|
||||
GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
|
||||
}
|
||||
|
||||
public float getX(int vertex) {
|
||||
return sCoords[3*vertex];
|
||||
}
|
||||
|
||||
public float getY(int vertex) {
|
||||
return sCoords[3*vertex+1];
|
||||
}
|
||||
|
||||
private final static int VERTS = 3;
|
||||
|
||||
private FloatBuffer mFVertexBuffer;
|
||||
private FloatBuffer mTexBuffer;
|
||||
private ShortBuffer mIndexBuffer;
|
||||
// A unit-sided equalateral triangle centered on the origin.
|
||||
private final static float[] sCoords = {
|
||||
// X, Y, Z
|
||||
-0.5f, -0.25f, 0,
|
||||
0.5f, -0.25f, 0,
|
||||
0.0f, 0.559016994f, 0
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user