织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>嵌入式开发>Android>

android3D场景绘制1——房间的绘制

落鹤生 发布于 2013-10-27 15:01 点击:次 
相信大家都会画矩形了,下面我们来画一个房间,大家想想怎么画了,我以前想用索引法把每个面都画出来,但是遇到了很多问题,画不出我想要的结果,其实还有 种方法,那就是通过旋转,和位移变换,把矩形旋转和位移到长方体的各个面,再加工一下,这样就变成小房间了
TAG:

相信大家都会画矩形了,下面我们来画一个房间,大家想想怎么画了,我以前想用索引法把每个面都画出来,但是遇到了很多问题,画不出我想要的结果,其实还有 种方法,那就是通过旋转,和位移变换,把矩形旋转和位移到长方体的各个面,再加工一下,这样就变成小房间了,下面我们来看看效果和代码吧。

\

GLSurfaceViewActivity.java

  1. package yy.cal;  
  2.  
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.LinearLayout;  
  6.  
  7. public class GLSurfaceViewActivity extends Activity {  
  8.     private MySurfaceView mSurfaceView;//声明MySurfaceView对象  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);       
  12.         mSurfaceView=new MySurfaceView(this);//创建MySurfaceView对象  
  13.         mSurfaceView.requestFocus();//获取焦点  
  14.         mSurfaceView.setFocusableInTouchMode(true);//设置为可触控  
  15.         LinearLayout ll=(LinearLayout)this.findViewById(R.id.main_liner);//获得线性布局的引用  
  16.         ll.addView(mSurfaceView);  
  17.     }  
  18.  
  19.     @Override  
  20.     protected void onPause() {  
  21.         // TODO Auto-generated method stub  
  22.         super.onPause();  
  23.         mSurfaceView.onPause();  
  24.     }  
  25.  
  26.     @Override  
  27.     protected void onResume() {  
  28.         // TODO Auto-generated method stub  
  29.         super.onResume();  
  30.         mSurfaceView.onResume();  
  31.     }    

MySurfaceView.java

  1. package yy.cal;  
  2.  
  3. import javax.microedition.khronos.egl.EGLConfig;  
  4. import javax.microedition.khronos.opengles.GL10;  
  5. import android.content.Context;  
  6. import android.opengl.GLSurfaceView;  
  7. import android.opengl.GLU;  
  8. import android.view.MotionEvent;  
  9.  
  10. public class MySurfaceView extends GLSurfaceView{  
  11.     private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度缩放比例  
  12.     private SceneRenderer mRenderer;//场景渲染器   
  13.     private float mPreviousX;//上次的触控位置X坐标  
  14.    
  15.     public MySurfaceView(Context context) {  
  16.         super(context);  
  17.         mRenderer = new SceneRenderer();    //创建场景渲染器  
  18.         setRenderer(mRenderer);             //设置渲染器       
  19.         setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染     
  20.     }  
  21.     
  22.     //触摸事件回调方法  
  23.     @Override   
  24.     public boolean onTouchEvent(MotionEvent e) {  
  25.         float x = e.getX();  
  26.         switch (e.getAction()) {  
  27.         case MotionEvent.ACTION_MOVE:  
  28.             float dx = x - mPreviousX;//计算触控笔X位移  
  29.             mRenderer.angle += dx * TOUCH_SCALE_FACTOR;//设置沿x轴旋转角度  
  30.               
  31.             requestRender();//重绘画面  
  32.         }     
  33.         mPreviousX = x;//记录触控笔位置  
  34.         return true;  
  35.     }  
  36.  
  37.     private class SceneRenderer implements GLSurfaceView.Renderer   
  38.     {     
  39.         Cube cube=new Cube();//立方体  
  40.         float angle=45;//总旋转角度  
  41.           
  42.         public void onDrawFrame(GL10 gl) {  
  43.             //设置为打开背面剪裁  
  44.             gl.glEnable(GL10.GL_CULL_FACE);  
  45.  
  46.            //设置着色模型为平滑着色     
  47.             gl.glShadeModel(GL10.GL_SMOOTH);  
  48.               
  49.             //清除颜色缓存于深度缓存  
  50.             gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  51.             //设置当前矩阵为模式矩阵  
  52.             gl.glMatrixMode(GL10.GL_MODELVIEW);  
  53.             //设置当前矩阵为单位矩阵  
  54.             gl.glLoadIdentity();      
  55.               
  56.             GLU.gluLookAt//不太可能变形的视角——小视角  
  57.             (  
  58.                     gl,   
  59.                     0f,   //人眼位置的X  
  60.                     10f,    //人眼位置的Y  
  61.                     15.0f,   //人眼位置的Z  
  62.                     0,  //人眼球看的点X  
  63.                     0f,   //人眼球看的点Y  
  64.                     0,   //人眼球看的点Z  
  65.                     0,   
  66.                     1,   
  67.                     0  
  68.             );    
  69.               
  70.  
  71.             //旋转总坐标系  
  72.             gl.glRotatef(angle, 0, 1, 0);  
  73.               
  74.             //绘制右立方体  
  75.             gl.glPushMatrix();  
  76.            // gl.glTranslatef(2, 0, 0);  
  77.             cube.drawSelf(gl);  
  78.             gl.glPopMatrix();  
  79.         }  
  80.  
  81.         public void onSurfaceChanged(GL10 gl, int width, int height) {  
  82.             //设置视窗大小及位置   
  83.             gl.glViewport(0, 0, width, height);  
  84.             //设置当前矩阵为投影矩阵  
  85.             gl.glMatrixMode(GL10.GL_PROJECTION);  
  86.             //设置当前矩阵为单位矩阵  
  87.             gl.glLoadIdentity();  
  88.             //计算透视投影的比例  
  89.             float ratio = (float) height/width ;  
  90.             //调用此方法计算产生透视投影矩阵  
  91.             //gl.glFrustumf( -1, 1,-ratio, ratio, 1, 100);   //可能变形的视角——大视角    
  92.             gl.glFrustumf( -1, 1,-ratio, ratio, 8f, 100);     //不太可能变形的视角——小视角  
  93.         }  
  94.   
  95.         public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  96.             //关闭抗抖动   
  97.             gl.glDisable(GL10.GL_DITHER);  
  98.             //设置特定Hint项目的模式,这里为设置为使用快速模式  
  99.             gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);  
  100.             //设置屏幕背景色黑色RGBA  
  101.             gl.glClearColor(0,0,0,0);              
  102.             //启用深度测试  
  103.             gl.glEnable(GL10.GL_DEPTH_TEST);  
  104.         }  
  105.     }  

