使用openGL步骤:
1.创建GLSurfaceView对象
2.创建GLSurfaceView.renderer实现类.
3.设置activity的contentView,以及设置view的render对象.
4.实现render类的过程.
onSurfaceCreate()方法
设置清屏的颜色和启用顶点缓冲区//设置清屏色
gl.glClearColor(0, 0, 0, 1);
//启用顶点缓冲区
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);onSurfaceChanged()方法
1.设置viewport(视口//输出画面的区域)gl.glViewport(0, 0, width, height);
2.操纵投影矩阵,设置平截头体(比例通常和视口比例相同,否则输出画面会走样)
//矩阵模式,投影矩阵,openGL基于状态机 gl.glMatrixMode(GL10.GL_PROJECTION); //加载单位矩阵(归零) gl.glLoadIdentity(); //平截头体(视景体) 参数对应,左,右,下,上,近平面,远平面(画图形要在这些值范围之内,否则要被截裁的) gl.glFrustumf(-ratio, ratio, -1f, 1f, 3, 7);
onDrawFrame()方法
1.清除颜色缓冲区gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
2.操纵模型视图矩阵,设置眼球的参数
//之前创建的时候是投影矩阵,现在要设置眼球参数的话呀改成模型视图矩阵,否则可以不改gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity();//加载单位矩阵GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);//gl后第一组三个参数是眼球座标,中间三个参数是眼球的观察点,后三个参数是眼球向上的向量
3.定义图形顶点座标值数组(一般用浮点数,整数也可以的)
float[] coords = { 0f,0.5f,0f, -0.5f,-0.5f,0f, 0.5f,-0.5f,0f };
4.将顶点座标转换成缓冲区数据
//分配字节缓存区空间(效率更高),存放顶点座标数据 ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);//一个浮点数占4位 //设置的顺序(本地顺序) ibb.order(ByteOrder.nativeOrder()); //放置顶点座标数组(第一步是包装成浮点缓冲区) FloatBuffer fbb = ibb.asFloatBuffer(); fbb.put(coords); //定位指针的位置,从该位置开始读取顶点数据 ibb.position(0);
5.设置绘图颜色
gl.glColor4f(1f, 0f, 0f, 1f);//和安卓不同,这里是rgba 安卓原生的是argb //glColorXX 这里4是4个浮点数。 f是float
6.指定顶点缓冲区指针
//3:3维点,使用三个座标值表示一个点 //type:每个点的数据类型 //stride:0,跨度. //ibb:指定顶点缓冲区 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ibb);
7.绘图(最主要的)
//0:起始点: //3:绘制点的数量 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //一共三种模式,画点,画线,画三角形(图元)。平面也是三角形//球和环是无数个三角形
附上 绘制一个三角形的代码
opengl使用的是笛卡尔座标系,与屏幕座标系不一样的。左下角才是原点。
package com.example.administrator.myapplication;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends AppCompatActivity
{
float ratio;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
MyGLSurfaceView view = new MyGLSurfaceView(this);
view.setRenderer(new MyRenderer());//渲染器
setContentView(view);
}
class MyGLSurfaceView extends GLSurfaceView
{
public MyGLSurfaceView(Context context)
{
super(context);
}
public MyGLSurfaceView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
}
class MyRenderer implements android.opengl.GLSurfaceView.Renderer
{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
//设置表层画面
gl.glClearColor(0, 0, 0, 1);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//启用顶点缓存区
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
//设置视口和画面区域
gl.glViewport(0, 0, width, height);
ratio = (float) width/(float) height;
//矩阵模式,投影矩阵,opengGL基于状态机
gl.glMatrixMode(GL10.GL_PROJECTION);
//加载单位矩阵
gl.glLoadIdentity();
//平截头体
gl.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);
}
@Override
public void onDrawFrame(GL10 gl)
{
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//模型视图矩阵
gl.glMatrixMode((GL10.GL_MODELVIEW));
//加载单位矩阵
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0, 1, 0);
//画三角形
float[] coords = {0f, ratio, 0f, -1f, -ratio, 0f, 1f, -ratio, 0f};
//分配字节缓存空间,存放顶点数据
ByteBuffer ib = ByteBuffer.allocateDirect(coords.length * 4);
//设置的顺序(本地顺序)
ib.order(ByteOrder.nativeOrder());
//放置顶点数据
FloatBuffer fbb = ib.asFloatBuffer();
fbb.put(coords);
//定位指正的位置。冲该位置读取顶点数据
ib.position(0);
gl.glColor4f(1f, 0f, 0f, 1f);
//三维的点
//stride//跨度
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ib);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
}
}