android ndk c++ 绘制图片方式

cpp 复制代码
extern "C" JNIEXPORT void JNICALL
    Java_tv_danmaku_ijk_nativedemo_MainActivity_drawBitmap(JNIEnv *env, jobject thiz, jobject surface, jobject bitmap) {
        AndroidBitmapInfo info;
        if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
            LOGE("AndroidBitmap_getInfo error"); return;
        }
        char *data = NULL;
        if (AndroidBitmap_lockPixels(env,bitmap,(void **) &data) < 0){
         LOGE("AndroidBitmap_lockPixels error");
         return;
        }
        if (AndroidBitmap_unlockPixels(env, bitmap) < 0){
            LOGE("AndroidBitmap_unlockPixels error");
            return;
        }
        ANativeWindow *window = ANativeWindow_fromSurface(env,surface);
        if (window == NULL) { LOGE("window is null"); return; }
        int32_t result = ANativeWindow_setBuffersGeometry(window, info.width, info.height, WINDOW_FORMAT_RGBA_8888);
        if (result < 0) {
        LOGE("ANativeWindow_setBuffersGeometry error");
             ANativeWindow_release(window);
              window = NULL;
              return;
         }
         ANativeWindow_acquire(window);
         ANativeWindow_Buffer buffer;
         if (ANativeWindow_lock(window, &buffer, NULL) < 0) {
             LOGE("ANativeWindow_lock error");
             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.width*y + x]; 
             } 
             line = line + buffer.stride; 
         } 
         if (ANativeWindow_unlockAndPost(window) < 0) { 
            LOGE("ANativeWindow_unlockAndPost error"); 
         } 
         ANativeWindow_release(window); 
        }
    }

另一种方式

cpp 复制代码
    extern "C" JNIEXPORT void JNICALL
    Java_tv_danmaku_ijk_nativedemo_MainActivity_drawBitmapSurface(JNIEnv *env, jobject thiz, jobject surface, jobject bitmap, jstring vertex_shader, jstring fragment_shader) {
    ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
    EGLint majorVersion, minorVersion;
    EGLDisplay eglDisplay;
    EGLSurface eglSurface;
    EGLContext eglContext;
    GLuint program;
    // EGL初始化
    eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (eglInitialize(eglDisplay, &majorVersion, &minorVersion) == EGL_FALSE){
    LOGE("eglInitialize error");
    return; }
    // 配置Surface
    const EGLint attribs[] = {
        EGL_RENDERABLE_TYPE,
         EGL_OPENGL_ES3_BIT,
         EGL_SURFACE_TYPE,
         EGL_WINDOW_BIT,
         EGL_BLUE_SIZE, 8,
         EGL_GREEN_SIZE, 8,
         EGL_RED_SIZE, 8,
         EGL_ALPHA_SIZE, 8,
         EGL_NONE
        };

        EGLConfig configs;
        EGLint numConfig;
        eglChooseConfig(eglDisplay, attribs, &configs, 1, &numConfig);
        eglSurface = eglCreateWindowSurface(eglDisplay, configs, window, NULL);
        // 创建上下文
        const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
        eglContext = eglCreateContext(eglDisplay, configs, NULL, contextAttribs);
        eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
        GLuint vertexShader, fragmentShader;
        // 创建着色器
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        const char* vertexShaderSource = env->GetStringUTFChars(vertex_shader, nullptr);
         const char* fragmentShaderSource = env->GetStringUTFChars(fragment_shader, nullptr);
         glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
         glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
         env->ReleaseStringUTFChars(vertex_shader, vertexShaderSource);
         env->ReleaseStringUTFChars(fragment_shader, fragmentShaderSource);
         // 调用glCompileShader 编译着色器,并检查编译状态
         glCompileShader(vertexShader);
         glCompileShader(fragmentShader);
         GLint success;
          glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
          if (!success){
           GLchar infoLog[1024];
           glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog);
            LOGE("glGetShaderiv error %s", infoLog); }
            // 编译着色器
            program = glCreateProgram();
            glAttachShader(program,vertexShader);
            glAttachShader(program, fragmentShader);
            glLinkProgram(program);
            GLint linkStatus;
            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
            if (linkStatus == GL_FALSE){ GLchar infoLog[512];
                glGetProgramInfoLog(program, 512, NULL, infoLog);
                LOGE("glLinkProgram error %s", infoLog);
            }
             LOGE("glLinkProgram surccess ");
             // 绑定纹理
             GLuint texture;
             glGenTextures(1, &texture);
             glBindTexture(GL_TEXTURE_2D, texture);
             // 加载位图数据
             AndroidBitmapInfo info;
             void* pixels;
              AndroidBitmap_getInfo(env, bitmap, &info);
              AndroidBitmap_lockPixels(env, bitmap, &pixels);
              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
              GLint matrixId = glGetUniformLocation(program, "deformationMatrix");
              GLfloat deformMatrix[16] = {
                   1.0f, 0.0f, 0.0f, 0.0f, // 第一列
                   0.0f, 1.0f, 0.0f, 0.0f, // 第二列
                   0.0f, 0.0f, 1.0f, 0.0f, // 第三列
                   0.0f, 0.0f, 0.0f, 1.0f // 第四列
              };
                // 设置变形矩阵
                glUniformMatrix4fv(matrixId, 1, GL_FALSE, deformMatrix);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
                eglSwapBuffers(eglDisplay, eglSurface);
                AndroidBitmap_unlockPixels(env, bitmap);
                LOGE("----->>>> surccess ");
              }
          }
相关推荐
Java后端的Ai之路2 小时前
【Python教程10】-开箱即用
android·开发语言·python
散峰而望2 小时前
【基础算法】算法的“预谋”:前缀和如何改变游戏规则
开发语言·数据结构·c++·算法·github·动态规划·推荐算法
仰泳的熊猫2 小时前
题目1432:蓝桥杯2013年第四届真题-剪格子
数据结构·c++·算法·蓝桥杯·深度优先·图论
深蓝电商API2 小时前
异步爬虫中代理池的并发管理
开发语言·爬虫·python
B站计算机毕业设计超人2 小时前
计算机毕业设计PySpark+Hive+Django小红书评论情感分析 小红书笔记可视化 小红书舆情分析预测系统 大数据毕业设计(源码+LW+PPT+讲解)
大数据·人工智能·hive·爬虫·python·spark·课程设计
2601_949809592 小时前
flutter_for_openharmony家庭相册app实战+隐私设置实现
android·javascript·flutter
我命由我123452 小时前
Android 开发 Room 数据库升级问题:A migration from 6 to 7 was required but not found.
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
黄筱筱筱筱筱筱筱2 小时前
7.适合新手小白学习Python的异常处理(Exception)
java·前端·数据库·python
闻缺陷则喜何志丹2 小时前
【数论 快速指数幂 龟速乘】P8652 [蓝桥杯 2017 国 C] 小数第 n 位|普及+
c++·蓝桥杯·数论·快速指数幂·龟速乘