OpenGL ES 3.0学习实践

  • android平台下OpenGL ES 3.0从零开始
  • android平台下OpenGL ES 3.0绘制纯色背景
  • android平台下OpenGL ES 3.0绘制圆点、直线和三角形
  • android平台下OpenGL ES 3.0绘制彩色三角形
  • android平台下OpenGL ES 3.0从矩形中看矩阵和正交投影
  • android平台下OpenGL ES 3.0着色语言基础知识(上)
  • android平台下OpenGL ES 3.0着色语言基础知识(下)
  • android平台下OpenGL ES 3.0实例详解顶点属性、顶点数组
  • android平台下OpenGL ES 3.0实例详解顶点缓冲区对象(VBO)和顶点数组对象(VAO)
  • android平台下OpenGL ES 3.0绘制立方体的几种方式
  • android平台下OpenGL ES 3.0实现2D纹理贴图显示bitmap
  • android平台下OpenGL ES 3.0基于GLSurfaceView对相机Camera预览实时处理
  • android平台下OpenGL ES 3.0基于TextureView对相机Camera预览实时处理
  • android平台下基于ANativeWindow实现渲染bitmap图像

概述

原生Window API支持我们在ndk下开发原生的绘制功能,后续的一些视频渲染,包括相机采集预览等都可以通过这些API来实现,笔者今天通过几个简单的API来实践一下native层的绘制功能

配置环境

笔者Android Studio配置的是android-ndk-r16b版本,操作系统是ubuntu 16.05

绘制背景色

还是从最简单的入手,开始尝试绘制背景颜色,我们此次使用的方案是SurfaceView+ANativeWindow的方式,基于之前的项目工程

先定义Java层的本地方法

/*** @anchor: andy* @date: 2018-11-13* @description:*/
public class NativeWindowSample {static {System.loadLibrary("native-window");}/*** 绘制指定颜色背景** @param surface* @param color*/public native void drawColor(Object surface, int color);/*** 绘制指定颜色背景** @param surface* @param bitmap*/public native void drawBitmap(Object surface, Object bitmap);}

配置CMakeLists.txt文件内容如下:


cmake_minimum_required(VERSION 3.4.1)##官方标准配置
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -Wall")add_library(native-windowSHAREDsrc/main/cpp/native_window.cpp)target_link_libraries(native-window${OPENGL_LIB}androidjnigraphicslog)

build.gradle中的配置,这里不赘述,比较简单

在我们的子工程目录src/main/cpp下新建我们的native_window.cppnative_window.h文件:

来看看native_window.cppdrawColor的实现:

void drawColor(JNIEnv *env, jobject obj, jobject surface, jint colorARGB) {//分离ARGBint alpha = (colorARGB >> 24) & 0xFF;int red = (colorARGB >> 16) & 0xFF;int green = (colorARGB >> 8) & 0xFF;int blue = colorARGB & 0xFF;int colorABGR = (alpha << 24) | (blue << 16) | (green << 8) | red;//获取目标surfaceANativeWindow *window = ANativeWindow_fromSurface(env, surface);if (NULL == window) {ThrowException(env, "java/lang/RuntimeException", "unable to get native window");return;}//默认的是RGB_565int32_t result = ANativeWindow_setBuffersGeometry(window, 640, 640, WINDOW_FORMAT_RGBA_8888);if (result < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to set buffers geometry");//释放窗口ANativeWindow_release(window);window = NULL;return;}ANativeWindow_acquire(window);ANativeWindow_Buffer buffer;if (ANativeWindow_lock(window, &buffer, NULL) < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to lock native window");//释放窗口ANativeWindow_release(window);window = NULL;return;}uint32_t *line = (uint32_t *) buffer.bits;for (int y = 0; y < buffer.height; y++) {for (int x = 0; x < buffer.width; x++) {line[x] = colorABGR;}line = line + buffer.stride;}if (ANativeWindow_unlockAndPost(window) < 0) {ThrowException(env, "java/lang/RuntimeException","unable to unlock and post to native window");}//释放窗口ANativeWindow_release(window);
}

这里要注意的就是,我们从Java层传入的是32位的ARGB的颜色,直接写入我们的windowBuffer,颜色显示可能不正确,需要按照ANativeWindow_Buffer指定的颜色顺序作一次转换

绘制一个灰色背景:

mNativeWindowSample.drawColor(mSurfaceView.getHolder().getSurface(), Color.GRAY);

绘制bitmap

直接绘制bitmap也比较简单,但是我们需要通过AndroidBitmap_lockPixels方法获取bitmap对应的本地的数据的指针,通过这个指针来读取对应的像素数据,注释也比较清楚

