zoukankan      html  css  js  c++  java
  • 3d 绘图纹理

    http://blog.csdn.net/hmg25/article/details/6740136

    (球上纹理)

    package com.ct.testmyfirst3d;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.CompoundButton;
    import android.widget.CompoundButton.OnCheckedChangeListener;
    import android.widget.LinearLayout;
    import android.widget.ToggleButton;
    
    public class TextureActivity extends Activity{
        TextureSurface mSurface;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mSurface = new TextureSurface(this);
            mSurface.requestFocus();
            mSurface.setFocusableInTouchMode(true);
            
            LinearLayout llLayout = (LinearLayout)findViewById(R.id.main_liner);
            llLayout.addView(mSurface);
            ToggleButton tb = (ToggleButton)findViewById(R.id.ToggleButton01);
            tb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    // TODO Auto-generated method stub
                    mSurface.setSmoothFlag(!mSurface.isSmoothFlag()); 
                }
            });
        }
        
    }
    package com.ct.testmyfirst3d;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.R.integer;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.opengl.GLSurfaceView;
    import android.opengl.GLUtils;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    
    public class TextureSurface extends GLSurfaceView{
    
        private final float TOUCH_SCALE_FACTOR = 180.0f/320;
        private SceneRenderer mRenderer;
        private float mPreviousX;
        private float mPreviousY;
        private boolean smoothFlag = true;
        private int lightAngleaGreen;
        private int lightAngleRed;
        int textureId;
        public TextureSurface(Context context) {
            super(context);
            mRenderer = new SceneRenderer();
            setRenderer(mRenderer);
            setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
            
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            float y = event.getY();
            float x = event.getX();
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float dy = y - mPreviousY;//计算触控笔Y位移  
                float dx = x - mPreviousX;//计算触控笔Y位移  
                mRenderer.ball.mAngleX += dy * TOUCH_SCALE_FACTOR;//设置沿x轴旋转角度  
                mRenderer.ball.mAngleZ += dx * TOUCH_SCALE_FACTOR;//设置沿z轴旋转角度  
                requestRender();//重绘画面  
                break;
    
            default:
                break;
            }
            
             mPreviousY = y;//记录触控笔位置  
                mPreviousX = x;//记录触控笔位置  
                return true;  
        }
        
        public void setSmoothFlag(boolean smoothFlag){
            this.smoothFlag = smoothFlag;
        }
        
         public boolean isSmoothFlag() {  
                return smoothFlag;  
            }
         
        
        private class SceneRenderer implements GLSurfaceView.Renderer{
            Ball ball;
            public SceneRenderer(){
                new Thread(){
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try{
                            Thread.sleep(1000);
                        }catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
                        while (true) {
                            lightAngleaGreen+=5;
                            lightAngleRed+=5;
                            requestRender();
                            try {
                                Thread.sleep(50);
                            } catch (Exception e) {
                                // TODO: handle exception
                                e.printStackTrace();
                            }
                            
                        }
                    }
                    
                }.start();
            }
            @Override
            public void onDrawFrame(GL10 gl) {
                // TODO Auto-generated method stub
                if(smoothFlag){
                    //进行平滑着色
                     gl.glShadeModel(GL10.GL_SMOOTH);
                }
                else {
                    //相反的 
                    gl.glShadeModel(GL10.GL_FLAT);
                }
                //设定绿色光源的位置  
                float lxGreen=(float)(7*Math.cos(Math.toRadians(lightAngleaGreen)));  
                float lzGreen=(float)(7*Math.sin(Math.toRadians(lightAngleaGreen)));  
                float[] positionParamsGreen={lxGreen,0,lzGreen,1};//最后的1表示使用定位光  
                gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, positionParamsGreen,0);   
                  
                //设定红色光源的位置  
                float lyRed=(float)(7*Math.cos(Math.toRadians(lightAngleRed)));  
                float lzRed=(float)(7*Math.sin(Math.toRadians(lightAngleRed)));  
                float[] positionParamsRed={0,lyRed,lzRed,1};//最后的1表示使用定位光  
                gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionParamsRed,0);
                
              //清除颜色缓存  
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
                //设置当前矩阵为模式矩阵  
                gl.glMatrixMode(GL10.GL_MODELVIEW);  
                //设置当前矩阵为单位矩阵  
                gl.glLoadIdentity();       
                  
                gl.glTranslatef(0, 0f, -1.8f);    
                  
                gl.glPushMatrix();//保护变换矩阵现场  
                ball.drawSelf(gl);//绘制球  
                gl.glPopMatrix();//恢复变换矩阵现场 
            }
    
            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height) {
                // TODO Auto-generated method stub
                 //设置视窗大小及位置   
                gl.glViewport(0, 0, width, height);  
                //设置当前矩阵为投影矩阵  
                gl.glMatrixMode(GL10.GL_PROJECTION);  
                //设置当前矩阵为单位矩阵  
                gl.glLoadIdentity();  
                //计算透视投影的比例  
                float ratio = (float) width / height;  
                //调用此方法计算产生透视投影矩阵  
                gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);  
            }
    
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
                // TODO Auto-generated method stub
                  //关闭抗抖动   
                gl.glDisable(GL10.GL_DITHER);  
                //设置特定Hint项目的模式,这里为设置为使用快速模式  
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);  
                //设置屏幕背景色黑色RGBA  
                gl.glClearColor(0,0,0,0);  
                //设置着色模型为平滑着色     
                gl.glShadeModel(GL10.GL_SMOOTH);//GL10.GL_SMOOTH  GL10.GL_FLAT  
                //启用深度测试  
                gl.glEnable(GL10.GL_DEPTH_TEST);  
                  
                gl.glEnable(GL10.GL_LIGHTING);//允许光照      
                  
                initGreenLight(gl);//初始化绿色灯  
                initRedLight(gl);//初始化红色灯  
                initMaterial(gl);//初始化材质  
                  
                textureId=initTexture(gl,R.drawable.duke);//初始化纹理  
                ball=new Ball(4,textureId);  
            }  
            
            }
        //初始化绿色灯  
        private void initGreenLight(GL10 gl)  
        {  
            gl.glEnable(GL10.GL_LIGHT0);//打开0号灯    
              
            //环境光设置  
            float[] ambientParams={0.1f,0.1f,0.1f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientParams,0);              
              
            //散射光设置  
            float[] diffuseParams={0f,1f,0f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseParams,0);   
              
            //反射光设置  
            float[] specularParams={1f,1f,1f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularParams,0);       
        }  
        
        //初始化红色灯  
        private void initRedLight(GL10 gl)  
        {      
            gl.glEnable(GL10.GL_LIGHT1);//打开1号灯    
              
            //环境光设置  
            float[] ambientParams={0.2f,0.2f,0.2f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, ambientParams,0);              
              
            //散射光设置  
            float[] diffuseParams={1f,0f,0f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseParams,0);   
              
            //反射光设置  
            float[] specularParams={1f,1f,1f,1.0f};//光参数 RGBA  
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_SPECULAR, specularParams,0);   
        }  
        
        //初始化材质  
        private void initMaterial(GL10 gl)  
        {//材质为白色时什么颜色的光照在上面就将体现出什么颜色  
            //环境光为白色材质  
            float ambientMaterial[] = {1.0f, 1.0f, 1.0f, 1.0f};  
            gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientMaterial,0);  
            //散射光为白色材质  
            float diffuseMaterial[] = {1.0f, 1.0f, 1.0f, 1.0f};  
            gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseMaterial,0);  
            //高光材质为白色  
            float specularMaterial[] = {1f, 1f, 1f, 1.0f};  
            gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specularMaterial,0);  
            gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 100.0f);  
        }  
        public int initTexture(GL10 gl,int textureId)//textureId  
        {  
            int[] textures = new int[1];  
            gl.glGenTextures(1, textures, 0);      
            int currTextureId=textures[0];      
            gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId);  
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);  
            gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);  
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);  
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);  
              
            InputStream is = this.getResources().openRawResource(textureId);  
            Bitmap bitmapTmp;   
            try   
            {  
                bitmapTmp = BitmapFactory.decodeStream(is);  
            }   
            finally   
            {  
                try   
                {  
                    is.close();  
                }   
                catch(IOException e)   
                {  
                    e.printStackTrace();  
                }  
            }  
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);  
            bitmapTmp.recycle();   
              
            return currTextureId;  
        }  
        
        
        
        
            
        }
        
        
    package com.ct.testmyfirst3d;
    
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    import java.nio.IntBuffer;
    import java.util.ArrayList;
    
    import javax.microedition.khronos.opengles.GL10;
    
    import android.R.integer;
    
    public class Ball {
    
        private IntBuffer mVertexBuffer;//定点坐标数据缓冲
        private IntBuffer mNormalBuffer;//顶点向量数据缓冲
        
        private FloatBuffer mTextureBuffer;//顶点纹理数据缓冲
        public float mAngleX;
        public float mAngleY;
        public float mAngleZ;
        int vCount=0;//顶点数量  
        int textureId;//纹理ID  
        public Ball(int scale,int textureId){
            this.textureId = textureId;
            final int UNIT_SIZE=10000;  
            //实际顶点坐标数据的初始化================begin============================  
            ArrayList<Integer> alVertix=new ArrayList<Integer>();//存放顶点坐标的ArrayList  
            final int angleSpan=18;//将球进行单位切分的角度  
            for(int vAngle=-90;vAngle<=90;vAngle=vAngle+angleSpan)//垂直方向angleSpan度一份  
            {  
                for(int hAngle=0;hAngle<360;hAngle=hAngle+angleSpan)//水平方向angleSpan度一份  
                {//纵向横向各到一个角度后计算对应的此点在球面上的坐标  
                    double xozLength=scale*UNIT_SIZE*Math.cos(Math.toRadians(vAngle));  
                    int x=(int)(xozLength*Math.cos(Math.toRadians(hAngle)));  
                    int z=(int)(xozLength*Math.sin(Math.toRadians(hAngle)));  
                    int y=(int)(scale*UNIT_SIZE*Math.sin(Math.toRadians(vAngle)));  
                    //将计算出来的XYZ坐标加入存放顶点坐标的ArrayList  
                    alVertix.add(x);alVertix.add(y);alVertix.add(z);  
                }  
            }     
            vCount=alVertix.size()/3;//顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标  
              
            //将alVertix中的坐标值转存到一个int数组中  
            int vertices[] = new int[vCount*3];
                for(int i=0;i<alVertix.size();i++){
                    vertices[i] = alVertix.get(i);
                }
                alVertix.clear();
                ArrayList<Float> alTexture = new ArrayList<Float>();
                
                 int row=(180/angleSpan)+1;//球面切分的行数  
                 int col=360/angleSpan;//球面切分的列数  
                 
                 for(int i=0;i<row;i++)//对每一行循环  
                 {  
                     if(i>0&&i<row-1)  
                     {//中间行  
                         for(int j=-1;j<col;j++)  
                         {//中间行的两个相邻点与下一行的对应点构成三角形  
                             int k=i*col+j;  
                             //第1个三角形顶点                    
                             alVertix.add(vertices[(k+col)*3]);  
                             alVertix.add(vertices[(k+col)*3+1]);  
                             alVertix.add(vertices[(k+col)*3+2]);                      
                             alTexture.add(0.0f);alTexture.add(0.0f);  
                               
                             //第2个三角形顶点        
                             alVertix.add(vertices[(k+1)*3]);  
                             alVertix.add(vertices[(k+1)*3+1]);  
                             alVertix.add(vertices[(k+1)*3+2]);                    
                             alTexture.add(1.0f);alTexture.add(1.0f);  
                               
                             //第3个三角形顶点  
                             alVertix.add(vertices[k*3]);  
                             alVertix.add(vertices[k*3+1]);  
                             alVertix.add(vertices[k*3+2]);    
                             alTexture.add(1.0f);alTexture.add(0.0f);  
                         }  
                         for(int j=0;j<col+1;j++)  
                         {//中间行的两个相邻点与上一行的对应点构成三角形                 
                             int k=i*col+j;  
                               
                             //第1个三角形顶点                    
                             alVertix.add(vertices[(k-col)*3]);  
                             alVertix.add(vertices[(k-col)*3+1]);  
                             alVertix.add(vertices[(k-col)*3+2]);                      
                             alTexture.add(1f);alTexture.add(1f);  
                               
                             //第2个三角形顶点                    
                             alVertix.add(vertices[(k-1)*3]);  
                             alVertix.add(vertices[(k-1)*3+1]);  
                             alVertix.add(vertices[(k-1)*3+2]);                    
                             alTexture.add(0.0f);alTexture.add(0.0f);  
                               
                             //第3个三角形顶点                    
                             alVertix.add(vertices[k*3]);  
                             alVertix.add(vertices[k*3+1]);  
                             alVertix.add(vertices[k*3+2]);                    
                             alTexture.add(0f);alTexture.add(1f);      
                         }  
                     }  
                 }  
                   
                 vCount=alVertix.size()/3;//顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标  
                   
                 //将alVertix中的坐标值转存到一个int数组中  
                 vertices=new int[vCount*3];  
                 for(int i=0;i<alVertix.size();i++)  
                 {  
                     vertices[i]=alVertix.get(i);  
                 }  
                   
                 //创建绘制顶点数据缓冲  
                 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);  
                 vbb.order(ByteOrder.nativeOrder());//设置字节顺序  
                 mVertexBuffer = vbb.asIntBuffer();//转换为int型缓冲  
                 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据  
                 mVertexBuffer.position(0);//设置缓冲区起始位置       
                   
                 //创建顶点法向量数据缓冲  
                 ByteBuffer nbb = ByteBuffer.allocateDirect(vertices.length*4);  
                 nbb.order(ByteOrder.nativeOrder());//设置字节顺序  
                 mNormalBuffer = vbb.asIntBuffer();//转换为int型缓冲  
                 mNormalBuffer.put(vertices);//向缓冲区中放入顶点坐标数据  
                 mNormalBuffer.position(0);//设置缓冲区起始位置  
                   
                 //创建纹理坐标缓冲  
                 float textureCoors[]=new float[alTexture.size()];//顶点纹理值数组  
                 for(int i=0;i<alTexture.size();i++)   
                 {  
                     textureCoors[i]=alTexture.get(i);  
                 }  
                   
                 ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4);  
                 cbb.order(ByteOrder.nativeOrder());//设置字节顺序  
                 mTextureBuffer = cbb.asFloatBuffer();//转换为int型缓冲  
                 mTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据  
                 mTextureBuffer.position(0);//设置缓冲区起始位置  
                   
                 //三角形构造顶点、纹理、法向量数据初始化==
                
    
            
        }
        
        public void drawSelf(GL10 gl){
            gl.glRotatef(mAngleZ, 0, 0, 1);//沿Z轴旋转  
            gl.glRotatef(mAngleX, 1, 0, 0);//沿X轴旋转  
            gl.glRotatef(mAngleY, 0, 1, 0);//沿Y轴旋转  
              
            //允许使用顶点数组  
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
            //为画笔指定顶点坐标数据  
            gl.glVertexPointer  
            (  
                    3,              //每个顶点的坐标数量为3  xyz   
                    GL10.GL_FIXED,  //顶点坐标值的类型为 GL_FIXED  
                    0,              //连续顶点坐标数据之间的间隔  
                    mVertexBuffer   //顶点坐标数据  
            );  
              
            //允许使用法向量数组  
            gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);  
            //为画笔指定顶点法向量数据  
            gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);  
              
            //开启纹理  
            gl.glEnable(GL10.GL_TEXTURE_2D);     
            //允许使用纹理ST坐标缓冲  
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
            //为画笔指定纹理ST坐标缓冲  
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);  
            //绑定当前纹理  
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  
              
            //绘制图形  
            gl.glDrawArrays  
            (  
                    GL10.GL_TRIANGLES,      //以三角形方式填充  
                    0,                      //开始点编号  
                    vCount                  //顶点数量  
            );
            
        }
    }

    (在F:\java\TestMyFirst3d)

  • 相关阅读:
    vue自动路由-单页面项目(非build时构建)
    建立多页面vue.js项目
    C#调用C++(QT5.5.1项目)的C++/CLI(CLR项目)项目技术笔记
    自建Socket转发,使用远程桌面(mstsc)连接家中电脑
    用Vue.js搭建一个小说阅读网站
    在CentOS中部署.Net Core2.1网站
    高价值干货:这可能是你见过最全的网络爬虫总结
    【DevCloud·敏捷智库】如何利用用户故事了解需求
    项目管理:如何显性管理并提升Story分解能力
    【API进阶之路】老板给我涨薪30%!如何通过SDK接口搞定千万级流量直播
  • 原文地址:https://www.cnblogs.com/ct732003684/p/2933081.html
Copyright © 2011-2022 走看看