我是靠谱客的博主 霸气百褶裙,最近开发中收集的这篇文章主要介绍OpenGL绘制旋转立方体实例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

通过上一节我们已经学会了使用OpenGL绘制2D图形,下面我们学习如果使用OpenGL绘制3D图形,让我们真正感受一下OpenGL的强大功能吧@

        上一节我们是绘制了一个旋转的三角形和正方形,今天我们来使用OpenGL绘制一个旋转的正方体。

        绘制正方体基本上和绘制三角形,正方形差不多,重点在于构建正方体的坐标。在构建这些顶点坐标时,要让对象绕自身的轴旋转,必须让对象的中心坐标总是(0.0f,0.0f,0.0f),并且按逆时针的顺序绘制。

        废话不多说,下面看实例:

        首先建立一个OpenGLView类继承GLSurfaceView

  

[html] view plain copy print ?
  1. public class OpenGLView extends GLSurfaceView{  
  2.       
  3.     private GLReader glReader;  
  4.   
  5.     public OpenGLView(Context context) {  
  6.         super(context);  
  7.         // TODO Auto-generated constructor stub  
  8.         glReader=new GLReader();  
  9.         setRenderer(glReader);  
  10.     }  
  11.   
  12. }  
public class OpenGLView extends GLSurfaceView{
private GLReader glReader;
public OpenGLView(Context context) {
super(context);
// TODO Auto-generated constructor stub
glReader=new GLReader();
setRenderer(glReader);
}
}

接下来是我们的activity类:

 

[html] view plain copy print ?
  1. public class SimpleOpenGLActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.           
  7.        OpenGLView view=new OpenGLView(this);  
  8.           
  9.         setContentView(view);   
  10.          
  11.     }  
  12. }  
public class SimpleOpenGLActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OpenGLView view=new OpenGLView(this);
setContentView(view);
}
}

最后是我们的核心类,用来渲染3D图形的类GLReader实现Renderer接口:

