title: Android textured Sphere
body: <p>I want to draw an earth globe on android. At this point I need help with the UV texture coordinates. I'm using this earth texture (kibotu.net/earth.jpg). Currently it looks like this front side (kibotu.net/earthsphere.png), but 90° rotated it looks like this (kibotu.net/earthsphere2.png).</p>
  
  <p>Since OpenGL ES doesn't support Quadrics and it has not a native GLUT library I find it rather difficult. So maybe someone came across the same Problem and can help me. </p>
  
  <p>My first approach was to use Blender and export it as OBJ File and load it into my application. However there are 2 side effects: totally weird looking normals (kibotu.net/sphere.png) and most importantly no texture coordinates.</p>
  
  <p>(I've used these Blender Export Options [kibotu.net/blenderobjoptions.png])</p>
  
  <p>My second attempt was to use the <a href="http://freeglut.sourceforge.net/" rel="nofollow noreferrer">freeglut</a> library to do the job. Now I've got a nice looking sphere (kibotu.net/sphere5.png). However there are no texture coordinates either. Since it's last version was released on 27 November 2009 I very much doubt that there will be an update any time soon.</p>
  
  <p>So after that I've tried to apply the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/UV_mapping" rel="nofollow noreferrer">wiki approach to calculate sphere uvs</a>. However it looked like this kibotu.net/sphere2.png. I was searching every single stackoverflow thread after this problem and came across <a href="https://stackoverflow.com/questions/7228683/uv-mapping-opengles">this uv approach</a>. However there is no final solution. I've applied it to the freeglut code.</p>
  
  <pre><code>static private FloatBuffer sphereVertex;
  static private FloatBuffer sphereNormal;
  static private FloatBuffer sphereTexture;
  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) );
      sphereTexture = OpenGLUtils.allocateFloatBuffer( 4* 4 * stacks * (slices+1) );
  
      int i, j; 
      float slicestep, stackstep;
  
      stackstep = ((float)Math.PI) / stacks;
      slicestep = 2.0f * ((float)Math.PI) / slices;
  
      int counter = 0;
  
      for (i = 0; i &lt; 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,u,v,dx,dy,dz;
          for (j = 0; j &lt;= 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( dx = nv * radius);
  
              nv=y * s0;
              sphereNormal.put(nv);
              sphereVertex.put( dy = nv * radius);
  
              nv=c0;
  
              sphereNormal.put(nv);
              sphereVertex.put( dz = nv * radius);
              // uv 1
              if (dz &lt; 0)
                  u = (float) (1 + dx/Math.sqrt(dx*dx+dy*dy+dz*dz)  / 4);
              else
                  u = (float) (1 - (1 + dx/Math.sqrt(dx*dx+dy*dy+dz*dz) ) / 4);
  
              v = (float) (0.5 + ( -dy/Math.sqrt(dx*dx+dy*dy+dz*dz) ) /2);
  
              // u = (float) (dx / Math.sqrt(dx*dx + dy*dy +dz*dz));
              // v = (float) (dy / Math.sqrt(dx*dx + dy*dy +dz*dz));
              sphereTexture.put(u);
              sphereTexture.put(v);
  
              nv=x * s1;
  
              sphereNormal.put(nv);
              sphereVertex.put( dx = nv * radius);
  
              nv=y * s1;
  
              sphereNormal.put(nv);
              sphereVertex.put( dy = nv * radius);
  
              nv=c1;
  
              sphereNormal.put(nv);
              sphereVertex.put( dz = nv * radius);
  
              // uv 2
              if (dz &lt; 0)
                  u = (float) (1 + dx/Math.sqrt(dx*dx+dy*dy+dz*dz)  / 4);
              else
                  u = (float) (1 - (1 + dx/Math.sqrt(dx*dx+dy*dy+dz*dz) ) / 4);
  
              v = (float) (0.5 + ( -dy/Math.sqrt(dx*dx+dy*dy+dz*dz) ) /2);
  
              sphereTexture.put(u);
              sphereTexture.put(v);
          }
      }
      sphereNormal.position(0);
      sphereVertex.position(0);
      sphereTexture.position(0);
  }
  </code></pre>
  
  <p>And the drawing algorithm: </p>
  
  <pre><code>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;
                  sphereTexture = null;
  
                  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, OpenGLUtils.allocateFloatBuffer(0));
                  gl.glNormalPointer(GL10.GL_FLOAT, 0, OpenGLUtils.allocateFloatBuffer(0));
                  gl.glTexCoordPointer(2, 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.glTexCoordPointer(2, GL10.GL_FLOAT, 0, sphereTexture);
  
          gl.glEnableClientState (GL10.GL_VERTEX_ARRAY);
          gl.glEnableClientState (GL10.GL_NORMAL_ARRAY);
          gl.glEnableClientState (GL10.GL_TEXTURE_COORD_ARRAY);
  
          triangles = (slices + 1) * 2;
          for(i = 0; i &lt; stacks; i++)
              gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * triangles, triangles);
  
          gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
          gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
          gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
      }
  }
  </code></pre>
  
  <p>Can anyone help me figuring this out please?</p>