/*
* This class is based glutes_shape.c,check it.
http://glutes.sourceforge.net/
*/
/*
* Copyright (C) 2008 aki@akjava.com
*
* 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.
*/
//original code license is below
/*
* glutes_shape.c
*
* Copyright (c) 2005 Joachim Pouderoux All Rights Reserved.
* Copyright (c) 2003 David Blythe All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//package com.akjava.lib.android.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.opengl.GLUtils;
import android.util.Log;
class OpenGLUtils {
public static FloatBuffer allocateFloatBuffer(int capacity) {
ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
vbb.order(ByteOrder.nativeOrder());
return vbb.asFloatBuffer();
}
public static IntBuffer allocateInttBuffer(int capacity) {
ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
vbb.order(ByteOrder.nativeOrder());
return vbb.asIntBuffer();
}
public static ShortBuffer allocateShortBuffer(int capacity) {
ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
vbb.order(ByteOrder.nativeOrder());
return vbb.asShortBuffer();
}
public static void addVertex3f(FloatBuffer buffer, float x, float y, float z) {
buffer.put(x);
buffer.put(y);
buffer.put(z);
}
public static void addIndex(ShortBuffer buffer, int index1, int index2,
int index3) {
buffer.put((short) index1);
buffer.put((short) index2);
buffer.put((short) index3);
}
public static void addCoord2f(FloatBuffer buffer, float x, float y) {
buffer.put(x);
buffer.put(y);
}
public static void addColorf(FloatBuffer buffer, float r, float g, float b,
float a) {
buffer.put(r);
buffer.put(g);
buffer.put(b);
buffer.put(a);
}
public static FloatBuffer toFloatBufferPositionZero(float[] values) {
ByteBuffer vbb = ByteBuffer.allocateDirect(values.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer buffer = vbb.asFloatBuffer();
buffer.put(values);
buffer.position(0);
return buffer;
}
public static ShortBuffer toShortBuffer(short[] values) {
ByteBuffer vbb = ByteBuffer.allocateDirect(values.length * 2);
vbb.order(ByteOrder.nativeOrder());
ShortBuffer buffer = vbb.asShortBuffer();
buffer.put(values);
buffer.position(0);
return buffer;
}
public static Bitmap loadBitmap(Context mContext, int id) {
Options opt = new Options();
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),
id, opt);
System.out.println(bitmap.getConfig());
if (!sizeCheck(bitmap)) {
throw new RuntimeException(
"width or height not 2x size,it make invalid error on OpenGL:"
+ id);
}
return bitmap;
}
private static boolean sizeCheck(Bitmap bitmap) {
boolean ret = true;
int t = 2;
int w = bitmap.getWidth();
while (w != t) {
if (w % t == 1) {
Log.e("glutils w=", w + "," + t);
return false;
}
t *= 2;
if (t > w) {
return false;
}
}
t = 2;
int h = bitmap.getHeight();
while (h != t) {
if (h % t == 1) {
Log.e("glutils h=", h + "," + t);
return false;
}
t *= 2;
if (t > h) {
return false;
}
}
return ret;
}
/**
* this is for resized GLU.gluOrtho2D (gl,-1f, 1.0f, -1f, 1.0f);
*
* @param x
* @param y
* @param screenWidth
* @param screenHeight
* @return
*/
public static float[] toOpenGLCordinate(float x, float y, int screenWidth,
int screenHeight) {
float sx = ((float) x / screenWidth) * 2 - 1.0f;
float sy = ((float) y / screenHeight) * 2 - 1.0f;
sy *= -1;
return new float[] { sx, sy };
}
/*
* y should *=-1;
*/
public static float toOpenGLCordinate(float x, int screenWidth) {
Log.i("myapp", "x=" + x + "," + screenWidth);
float sx = ((float) x / screenWidth) * 2 - 1.0f;
return sx;
}
public static float realToVirtialValue(int x, int real, float virtial) {
return virtial / real * x;
}
public static int virtualToRealvalue(float x, int real, float virtial) {
// using DecimalFormat make gc
return (int) ((float) x / (virtial / real));
}
private static FloatBuffer mTextureBuffer;
private static FloatBuffer mFVertexBuffer;
private static ShortBuffer mIndexBuffer;
public static FloatBuffer getBoxTriangleTextureBuffer() {
if (mTextureBuffer == null) {
mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 2);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
mTextureBuffer.position(0);
}
return mTextureBuffer;
}
public static FloatBuffer getBoxTriangleFlipVerticalTextureBuffer() {
if (mTextureBuffer == null) {
mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 2);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
mTextureBuffer.position(0);
}
return mTextureBuffer;
}
public static FloatBuffer getBoxTextureBuffer() {
if (mTextureBuffer == null) {
mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 4 * 2);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
mTextureBuffer.position(0);
}
return mTextureBuffer;
}
public static ShortBuffer getBoxIndexBuffer() {
if (mIndexBuffer == null) {
mIndexBuffer = OpenGLUtils.allocateShortBuffer(6 * 2);
mIndexBuffer.put((short) 0);
mIndexBuffer.put((short) 1);
mIndexBuffer.put((short) 2);
mIndexBuffer.put((short) 2);
mIndexBuffer.put((short) 3);
mIndexBuffer.put((short) 1);
mIndexBuffer.position(0);
}
return mIndexBuffer;
}
public static FloatBuffer getBoxVertexBuffer() {
if (mFVertexBuffer == null) {
mFVertexBuffer = OpenGLUtils.allocateFloatBuffer(4 * 4 * 3);
OpenGLUtils.addVertex3f(mFVertexBuffer, -1, -1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, 1, 1f, 0);
mFVertexBuffer.position(0);
}
return mFVertexBuffer;
}
public static FloatBuffer getBoxTriangleVertexBuffer() {
if (mFVertexBuffer == null) {
mFVertexBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 3);
OpenGLUtils.addVertex3f(mFVertexBuffer, -1, -1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, 1, 1f, 0);
OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);
mFVertexBuffer.position(0);
}
return mFVertexBuffer;
}
// TODO ??????????????
/*
* bitmap???????????
*/
public static void bindTextureImage(GL10 gl, final int id,
final Bitmap bitmap) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, id);
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.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_NEAREST);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
public class GLUT {
public static class SolidCube {
public static float v[] = new float[108]; // 108 = 6*18
public static float cubev[] = { -1f, -1f, 1f, /* front */
1f, -1f, 1f, -1f, 1f, 1f,
1f, -1f, 1f, 1f, 1f, 1f, -1f, 1f, 1f,
-1f, 1f, -1f, /* back */
1f, -1f, -1f, -1f, -1f, -1f,
-1f, 1f, -1f, 1f, 1f, -1f, 1f, -1f, -1f,
-1f, -1f, -1f, /* left */
-1f, -1f, 1f, -1f, 1f, -1f,
-1f, -1f, 1f, -1f, 1f, 1f, -1f, 1f, -1f,
1f, -1f, 1f, /* right */
1f, -1f, -1f, 1f, 1f, 1f,
1f, -1f, -1f, 1f, 1f, -1f, 1f, 1f, 1f,
-1f, 1f, 1f, /* top */
1f, 1f, 1f, -1f, 1f, -1f,
1f, 1f, 1f, 1f, 1f, -1f, -1f, 1f, -1f,
-1f, -1f, -1f, /* bottom */
1f, -1f, -1f, -1f, -1f, 1f,
1f, -1f, -1f, 1f, -1f, 1f, -1f, -1f, 1f, };
static float cuben[] = { 0, 0, 1f, /* front */
0, 0, 1f, 0, 0, 1f,
0, 0, 1f, 0, 0, 1f, 0, 0, 1f,
0, 0, -1f, /* back */
0, 0, -1f, 0, 0, -1f,
0, 0, -1f, 0, 0, -1f, 0, 0, -1f,
-1f, 0, 0, /* left */
-1f, 0, 0, -1f, 0, 0,
-1f, 0, 0, -1f, 0, 0, -1f, 0, 0,
1f, 0, 0, /* right */
1f, 0, 0, 1f, 0, 0,
1f, 0, 0, 1f, 0, 0, 1f, 0, 0,
0, 1f, 0, /* top */
0, 1f, 0, 0, 1f, 0,
0, 1f, 0, 0, 1f, 0, 0, 1f, 0,
0, -1f, 0, /* bottom */
0, -1f, 0, 0, -1f, 0,
0, -1f, 0, 0, -1f, 0, 0, -1f, 0, };
private static FloatBuffer loadCuben() {
cubenBuffer = OpenGLUtils.allocateFloatBuffer(108 * 4);
for (int i = 0; i < 108; i++)
cubenBuffer.put(cuben[i]);
cubenBuffer.position(0);
return cubenBuffer;
}
private static FloatBuffer cubevBuffer;
private static FloatBuffer cubenBuffer;
private static float param;
private static FloatBuffer loadCubev(float size) {
size /= 2;
cubevBuffer = OpenGLUtils.allocateFloatBuffer(108 * 4);
for (int i = 0; i < 108; i++) {
cubevBuffer.put(cubev[i] * size);
Log.d("", "" + cubev[i] * size);
}
cubevBuffer.position(0);
return cubevBuffer;
}
public static void draw(GL10 gl, float size) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
if (cubevBuffer != null) {
if (param != size) {
cubevBuffer = null;
cubenBuffer = null;
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (cubenBuffer == null) {
cubevBuffer = loadCubev(size);
cubenBuffer = loadCuben();
param = size;
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubevBuffer);
gl.glNormalPointer(GL10.GL_FLOAT, 0, cubenBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 36);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
public static void glutSolidCube(GL10 gl, float size) {
SolidCube.draw(gl, size);
}
public static void glutSolidTorus(GL10 gl, float ir, float or, int sides,
int rings) {
SolidTorus.draw(gl, ir, or, sides, rings);
}
public static class SolidTorus {
private static FloatBuffer p = null, q = null;
private static FloatBuffer v = null, n = null;
private static float parms[] = new float[4];// static
/*
* sometime it make heap problem
*/
private static void draw(GL10 gl, float ir, float or, int sides,
int rings) {
int SIZEOF = 4;
int i, j, k, triangles;
float s, t, x, y, z, twopi, nx, ny, nz;
float sin_s, cos_s, cos_t, sin_t, twopi_s, twopi_t;
float twopi_sides, twopi_rings;
// maybe clear buffer.
if (v != null) {
if (parms[0] != ir || parms[1] != or || parms[2] != sides
|| parms[3] != rings) {
// free(v);
// free(n);
n = v = null; // maybe free later.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (v == null) {
parms[0] = ir;
parms[1] = or;
parms[2] = (float) sides;
parms[3] = (float) rings;
// this size is maybe wrong.
p = v = OpenGLUtils.allocateFloatBuffer((int) (sides
* (rings + 1) * 2 * 3 * SIZEOF));
q = n = OpenGLUtils.allocateFloatBuffer((int) (sides
* (rings + 1) * 2 * 3 * SIZEOF));
twopi = 2.0f * (float) Math.PI;
twopi_sides = twopi / sides;
twopi_rings = twopi / rings;
for (i = 0; i < sides; i++) {
for (j = 0; j <= rings; j++) {
for (k = 1; k >= 0; k--) {
s = (i + k) % sides + 0.5f;
t = (float) (j % rings);
twopi_s = s * twopi_sides;
twopi_t = t * twopi_rings;
cos_s = (float) Math.cos(twopi_s);
sin_s = (float) Math.sin(twopi_s);
cos_t = (float) Math.cos(twopi_t);
sin_t = (float) Math.sin(twopi_t);
x = (or + ir * (float) cos_s) * (float) cos_t;
y = (or + ir * (float) cos_s) * (float) sin_t;
z = ir * (float) sin_s;
p.put(x);
p.put(y);
p.put(z);
nx = (float) cos_s * (float) cos_t;
ny = (float) cos_s * (float) sin_t;
nz = (float) sin_s;
q.put(nx);
q.put(ny);
q.put(nz);
}
}
}
}
v.position(0);
n.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, v);
gl.glNormalPointer(GL10.GL_FLOAT, 0, n);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
triangles = ((int) rings + 1) * 2;
for (i = 0; i < sides; i++) {
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, triangles * i,
triangles);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
public static void glutSolidBox(GL10 gl, float Width, float Depth,
float Height) {
SolidBox.draw(gl, Width, Depth, Height);
}
public static class SolidBox {
static float boxvec[][] = { { -1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f },
{ 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, -1.0f } };
static ShortBuffer boxndex[] = {
OpenGLUtils.toShortBuffer(new short[] { 0, 1, 2 }),
OpenGLUtils.toShortBuffer(new short[] { 0, 2, 3 }),
OpenGLUtils.toShortBuffer(new short[] { 3, 2, 6 }),
OpenGLUtils.toShortBuffer(new short[] { 3, 6, 7 }),
OpenGLUtils.toShortBuffer(new short[] { 6, 4, 7 }),
OpenGLUtils.toShortBuffer(new short[] { 6, 5, 4 }),
OpenGLUtils.toShortBuffer(new short[] { 4, 5, 1 }),
OpenGLUtils.toShortBuffer(new short[] { 4, 1, 0 }),
OpenGLUtils.toShortBuffer(new short[] { 2, 1, 5 }),
OpenGLUtils.toShortBuffer(new short[] { 2, 5, 6 }),
OpenGLUtils.toShortBuffer(new short[] { 3, 7, 4 }),
OpenGLUtils.toShortBuffer(new short[] { 3, 4, 0 }) };
static FloatBuffer vBuffer;
static float parms[] = new float[3];
public static void draw(GL10 gl, float Width, float Depth, float Height) {
// maybe clear buffer.
if (vBuffer != null) {
if (parms[0] != Width || parms[1] != Depth
|| parms[2] != Height) {
// free(v);
// free(n);
vBuffer = null; // maybe free later.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
int i;
if (vBuffer == null) {
float v[] = new float[8 * 3];
v[0 * 3 + 0] = v[1 * 3 + 0] = v[2 * 3 + 0] = v[3 * 3 + 0] = -Width / 2.0f;
v[4 * 3 + 0] = v[5 * 3 + 0] = v[6 * 3 + 0] = v[7 * 3 + 0] = Width / 2.0f;
v[0 * 3 + 1] = v[1 * 3 + 1] = v[4 * 3 + 1] = v[5 * 3 + 1] = -Depth / 2.0f;
v[2 * 3 + 1] = v[3 * 3 + 1] = v[6 * 3 + 1] = v[7 * 3 + 1] = Depth / 2.0f;
v[0 * 3 + 2] = v[3 * 3 + 2] = v[4 * 3 + 2] = v[7 * 3 + 2] = -Height / 2.0f;
v[1 * 3 + 2] = v[2 * 3 + 2] = v[5 * 3 + 2] = v[6 * 3 + 2] = Height / 2.0f;
vBuffer = OpenGLUtils.toFloatBufferPositionZero(v);
parms[0] = Width;
parms[1] = Depth;
parms[2] = Height;
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
for (i = 0; i < 6; i++) {
gl.glNormal3f(boxvec[i][0], boxvec[i][1], boxvec[i][2]);
gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT,
boxndex[i * 2]);
gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT,
boxndex[i * 2 + 1]);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
public static void glutWireBox(GL10 gl, float Width, float Depth,
float Height) {
WireBox.draw(gl, Width, Depth, Height);
}
public static class WireBox {
static FloatBuffer vBuffer;
static float parms[] = new float[3];
static ShortBuffer wireboxndex[] = {
OpenGLUtils.toShortBuffer(new short[] { 0, 1, 2, 3 }),
OpenGLUtils.toShortBuffer(new short[] { 3, 2, 6, 7 }),
OpenGLUtils.toShortBuffer(new short[] { 7, 6, 5, 4 }),
OpenGLUtils.toShortBuffer(new short[] { 4, 5, 1, 0 }),
OpenGLUtils.toShortBuffer(new short[] { 5, 6, 2, 1 }),
OpenGLUtils.toShortBuffer(new short[] { 7, 4, 0, 3 }) };
public static void draw(GL10 gl, float Width, float Depth, float Height) {
if (vBuffer != null) {
if (parms[0] != Width || parms[1] != Depth
|| parms[2] != Height) {
// free(v);
// free(n);
vBuffer = null; // maybe free later.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
int i;
if (vBuffer == null) {
float v[] = new float[8 * 3];
v[0 * 3 + 0] = v[1 * 3 + 0] = v[2 * 3 + 0] = v[3 * 3 + 0] = -Width / 2.0f;
v[4 * 3 + 0] = v[5 * 3 + 0] = v[6 * 3 + 0] = v[7 * 3 + 0] = Width / 2.0f;
v[0 * 3 + 1] = v[1 * 3 + 1] = v[4 * 3 + 1] = v[5 * 3 + 1] = -Depth / 2.0f;
v[2 * 3 + 1] = v[3 * 3 + 1] = v[6 * 3 + 1] = v[7 * 3 + 1] = Depth / 2.0f;
v[0 * 3 + 2] = v[3 * 3 + 2] = v[4 * 3 + 2] = v[7 * 3 + 2] = -Height / 2.0f;
v[1 * 3 + 2] = v[2 * 3 + 2] = v[5 * 3 + 2] = v[6 * 3 + 2] = Height / 2.0f;
vBuffer = OpenGLUtils.toFloatBufferPositionZero(v);
parms[0] = Width;
parms[1] = Depth;
parms[2] = Height;
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
for (i = 0; i < 6; i++) {
gl.glNormal3f(SolidBox.boxvec[i][0], SolidBox.boxvec[i][1],
SolidBox.boxvec[i][2]);
gl.glDrawElements(GL10.GL_LINE_LOOP, 4, GL10.GL_UNSIGNED_SHORT,
wireboxndex[i]);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
public static void glutWireCube(GL10 gl, float size) {
WireCube.draw(gl, size);
}
public static class WireCube {
static float v[] = new float[72];
static float cubev[] = // 72 = 3*6*4
{ -1.0f, -1.0f, 1.0f, /* front */
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, /* back */
1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, /* left */
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f, /* right */
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, /* top */
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, /* bottom */
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, };
static float cuben[] = { 0f, 0f, 1.0f, /* front */
0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f,
0f, 0f, -1.0f, /* back */
0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f,
-1.0f, 0f, 0f, /* left */
-1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f,
1.0f, 0f, 0f, /* right */
1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f,
0f, 1.0f, 0f, /* top */
0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f,
0f, -1.0f, 0f, /* bottom */
0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, };
private static FloatBuffer cubenBuffer;
private static FloatBuffer loadCuben() {
if (cubenBuffer == null) {
cubenBuffer = OpenGLUtils.allocateFloatBuffer(72 * 4);
for (int i = 0; i < 72; i++)
cubenBuffer.put(cuben[i]);
cubenBuffer.position(0);
}
return cubenBuffer;
}
private static FloatBuffer cubevBuffer;
private static FloatBuffer loadCubev(float size) {
// TODO size
if (cubevBuffer == null) {
size /= 2;
cubevBuffer = OpenGLUtils.allocateFloatBuffer(72 * 4);
for (int i = 0; i < 72; i++) {
cubevBuffer.put(cubev[i] * size);
Log.d("", "" + cubev[i] * size);
}
cubevBuffer.position(0);
}
return cubevBuffer;
}
private static float param;
public static void draw(GL10 gl, float size) {
if (cubevBuffer != null) {
if (param != size) {
cubevBuffer = null;
cubenBuffer = null;
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (cubenBuffer == null) {
cubevBuffer = loadCubev(size);
cubenBuffer = loadCuben();
param = size;
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubevBuffer);
gl.glNormalPointer(GL10.GL_FLOAT, 0, cubenBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (int i = 0; i < 6; i++)
gl.glDrawArrays(GL10.GL_LINE_LOOP, 4 * i, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
public static void glutWireTorus(GL10 gl, float dInnerRadius,
float dOuterRadius, int nSides, int nRings) {
WireTorus.draw(gl, dInnerRadius, dOuterRadius, nSides, nRings);
}
public static class WireTorus {
private static FloatBuffer p = null, q = null;
private static FloatBuffer v = null, n = null;
private static float parms[] = new float[4];// static
/*
* sometime it make heap problem
*/
private static void draw(GL10 gl, float ir, float or, int sides,
int rings) {
int SIZEOF = 4;
int i, j, k, triangles;
float s, t, x, y, z, twopi, nx, ny, nz;
float sin_s, cos_s, cos_t, sin_t, twopi_s, twopi_t;
float twopi_sides, twopi_rings;
// maybe clear buffer.
if (v != null) {
if (parms[0] != ir || parms[1] != or || parms[2] != sides
|| parms[3] != rings) {
// free(v);
// free(n);
n = v = null; // maybe free later.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (v == null) {
parms[0] = ir;
parms[1] = or;
parms[2] = (float) sides;
parms[3] = (float) rings;
// this size is maybe wrong.
p = v = OpenGLUtils.allocateFloatBuffer((int) (sides
* (rings + 1) * 2 * 3 * SIZEOF));
q = n = OpenGLUtils.allocateFloatBuffer((int) (sides
* (rings + 1) * 2 * 3 * SIZEOF));
twopi = 2.0f * (float) Math.PI;
twopi_sides = twopi / sides;
twopi_rings = twopi / rings;
for (i = 0; i < sides; i++) {
for (j = 0; j <= rings; j++) {
for (k = 1; k >= 0; k--) {
s = (i + k) % sides + 0.5f;
t = (float) (j % rings);
twopi_s = s * twopi_sides;
twopi_t = t * twopi_rings;
cos_s = (float) Math.cos(twopi_s);
sin_s = (float) Math.sin(twopi_s);
cos_t = (float) Math.cos(twopi_t);
sin_t = (float) Math.sin(twopi_t);
x = (or + ir * (float) cos_s) * (float) cos_t;
y = (or + ir * (float) cos_s) * (float) sin_t;
z = ir * (float) sin_s;
p.put(x);
p.put(y);
p.put(z);
nx = (float) cos_s * (float) cos_t;
ny = (float) cos_s * (float) sin_t;
nz = (float) sin_s;
q.put(nx);
q.put(ny);
q.put(nz);
}
}
}
}
// Log.d("cap",""+v+","+p+"");
v.position(0);
n.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, v);
gl.glNormalPointer(GL10.GL_FLOAT, 0, n);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
triangles = ((int) rings + 1) * 2;
for (i = 0; i < sides; i++) {
gl.glDrawArrays(GL10.GL_LINE_LOOP, triangles * i, triangles);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
/*
* I faild from glutes_geometory.c public static class WireTorus{ static int
* SIZEOF=4; static FloatBuffer vertex,normal; private static float
* parms[]=new float[4];//static static void draw( GL10 gl,float
* dInnerRadius, float dOuterRadius, int nSides, int nRings ) { float
* iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
*
* int i, j; float spsi, cpsi, sphi, cphi ;
*
* //maybe clear buffer. if (vertex!=null) { if (parms[0] != dInnerRadius ||
* parms[1] != dOuterRadius || parms[2] != nSides || parms[3] != nRings) {
*
* //free(v); //free(n); normal = vertex = null; //maybe free later.
*
* gl.glVertexPointer(3,
* GL10.GL_FLOAT,0,OpenGLUtils.allocateFloatBuffer(0));
* gl.glNormalPointer(GL10.GL_FLOAT,0,OpenGLUtils.allocateFloatBuffer(0)); }
* }
*
* if(vertex==null){ parms[0] = dInnerRadius; parms[1] = dOuterRadius;
* parms[2] = (float)nSides; parms[3] = (float)nRings;
*
* vertex = OpenGLUtils.allocateFloatBuffer( SIZEOF* 3 * nSides * nRings );
* normal = OpenGLUtils.allocateFloatBuffer( SIZEOF* 3 * nSides * nRings );
*
* // gl.glPushMatrix();
*
* dpsi = (float) (2.0f * Math.PI / (float)nRings) ; dphi = (float) (-2.0f *
* Math.PI / (float)nSides) ; psi = 0.0f;
*
* for( j=0; j * (float) Math.sin ( psi ) ; phi = 0.0f;
*
* for( i=0; i *
* cphi = (float) Math.cos ( phi ) ; sphi = (float) Math.sin ( phi ) ;
* vertex.put(cpsi * ( oradius + cphi * iradius )) ; vertex.put(spsi * (
* oradius + cphi * iradius )) ; vertex.put( sphi * iradius );
*
* normal.put(cpsi * cphi ); normal.put( spsi * cphi) ; normal.put( sphi) ;
* phi += dphi; }
*
* psi += dpsi; }
*
* vertex.position(0); normal.position(0);
*
* // glPopMatrix(); }
*
* gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
* //gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
*
* gl.glEnableClientState (GL10.GL_VERTEX_ARRAY); //gl.glEnableClientState
* (GL10.GL_NORMAL_ARRAY); for( j=0; j * gl.glDrawArrays(GL10.GL_LINE_LOOP, nRings*j, nRings); }
*
*
*
*
*
* gl.glDisableClientState (GL10.GL_VERTEX_ARRAY); gl.glDisableClientState
* (GL10.GL_NORMAL_ARRAY);
*
* } }
*/
public static void glutSolidSphere(GL10 gl, float radius, int slices,
int stacks) {
SolidSphere.draw(gl, radius, slices, stacks);
}
public static class SolidSphere {
public static void draw(GL10 gl, float radius, int slices, int stacks) {
int i, triangles;
if (sphereVertex != null) {
if (sphere_parms[0] != radius || sphere_parms[1] != slices
|| sphere_parms[2] != stacks) {
sphereVertex = null;
sphereNormal = null;
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (sphereVertex == null) {
sphere_parms[0] = radius;
sphere_parms[1] = (float) slices;
sphere_parms[2] = (float) stacks;
plotSpherePoints(radius, stacks, slices);
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);
gl.glNormalPointer(GL10.GL_FLOAT, 0, sphereNormal);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
triangles = (slices + 1) * 2;
for (i = 0; i < stacks; i++)
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * triangles,
triangles);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
public static void glutWireSphere(GL10 gl, float radius, int slices,
int stacks) {
WireSphere.draw(gl, radius, slices, stacks);
}
public static class WireSphere {
public static void draw(GL10 gl, float radius, int slices, int stacks) {
if (sphereVertex != null) {
if (sphere_parms[0] != radius || sphere_parms[1] != slices
|| sphere_parms[2] != stacks) {
sphereVertex = null;
sphereNormal = null;
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if (sphereVertex == null) {
sphere_parms[0] = radius;
sphere_parms[1] = (float) slices;
sphere_parms[2] = (float) stacks;
plotSpherePoints(radius, stacks, slices);
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);
gl.glNormalPointer(GL10.GL_FLOAT, 0, sphereNormal);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
int f;
for (int i = 0; i < stacks; ++i) {
f = i * (slices + 1);
for (int j = 0; j <= slices; ++j)
gl.glDrawArrays(GL10.GL_LINE_LOOP, (f + j) * 2, 3);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
static private FloatBuffer sphereVertex;
static private FloatBuffer sphereNormal;
static float sphere_parms[] = new float[3];
private static void plotSpherePoints(float radius, int stacks, int slices) {
sphereVertex = OpenGLUtils.allocateFloatBuffer(4 * 6 * stacks
* (slices + 1));
sphereNormal = OpenGLUtils.allocateFloatBuffer(4 * 6 * stacks
* (slices + 1));
int i, j;
float slicestep, stackstep;
stackstep = ((float) Math.PI) / stacks;
slicestep = 2.0f * ((float) Math.PI) / slices;
for (i = 0; i < stacks; ++i) {
float a = i * stackstep;
float b = a + stackstep;
float s0 = (float) Math.sin(a);
float s1 = (float) Math.sin(b);
float c0 = (float) Math.cos(a);
float c1 = (float) Math.cos(b);
float nv;
for (j = 0; j <= slices; ++j) {
float c = j * slicestep;
float x = (float) Math.cos(c);
float y = (float) Math.sin(c);
nv = x * s0;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
nv = y * s0;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
nv = c0;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
nv = x * s1;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
nv = y * s1;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
nv = c1;
sphereNormal.put(nv);
sphereVertex.put(nv * radius);
}
}
sphereNormal.position(0);
sphereVertex.position(0);
}
public static void glutSolidCone(GL10 gl, float base, float height,
int slices, int stacks) {
SolidCone.glutCone(gl, base, height, slices, stacks, true);
}
public static void glutWireCone(GL10 gl, float base, float height,
int slices, int stacks) {
SolidCone.glutCone(gl, base, height, slices, stacks, false);
}
static float cone_parms[] = new float[4];
static private FloatBuffer coneVertex;
static private FloatBuffer coneNormal;
public static class SolidCone {
static int SIZEOF = 4;
public static void glutCone(GL10 gl, float base, float height,
int slices, int stacks, boolean isSolid) {
int i, j;
float twopi, nx, ny, nz;
if (coneVertex != null) {
if (cone_parms[0] != base || cone_parms[1] != height
|| cone_parms[2] != slices || cone_parms[3] != stacks) {
coneVertex = null;
coneNormal = null;
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
OpenGLUtils.allocateFloatBuffer(0));
}
}
if ((coneVertex == null) && (height != 0.0f)) {
float phi = (float) Math.atan(base / height);
float cphi = (float) Math.cos(phi);
float sphi = (float) Math.sin(phi);
cone_parms[0] = base;
cone_parms[1] = height;
cone_parms[2] = (float) slices;
cone_parms[3] = (float) stacks;
coneVertex = OpenGLUtils.allocateFloatBuffer(stacks
* (slices + 1) * 2 * 3 * SIZEOF);
coneNormal = OpenGLUtils.allocateFloatBuffer(stacks
* (slices + 1) * 2 * 3 * SIZEOF);
twopi = 2.0f * ((float) Math.PI);
for (i = 0; i < stacks; i++) {
float r = base * (1.0f - (float) i / stacks);
float r1 = base * (1.0f - (float) (i + 1.0) / stacks);
float z = height * i / stacks;
float z1 = height * (1.0f + i) / stacks;
for (j = 0; j <= slices; j++) {
float theta = j == slices ? 0.f : (float) j / slices
* twopi;
float ctheta = (float) Math.cos(theta);
float stheta = (float) Math.sin(theta);
nx = ctheta;
ny = stheta;
nz = sphi;
coneVertex.put(r1 * nx);
coneVertex.put(r1 * ny);
coneVertex.put(z1);
coneNormal.put(nx * cphi);
coneNormal.put(ny * cphi);
coneNormal.put(nz);
coneVertex.put(r * nx);
coneVertex.put(r * ny);
coneVertex.put(z);
coneNormal.put(nx * cphi);
coneNormal.put(ny * cphi);
coneNormal.put(nz);
}
}
coneVertex.position(0);
coneNormal.position(0);
}
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, coneVertex);
gl.glNormalPointer(GL10.GL_FLOAT, 0, coneNormal);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (i = 0; i < stacks; i++) {
if (isSolid) {
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * (slices + 1)
* 2, (slices + 1) * 2);
} else {
gl.glDrawArrays(GL10.GL_LINE_LOOP, i * (slices + 1) * 2,
(slices + 1) * 2);
}
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
}