zoukankan      html  css  js  c++  java
  • android应用开发揭秘第13章01示例,移动图像,opengl绘制星星问题解决!

    根据书上教程运行代码报错,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; //当前星星所处的角度
    }


    效果:


  • 相关阅读:
    Day4 0708
    Day2 0706
    两道递推公式题的解题报告
    博客还需优化
    飞行路线Luogu4568
    堆优化Dijkstra(Luogu 4779)
    2019四等奖的清明节征文
    2019四等奖的叶圣陶初稿
    Luogu P1072 Hankson的趣味题
    Loj10022 埃及分数(迭代加深搜索IDDFS)
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787306.html
Copyright © 2011-2022 走看看