public class MyRenderer implements Renderer{
private Context mcontext;
private int texture = -1;   
    private int one = 0x10000;     
    private int[] quarter = {
     -one,-one,one,   
             one,-one,one,   
             one,one,one,   
            -one,one,one,   
                               
            -one,-one,-one,   
            -one,one,-one,   
             one,one,-one,   
             one,-one,-one,   
                               
             -one,one,-one,   
             -one,one,one,   
             one,one,one,   
              one,one,-one,   
                               
            -one,-one,-one,   
             one,-one,-one,   
             one,-one,one,   
             -one,-one,one,   
                               
              one,-one,-one,   
              one,one,-one,   
              one,one,one,   
              one,-one,one,   
                               
              -one,-one,-one,   
               -one,-one,one,   
               -one,one,one,   
               -one,one,-one,};   
       
    private int[] texCoords = {
     one,0,0,0,0,one,one,one,    //右下角,左下角,左上角,右上角
             0,0,0,one,one,one,one,0,   
             one,one,one,0,0,0,0,one,   
             0,one,one,one,one,0,0,0,   
              0,0,0,one,one,one,one,0,   
               one,0,0,0,0,one,one,one,};   
         
       
    //准备正方体顶点     
    private IntBuffer quarterBuffer = BufferUtil.iBuffer(quarter);     
    //纹理映射数据   
    private IntBuffer texCoordsBuffer = BufferUtil.iBuffer(texCoords);    
       
    //private IntBuffer indicesBuffer = BufferUtil.iBuffer(indices);    
    ByteBuffer indicesBuffer = ByteBuffer.wrap(new byte[]{   
            0,1,3,2,   
            4,5,7,6,   
            8,9,11,10,   
            12,13,15,14,   
            16,17,19,18,   
            20,21,23,22,   
    });   
       
    private float rotateX; //用于正方体x轴的旋转;   
    private float rotateY; //用于正方体y轴的旋转;   
    private float rotateZ; //用于正方体z轴的旋转;   
    private float translatefX;//用于在X轴移动正方体   
    private boolean app=true; 
    private float att;
    
