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 ");
              }
          }
相关推荐
zzzzzz31020 分钟前
假如我是掘金管理员,我先给评论区装个'代码审查'系统
python·程序员·机器人
郝学胜_神的一滴20 分钟前
CMake 021: IF 条件判据详诠
c++·cmake
YXL1111YXL34 分钟前
Handler 消息回收与协程异步执行的时序陷阱
android
砍材农夫1 小时前
python环境|conda安装和使用(2)
后端·python
恋猫de小郭1 小时前
KMP / CMP 鸿蒙版本 Beta 发布,他有什么特别之处?
android·前端·flutter
三少爷的鞋2 小时前
Android 协程并发控制:别动线程池,控制好并发语义就够了
android
程序员龙叔13 小时前
编写高质量 Skill 系列 -- 如何设计需求分析与用例生成的 SKILL
自动化测试·软件测试·python·软件测试工程师·接口测试·性能测试·skill·ai测试
_wyt00114 小时前
洛谷 B3930 [GESP202312 五级] 烹饪问题 题解
c++·gesp
用户83562907805116 小时前
使用 Python 操作 Word 内容控件
后端·python