必威体育Betway必威体育官网
当前位置:首页 > IT技术

从零开始之OpenGL ES 2.0【0】

时间:2019-05-30 23:41:04来源:IT技术作者:seo实验室小编阅读:80次「手机版」
 

opengles2.0

刚刚接触OpenGL ES一头雾水,完全不知道从什么地方入手。本文的OpenGL ES 为 OpenGL ES2.0,为什么要从2.0开始学习呢,因为后续的3.0版本兼容2.0语法基本相同,1.0已经成为过去式,2.0及以后版本不兼容1.0了。

为了方便学习与记忆。决定脚踏实地从浅入深的了解OpenGL ES,而不是直接从一个完整的项目一点一点讲解。既然是从浅入深的了解那么就要从最简单的例子开始了。

在开始之前还要简单做一些说明:

一、OpenGL ES的构成

OpenGL ES所有只有 点、线、三角形。所有图形都是由以上三种构成的。如果需要复杂的3d图形可以使用3D图形工具生成后使用。

二、OpenGL ES的坐标系

OpenGL ES坐标系有顶点坐标和纹理坐标看下图

                    顶点坐标

               纹理坐标

三、OpenGL ES的着色器

OpenGL ES有两个着色器:顶点着色器、片元着色器。

最简单的着色器代码

    //顶点着色器代码
    private final String vertex = "" +
            "attribute vec4 vPosition;" +
            "void main(){" +
            "gl_Position=vPosition;"+
            "}";
    //片元着色器代码
    private final String fragment = "" +
            "precision mediump float;" +
            "uniform vec4 vcolor;" +
            "void main(){" +
            "gl_FragColor=vColor;"+
            "}";

着色器代码可以放在代码内部也可以定义在外部储存设备上的文件中,读取文件内容设置也可以。它们使用GLSL语言撰写,具体语法后面会详细说明。

下面开始一个简单的例子,使用OpenGL画三角形。

1、创建一个View命名为DGLView继承GLsurfaceview实现Renderer接口;

2、创建一个Renderer命名为DGLRender实现Renderer接口。

3、在activity_main.xml内增加

package pers.wtt.opengles10.view;

import Android.content.context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import pers.wtt.opengles10.render.DGLRender;

/**
 * Created by WT on 2018/4/8.
 */
public class DGLView extends GLSurfaceView implements GLSurfaceView.Renderer{

    private DGLRender dglRender;

    public DGLView(Context context) {
        super(context);
        init();
    }

    public DGLView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        //初始化Renderer
        dglRender = new DGLRender();
        //设置EGLContext为2.0
        setEGLContextClientVersion(2);
        //设置render,绘制全靠它
        setRenderer(this);
        //设置render模式为只在绘制数据发生改变时才绘制view
        //此设置会阻止绘制GLSurfaceView的帧,直到你调用了requestRender(),这样会非常高效。
        setRenderMode(RENDERMODE_WHEN_DIRTY);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        dglRender.onSurfaceCreated(gl, config);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        dglRender.onSurfaceChanged(gl, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        dglRender.onDrawFrame(gl);
    }
}
package pers.wtt.opengles10.render;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import java.nio.ByteBuffer;
import java.nio.Byteorder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Created by WT on 2018/4/8.
 */
public class DGLRender implements GLSurfaceView.Renderer {

    //顶点着色器代码
    private final String vertex = "" +
            "attribute vec4 vPosition;" +
            "void main(){" +
            "gl_Position=vPosition;"+
            "}";

