您的位置:首页 > 移动开发 > Android开发

Android OpenGL教程 一 基础概念

2018-01-13 16:38 423 查看
GLSurfaceView可以画2D、3D的图形,因为他可以通过先确定点的坐标,由两个点画出一个线,然后通过由三个点或四个点来确定一个面就是2D,最后分别将几个面都画出来就是3D。
所以首先我们学学这个坐标如何去确定



这个原点在屏幕中心,这个要记住,然后z轴的正方向是向屏幕外的

然后就是了解GLSuerfaceVIew

首先想显示一个GLSurfaceView很容易

        mGLView = new GLSurfaceView(this); //这里使用的是自定义的GLSurfaceView的子类

        mGLView.setRenderer(new GLRenderer());

        setContentView(mGLView);

但是这个Renderer必须我们自定义来解决,OpenGL很大功夫都花在Renderer上了

首先我们用坐标画一条线

        private float[] mTriangleArray={

                -1.0f,0.0f,0.0f,

                1.0f,0.0f,0.0f

        };

给个颜色

        private float[] mColor ={

                1.0f,0.0f,0.0f,1.0f,

                1.0f,0.0f,0.0f,1.0f

        };

然后在创建Renderer时将这些数据写入内存

        public GLRenderer() {

            //点相关

            //先初始化buffer,数组的长度*4,因为一个float占4个字节

            ByteBuffer bb = ByteBuffer.allocateDirect(mTriangleArray.length * 4);

            //以本机字节顺序来修改此缓冲区的字节顺序

            bb.order(ByteOrder.nativeOrder());

            mTriangleBuffer = bb.asFloatBuffer();

            //将给定float[]数据从当前位置开始,依次写入此缓冲区

            mTriangleBuffer.put(mTriangleArray);

            //设置此缓冲区的位置。如果标记已定义并且大于新的位置,则要丢弃该标记。

            mTriangleBuffer.position(0);

            //颜色相关

            ByteBuffer bb2 = ByteBuffer.allocateDirect(mColor.length * 4);

            bb2.order(ByteOrder.nativeOrder());

            mColorBuffer = bb2.asFloatBuffer();

            mColorBuffer.put(mColor);

            mColorBuffer.position(0);

        }

GLSurfaceView运行时,开始先运行onSurfaceCreated函数,我们用一个函数现将背景变成白色

        @Override

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {

            // 设置白色为清屏

            gl.glClearColor(1, 1, 1, 1);

        }

然后在onDrawFrame绘制图形,这个函数运用了很多其他的函数

glEnable()启用相关功能,glDisable()关闭相关功能。,glClear清屏,glLoadIdentity将初始矩阵换成单位矩阵,这些一般都默认要有

        @Override

        public void onDrawFrame(GL10 gl) {

            // 清除屏幕和深度缓存

            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

            // 重置当前的模型观察矩阵

            gl.glLoadIdentity();

            // 允许设置顶点

            //GL10.GL_VERTEX_ARRAY顶点数组

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

            // 允许设置颜色

            //GL10.GL_COLOR_ARRAY颜色数组

            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

            //将三角形在z轴上移动

            gl.glTranslatef(0f, 0.0f, -2.0f);

            // 设置三角形

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);

            // 设置三角形颜色

            gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);

            // 绘制三角形

            gl.glDrawArrays(GL10.GL_LINES, 0, mTriangleArray.length/3);

            // 取消颜色设置

            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

            // 取消顶点设置

            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

            //绘制结束

            gl.glFinish();

        }

最后就是这个GLSurfaceView的显示屏幕大小变化是由onSurfaceChanged来控制,glFrustumf是为了将整个GLSurfaceView显示的内容变小或换位置

        @Override

        public void onSurfaceChanged(GL10 gl, int width, int height) {

            float ratio = (float) width / height;

            // 设置OpenGL场景的大小,(0,0)表示窗口内部视口的左下角,(w,h)指定了视口的大小

            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();

        }

最后,完整代码如下:

public class MainActivity extends Activity {
private GLSurfaceView mGLView;

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(this); //这里使用的是自定义的GLSurfaceView的子类
mGLView.setRenderer(new GLRenderer());
setContentView(mGLView);
}

public void onPause(){
super.onPause();
mGLView.onPause();
}

public void onResume(){
super.onResume();
mGLView.onResume();
}

public class GLRenderer implements GLSurfaceView.Renderer {

private float[] mTriangleArray={
-1.0f,0.0f,0.0f,
1.0f,0.0f,0.0f
};

private float[] mColor ={
1.0f,0.0f,0.0f,1.0f,
1.0f,0.0f,0.0f,1.0f
};
private FloatBuffer mTriangleBuffer;
private FloatBuffer mColorBuffer;

public GLRenderer() {
//点相关
//先初始化buffer,数组的长度*4,因为一个float占4个字节
ByteBuffer bb = ByteBuffer.allocateDirect(mTriangleArray.length * 4);
//以本机字节顺序来修改此缓冲区的字节顺序
bb.order(ByteOrder.nativeOrder());
mTriangleBuffer = bb.asFloatBuffer();
//将给定float[]数据从当前位置开始,依次写入此缓冲区
mTriangleBuffer.put(mTriangleArray);
//设置此缓冲区的位置。如果标记已定义并且大于新的位置,则要丢弃该标记。
mTriangleBuffer.position(0);

//颜色相关
ByteBuffer bb2 = ByteBuffer.allocateDirect(mColor.length * 4);
bb2.order(ByteOrder.nativeOrder());
mColorBuffer = bb2.asFloatBuffer();
mColorBuffer.put(mColor);
mColorBuffer.position(0);
}

@Override
public void onDrawFrame(GL10 gl) {

// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();

// 允许设置顶点
//GL10.GL_VERTEX_ARRAY顶点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 允许设置颜色
//GL10.GL_COLOR_ARRAY颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

//将三角形在z轴上移动
gl.glTranslatef(0f, 0.0f, -2.0f);

// 设置三角形
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);
// 设置三角形颜色
gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
// 绘制三角形
gl.glDrawArrays(GL10.GL_LINES, 0, mTriangleArray.length/3);

// 取消颜色设置
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
// 取消顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//绘制结束
gl.glFinish();

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio = (float) width / height;
// 设置OpenGL场景的大小,(0,0)表示窗口内部视口的左下角,(w,h)指定了视口的大小
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) {
// 设置白色为清屏
gl.glClearColor(1, 1, 1, 1);

}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: