/* * 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.tid.opengljava; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; import android.util.Log; 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<nRings; j++ ) { cpsi = (float) Math.cos ( psi ) ; spsi = (float) Math.sin ( psi ) ; phi = 0.0f; for( i=0; i<nSides; 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<nRings; 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); } } }