public void onSurfaceCreated(GL10 gl, EGLConfig config) {
initOpenGLVertexs() ;
}
private FloatBuffer vertexBuffer = null ;
private FloatBuffer normalBuffer = null ;
private int vertexCount = 0 ;
private void glesNormalize(float[] v, int offset) {
float len = (float) Math.sqrt(v[offset+0] * v[offset+0] + v[offset+1] * v[offset+1] + v[offset+2] * v[offset+2]);
v[offset+0] /= len;
v[offset+1] /= len;
v[offset+2] /= len;
}
private void initOpenGLVertexs(){
int slices = 180 ;
int stacks = 90 ;
float radius = 100f ;
double perAngleW = 2 * Math.PI / slices;
double perAngleH = Math.PI / stacks;
float[] vertexArray = new float[slices*stacks*2*3*3];
float[] normalArray = new float[slices*stacks*2*3*3];
int vertexIndex = 0 ;
int normalIndex = 0 ;
for (int a = 0; a < stacks; a++) {
for (int b = 0; b < slices; b++) {
float x1 = (float) (radius * Math.sin(a * perAngleW) * Math.cos(b* perAngleH));
float z1 = (float) (radius * Math.sin(a * perAngleW) * Math.sin(b* perAngleH));
float y1 = (float) (radius * Math.cos(a * perAngleW));
float x2 = (float) (radius * Math.sin((a + 1) * perAngleW) * Math.cos(b * perAngleH));
float z2 = (float) (radius * Math.sin((a + 1) * perAngleW) * Math.sin(b * perAngleH));
float y2 = (float) (radius * Math.cos((a + 1) * perAngleW));
float x3 = (float) (radius * Math.sin((a + 1) * perAngleW) * Math.cos((b + 1) * perAngleH));
float z3 = (float) (radius * Math.sin((a + 1) * perAngleW) * Math.sin((b + 1) * perAngleH));
float y3 = (float) (radius * Math.cos((a + 1) * perAngleW));
float x4 = (float) (radius * Math.sin(a * perAngleW) * Math.cos((b + 1) * perAngleH));
float z4 = (float) (radius * Math.sin(a * perAngleW) * Math.sin((b + 1) * perAngleH));
float y4 = (float) (radius * Math.cos(a * perAngleW));
vertexArray[vertexIndex++] = (x1);
vertexArray[vertexIndex++] = (y1);
vertexArray[vertexIndex++] = (z1);
vertexArray[vertexIndex++] = (x2);
vertexArray[vertexIndex++] = (y2);
vertexArray[vertexIndex++] = (z2);
vertexArray[vertexIndex++] = (x3);
vertexArray[vertexIndex++] = (y3);
vertexArray[vertexIndex++] = (z3);
vertexArray[vertexIndex++] = (x3);
vertexArray[vertexIndex++] = (y3);
vertexArray[vertexIndex++] = (z3);
vertexArray[vertexIndex++] = (x4);
vertexArray[vertexIndex++] = (y4);
vertexArray[vertexIndex++] = (z4);
vertexArray[vertexIndex++] = (x1);
vertexArray[vertexIndex++] = (y1);
vertexArray[vertexIndex++] = (z1);
normalArray[normalIndex++] = (x1);
normalArray[normalIndex++] = (y1);
normalArray[normalIndex++] = (z1);
glesNormalize(normalArray, normalIndex-3);
normalArray[normalIndex++] = (x2);
normalArray[normalIndex++] = (y2);
normalArray[normalIndex++] = (z2);
glesNormalize(normalArray, normalIndex-3);
normalArray[normalIndex++] = (x3);
normalArray[normalIndex++] = (y3);
normalArray[normalIndex++] = (z3);
glesNormalize(normalArray, normalIndex-3);
normalArray[normalIndex++] = (x3);
normalArray[normalIndex++] = (y3);
normalArray[normalIndex++] = (z3);
glesNormalize(normalArray, normalIndex-3);
normalArray[normalIndex++] = (x4);
normalArray[normalIndex++] = (y4);
normalArray[normalIndex++] = (z4);
glesNormalize(normalArray, normalIndex-3);
normalArray[normalIndex++] = (x1);
normalArray[normalIndex++] = (y1);
normalArray[normalIndex++] = (z1);
glesNormalize(normalArray, normalIndex-3);
}
}
vertexCount = vertexArray.length / 3;
vertexBuffer = ByteBuffer.allocateDirect(vertexArray.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuffer.put(vertexArray);
vertexBuffer.position(0);
normalBuffer = ByteBuffer.allocateDirect(normalArray.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
normalBuffer.put(normalArray);
normalBuffer.position(0);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES10.glViewport(0, 0, width, height); // 设置视口宽度高度。
GLES10.glEnable(GLES10.GL_DEPTH_TEST); // 开启深度测试
// {修改投影矩阵
GLES10.glMatrixMode(GLES10.GL_PROJECTION); // 修改投影矩阵
GLES10.glLoadIdentity(); // 复位,将投影矩阵归零
GLU.gluPerspective(gl, 60.0f, ((float) width) / height, 0.1f, 400f);
// }
//{
GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
GLES10.glLoadIdentity();//归零模型视图
GLU.gluLookAt(gl, 0, 0, 300, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//}
GLES10.glEnable(GLES10.GL_LIGHTING);
GLES10.glEnable(GLES10.GL_LIGHT0);
GLES10.glLightfv(GLES10.GL_LIGHT0, GLES10.GL_POSITION, new float[]{100, 200, 300, 0}, 0);
}
接下来我们需要创建一个材质。材质属性是一个全局状态量,当你设置到OpenGL之后,除非手动更改它,那画任意物体都会引用这个材质信息。由于我们只有一个球,没有多个物体,不需要切换,所以可以在前面只指定一次即可。
private float[] ambient = null ;
private float[] diffuse = null ;
private float[] specular = null ;
private float[] emmissive = null ;
private float shininess = 0.0f ;
private void initOpenGLMaterial(){
ambient = new float[]{0.0f,0.2f,0.0f,1.0f};
diffuse = new float[]{0.0f,0.8f,0.0f,1.0f};
specular = new float[]{0.6f,0.6f,0.6f,1.0f};
emmissive = new float[]{0.0f,0.1f,0.0f,1.0f};
shininess = 20f ;
GLES10.glMaterialfv(
GLES10.GL_FRONT_AND_BACK,
GLES10.GL_AMBIENT,
this.ambient, 0);
GLES10.glMaterialfv(
GLES10.GL_FRONT_AND_BACK,
GLES10.GL_DIFFUSE,
this.diffuse, 0);
GLES10.glMaterialfv(
GLES10.GL_FRONT_AND_BACK,
GLES10.GL_SPECULAR,
this.specular, 0);
GLES10.glMaterialfv(
GLES10.GL_FRONT_AND_BACK,
GLES10.GL_EMISSION,
this.emmissive, 0);
GLES10.glMaterialf(
GLES10.GL_FRONT_AND_BACK,
GLES10.GL_SHININESS,
this.shininess);
}
然后在onSurfaceCreated里调用initOpenGLMaterial吧。
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
initOpenGLVertexs() ;
initOpenGLMaterial();
}
public void onDrawFrame(GL10 gl) {
GLES10.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 清空场景为黑色。
GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT | GLES10.GL_DEPTH_BUFFER_BIT);// 清空相关缓存。
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
GLES10.glVertexPointer(3, GLES10.GL_FLOAT, 0, vertexBuffer);
GLES10.glEnableClientState(GLES10.GL_NORMAL_ARRAY);
GLES10.glNormalPointer(GLES10.GL_FLOAT, 0, normalBuffer);
GLES10.glDrawArrays(GLES10.GL_TRIANGLES, 0, vertexCount);
GLES10.glFlush();
}