概述
通过上一节我们已经学会了使用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);
- }
- }
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类:
- 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);
- }
- }
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接口:
- 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
- }
- }
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绘制旋转立方体实例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复