[html] view plain copy print ?
  1. package cn.com.karl.opengl;  
  2.   
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6. import java.nio.IntBuffer;  
  7.   
  8. import javax.microedition.khronos.egl.EGLConfig;  
  9. import javax.microedition.khronos.opengles.GL10;  
  10. import javax.microedition.khronos.opengles.GL11;  
  11.   
  12. import android.opengl.GLSurfaceView.Renderer;  
  13. import android.opengl.GLU;  
  14.   
  15. public class GLReader implements Renderer{  
  16.       
  17.      float box[] = new float[] {    
  18.                 // FRONT    
  19.                 -0.5f, -0.5f,  0.5f,    
  20.                  0.5f, -0.5f,  0.5f,    
  21.                 -0.5f,  0.5f,  0.5f,    
  22.                  0.5f,  0.5f,  0.5f,    
  23.                 // BACK    
  24.                 -0.5f, -0.5f, -0.5f,    
  25.                 -0.5f,  0.5f, -0.5f,    
  26.                  0.5f, -0.5f, -0.5f,    
  27.                  0.5f,  0.5f, -0.5f,    
  28.                 // LEFT    
  29.                 -0.5f, -0.5f,  0.5f,    
  30.                 -0.5f,  0.5f,  0.5f,    
  31.                 -0.5f, -0.5f, -0.5f,    
  32.                 -0.5f,  0.5f, -0.5f,    
  33.                 // RIGHT    
  34.                  0.5f, -0.5f, -0.5f,    
  35.                  0.5f,  0.5f, -0.5f,    
  36.                  0.5f, -0.5f,  0.5f,    
  37.                  0.5f,  0.5f,  0.5f,    
  38.                 // TOP    
  39.                 -0.5f,  0.5f,  0.5f,    
  40.                  0.5f,  0.5f,  0.5f,    
  41.                  -0.5f,  0.5f, -0.5f,    
  42.                  0.5f,  0.5f, -0.5f,    
  43.                 // BOTTOM    
  44.                 -0.5f, -0.5f,  0.5f,    
  45.                 -0.5f, -0.5f, -0.5f,    
  46.                  0.5f, -0.5f,  0.5f,    
  47.                  0.5f, -0.5f, -0.5f,    
  48.             };    
  49.         
  50.         FloatBuffer cubeBuff;    
  51.             
  52.         float xrot = 0.0f;    
  53.         float yrot = 0.0f;    
  54.         /**   
  55.          * 将float数组转换存储在字节缓冲数组   
  56.          * @param arr   
  57.          * @return   
  58.          */    
  59.         public FloatBuffer makeFloatBuffer(float[] arr) {    
  60.             ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);//分配缓冲空间,一个float占4个字节    
  61.             bb.order(ByteOrder.nativeOrder()); //设置字节顺序, 其中ByteOrder.nativeOrder()是获取本机字节顺序    
  62.             FloatBuffer fb = bb.asFloatBuffer(); //转换为float型    
  63.             fb.put(arr);        //添加数据    
  64.             fb.position(0);      //设置数组的起始位置    
  65.             return fb;    
  66.         }    
  67.             
  68.     public GLReader(){  
  69.          cubeBuff = makeFloatBuffer(box);//转换float数组    
  70.     }  
  71.       
  72.      //所有的绘图操作都在此方法中执行  
  73.     public void onDrawFrame(GL10 gl) {  
  74.         // TODO Auto-generated method stub  
  75.           
  76.          gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存    
  77.            
  78.             gl.glMatrixMode(GL10.GL_MODELVIEW);   //切换至模型观察矩阵    
  79.             gl.glLoadIdentity();// 重置当前的模型观察矩阵    
  80.             GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);//设置视点和模型中心位置    
  81.             
  82.             gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);//设置顶点数据    
  83.             gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    
  84.             
  85.             gl.glRotatef(xrot, 1, 0, 0);  //绕着(0,0,0)与(1,0,0)即x轴旋转    
  86.             gl.glRotatef(yrot, 0, 1, 0);    
  87.                 
  88.             //六个面一个面绘制一种颜色  
  89.             gl.glColor4f(1.0f, 0, 0, 1.0f);   //设置颜色,红色    
  90.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);  //绘制正方型FRONT面    
  91.             gl.glColor4f(1.0f, 1.0f, 0, 1.0f);   
  92.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);    
  93.             
  94.             gl.glColor4f(0, 1.0f, 0, 1.0f);    
  95.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);    
  96.             gl.glColor4f(0, 1.0f, 1.0f, 1.0f);  
  97.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);    
  98.                 
  99.             gl.glColor4f(0, 0, 1.0f, 1.0f);    
  100.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);   
  101.             gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);    
  102.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);    
  103.             
  104.             xrot += 1.0f;    
  105.             yrot += 0.5f;    
  106.     }  
  107.     //当窗口大小改变时调用  
  108.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  109.         // TODO Auto-generated method stub  
  110.           
  111.         //设置OpenGL的场景大小  
  112.         gl.glViewport(0, 0, width, height);  
  113.         gl.glMatrixMode(GL10.GL_PROJECTION); // 设置投影矩阵    
  114.         gl.glLoadIdentity();  //设置矩阵为单位矩阵,相当于重置矩阵           
  115.         GLU.gluPerspective(gl, 45.0f, ((float) width) / height, 0.1f, 10f);//设置透视范围      
  116.     }  
  117.     //当窗口被创建是调用  
  118.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  119.         // TODO Auto-generated method stub  
  120.           
  121.             gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清屏时背景的颜色,R,G,B,A    
  122.            
  123.             gl.glEnable(GL10.GL_DEPTH_TEST); //启用深度缓存    
  124.             gl.glEnable(GL10.GL_CULL_FACE);  //启用背面剪裁    
  125.             gl.glClearDepthf(1.0f);    // 设置深度缓存值    
  126.             gl.glDepthFunc(GL10.GL_LEQUAL);  // 设置深度缓存比较函数,GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值(通过gl.glClearDepthf(1.0f)设置)时通过深度测试       
  127.             gl.glShadeModel(GL10.GL_SMOOTH);// 设置阴影模式GL_SMOOTH    
  128.     }  
  129.       
  130.       
  131.         
  132.   
  133. }  