    //片元着色器代码
    private final String fragment = "" +
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main(){" +
            "gl_FragColor=vColor;"+
            "}";

    //顶点坐标
    private final float[] pos = {
            -0.5f,-0.5f,0.0f,
            0.5f,0.5f,0.0f,
            0.5f,-0.5f,0.0f,
    };

    //颜色值
    private final float[] colors = {
            1.0f,0.0f,0.0f,1.0f
    };

    //GL程序
    int program;
    // 顶点坐标Buffer
    FloatBuffer vertexBuffer;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //将背景设置为灰色,这里只是设置,并没有立即生效
        GLES20.glClearColor(0.5f,0.5f,0.5f,1.0f);
        //创建一个顶点坐标Buffer,一个float为4字节所以这里需要
        ByteBuffer byteBuffer = ByteBuffer.allocatedirect(pos.length*4);
        byteBuffer.order(ByteOrder.nativeOrder());
        vertexBuffer  = byteBuffer.asFloatBuffer();
        vertexBuffer .put(pos);
        vertexBuffer .position(0);
        //装载顶点着色器和片元着色器,从source
        int vertexshader = loadShader(GLES20.GL_VERTEX_SHADER, vertex);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragment);
        //创建Opengl程序,获取程序句柄,为了方便onDrawFrame方法使用所以声明为成员变量
        program = GLES20.glCreateProgram();
        //激活着色器
        GLES20.glattachShader(program, vertexShader);
        GLES20.glAttachShader(program, fragmentShader);
        //链接程序
        GLES20.glLinkProgram(program);
    }

    /**
     * 装载着色器从资源代码,需要检测是否生成成功,暂时不检测
     * @param type 着色器类型
     * @param source 着色器代码源
     * @return 返回着色器句柄
     */
    private int loadShader(int type, String source) {
        int shader = 0;
        shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, source);
        GLES20.glCompileShader(shader);
        return shader;
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //当大小改变时重置视区大小
        GLES20.glViewport(0,0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //清空缓冲区,与  GLES20.glClearColor(0.5f,0.5f,0.5f,1.0f);对应
        GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_depth_BUFFER_BIT);
        //使用OpenGL程序
        GLES20.glUseProgram(program);
        //获取顶点着色器变量vPosition
        int vPositionhandler = GLES20.glGetAttribLocation(program, "vPosition");
        //允许使用顶点坐标数组
        GLES20.glEnableVertexAttribArray(vPositionHandler);
        //第一个参数顶点属性的索引值
        // 第二个参数顶点属性的组件数量。必须为1、2、3或者4,如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a))
        // 第三个参数数组中每个组件的数据类型
        // 第四个参数指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)
        // 第五个参数指定连续顶点属性之间的偏移量,这里由于是三个点 每个点4字节(float) 所以就是 3*4
        // 第六个参数前面的顶点坐标数组
        GLES20.glVertexAttribPointer(vPositionHandler, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer);
        //获取片元着色器变量vColor
        int vColor = GLES20.glGetUniformLocation(program, "vColor");
        GLES20.glUniform4fv(vColor, 1, colors, 0);
        //三角形绘制方式
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_strip, 0, 3);
        //禁止使用顶点坐标数组
        GLES20.gldisableVertexAttribArray(vPositionHandler);
    }

}
<?xml version="1.0" encoding="utf-8"?>
<Linearlayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello world!"/>

    <pers.wtt.opengles10.view.DGLView
        android:id="@+id/dglView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    </pers.wtt.opengles10.view.DGLView>

</LinearLayout>

到这里就可以运行一下APP看看效果了。运行结果图如下。

相关阅读

详细解读百度搜索细雨算法2.0

  对前阵子即将上线的细雨算法2.0,百度官方近日给出了针对细雨算法2.0的具体问题的错误示例和整改建议,帮助站长们具体地理解细雨

【OpenGL】OpenGL教程(1)——准备

原文:http://www.cnblogs.com/collectionne/p/6617364.html GLFW OpenGL是一个图形库,而要画图,就需要先创建一个窗口。不幸的是,Open

部署ESXI(Vclient 连接虚拟化服务器)

EXSI5.5只能在64位X86CPU的服务器上安装和运行。 ESXI5.5要求主机至少具有两个内核的CPU。 ESXI5.5至少需要4GB的物理内存。 ESXI

@RequestBody,415Unsupported Media Type错误,真正有用

用了一上午查找问题解决方案,网上的试验了一遍都没用,最后终于解决~我的答案在最后 问题:前端传json,后端也返回json,出现格式不匹配报

oracle中的greatest 函数和 least函数

greatest (max(one),max(two),max(three))求多列的最大值,oracle中的greatest 函数 已知表TB的数据如下 SQL> select * from tb; 

分享到:

栏目导航

推荐阅读

热门阅读