2011-09-21 26 views
5

Tôi muốn vẽ hình cầu trái đất trên Android. Tại thời điểm này tôi cần giúp đỡ với các tọa độ kết cấu UV. Tôi đang sử dụng kết cấu trái đất này (kibotu.net/earth.jpg). Hiện tại nó trông giống như mặt trước này (kibotu.net/earthsphere.png), nhưng 90 ° xoay nó trông như thế này (kibotu.net/earthsphere2.png).Kết cấu Android Sphere

Vì OpenGL ES không hỗ trợ Quadrics và nó không phải là một thư viện GLUT gốc tôi thấy nó khá khó khăn. Vì vậy, có thể ai đó đã gặp vấn đề tương tự và có thể giúp tôi.

Cách tiếp cận đầu tiên của tôi là sử dụng Máy xay sinh tố và xuất nó dưới dạng tệp OBJ và tải nó vào ứng dụng của tôi. Tuy nhiên có 2 tác dụng phụ: normals tìm kiếm hoàn toàn kỳ lạ (kibotu.net/sphere.png) và quan trọng nhất là không có tọa độ kết cấu.

(Tôi đã sử dụng những Blender Xuất Tùy chọn [kibotu.net/blenderobjoptions.png])

nỗ lực thứ hai của tôi là sử dụng thư viện freeglut để thực hiện công việc. Bây giờ tôi đã có một hình cầu đẹp (kibotu.net/sphere5.png). Tuy nhiên không có tọa độ kết cấu. Vì nó là phiên bản cuối cùng đã được phát hành vào ngày 27 tháng 11 năm 2009, tôi rất nghi ngờ rằng sẽ có một bản cập nhật bất cứ lúc nào sớm.

Vì vậy, sau đó tôi đã cố gắng áp dụng wiki approach to calculate sphere uvs. Tuy nhiên nó trông như thế này kibotu.net/sphere2.png. Tôi đã tìm kiếm tất cả các thread stackoverflow duy nhất sau khi vấn đề này và đi qua this uv approach. Tuy nhiên không có giải pháp cuối cùng. Tôi đã áp dụng nó vào mã freeglut.

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 < 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 <= 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 < 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 < 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); 
} 

Và các thuật toán vẽ:

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 < 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); 
    } 
} 

thể bất cứ ai giúp tôi tìm ra này xin vui lòng?

Trả lời

1

Bạn có thể lấy bất kỳ lưới tam giác nào cho một hình cầu (đơn vị) và áp dụng ánh xạ từ đỉnh (X, Y, Z) đến (UV).

Tôi quá lười/bận (xóa bất kỳ điều gì bạn muốn) để xem mã của bạn, nhưng bạn có thể tìm thấy câu trả lời trong chương 6 của Watt & "Kỹ thuật tạo hình và hiển thị nâng cao" của Watt. Nó đưa ra một số cách tiếp cận đơn giản để tạo ra các hợp kim UV thích hợp cho các hình cầu.

IIRC, để tránh quá méo ở cực, ánh xạ của chúng sử dụng sin để siết chặt/kéo giãn bản đồ vĩ độ.

+0

Giải pháp cuối cùng có thể được tìm thấy tại đây: https://github.com/kibotu/net.gtamps/blob/refactoring3d/android/graphic/src/net/gtamps/android/renderer/graph/scene/primitives/Sphere .java –

Các vấn đề liên quan