您的位置:首页 > 移动开发 > Android开发

android应用开发揭秘第13章01示例,移动图像,opengl绘制星星问题解决!

2014-01-18 17:02 796 查看
根据书上教程运行代码报错,2.2的黑屏无效果,4.1的闪退。后研究发现,问题出在在一个物体同时启用了颜色数组和纹理,注释掉

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
运行即可。

核心代码如下

package com.xieyuan.test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Intent;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class GLRender implements Renderer{

private final static int ONE=0x10000;

//星星总数
private final static int NUM=50;
//存放星星的数组
private Star[] stars=new Star[NUM];

//闪烁的星星
boolean twinkle=true;

//离观察者的距离
float ZOOM=-10f;
//星星的倾角
float tilt=90f;
//闪烁星星的自转
float spin;

private boolean key;
Random random=new Random();

//纹理ID
private int texture;

IntBuffer coord=GLNioUtil.IntBufferUtil(new int[]{
0,0,ONE,0,ONE,ONE,0,ONE
});
IntBuffer vertexs=GLNioUtil.IntBufferUtil(new int[]{
-ONE-ONE,0,
ONE,-ONE,0,
ONE,ONE,0,
-ONE,ONE,0
});
ByteBuffer indices=GLNioUtil.ByteBufferUtil(new byte[]{
1,0,2,3
});

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//清除屏幕为黑色背景
gl.glClearColor(0f, 0f, 0f, 0f);
//透视修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

//创建纹理
IntBuffer intBuffer=IntBuffer.allocate(1);
gl.glGenTextures(1, intBuffer);
texture=intBuffer.get();
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap[3], 0);

//启用纹理映射
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0f, 0f, 0f, 0.5f);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
//设置混色函数
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
//启用混色
gl.glEnable(GL10.GL_BLEND);

for(int i=0;i<NUM;i++){
Star star=new Star();
star.angle=0f; //所有星星的角度都是从0开始
star.dist=(float)i/(float)NUM*5.0f; //计算星星里中间的距离
star.r=random.nextInt(256);			// 为star[loop]设置随机红色分量
star.g=random.nextInt(256);			// 为star[loop]设置随机红色分量
star.b=random.nextInt(256);			// 为star[loop]设置随机红色分量
stars[i] = star;
}
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio=(float)width/(float)height;
//设置场景大小
gl.glViewport(0, 0, width, height);
//设置投影举证
gl.glMatrixMode(GL10.GL_PROJECTION);
//重置投影矩阵
gl.glLoadIdentity();
//设置视口大小
gl.glFrustumf(-ratio, ratio, -1,1, 1, 10);
//设置模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}

@Override
public void onDrawFrame(GL10 gl) {
//清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
//选择纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
for(int i=0;i<NUM;i++){
gl.glLoadIdentity();
// 深入屏幕里面
gl.glTranslatef(0f, 0f, ZOOM);
// 倾斜视角
gl.glRotatef(tilt, 1f, 0f, 0f);
// 旋转至当前所画星星的角度
gl.glRotatef(stars[i].angle,0f,1f,0f);
// 沿X轴正向移动
gl.glTranslatef(stars[i].dist, 0f, 0f);
// 取消当前星星的角度
gl.glRotatef(-stars[i].angle, 0f, 1f, 0f);
// 取消屏幕倾斜
gl.glRotatef(-tilt, 1f, 0f, 0f);

//设置顶点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//设置颜色数组
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// 启用闪烁效果
if(twinkle){
// 使用byte型数值指定一个颜色
gl.glColor4f((float)stars[NUM-i-1].r/255f,
(float)stars[NUM-i-1].g/255f,
(float)stars[NUM-i-1].b/255f,
1f
);
gl.glVertexPointer(3, GL10.GL_FIXED, 0,vertexs);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coord);

coord.position(0);
vertexs.position(0);
indices.position(0);

//gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE,indices);

gl.glFinish();
}
//绕z轴旋转星星
gl.glRotatef(spin, 0f,0f,1f);
// 使用byte型数值指定一个颜色
gl.glColor4f((float)stars[(NUM-i)-1].r/255.0f,(float)stars[(NUM-i)-1].g/255.0f,(float)stars[(NUM-i)-1].b/255.0f,1.0f);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexs);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coord);

coord.position(0);
vertexs.position(0);
indices.position(0);

//绘制正方形结束
gl.glFinish();

// gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
//取消顶点数组
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

spin+=0.01f;					// 星星的公转
stars[i].angle+=(float)(i)/(float)NUM;		// 改变星星的自转角度
stars[i].dist-=0.01f;				// 改变星星离中心的距离

if (stars[i].dist<0.0f)			// 星星到达中心了么
{
stars[i].dist+=5.0f;			// 往外移5个单位
stars[i].r=random.nextInt(256);		// 赋一个新红色分量
stars[i].g=random.nextInt(256);		// 赋一个新绿色分量
stars[i].b=random.nextInt(256);		// 赋一个新蓝色分量
}

}

}

}

class Star{
int r,g,b;
float dist;  //星星距离中心的距离
float angle=0f; //当前星星所处的角度
}


效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: