简体   繁体   English

Android纹理球体

[英]Android textured Sphere

I want to draw an earth globe on android. 我想在android上绘制一个地球地球仪。 At this point I need help with the UV texture coordinates. 此时我需要UV纹理坐标的帮助。 I'm using this earth texture (kibotu.net/earth.jpg). 我正在使用这个地球纹理(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). 目前它看起来像这个正面(kibotu.net/earthsphere.png),但90°旋转它看起来像这样(kibotu.net/earthsphere2.png)。

Since OpenGL ES doesn't support Quadrics and it has not a native GLUT library I find it rather difficult. 由于OpenGL ES不支持Quadrics,并且它没有原生GLUT库,我觉得它很难。 So maybe someone came across the same Problem and can help me. 所以也许有人遇到同样的问题,可以帮助我。

My first approach was to use Blender and export it as OBJ File and load it into my application. 我的第一种方法是使用Blender并将其导出为OBJ文件并将其加载到我的应用程序中。 However there are 2 side effects: totally weird looking normals (kibotu.net/sphere.png) and most importantly no texture coordinates. 然而,有两个副作用:完全奇怪的看起来正常(kibotu.net/sphere.png),最重要的是没有纹理坐标。

(I've used these Blender Export Options [kibotu.net/blenderobjoptions.png]) (我使用过这些Blender导出选项[kibotu.net/blenderobjoptions.png])

My second attempt was to use the freeglut library to do the job. 我的第二次尝试是使用freeglut库来完成这项工作。 Now I've got a nice looking sphere (kibotu.net/sphere5.png). 现在我有一个漂亮的球体(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. 由于它的最后一个版本于2009年11月27日发布,我非常怀疑将很快发布更新。

So after that I've tried to apply the wiki approach to calculate sphere uvs . 所以在那之后我尝试应用wiki方法来计算球体uvs However it looked like this kibotu.net/sphere2.png. 但它看起来像这个kibotu.net/sphere2.png。 I was searching every single stackoverflow thread after this problem and came across this uv approach . 我在这个问题之后搜索每个stackoverflow线程,并遇到了这种uv方法 However there is no final solution. 然而,没有最终解决方案。 I've applied it to the freeglut code. 我已将它应用于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);
}

And the drawing algorithm: 和绘图算法:

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

Can anyone help me figuring this out please? 谁能帮我解决这个问题呢?

You should be able to take any triangle mesh for a (unit) sphere and apply a mapping from vertex (X,Y,Z) to (UV). 您应该能够为(单位)球体采用任何三角形网格,并应用从顶点(X,Y,Z)到(UV)的映射。

I'm too lazy / busy (delete whichever you wish) to go through your code, but you might find the answer in chapter 6 of Watt & Watt's "Advanced Animation and Rendering Techniques". 我太懒/忙(删除任何你想要的)来完成你的代码,但你可能会在Watt&Watt的“高级动画和渲染技术”的第6章找到答案。 It gives some simple approaches to generating suitable UV coords for spheres. 它提供了一些简单的方法来为球体生成合适的UV线。

IIRC, to avoid too much distortion at the poles, their mapping uses sine to squeeze/stretch the latitude mapping. IIRC,为了避免极点处的太多失真,它们的映射使用正弦来挤压/拉伸纬度映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM