Many times, if we want to use opengles to render and draw on the Native layer, we hope to render and draw some text.
But OpenGL ES does not actually support drawing text directly, but the Android JAVA layer has a complete set of text drawing methods, such as using bitmap, the code for drawing text on bitmap is as follows:
//create the canvas
Bitmap originBmp = Bitmap.createBitmap(320, 200, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(originBmp);
//get content from res
textPaint.setTextSize(15.0F);
String content = act.getString(R.string.dialog_content);
StaticLayout clayout= new StaticLayout(content , textPaint, originBmp.getWidth()-8,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
canvas.translate(0, 40);
clayout.draw(canvas);
Pass this bitmap with text to Native, and then bind it to the texture to achieve opengles rendering text
. In fact, opengles also provides a set of java layer APIs that can directly bind the bitmap to the texture. The code is as follows:
//this static method must be called by opengl rendor thread
//which opengles environment has been successfully setup.
public static int generateSeethroughDilogTexture(Activity act,String text) {
Log.e(TAG,"generateSeethroughDilogTexture "+text+" E");
//create the canvas
Bitmap originBmp = Bitmap.createBitmap(320, 200, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(originBmp);
//get dialog content from res
textPaint.setTextSize(15.0F);
String content = act.getString(R.string.dialog_content);
text = content;
StaticLayout clayout= new StaticLayout(text, textPaint, originBmp.getWidth()-8,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
canvas.translate(0, 40);
clayout.draw(canvas);
int[] tex = new int[1];//need delete later
GLES20.glGenTextures(1, tex, 0);
GLES20.glBindTexture(GL10.GL_TEXTURE_2D, tex[0]);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, originBmp , 0);
textPaint=null;
canvas =null;
newBitmap.recycle();
newBitmap=null;
Log.d(TAG,"generateSeethroughDilogTexture texId:"+ tex[0]+" X");
return tex[0];
}
You only need to pass the tex to the Native layer. The
java code can actively set the texture id to the Native layer through the Native method. There are many demos of this method. It is not introduced.
Native can also actively call the Java method to obtain the texture ID
code. as follows:
int generateSeethroughDilogTexture(TimeWarpInitParms* initParms)
{
LOG( "generateSeethroughDilogTexture E");
// The current thread is presumably already attached, so this
// should just return a valid environment.
JNIEnv * jniEnv=NULL;
const jint rtn = JavaVm->AttachCurrentThread(&jniEnv, 0);
if (rtn != JNI_OK) {
LOG( "AttachCurrentThread() returned %i", rtn);
}
//in unity app,this activity is UnityPlayerNativeActivity.java
jclass activityClass = jniEnv->GetObjectClass(initParms->ActivityObject);
if (activityClass == NULL){
LOG("try activityClass failed!");
return -1;
}
const jmethodID method = jniEnv->GetStaticMethodID( activityClass,
"generateSeethroughDilogTexture",
"(Landroid/app/Activity;Ljava/lang/String;)I" );
if ( !method ){
LOG("try method failed");
return -1;
}
const char* content = "this is my test";
jstring jcontent = jniEnv->NewStringUTF(content);//may be shou delete later
int textureId = jniEnv->CallStaticIntMethod( activityClass, method,initParms->ActivityObject,jcontent);
LOG( "generateSeethroughDilogTexture textureId %d X",textureId);
JavaVm->DetachCurrentThread();
return textureId;
}