package edu.union;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class SphereGenerator {
FloatBuffer strip, fan_top, fan_bottom;
FloatBuffer tex_strip, tex_fan_top, tex_fan_bottom;
float radius;
int stacks, slices;
int tex;
public SphereGenerator(int tex, int stacks, int slices, float radius) {
this.tex = tex;
this.stacks = stacks;
this.slices = slices;
this.radius = radius;
unitSphere(stacks, slices);
}
public void draw(GL10 gl) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fan_top);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, fan_top);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tex_fan_top);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices + 2);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, strip);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, strip);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (slices + 1) * 2 * stacks);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fan_bottom);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, fan_bottom);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tex_fan_bottom);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices + 2);
}
protected FloatBuffer[] makeEndCap(int stacks, int slices, boolean top) {
// Calculate the Triangle Fan for the endcaps
int triangleFanVertexCount = slices + 2;
float dtheta = (float)(2.0 * Math.PI / slices);
float drho = (float)(Math.PI / stacks);
float[] fanVertices = new float[triangleFanVertexCount * 3];
float[] fanTextures = new float[triangleFanVertexCount * 2];
float theta = 0;
float sin_drho = (float)Math.sin(drho);
//float cos_drho = (float)Math.cos(Math.PI / stacks);
int tex_index = 0;
fanTextures[tex_index++] = (top ? 0 : 1.0f);
fanTextures[tex_index++] = 0.5f;
int index = 0;
fanVertices[index++] = 0.0f;
fanVertices[index++] = 0.0f;
fanVertices[index++] = (top ? 1 : -1);
for (int j = 0; j <= slices; j++)
{
theta = (j == slices) ? 0.0f : j * (top ? 1 : -1) * dtheta;
float x = (float)-Math.sin(theta) * sin_drho;
float y = (float)Math.cos(theta) * sin_drho;
float z = (top ? 1 : -1) * (float)Math.cos(drho);
fanTextures[tex_index++] = x;
fanTextures[tex_index++] = y;
fanVertices[index++] = x;
fanVertices[index++] = y;
fanVertices[index++] = z;
}
FloatBuffer[] result = new FloatBuffer[2];
result[0] = GLTutorialBase.makeFloatBuffer(fanVertices);
result[1] = GLTutorialBase.makeFloatBuffer(fanTextures);
return result;
}
protected void unitSphere(int stacks, int slices) {
float drho = (float)(Math.PI / stacks);
float dtheta = (float)(2.0 * Math.PI / slices);
FloatBuffer[] buffs = makeEndCap(stacks, slices, true);
fan_top = buffs[0];
tex_fan_top = buffs[1];
buffs = makeEndCap(stacks, slices, false);
fan_bottom = buffs[0];
tex_fan_bottom = buffs[1];
// Calculate the triangle strip for the sphere body
int triangleStripVertexCount = (slices + 1) * 2 * stacks;
float[] stripVertices = new float[triangleStripVertexCount * 3];
int index = 0;
for (int i = 0; i < stacks; i++) {
float rho = i * drho;
for (int j = 0; j <= slices; j++)
{
float theta = (j == slices) ? 0.0f : j * dtheta;
float x = (float)(-Math.sin(theta) * Math.sin(rho));
float y = (float)(Math.cos(theta) * Math.sin(rho));
float z = (float)Math.cos(rho);
// TODO: Implement texture mapping if texture used
// TXTR_COORD(s, t);
stripVertices[index++] = x;
stripVertices[index++] = y;
stripVertices[index++] = z;
x = (float)(-Math.sin(theta) * Math.sin(rho + drho));
y = (float)(Math.cos(theta) * Math.sin(rho + drho));
z = (float)Math.cos(rho + drho);
// TODO: Implement texture mapping if texture used
// TXTR_COORD(s, t);
stripVertices[index++] = x;
stripVertices[index++] = y;
stripVertices[index++] = z;
}
}
strip = GLTutorialBase.makeFloatBuffer(stripVertices);
}
}