- 創建的ByteBuffer在Java中稱爲緩衝區ByteBuffer.allocateDirect(someBufferSize)與數據
- 通行證緩衝到C++作爲jobject
- 填充緩衝 - jbuffer
- 使用env-> GetDirectBufferAddress(jbuffer)獲取緩衝區直接指針
- 使用C++端的緩衝區數據。如何防止GC清理我們的緩衝區或它永遠不會發生?
- 完成工作 - 我們現在不需要jbuffer。
- 發佈jbuffer?免費(jbuffer) - 將引發一個無效地址錯誤
長的部分
我用下面的代碼加載與Java AssetManager PNG文件使用它們的Open GL ES 2.0紋理的創建。
Java端PNG類
import java.nio.ByteBuffer;
import android.graphics.Bitmap;
public class PNG
{
private static final int BYTES_PER_PIXEL_PNG = 4;
private static final String LOG_TAG = "[PNG]";
public int width;
public int height;
public ByteBuffer pixels;
public PNG(Bitmap bitmap)
{
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.pixels = ByteBuffer.allocateDirect(this.width * this.height * BYTES_PER_PIXEL_PNG);
bitmap.copyPixelsToBuffer(this.pixels);
}
}
public static PNG loadPNG(String path)
{
InputStream is = null;
try
{
is = ASSETS_MANAGER.open(path);//get png file stream with AssetsManager instance
}
catch (IOException e)
{
Log.e(LOG_TAG, "Can't load png - " + path, e);
}
return new PNG(BitmapFactory.decodeStream(is));
}
C++側PNG
typedef struct png
{
int width;
int height;
char* pixels;
} png;
png* load_png(const char* path)
{
png* res = (res*) malloc(sizeof(png);
...
jobject _png = env->CallStaticObjectMethod(get_java_lib_class(), get_method_id(JAVA_LIB_LOAD_PNG, JAVA_LIB_LOAD_PNG_SIGN), _path);//Calling loadPng() from Java, get PNG jobject
jobject _pixels = env->GetObjectField(_png, PNG_FIELDS->PNG_PIXELS_ID);//Getting pixels field from Java PNG jobject
res->pixels = (char*) env->GetDirectBufferAddress(_pixels);//Get direct pointer to our pixel data
//Cleanup
...
env->DeleteLocalRef(_png);
env->DeleteLocalRef(_pixels);
return res;
}
然後,使用PNG來創建紋理
void test_create_tex(const char* path)
{
...
png* source = load_png(path);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, source->width, source->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, source->pixels);
//We don't need source pixel data any more
//free(source->pixels);//INVALID HEAP ADDRESS (deadbaad)
free(source);
}
那麼在C++端使用它的直接指針後如何釋放字節緩衝區呢?它是直接分配的(就像malloc - 在本機端),必須釋放,否則我會得到OutOfMemory錯誤。
與http://stackoverflow.com/questions/1246983/when-and-how-are-nio-direct-buffers-freed – Raedwald