OpenGL学习

Posted Fishbonell

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL学习相关的知识,希望对你有一定的参考价值。

  OpenGL(全写Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。在游戏和特效领域,使用非常广泛。在移动平台上android支持了OpenGL ES。今天,我开始学习OpenGL ES 并在此记录学习的过程。

  Android提供了GLSurfaceView,是一个支持OpenGL ES的控件,封装了OpenGL的复杂流程。今天记录一下它的使用方法。

  

public class MainActivity extends AppCompatActivity {

    private GLSurfaceView glSurfaceView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glSurfaceView = new GLSurfaceView(this);
        glSurfaceView.setRenderer(new GLSurfaceViewRender());
        setContentView(glSurfaceView);

    }

    @Override
    protected void onResume() {
        super.onResume();
        glSurfaceView.onResume();
    }


    @Override
    protected void onPause() {
        super.onPause();
        glSurfaceView.onPause();
    }


}

  GLSurfaceViewRender是我们自定义的类,它实现了GLSurfaceView.Renderer的接口,封装了GLSurfaceView的相关操作和生命周期。

  

public class GLSurfaceViewRender implements GLSurfaceView.Renderer {

    private float[] mTriangleArray = {
            // X, Y, Z 这是一个等边三角形
            -0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.4f, 0 };


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 设置背景颜色
        gl.glClearColor(0.9f, 0.8f, 1f, 0.9f);
        // 启用顶点数组(否则glDrawArrays不起作用)
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 设置输出屏幕大小
        gl.glViewport(0, 0, width, height);


    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // 清除屏幕和深度缓存(如果不调用该代码, 将不显示glClearColor设置的颜色)
        // 同样如果将该代码放到 onSurfaceCreated 中屏幕会一直闪动
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        // 获取颜色
        gl.glColor4f(1.0f, 0.4f, 0.4f, 0.8f);
        // 获取形状数组
        FloatBuffer mTriangleBuffer = BufferUtil
                .floatToBuffer(mTriangleArray);
        // 每个点用几个数字描述;
        // 每个顶点坐标的变量类型;
        // 取数据时的间隔,因为有些人习惯把颜色数据也放里边,如果这样,你需要跳过这些点.意思就是每隔stride取一个点;
        // 每个顶点的坐标
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);
        /**
         * 参数1:有三种取值
         1.GL_TRIANGLES:每三个顶之间绘制三角形,之间不连接
         2.GL_TRIANGLE_FAN:以V0V1V2,V0V2V3,V0V3V4,……的形式绘制三角形
         3.GL_TRIANGLE_STRIP:顺序在每三个顶点之间均绘制三角形。这个方法可以保证从相同的方向上所有三角形均被绘制。以V0V1V2,V1V2V3,V2V3V4……的形式绘制三角形

         参数2:从数组缓存中的哪一位开始绘制,一般都定义为0
         参数3:顶点的数量
         */
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        //  加载glLoadIdentity(),等于是将之前矩阵变换导致变化过的栈顶矩阵重新归位,置为单位矩阵!等于是之前的矩阵变换带来的影响到此为止了!
        gl.glLoadIdentity();
        // 平移 (矩阵相乘)
        gl.glTranslatef(-0.2f, 0.3f, 0f);

    }

    static class BufferUtil {
        public static FloatBuffer mBuffer;

        public static FloatBuffer floatToBuffer(float[] a) {
            // 先初始化buffer,数组的长度*4,因为一个float占4个字节
            ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
            // 数组排序用nativeOrder
            mbb.order(ByteOrder.nativeOrder());
            mBuffer = mbb.asFloatBuffer();
            mBuffer.put(a);
            mBuffer.position(0);
            return mBuffer;
        }
    }
}

  以上是用OpenGL 画一个三角形的过程,注释记录详细。

  初步的,就是这样。

  Done~

以上是关于OpenGL学习的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 纹理学习总结

openGL之API学习(一六七)默认着色器 顶点属性索引 别名索引

我的OpenGL学习进阶之旅NDK开发中find_library查找的系统动态库在哪里?

我的OpenGL学习进阶之旅NDK开发中find_library查找的系统动态库在哪里?

OpenGL片段着色器不照亮场景

片段着色器中未使用纹理数据 - OpenGL