I am trying to run video on 3d surfaces in android. I am able to run it properly on a squareso I proceeded for a sphere. I found multiple algorithms and functions to generate sphere vertices and tex coords with or without indexes and tried them. Below are the two functions that are partially working 1st gives improperly mapped textures
public void sphere(final int depth, final float radius) {
// Clamp depth to the range 1 to MAXIMUM_ALLOWED_DEPTH;
final int d = Math.max(1, Math.min(MAXIMUM_ALLOWED_DEPTH, depth));
// Calculate basic values for the sphere.
this.mTotalNumStrips = power(2, d - 1) * VERTEX_MAGIC_NUMBER;
numVerticesPerStrip = power(2, d) * 3;
final double altitudeStepAngle = ONE_TWENTY_DEGREES / power(2, d);
final double azimuthStepAngle = THREE_SIXTY_DEGREES / mTotalNumStrips;
double x, y, z, h, altitude, azimuth; int vertexPos = 0;
int texturePos = 0;
//textureBuffer= new ArrayList<FloatBuffer>();
/** Mapping texture coordinates for the vertices. */
//mTexture = new ArrayList<float[]>();
//mVertices= new ArrayList<float[]>();
//mVertices = new float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX *mTotalNumStrips]; // NOPMD
// mTexture = new float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE * mTotalNumStrips]; // NOPMD
/*for (int stripNum = 0; stripNum < this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this strip.
// Calculate position of the first vertex in this strip.
altitude = NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVerticesPerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// First point - Texture.
mTexture[texturePos++] = (float) (1 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// Second point - Texture.
mTexture[texturePos++] = (float) (1 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
*/
mVertices = new float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX *mTotalNumStrips]; // NOPMD
mTexture = new float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE*mTotalNumStrips]; // NOPMD
for (int stripNum = 0; stripNum < this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this strip.
// int vertexPos = 0;
// int texturePos = 0;
// Calculate position of the first vertex in this strip.
altitude = NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVerticesPerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// First point - Texture.
mTexture[texturePos++] = (float) (1.0 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1.0 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// Second point - Texture.
mTexture[texturePos++] = (float) (1.0 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1.0 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
// this.mVertices.add(mVertices);
// this.mTexture.add(textureBuffer);
}
}
The 2nd working function gives me only half sphere on right side The function is as below
public void Sphere3D(//context:Context3D,
int slices,
int stacks)
// double posX, double posY,double posZ,
// double scaleX, double scaleY,double scaleZ)
{
// Make the model->world transformation matrix to position and scale the sphere
// Cap parameters
if (slices < MIN_SLICES)
{
slices = MIN_SLICES;
}
if (stacks < MIN_STACKS)
{
stacks = MIN_STACKS;
}
// Data we will later upload to the GPU
//var positions:Vector.<Number>;
//var texCoords:Vector.<Number>;
//var tris:Vector.<uint>;
// Pre-compute many constants used in tesselation
final double stepTheta = (2.0*Math.PI) / slices;
final double stepPhi = Math.PI / stacks;
final double stepU = 1.0 / slices;
final double stepV = 1.0 / stacks;
final int verticesPerStack = slices + 1;
final int numVertices = verticesPerStack * (stacks+1);
// Allocate the vectors of data to tesselate into
//positions = new Vector.<Number>(numVertices*3);
mVertices=new float[numVertices*3];
//texCoords = new Vector.<Number>(numVertices*2);
mTexture=new float[numVertices*2];
//tris = new Vector.<uint>(slices*stacks*6);
mIndexes= new short[slices*stacks*6];
// Pre-compute half the sin/cos of thetas
double halfCosThetas[] = new double[verticesPerStack];
double halfSinThetas[] = new double[verticesPerStack];
int curTheta= 0;
for (int slice=0; slice < verticesPerStack; ++slice)
{
halfCosThetas[slice] = Math.cos(curTheta) * 0.5;
halfSinThetas[slice] = Math.sin(curTheta) * 0.5;
curTheta += stepTheta;
}
// Generate positions and texture coordinates
double curV = 1.0;
double curPhi = Math.PI;
int posIndex=0;
int texCoordIndex=0;
for (int stack = 0; stack < stacks+1; ++stack)
{
double curU = 1.0;
double curY = Math.cos(curPhi) * 0.5;
double sinCurPhi = Math.sin(curPhi);
for (int slice = 0; slice < verticesPerStack; ++slice)
{
mVertices[posIndex++] = (float)(halfCosThetas[slice]*sinCurPhi);
mVertices[posIndex++] =(float) curY;
mVertices[posIndex++] = (float)(halfSinThetas[slice] * sinCurPhi);
mTexture[texCoordIndex++] = (float)curU;
mTexture[texCoordIndex++] = (float)curV;
curU -= stepU;
}
curV -= stepV;
curPhi -= stepPhi;
}
// Generate tris
int lastStackFirstVertexIndex= 0;
int curStackFirstVertexIndex = verticesPerStack;
int triIndex=0;
for (int stack = 0; stack < stacks; ++stack)
{
for (int slice = 0; slice < slices; ++slice)
{
// Bottom tri of the quad
mIndexes[triIndex++] = (short)(lastStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] = (short)(curStackFirstVertexIndex + slice);
mIndexes[triIndex++] = (short)(lastStackFirstVertexIndex + slice);
// Top tri of the quad
mIndexes[triIndex++] =(short)( lastStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] =(short)( curStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] =(short)( curStackFirstVertexIndex + slice);
}
lastStackFirstVertexIndex += verticesPerStack;
curStackFirstVertexIndex += verticesPerStack;
}
// Create vertex and index buffers
/*this.positions = context.createVertexBuffer(positions.length/3, 3);
this.positions.uploadFromVector(positions, 0, positions.length/3);
this.texCoords = context.createVertexBuffer(texCoords.length/2, 2);
this.texCoords.uploadFromVector(texCoords, 0, texCoords.length/2);
this.tris = context.createIndexBuffer(tris.length);
this.tris.uploadFromVector(tris, 0, tris.length);*/
}
what I need is mVertices , mIndees and mTexture to be filled with vertices , indices and texture respectively and if the function does not create indexed coordinates I am drawing normally.
I have been trying to understand the algorithm and detect the issue in both of them but unable to get any leads. Please let me know if further information is required