ColorRect.java

  1. package yy.cal;  
  2.  
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6. import java.nio.IntBuffer;  
  7. import javax.microedition.khronos.opengles.GL10;  
  8.  
  9. public class ColorRect {  
  10.     private FloatBuffer   mVertexBuffer;//顶点坐标数据缓冲  
  11.     private IntBuffer   mColorBuffer;//顶点着色数据缓冲  
  12.     int vCount=0;//顶点数量  
  13.       
  14.     public ColorRect(float width,float height)  
  15.     {  
  16.         //顶点坐标数据的初始化================begin============================  
  17.         vCount=6;  
  18.         final float UNIT_SIZE=4.0f;  
  19.         float vertices[]=new float[]  
  20.         {  
  21.             0,0,0,  
  22.             width*UNIT_SIZE,height*UNIT_SIZE,0,  
  23.             -width*UNIT_SIZE,height*UNIT_SIZE,0,  
  24.             -width*UNIT_SIZE,-height*UNIT_SIZE,0,  
  25.             width*UNIT_SIZE,-height*UNIT_SIZE,0,  
  26.             width*UNIT_SIZE,height*UNIT_SIZE,0  
  27.         };  
  28.           
  29.         //创建顶点坐标数据缓冲  
  30.         //vertices.length*4是因为一个整数四个字节  
  31.         ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);  
  32.         vbb.order(ByteOrder.nativeOrder());//设置字节顺序  
  33.         mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲  
  34.         mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据  
  35.         mVertexBuffer.position(0);//设置缓冲区起始位置  
  36.  
  37.         //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer  
  38.         //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题  
  39.         //顶点坐标数据的初始化================end============================  
  40.           
  41.         //顶点着色数据的初始化================begin============================  
  42.         final int one = 65535;  
  43.         int colors[]=new int[]//顶点颜色值数组,每个顶点4个色彩值RGBA  
  44.         {  
  45.                 one,one,one,0,  
  46.                 0,0,one,0,  
  47.                 0,0,one,0,  
  48.                 0,0,one,0,  
  49.                 0,0,one,0,            
  50.                 0,0,one,0,  
  51.         };  
  52.   
  53.           
  54.         //创建顶点着色数据缓冲  
  55.         //vertices.length*4是因为一个int型整数四个字节  
  56.         ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);  
  57.         cbb.order(ByteOrder.nativeOrder());//设置字节顺序  
  58.         mColorBuffer = cbb.asIntBuffer();//转换为int型缓冲  
  59.         mColorBuffer.put(colors);//向缓冲区中放入顶点着色数据  
  60.         mColorBuffer.position(0);//设置缓冲区起始位置  
  61.         //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer  
  62.         //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题  
  63.         //顶点着色数据的初始化================end============================  
  64.     }  
  65.  
  66.     public void drawSelf(GL10 gl)  
  67.     {          
  68.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//启用顶点坐标数组  
  69.         gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//启用顶点颜色数组  
  70.   
  71.         //为画笔指定顶点坐标数据  
  72.         gl.glVertexPointer  
  73.         (  
  74.                 3,              //每个顶点的坐标数量为3  xyz   
  75.                 GL10.GL_FLOAT,  //顶点坐标值的类型为GL_FIXED  
  76.                 0,              //连续顶点坐标数据之间的间隔  
  77.                 mVertexBuffer   //顶点坐标数据  
  78.         );  
  79.           
  80.         //为画笔指定顶点着色数据  
  81.         gl.glColorPointer  
  82.         (  
  83.                 4,              //设置颜色的组成成分,必须为4—RGBA  
  84.                 GL10.GL_FIXED,  //顶点颜色值的类型为GL_FIXED  
  85.                 0,              //连续顶点着色数据之间的间隔  
  86.                 mColorBuffer    //顶点着色数据  
  87.         );  
  88.  
  89.         //绘制图形  
  90.         gl.glDrawArrays  
  91.         (  
  92.                 GL10.GL_TRIANGLE_FAN,       //以三角形方式填充  
  93.                 0,                      //开始点编号  
  94.                 vCount                  //顶点的数量  
  95.         );  
  96.     }  

