通过上一节我们已经学会了使用OpenGL绘制2D图形,下面我们学习如果使用OpenGL绘制3D图形,让我们真正感受一下OpenGL的强大功能吧@
上一节我们是绘制了一个旋转的三角形和正方形,今天我们来使用OpenGL绘制一个旋转的正方体。
绘制正方体基本上和绘制三角形,正方形差不多,重点在于构建正方体的坐标。在构建这些顶点坐标时,要让对象绕自身的轴旋转,必须让对象的中心坐标总是(0.0f,0.0f,0.0f),并且按逆时针的顺序绘制。
废话不多说,下面看实例:
首先建立一个OpenGLView类继承GLSurfaceView
- public class OpenGLView extends GLSurfaceView{
- private GLReader glReader;
- public OpenGLView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- glReader=new GLReader();
- setRenderer(glReader);
- }
- }
复制代码
1
2
3
4
5
6
7
8
9public class OpenGLView extends GLSurfaceView{ private GLReader glReader; public OpenGLView(Context context) { super(context); // TODO Auto-generated constructor stub glReader=new GLReader(); setRenderer(glReader); } }
接下来是我们的activity类:
- 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);
- }
- }
复制代码
1
2
3
4
5
6
7
8
9public 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接口:
- 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
- }
- }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144package 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绘制旋转立方体实例内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复