流程

1、编写着色器(顶点着色器和片元着色器)

2、设置顶点、纹理坐标

3、加载着色器

4、创建纹理

5、渲染图片


OpenGL ES 中的顶点坐标与纹理坐标


绘制四边形

规定:图形环绕方向必须一致

参数属性:三角形    GL_TRIANGLES
v1, v2, v3,
v3, v2, v4,

参数属性:三角形扇    GL_TRIANGLE_STRIP:
偶数:n-1, n-2, n
奇数:n-2, n-1, n


顶点内存数组

1、绘制坐标范围
    float[] vertexData = {
                       -1f, -1f,
                       1f, -1f,
                      -1f, 1f,
                      1f, 1f               };

2、为坐标分配本地内存地址
    FloatBuffer vertexBuffer;
    vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(vertexData);
    vertexBuffer.position(0);


vertex_shader.glsl    顶点着色器shader

attribute vec4 v_Position;     //顶点坐标
attribute vec2 f_Position;      //纹理坐标
varying vec2 ft_Position;       //
void main() {
    ft_Position = f_Position;
    gl_Position = v_Position;
}

attribute 只能在vertex中使用varying 用于vertex顶点着色器    和    fragment片元着色器之间传递值


fragment_shader.glsl    片元着色器shader

precision mediump float;     //绘制精度
varying vec2 ft_Position;     //与顶点着色器中传值
uniform sampler2D sTexture;    //图片
void main() {
    gl_FragColor=texture2D(sTexture, ft_Position);
}

注: uniform 用于在application中向vertex和fragment中传递值。


OpenGL ES加载Shader

1、创建shader( shaderType 着色器类型:顶点或片元)
    int shader = GLES20.glCreateShader(shaderType);
2、加载shader源码并编译shader 
    GLES20.glShaderSource(shader, source);    //source  着色器语言中的字符串
    GLES20.glCompileShader(shader);                //编译
3、检查是否编译成功:
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
4、创建一个渲染程序:
    int program = GLES20.glCreateProgram();
5、将着色器程序添加到渲染程序中:
    GLES20.glAttachShader(program, vertexShader);     //将指定的顶点/纹理添加至程序里面
6、链接源程序:
    GLES20.glLinkProgram(program);

7、检查链接源程序是否成功
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
8、得到着色器中的属性:
int vPosition  = GLES20.glGetAttribLocation(program, "v_Position");
9、使用源程序:
    GLES20.glUseProgram(program);
10、使顶点属性数组有效:
    GLES20.glEnableVertexAttribArray(vPosition);    
11、为顶点属性    vPosition     赋值:
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8 ,vertexBuffer);   // 2 两个属性确定一个点   GL_FLOAT类型     false是否需要归一化   8两点之间的跨度    vertexBuffer本地缓存

//   取8位变成2个点    
12、绘制图形:
     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);    //三角形带


工具方法

// 1 .从raw文件中获取字符串
public static String getRawResource(Context context, int rawId) {InputStream inputStream = context.getResources().openRawResource(rawId);BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuffer sb = new StringBuffer();String line;try {while ((line = reader.readLine()) != null) {sb.append(line).append("\n");}reader.close();} catch (Exception e) {e.printStackTrace();}return sb.toString();
}//2 .根据顶点着色器字符串和片元着色器字符串创建 shader
private static int loadShader(int shaderType, String source) {int shader = GLES20.glCreateShader(shaderType);if (shader != 0) {GLES20.glShaderSource(shader, source);GLES20.glCompileShader(shader);int[] compile = new int[1];GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compile, 0);if (compile[0] != GLES20.GL_TRUE) {GLES20.glDeleteShader(shader);shader = 0;}return shader;} else {return 0;}
}//3 .根据shader创建program
public static int createProgram(String vertexSource, String fragmentSoruce) {int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSoruce);if (vertexShader != 0 && fragmentShader != 0) {int program = GLES20.glCreateProgram();GLES20.glAttachShader(program, vertexShader);GLES20.glAttachShader(program, fragmentShader);GLES20.glLinkProgram(program);return program;}return 0;
}