void drawBitmap(JNIEnv *env, jobject obj, jobject surface, jobject bitmap) {//获取bitmap的信息,比如宽和高AndroidBitmapInfo info;if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to get bitmap info");return;}char *data = NULL;//获取bitmap对应的native指针if (AndroidBitmap_lockPixels(env, bitmap, (void **) &data) < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to lock pixels");return;}if (AndroidBitmap_unlockPixels(env, bitmap) < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to unlock pixels");return;}//获取目标surfaceANativeWindow *window = ANativeWindow_fromSurface(env, surface);if (NULL == window) {ThrowException(env, "java/lang/RuntimeException", "unable to get native window");return;}//这里设置为RGBA的方式,总共是4字节32位int32_t result = ANativeWindow_setBuffersGeometry(window, info.width, info.height,WINDOW_FORMAT_RGBA_8888);if (result < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to set buffers geometry");//释放窗口ANativeWindow_release(window);window = NULL;return;}ANativeWindow_acquire(window);ANativeWindow_Buffer buffer;//锁定窗口的绘图表面if (ANativeWindow_lock(window, &buffer, NULL) < 0) {ThrowException(env, "java/lang/RuntimeException", "unable to lock native window");//释放窗口ANativeWindow_release(window);window = NULL;return;}//转换为像素点来处理int32_t *bitmapPixes = (int32_t *) data;uint32_t *line = (uint32_t *) buffer.bits;for (int y = 0; y < buffer.height; y++) {for (int x = 0; x < buffer.width; x++) {line[x] = bitmapPixes[buffer.height * y + x];}line = line + buffer.stride;}//解锁窗口的绘图表面if (ANativeWindow_unlockAndPost(window) < 0) {ThrowException(env, "java/lang/RuntimeException","unable to unlock and post to native window");}//释放ANativeWindow_release(window);
}

绘制一个bitmap对象

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.main, options);
mNativeWindowSample.drawBitmap(mSurfaceView.getHolder().getSurface(), bitmap);

项目地址:
https://github.com/byhook/opengles4android

android平台下基于ANativeWindow实现渲染bitmap图像相关推荐

  1. android opencv中图像分割,opencv在android平台下的开发【4】-图像滤波详解

    前言 在上一篇opencv-android-图像平滑处理文章中,简单介绍了几种图像平滑,也就是图像模糊的方法,使用了几个简单的滤波器,这都属于图像的滤波操作. opencv针对图像的处理提供了imgp ...

  2. Android平台下基于XMPP的IM研究

    由于项目需要做一个基于XMPP协议的Android通讯软件.故开始研究XMPP XMPP协议采用的是客户端-服务器架构,所有从一个客户端发到另一个客户端的消息和数据都必须经过XMPP服务器转发,而且支 ...

  3. Android平台下的图片/视频转Ascii码图片/视频 (一)

    前一阵看鸿洋公众号日推,看到一个几年前就感觉有意思的一个技术,那就是图片转Ascii码,记得上大学时玩过windows的图片或视频转ascii码,可惜那个软件不好用,有bug,转视频的时候动不动就卡死 ...

  4. android 身份认证技术,Android平台上基于人脸识别的身份认证系统的设计与实现

    摘要: 随着移动互联网与人工智能技术的发展,基于个人特征的生物识别技术代替传统的身份验证方式已经是大势所趋.而人脸识别是生物识别技术的一个重要组成部分,拥有其他生物识别技术没有的独特优势.本文主要针对 ...

  5. android平台下使用点九PNG技术

    "点九"是andriod平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png 智能手机中有自动横屏的功能,同一幅界面会在随着手机(或平板电脑)中的方向传感器的参数不 ...

  6. 深度学习核心技术精讲100篇(五十一)-Spark平台下基于LDA的k-means算法实现

    本文主要在Spark平台下实现一个机器学习应用,该应用主要涉及LDA主题模型以及K-means聚类.通过本文你可以了解到: 文本挖掘的基本流程 LDA主题模型算法 K-means算法 Spark平台下 ...

  7. 如何在Android平台下进行Socket通信

    如何在Android平台下进行Socket通信 首先在Java se平台上新建一个Socket服务端: public static void main(String[] args) { try { S ...

  8. windows平台下基于QT和OpenCV搭建图像处理平台

        在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...

  9. 高通Android平台下关于display部分的几个关键问题

    高通Android平台下关于display部分的几个关键问题 2011-04-07 18:59 From: http://hi.baidu.com/leowenj/blog/item/3fe59f74 ...

最新文章

  1. Collections 类
  2. 手把手教你用Python构建自己的「王二狗」
  3. 【原】Linux find 命令整理
  4. 对进入单用户进行加密
  5. Mongodb的安装部署
  6. 006 技能数组分析和代码编写
  7. webRTC实战总结
  8. 数据分析师能用到mysql_浅谈数据分析师的必备技能SQL
  9. d3 v4 api transitions
  10. CommandLineToArgvW
  11. 二进制空间权重矩阵_Stata_ 空间权重矩阵的构建
  12. 生物信息学分析常用网站
  13. String intern方法
  14. Inside-OutsideNet
  15. 【Android 逆向】ART 脱壳 ( dex2oat 脱壳 | /art/dex2oat/dex2oat.cc#Dex2oat 函数源码 )
  16. 常见地图坐标系以及转换方法、转换工具
  17. Win8系统怎么看电脑是32位还是64位?
  18. 没人比程序员更讨厌软件
  19. 智慧时代,如何让路口交通安全又高效?
  20. 有趣的海盗分金问题(博弈论)

热门文章

  1. 同为博客,不同风格 ——Hexo另类搭建
  2. 音乐心理学 | 乐理知识
  3. 亚马逊测评做单总是被砍单封号是什么原因?
  4. Java压缩字符串的方法收集
  5. 【Linux】Centos安装mvn命令(maven)
  6. 怎么将heic转为jpg格式,哪个图片转换器好用
  7. Java中过大整数储存问题(bushi
  8. 期货交易原理(期货交易原理与实务)
  9. 【Unity开发小技巧】模型单指旋转双指缩放功能代码(多种情况)
  10. SVN系列——使用教程