package cn.com.karl.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class GLReader implements Renderer{
float box[] = new float[] {
// FRONT
-0.5f, -0.5f,
0.5f,
0.5f, -0.5f,
0.5f,
-0.5f,
0.5f,
0.5f,
0.5f,
0.5f,
0.5f,
// BACK
-0.5f, -0.5f, -0.5f,
-0.5f,
0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f,
0.5f, -0.5f,
// LEFT
-0.5f, -0.5f,
0.5f,
-0.5f,
0.5f,
0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f,
0.5f, -0.5f,
// RIGHT
0.5f, -0.5f, -0.5f,
0.5f,
0.5f, -0.5f,
0.5f, -0.5f,
0.5f,
0.5f,
0.5f,
0.5f,
// TOP
-0.5f,
0.5f,
0.5f,
0.5f,
0.5f,
0.5f,
-0.5f,
0.5f, -0.5f,
0.5f,
0.5f, -0.5f,
// BOTTOM
-0.5f, -0.5f,
0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f,
0.5f,
0.5f, -0.5f, -0.5f,
};
FloatBuffer cubeBuff;
float xrot = 0.0f;
float yrot = 0.0f;
/**
* 将float数组转换存储在字节缓冲数组
* @param arr
* @return
*/
public FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);//分配缓冲空间,一个float占4个字节
bb.order(ByteOrder.nativeOrder()); //设置字节顺序, 其中ByteOrder.nativeOrder()是获取本机字节顺序
FloatBuffer fb = bb.asFloatBuffer(); //转换为float型
fb.put(arr);
//添加数据
fb.position(0);
//设置数组的起始位置
return fb;
}
public GLReader(){
cubeBuff = makeFloatBuffer(box);//转换float数组
}
//所有的绘图操作都在此方法中执行
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存
gl.glMatrixMode(GL10.GL_MODELVIEW);
//切换至模型观察矩阵
gl.glLoadIdentity();// 重置当前的模型观察矩阵
GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);//设置视点和模型中心位置
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);//设置顶点数据
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glRotatef(xrot, 1, 0, 0);
//绕着(0,0,0)与(1,0,0)即x轴旋转
gl.glRotatef(yrot, 0, 1, 0);
//六个面一个面绘制一种颜色
gl.glColor4f(1.0f, 0, 0, 1.0f);
//设置颜色,红色
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//绘制正方型FRONT面
gl.glColor4f(1.0f, 1.0f, 0, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
gl.glColor4f(0, 1.0f, 0, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
gl.glColor4f(0, 1.0f, 1.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
gl.glColor4f(0, 0, 1.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
xrot += 1.0f;
yrot += 0.5f;
}
//当窗口大小改变时调用
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
//设置OpenGL的场景大小
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION); // 设置投影矩阵
gl.glLoadIdentity();
//设置矩阵为单位矩阵,相当于重置矩阵
GLU.gluPerspective(gl, 45.0f, ((float) width) / height, 0.1f, 10f);//设置透视范围
}
//当窗口被创建是调用
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清屏时背景的颜色,R,G,B,A
gl.glEnable(GL10.GL_DEPTH_TEST); //启用深度缓存
gl.glEnable(GL10.GL_CULL_FACE);
//启用背面剪裁
gl.glClearDepthf(1.0f);
// 设置深度缓存值
gl.glDepthFunc(GL10.GL_LEQUAL);
// 设置深度缓存比较函数,GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值(通过gl.glClearDepthf(1.0f)设置)时通过深度测试
gl.glShadeModel(GL10.GL_SMOOTH);// 设置阴影模式GL_SMOOTH
}
}

上面比较重要的部分都做了注释,所以这里也不做过多的解释,最后看一些运行后效果怎么样。



最后

以上就是霸气百褶裙为你收集整理的OpenGL绘制旋转立方体实例的全部内容,希望文章能够帮你解决OpenGL绘制旋转立方体实例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部