    //定义环境光   
    private FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f, 0.5f, 0.5f, 1.0f });   
    //定义漫射光   
    private FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f, 1.0f, 1.0f, 1.0f });   
    //定义光源的位置   
   private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f, 0.0f, 2.0f, 1.0f });      
    //咳,咳现在开始画图了     
    @Override     
    public void onDrawFrame(GL10 gl) {     
        // TODO Auto-generated method stub     
        //清楚屏幕和深度缓存     
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);   
          //重置当前的观察模型矩阵   
          gl.glLoadIdentity(); 
          //开启光源
          gl.glEnable(GL10.GL_LIGHTING);  
          //现将屏幕向里移动,用来画正方体     
          gl.glTranslatef(translatefX, 0.0f, -4.0f+att);    
          //设置3个方向的旋转   
          gl.glRotatef(rotateX, 1.0f, 0.0f, 0.0f);   
          gl.glRotatef(rotateY, 0.0f, 1.0f, 0.0f);   
          gl.glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);      
          //通知opnegl将文理名字texture绑定到指定的纹理目标上GL10.GL_TEXTURE_2D   
          gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);   
            
          gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    
          //纹理的使用与开启颜色渲染一样,需要开启纹理功能   
          gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   
             
          //设置正方体 各顶点   
          gl.glVertexPointer(3, GL10.GL_FIXED, 0, quarterBuffer);   
          gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoordsBuffer);   
             
          //绘制   
          gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  
           GL10.GL_UNSIGNED_BYTE, indicesBuffer);   
           for(int i=0; i<6; i++)
           {   
              gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i*4, 4);   
           }   
          gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   
          gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);   
             
          rotateX += 0.5f;   
          rotateY += 0.6f;    
          rotateZ += 0.3f; 
          
          if(translatefX<2.5f&&app==true)
           {
           translatefX +=0.02f;
           att+=0.01f;
           }
           
          if(translatefX>=2.5f||app==false)
           {app=false;
           translatefX -=0.02f;
           att-=0.01f;
              }
          if(translatefX<=-2.5f)
           app=true;
      }     
   
      //当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小     
      @Override     
      public void onSurfaceChanged(GL10 gl, int width, int height) {     
          // TODO Auto-generated method stub     
          //设置OpenGL场景大小     
          float ratio = (float) width / 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 onSurfaceCreated(GL10 gl, EGLConfig config) {     
          // TODO Auto-generated method stub     
          //设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值     
          gl.glClearColor(0, 0, 0, 0);   
          gl.glEnable(GL10.GL_CULL_FACE);   
          //启用阴影平滑     
          gl.glShadeModel(GL10.GL_SMOOTH);    
          gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试     
             
          //以下是关于深度缓存的设置,非常重要     
          gl.glClearDepthf(1.0f);//设置深度缓存     
          gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型     
             
          //告诉系统对透视进行修正     
          gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);     
          //允许2D贴图   
          gl.glEnable(GL10.GL_TEXTURE_2D);   
             
          IntBuffer intBuffer = IntBuffer.allocate(1);   
          //创建纹理   
          gl.glGenTextures(1, intBuffer);   
          texture = intBuffer.get();   
          //设置需要使用的纹理   
          gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);   
             
          Bitmap bmp = BitmapFactory.decodeResource(
           mcontext.getResources(), R.drawable.yangmi);   
          //生成纹理   
          GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);   
          // 线形滤波   
          gl.glTexParameterx(GL10.GL_TEXTURE_2D, 
           GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);   
          gl.glTexParameterx(GL10.GL_TEXTURE_2D,
           GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
          
          //设置环境光   
          gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);   
          //设置漫射光   
          gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);   
          //设置光源的位置   
          gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);   
          //开启ID号为GL_LIGHT1的光源   
          gl.glEnable(GL10.GL_LIGHT1);         }     
           
      
       
  public static class BufferUtil {     
      public static IntBuffer intBuffer;     
   
      public static IntBuffer iBuffer(int[] a) {     
          // 先初始化buffer,数组的长度*4,因为一个float占4个字节     
          ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);     
          // 数组排列用nativeOrder     
          mbb.order(ByteOrder.nativeOrder());     
          intBuffer = mbb.asIntBuffer();     
          intBuffer.put(a);     
          intBuffer.position(0);     
          return intBuffer;     
      }     
  }   
}logcat:05-22 01:28:30.771: W/dalvikvm(401): threadid=9: thread exiting with uncaught exception (group=0x40015560)
05-22 01:28:30.841: E/AndroidRuntime(401): FATAL EXCEPTION: GLThread 10
05-22 01:28:30.841: E/AndroidRuntime(401): java.lang.NullPointerException
05-22 01:28:30.841: E/AndroidRuntime(401):  at com.myopengl.MyRenderer.onSurfaceCreated(MyRenderer.java:189)
05-22 01:28:30.841: E/AndroidRuntime(401):  at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1348)
05-22 01:28:30.841: E/AndroidRuntime(401):  at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)求大神指出错误OpenGL ES

