我使用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));
}
}
}