GImgVideoView

package com.example.glivepush.opengl;import android.content.Context;
import android.util.AttributeSet;import com.example.glivepush.egl.GEGLSurfaceView;public class OpenGLView extends GEGLSurfaceView {public OpenGLView(Context context) {this(context, null);}public OpenGLView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public OpenGLView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setRender(new OpenGLRender(context));}
}

GImgVideoRender

package com.example.glivepush.opengl;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;import com.example.glivepush.R;
import com.example.glivepush.egl.GEGLSurfaceView;
import com.example.glivepush.egl.GShaderUtil;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;public class OpenGLRender implements GEGLSurfaceView.GGLRender {private Context context;//顶点坐标  主要用来在本地开辟内存private float[] vertexData = {-1f, -1f,1f, -1f,-1f, 1f,1f, 1f};//生成的本地内存private FloatBuffer vertexBuffer;//纹理坐标private float[] fragmentData = {0f, 1f,1f, 1f,0f, 0f,1f, 0f};//生成的本地内存private FloatBuffer fragmentBuffer;private int program;private int vPosition;private int fPosition;private int textureid;private int sampler;public OpenGLRender(Context context) {this.context = context;//生成的本地内存vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexData);vertexBuffer.position(0);fragmentBuffer = ByteBuffer.allocateDirect(fragmentData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(fragmentData);fragmentBuffer.position(0);}@Overridepublic void onSurfaceCreated() {//工具方法加载代码String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader_screen);String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader_screen);//工具方法创建programprogram = GShaderUtil.createProgram(vertexSource, fragmentSource);if (program > 0) {//取出顶点坐标vPosition = GLES20.glGetAttribLocation(program, "v_Position");//取出纹理坐标fPosition = GLES20.glGetAttribLocation(program, "f_Position");sampler = GLES20.glGetUniformLocation(program, "sTexture");}//生成纹理int[] textureIds = new int[1];GLES20.glGenTextures(1, textureIds, 0);textureid = textureIds[0];//绑定纹理GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid);//绑定至第0位GLES20.glActiveTexture(GLES20.GL_TEXTURE0);//将sampler绑定至第0位GLES20.glUniform1f(sampler, 0);//设置环绕过滤方法GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);//绘制图片Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.img_1);GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);bitmap.recycle();bitmap = null;//解绑GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);}@Overridepublic void onSurfaceChanged(int width, int height) {GLES20.glViewport(0, 0, width, height);}@Overridepublic void onDrawFrame() {//清屏GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);GLES20.glClearColor(1f, 0f, 0f, 1f);//使程序生效GLES20.glUseProgram(program);//重新绑定GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid);//使顶点属性数组有效GLES20.glEnableVertexAttribArray(vPosition);//为顶点属性赋值GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,vertexBuffer);//使纹理属性数组有效GLES20.glEnableVertexAttribArray(fPosition);//为顶点属性赋值GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,fragmentBuffer);//绘制图形GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);//解绑GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);}}

OpenGL ES 绘制图片相关推荐

  1. OpenGL ES:绘制函数glDrawArrays 和 glDrawElements 的区别

    from:https://www.jianshu.com/p/4d02c2cd21ea 写文章注册登录 首页 下载App OpenGL ES:绘制函数glDrawArrays 和 glDrawElem ...

  2. Android Studio OpenGL ES绘制三棱锥/四面体的多纹理贴图 每个面使用一张图片渲染

    本文参考了王刚的<疯狂Android讲义(第3版)>P554-P559 要求:利用OpenGL ES绘制一个三棱锥,并对每个面进行纹理贴图,每个面使用不同的图片进行渲染. 环境:Andro ...

  3. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

  4. 【Qt for Android】OpenGL ES 绘制彩色立方体

    Qt 内置对OpenGL ES的支持.选用Qt进行OpenGL ES的开发是很方便的,很多辅助类都已经具备.从Qt 5.0開始添加了一个QWindow类,该类既能够使用OpenGL绘制3D图形,也能够 ...

  5. 安卓学习笔记37:利用OpenGL ES绘制平面图形

    文章目录 零.学习目标 一.OpenGL概述 二.了解三维直角坐标系 三.案例演示 - 绘制三角形 (一)运行效果 (二)实现步骤 1.创建安卓应用[DrawTriangle] 2.建模:创建三角形类 ...

  6. android opengl es 绘制余弦曲线,Android OpenGL ES - 绘制线、面

    前言 之前一篇文章讲了如何绘制点,所谓两点成线,三点成面.一个立体图形就是由很多面组成,在OpenGL ES中,面特指一个三角形. 绘制调用glDrawArrays(int mode, int fir ...

  7. 2.x最终照着教程,成功使用OpenGL ES 绘制纹理贴图,添加了灰度图

    在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理. 学校时候不知道OpenGL的重要性,怕晦涩的语法.没有跟老师学习OpenGL的环境配置,现在仅仅能利用coco ...

  8. 2.x终于照着教程,成功使用OpenGL ES 绘制纹理贴图,增加了灰度图

    在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理.学校时候不知道OpenGL的重要性,怕晦涩的语法,没有跟老师学习OpenGL的环境配置,如今只能利用cocos2 ...

  9. Android 开发使用OpenGL ES绘制三棱锥并进行纹理贴图

    效果图: 直接上代码 MainActivity.java的代码 package com.zzu.shiyan3;import androidx.appcompat.app.AppCompatActiv ...

最新文章

  1. jquery方法animate操作图片移动
  2. WebService、WCF、WebAPI、MVC的区别
  3. C_Free引用链接库
  4. mysql数据库雪崩_缓存与数据库一致性之三:缓存穿透、缓存雪崩、key重建方案...
  5. 重物码垛搬运机器人_搬运码垛机器人的特点及应用
  6. 适合初学者的安卓开源项目_开源系列的初学者将从下周开始
  7. Bootstrap CSS编码规范之代码组织规范
  8. 【ZeroClipboard is not defined】的解决方法
  9. 证券期货信息安全等级保护测评
  10. html5设置谷歌浏览器兼容性,google浏览器
  11. 手机成像技术简谈(测光篇)
  12. 10大动图:秒懂各种常用通信协议原理
  13. oracle 的乘法,Oracle group by 相乘
  14. 解决swap file .swp already exists 问题
  15. ThinkPad R480 C盘 固态128G 升级到 512G + 系统无缝迁移,不用重装软件
  16. SpringBoot系列之@PropertySource读取yaml文件
  17. 查看WIN10 SDK的版本
  18. 如何生成题注和表注目录
  19. JavaScript运行原理解析
  20. 计算机在药店管理系统中的应用,计算机系统在药店管理系统中的应用(国外英语资料).doc...

热门文章

  1. 计算机网络DNS域名解析协议详解
  2. 解决方案和项目的区别_(实习招聘)PwC面试官问Advisory和Consulting有什么区别,怎么答?...
  3. HCIP第九天笔记(OSPF的路由回馈、路由策略、以及配置指南)
  4. 计算机专业的论文的格式,计算机专业毕业论文格式范例
  5. 文明游戏5的计算机配置,文明6配置要求高吗 文明6最低电脑配置与推荐电脑配置...
  6. Vivado使用技巧(24):HDL/XDC中设置综合属性
  7. 高维空间中椭圆的基本方程
  8. ubuntu虚拟机中的vscode:扩展失败XHR Failed
  9. 给实体机服务器重装Linux系统全记录
  10. OpenGL ES EGL eglQueryContext