解决方案 »

  1.   

    public class MyRenderer implements Renderer{
    private Context mcontext;
    private int texture = -1;   
        private int one = 0x10000;     
        private int[] quarter = {
          -one,-one,one,   
                 one,-one,one,   
                 one,one,one,   
                -one,one,one,   
                                   
                -one,-one,-one,   
                -one,one,-one,   
                 one,one,-one,   
                 one,-one,-one,   
                                   
                 -one,one,-one,   
                 -one,one,one,   
                 one,one,one,   
                  one,one,-one,   
                                   
                -one,-one,-one,   
                 one,-one,-one,   
                 one,-one,one,   
                 -one,-one,one,   
                                   
                  one,-one,-one,   
                  one,one,-one,   
                  one,one,one,   
                  one,-one,one,   
                                   
                  -one,-one,-one,   
                   -one,-one,one,   
                   -one,one,one,   
                   -one,one,-one,};   
           
        private int[] texCoords = {
          one,0,0,0,0,one,one,one,    //右下角,左下角,左上角,右上角
                 0,0,0,one,one,one,one,0,   
                 one,one,one,0,0,0,0,one,   
                 0,one,one,one,one,0,0,0,   
                  0,0,0,one,one,one,one,0,   
                   one,0,0,0,0,one,one,one,};   
             
           
        //准备正方体顶点     
        private IntBuffer quarterBuffer = BufferUtil.iBuffer(quarter);     
        //纹理映射数据   
        private IntBuffer texCoordsBuffer = BufferUtil.iBuffer(texCoords);    
           
        //private IntBuffer indicesBuffer = BufferUtil.iBuffer(indices);    
        ByteBuffer indicesBuffer = ByteBuffer.wrap(new byte[]{   
                0,1,3,2,   
                4,5,7,6,   
                8,9,11,10,   
                12,13,15,14,   
                16,17,19,18,   
                20,21,23,22,   
        });   
           
        private float rotateX; //用于正方体x轴的旋转;   
        private float rotateY; //用于正方体y轴的旋转;   
        private float rotateZ; //用于正方体z轴的旋转;   
        private float translatefX;//用于在X轴移动正方体   
        private boolean app=true; 
        private float att;
        
        //定义环境光   
        private FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f, 0.5f, 0.5f, 1.0f });   
        //定义漫射光   
        private FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f, 1.0f, 1.0f, 1.0f });   
        //定义光源的位置   
       private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f, 0.0f, 2.0f, 1.0f });      
        //咳,咳现在开始画图了     
        @Override     
        public void onDrawFrame(GL10 gl) {     
            // TODO Auto-generated method stub     
            //清楚屏幕和深度缓存     
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);   
              //重置当前的观察模型矩阵   
              gl.glLoadIdentity(); 
              //开启光源
              gl.glEnable(GL10.GL_LIGHTING);  
              //现将屏幕向里移动,用来画正方体     
              gl.glTranslatef(translatefX, 0.0f, -4.0f+att);    
              //设置3个方向的旋转   
              gl.glRotatef(rotateX, 1.0f, 0.0f, 0.0f);   
              gl.glRotatef(rotateY, 0.0f, 1.0f, 0.0f);   
              gl.glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);      
              //通知opnegl将文理名字texture绑定到指定的纹理目标上GL10.GL_TEXTURE_2D   
              gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);   
                
              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    
              //纹理的使用与开启颜色渲染一样,需要开启纹理功能   
              gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   
                 
              //设置正方体 各顶点   
              gl.glVertexPointer(3, GL10.GL_FIXED, 0, quarterBuffer);   
              gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoordsBuffer);   
                 
              //绘制   
              gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  
                GL10.GL_UNSIGNED_BYTE, indicesBuffer);   
               for(int i=0; i<6; i++)
               {   
                  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i*4, 4);   
               }   
              gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   
              gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);   
                 
              rotateX += 0.5f;   
              rotateY += 0.6f;    
              rotateZ += 0.3f; 
              
              if(translatefX<2.5f&&app==true)
               {
               translatefX +=0.02f;
               att+=0.01f;
               }
               
              if(translatefX>=2.5f||app==false)
               {app=false;
               translatefX -=0.02f;
               att-=0.01f;
                  }
              if(translatefX<=-2.5f)
               app=true;
          }     
       
          //当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小     
          @Override     
          public void onSurfaceChanged(GL10 gl, int width, int height) {     
              // TODO Auto-generated method stub     
              //设置OpenGL场景大小     
              float ratio = (float) width / 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 onSurfaceCreated(GL10 gl, EGLConfig config) {     
              // TODO Auto-generated method stub     
              //设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值     
              gl.glClearColor(0, 0, 0, 0);   
              gl.glEnable(GL10.GL_CULL_FACE);   
              //启用阴影平滑     
              gl.glShadeModel(GL10.GL_SMOOTH);    
              gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试     
                 
              //以下是关于深度缓存的设置,非常重要     
              gl.glClearDepthf(1.0f);//设置深度缓存     
              gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型     
                 
              //告诉系统对透视进行修正     
              gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);     
              //允许2D贴图   
              gl.glEnable(GL10.GL_TEXTURE_2D);   
                 
              IntBuffer intBuffer = IntBuffer.allocate(1);   
              //创建纹理   
              gl.glGenTextures(1, intBuffer);   
              texture = intBuffer.get();   
              //设置需要使用的纹理   
              gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);   
                 
              Bitmap bmp = BitmapFactory.decodeResource(
                mcontext.getResources(), R.drawable.yangmi);   
              //生成纹理   
              GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);   
              // 线形滤波   
              gl.glTexParameterx(GL10.GL_TEXTURE_2D, 
                GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);   
              gl.glTexParameterx(GL10.GL_TEXTURE_2D,
                GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
              
              //设置环境光   
              gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);   
              //设置漫射光   
              gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);   
              //设置光源的位置   
              gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);   
              //开启ID号为GL_LIGHT1的光源   
              gl.glEnable(GL10.GL_LIGHT1);         }     
               
          
           
      public static class BufferUtil {     
          public static IntBuffer intBuffer;     
       
          public static IntBuffer iBuffer(int[] a) {     
              // 先初始化buffer,数组的长度*4,因为一个float占4个字节     
              ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);     
              // 数组排列用nativeOrder     
              mbb.order(ByteOrder.nativeOrder());     
              intBuffer = mbb.asIntBuffer();     
              intBuffer.put(a);     
              intBuffer.position(0);     
              return intBuffer;     
          }     
      }   
    }