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 ");
              }
          }
相关推荐
penngo6 分钟前
# 使用Claude Code开发植物大战僵尸游戏(pygame,附源码)
python·游戏·pygame
hhb_61811 分钟前
Groovy语法进阶与工程实践指南
开发语言·python
hmywillstronger27 分钟前
Rhino 中文字方向问题的解析与解决方案
python
AI技术增长30 分钟前
Pytorch图像去噪实战(四):Attention UNet图像去噪实战,让模型重点恢复边缘和纹理区域
人工智能·pytorch·python
极客BIM工作室32 分钟前
OCCT开发实践:空间封闭曲线生成曲面的思考与总结
c++
xiaoyan201532 分钟前
2026爆肝!Flutter3.41纯手撸微信聊天APP原生应用
android·flutter·dart
2401_8330336239 分钟前
如何修复固定定位头部容器中悬浮下拉菜单的错位问题
jvm·数据库·python
z4424753261 小时前
CSS Grid布局如何实现网格项目的自动增长_设置grid-auto-flow- row
jvm·数据库·python
GeLx1 小时前
从反爬角度:Playwright CDP 模式、Playwright 传统模式与 DrissionPage 的比较
python·程序人生·playwright·drissionpage·pyppeteer·浏览器自动化控制