Cube.java

  1. package yy.cal;  
  2.  
  3. import javax.microedition.khronos.opengles.GL10;  
  4. import static yy.cal.Constant.*;  
  5.  
  6. public class Cube {  
  7.     //用于绘制各个面的颜色矩形  
  8.     ColorRect cr=new ColorRect(SCALE,SCALE);  
  9.       
  10.     public void drawSelf(GL10 gl)  
  11.     {  
  12.         //总绘制思想:通过把一个颜色矩形旋转移位到立方体每个面的位置  
  13.         //绘制立方体的每个面  
  14.         gl.glPushMatrix();  
  15.  
  16.         //绘制后小面  
  17.         gl.glPushMatrix();        
  18.         gl.glTranslatef(0, 0, -UNIT_SIZE*SCALE);  
  19.         cr.drawSelf(gl);          
  20.         gl.glPopMatrix();  
  21.  
  22.         //绘制下大面  
  23.         gl.glPushMatrix();            
  24.         gl.glTranslatef(0,-UNIT_SIZE*SCALE,0);  
  25.         gl.glRotatef(-90, 1, 0, 0);  
  26.         cr.drawSelf(gl);  
  27.         gl.glPopMatrix();  
  28.           
  29.         //绘制右大面  
  30.         gl.glPushMatrix();            
  31.         gl.glTranslatef(UNIT_SIZE*SCALE,0,0);         
  32.         gl.glRotatef(-90, 1, 0, 0);  
  33.         gl.glRotatef(-90, 0, 1, 0);  
  34.         cr.drawSelf(gl);  
  35.         gl.glPopMatrix();  
  36.  
  37.         //绘制左大面  
  38.         gl.glPushMatrix();            
  39.         gl.glTranslatef(-UNIT_SIZE*SCALE,0,0);        
  40.         gl.glRotatef(90, 0, 1, 0);  
  41.         cr.drawSelf(gl);  
  42.         gl.glPopMatrix();  
  43.  
  44.         gl.glPopMatrix();  
  45.     }  

Constant.java

  1. package yy.cal;  
  2.  
  3. public class Constant {  
  4.      public static final float UNIT_SIZE=4.0f;//单位尺寸  
  5.      public static final float SCALE=0.5f;//尺寸缩放比  
  6. }    

 

(dlnuchunge)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201310/16799.html]
本文出处:CSDN博客 作者:dlnuchunge
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容