GLES2.0 顶点和着色器 第二课

注意一下:
1、在OpenGL里面,只会绘制点,直线和三角形。
2、OpenGL作为本地系统库,是直接运行到硬件上的,没有虚拟机,垃圾回收和内存压缩。所有的 android.opengl.GLES2.0包中的方法,实际上都是使用 JNI 调用的本地方法库。
3、由于2的因素,所以openGL绘制需要的数据,都需要做一层转换,从java内存中转到 本地 内存中(我理解的就是 native)

// 因为上面 3 中 所描述的所以,数据的传输,我们采用的是 ByteBuffer
FloatBuffer vertexData;
    // 2 个 三角形
    float tableVerticesWithTriangles[] = {
            -0.5f,-0.5f,
            0.5f,0.5f,
            -0.5f,0.5f,

            -0.5f,-0.5f,
            0.5f,-0.5f,
            0.5f,0.5f,

            -0.5f,0f,
            0.5f,0f,

            0f,-0.25f,
            0f,0.25f};

ByteBuffer.allocateDirect(tableVerticesWithTriangles.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
// allocateDirect 方法是 C++ 中申请内存的方法,什么类型,每个类型多少字节
// 把数据 放到 FloatBuffer 的实例中
        vertexData.put(tableVerticesWithTriangles);

上面是java中的数据往 native 中作一个迁移吧。下面需要介绍着色器了,这个很重要。

OpenGL 中的着色器分为 顶点着色器 和 片元着色器
1、着色器是用来描述 openGL 需要绘制的内容的 代码,专门告诉GPU的
2、顶点着色器描述顶点的位置,属性(颜色,大小,渐变色等)
3、片元着色器描述点、线、三角形的颜色,渐变色,大小

// 给顶点增加 颜色属性
   private static String vertex_shader_step3 = "attribute vec4 a_Position; \n" +
           // a_Color 记录顶点的 颜色
           "attribute vec4 a_Color; \n" +
// 正交投影 的 矩阵 数据 (位置 a_Position * u_Matrix 得到一个新的位置 投影位置)
           "uniform mat4 u_Matrix; \n" +  // mat4 代表一个 4 X 4 的矩阵
           // varying 表明颜色是在变化的
           "varying vec4 v_Color; \n" +
           "void main()\n" +
           "{\n" +
           // gl_Position是OpenGL中提供的变量,装载顶点坐标
           "    gl_Position = a_Position * u_Matrix;\n" +
           "    v_Color = a_Color; \n"+
           // 指定 绘制 的 点的 大小
           "    gl_PointSize = 10.0;\n" +
           "}";

gl_Position gl_PointSize 都是一些固定的属性 attribute 、uniform和varying 是具有特殊意义的修饰词

attribute 声明一个属性数据 vec4 类型的数据,存放位置数据
varying 声明 渐变的颜色数据

// 片元着色器,主要还是 声明颜色的
public static final String fragment_shader_step3 = "precision mediump float;\n" +
           "varying vec4 v_Color; \n" +
           "void main() {\n" +
           // gl_FragColor 装载 当前片段的最终颜色
           // 这里使用的是 v_Color 也就是 varying的属性,说明该片元的颜色根据两个顶点计算之后使用
           "    gl_FragColor=v_Color;\n" +
           "}";

着色器的创建

/**
    *  创建 着色器 对象
    *  type : GLES20.GL_VERTEX_SHADER / GLES20.GL_FRAGMENT_SHADER
    *  shaderCode: 着色器 代码
    */
   public static int createShader(int type, String shaderCode) {
      // 1、创建一个 着色器 对象,并检查是否创建成功
      //TODO glCreateShader 在 native 中创建了 一个 着色器对象,并返回了这个 着色器的 id
      int shaderObjectId = GLES20.glCreateShader(type);
      if (shaderObjectId == 0) {
         System.out.println("majie " + TAG + "  Could not create new shader");
         return 0;
      }

      // 2、上传 着色器 源码 到 着色器 对象里
      // TODO shaderObjectId 代表着色器对象, shaderCode 是我们定义的 顶点着色器源码
      GLES20.glShaderSource(shaderObjectId, shaderCode);

      // 3、告诉 openGL 编译 第二步 上传的源码(字符串)
      GLES20.glCompileShader(shaderObjectId);

      // 4、获取 openGL 的编译结果
      int compileStatue[] = new int[1];
      // TODO openGL 的通用写法 --> 将 shaderObjectId 的编译结果 写到 compileStatue 中的第一个元素中
      GLES20.glGetShaderiv(shaderObjectId, GLES20.GL_COMPILE_STATUS, compileStatue, 0);

      // TODO 额外信息,可以获取 着色器 的编译日志
      System.out.println("majie " + TAG + "  Results of compiling source: " + compileStatue[0]
              + "  \n:" + GLES20.glGetShaderInfoLog(shaderObjectId));

      // 5、验证 编译状态 ,并 返回着色器的对象 ID TODO:TMD就是最开始生成的那个 ID
      if (compileStatue[0] == 0) {
         // 如果失败,就删除 shader 对象
         GLES20.glDeleteShader(shaderObjectId);
      }

      return shaderObjectId;
   }

这里要理解一个点,就是

因为 OpenGL 实际上是通过jni调用的 native 方法,所以 通过 GLES20 调用的方法,创建的实例,返回的一般都是int ,说白了应该是 内存地址 ,在通过指针去获取 其中的数据,在C++ 中进行操作和执行
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343