如何使用OpenGLES映射Android的球体

时间:2016-04-11 12:06:17

标签: java android opengl-es

我使用OpenGLES 2.0为Android绘制一个地球仪,但我得到了有线纹理绘图,纹理坐标有问题。有人可以帮帮我吗?这是我的球体结构:

  Sphere( Context context0, float r, int nSTACKS, int nSLICES ){
    context = context0;
    // get shader codes from res/raw/vshader and res/raw/fshader
    vsCode = getShaderCode( GLES20.GL_VERTEX_SHADER );
    fsCode = getShaderCode( GLES20.GL_FRAGMENT_SHADER );
    program = GLES20.glCreateProgram(); // create empty OpenGL ES Program
    vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vsCode );
    fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fsCode );
    GLES20.glAttachShader ( program, vertexShader ); // add the vertex shader to program
    GLES20.glAttachShader(program, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(program);                  // creates OpenGL ES program executables
    GLES20.glUseProgram( program);

    createSphere (r, nSLICES, nSTACKS );
    int nVertices = vertices.size();
    int k = 0;
    int m = nSTACKS;
    int n = nSLICES;
    float uTexture = 0;
    float vTexture = 0;
    // 2n(m-1) slices + 2(m-2)n stacks
    nTriangles = 2 * n * (m - 1);    //number of triangles
    drawOrders = new short[nTriangles][3];
    for ( int j = 0; j < n; j++ )
    {
        for ( int i = 0; i < m-1; i++ ) {
            short j1 = (short)(j + 1);
            if ( j == n - 1 ) j1 = 0;   //wrap around
            short ia = (short)( j * m + i ) ;
            short ib = (short)( j * m + i + 1);
            short ic = (short) (j1 * m + i );
            short id = (short)( j1 * m + i + 1 );

            drawOrders[k] = new short[3];
            drawOrders[k][0] = ia;
            drawOrders[k][1] = ib;
            drawOrders[k][2] = ic;
            k++;
            drawOrders[k] = new short[3];
            drawOrders[k][0] = ic;
            drawOrders[k][1] = ib;
            drawOrders[k][2] = id;
            k++;
        }
    }

    System.out.printf("k=%d, nTriangles=%d\n", k, nTriangles);
    float sphereCoords[] = new float[3*nVertices];
    k = 0;
    for ( int i = 0; i < nVertices; i++ ) {
        XYZ v = vertices.get ( i );
        sphereCoords[k++] = v.x;
        sphereCoords[k++] = v.y;
        sphereCoords[k++] = v.z;
    }

    //vertexBuffer
    ByteBuffer bb = ByteBuffer.allocateDirect(sphereCoords.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(sphereCoords);
    vertexBuffer.position(0);

    //texture
    float textureCoords[] = new float[2 * textures.size()];
    k = 0;
    for ( int i = 0; i < nVertices; i++ ) {
        UV w = textures.get ( i );
        textureCoords[k++] = w.u;
        textureCoords[k++] = w.v;
    }

    //textureCoordBuffer
    ByteBuffer bbtexture = ByteBuffer.allocateDirect(textureCoords.length * 4);
    bbtexture.order(ByteOrder.nativeOrder());
    textureCoordBuffer = bbtexture.asFloatBuffer();
    textureCoordBuffer.put(textureCoords);
    textureCoordBuffer.position(0);

    sphereIndices = new ShortBuffer[nTriangles];
    for ( int i = 0; i < nTriangles; i++) {
        ByteBuffer bbIndices = ByteBuffer.allocateDirect(
                // (# of coordinate values * 2 bytes per short)
                drawOrders[i].length * 2);

        bbIndices.order(ByteOrder.nativeOrder());
        sphereIndices[i] = bbIndices.asShortBuffer();
        sphereIndices[i].put( drawOrders[i] );
        sphereIndices[i].position(0);
    }
} // Sphere Constructor

private void createSphere ( float r, int nSlices, int nStacks )
{
    double phi,  theta;
    XYZ p = new XYZ();
    final double PI = 3.1415926;
    final double TWOPI = 2 * PI;

    UV t = new UV();

    for ( int j = 0; j < nSlices; j++ ) {
        phi = j * TWOPI / nSlices;
        for ( int i = 0; i < nStacks; i++ ) {
            theta = i * PI / (nStacks-1);  //0 to pi
            p.x = r * (float) (Math.sin ( theta ) * Math.cos(phi));
            p.y = r * (float) (Math.sin ( theta ) * Math.sin(phi));
            p.z = r * (float) Math.cos ( theta );
            vertices.add ( new XYZ ( p ) );

            t.u = (float)(p.x * 2 * PI);
            t.v = (float)((p.y - 0.5) *PI);
            textures.add(new UV(t));
        }
    }
}

我得到了这个纹理: enter image description here 有人可以帮我调整纹理坐标吗?感谢~~~

0 个答案:

没有答案