cppextern "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 ");
}
}