OpenGLES2.0學習筆記(三)字符文字的繪制

? ? ? ? 經過一段時間的學習港谊,我發(fā)現OpenGL是不支持字符繪制的贾漏,就是官方的API沒有字符繪制的方法惑申。但是如果有字符繪制的需求,還是有別的辦法來實現翅雏,那就是把字符轉換成圖片圈驼,然后通過渲染紋理的方式把圖片繪制出來。老規(guī)矩望几,先上效果圖:

OpenGLES字符繪制

頂點shader:

uniform mat4 vMatrix;

attribute vec4 vPosition;

attribute vec2 vTextureCoordinate;

varying vec2 aTextureCoordinate;

void main() {????

????aTextureCoordinate = vTextureCoordinate;???

? ? gl_Position = vMatrix * vPosition;

}

片段shader:

precision mediump float;

uniform sampler2D u_TextureUnit;

varying vec2 aTextureCoordinate;

void main() {

????gl_FragColor = texture2D(u_TextureUnit, aTextureCoordinate);

}

模型繪制類:

public class TextureModel {

????private int programId;

????private float[] matrix = new float[16];

????private int glHMatrix;

????private int glHPosition;

????private int glHCoordinates;

????private int glHTexture;

????private FloatBuffer bufPos;

????private FloatBuffer bufCoord;

????private Bitmap bitmap;

????private int[] textureId = new int[1];

????private final float[] sCoord = { 0.0f, 0.0f, 0f, 0.0f, 1.0f, 0f, 1.0f, 0.0f, 0f, 1.0f, 1.0f, 0f };

????public TextureModel(){

????????Matrix.setIdentityM(matrix, 0);

????????bufCoord = GlUtil.createFloatBuffer(sCoord);

????}

????public float[] getMatrix() { return matrix; }

????public void createProgram(){

????????programId = GlUtil.createProgram(ResReadUtils.readResource(R.raw.texture_vertex_shader), ResReadUtils.readResource(R.raw.texture_fragment_shader));

????????glHMatrix = GLES20.glGetUniformLocation(programId, "vMatrix");

????????glHPosition = GLES20.glGetAttribLocation(programId, "vPosition");

????????glHCoordinates = GLES20.glGetAttribLocation(programId, "vTextureCoordinate");

????????glHTexture = GLES20.glGetUniformLocation(programId, "u_TextureUnit");

????}

????public void setBitmap(Bitmap bitmap) { this.bitmap = bitmap; }

????public void createTexture(){

????????if (bitmap!=null && !bitmap.isRecycled()) {

????????????GLES20.glGenTextures(1, textureId, 0);

????????????GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);

????????????GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);

????????????GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);

????????????GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);? ?

?????????????GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

????????????GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

????????????GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);

????????????bitmap.recycle();

????????????GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

????????}

????}

????public void setDrawPosition(float[] position){

????????if (position==null || position.length!=12) { return; }

????????bufPos = GlUtil.createFloatBuffer(position);

????}

????public void deleteTexture(){

????????GLES20.glDeleteTextures(programId, textureId, 0);

????}

????public void drawSelf(){

????????GLES20.glUseProgram(programId);

????????GLES20.glUniformMatrix4fv(glHMatrix, 1, false, matrix, 0);

????????GLES20.glEnableVertexAttribArray(glHPosition);

????????GLES20.glEnableVertexAttribArray(glHCoordinates);

????????GLES20.glUniform1i(glHTexture, 0);

????????createTexture();

????????GLES20.glVertexAttribPointer(glHPosition, 3, GLES20.GL_FLOAT, false, 0, bufPos);

????????GLES20.glVertexAttribPointer(glHCoordinates, 3, GLES20.GL_FLOAT, false, 0, bufCoord);

????????GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

????????GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);

????????GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

????????GLES20.glDisableVertexAttribArray(glHPosition);

????????GLES20.glDisableVertexAttribArray(glHCoordinates);

????}

現在需要傳入字符的圖片和坐標位置:

Paint paint =new Paint();

paint.setAntiAlias(true);

paint.setColor(Color.RED);

paint.setStyle(Paint.Style.FILL);

paint.setTextSize(100f);

String text ="測試字符串绩脆!";

int textWidth = (int) paint.measureText(text, 0, text.length());

Paint.FontMetrics fm = paint.getFontMetrics();

float textHeight =? fm.bottom - fm.top + fm.leading;;

Bitmap bitmap = Bitmap.createBitmap(textWidth, (int)textHeight, Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(bitmap);

canvas.drawText(text, 0, textHeight-fm.bottom, paint);

glSurfaceView.setTexture(bitmap);

RenderFilter調用方法:

public void setTextureBitmap(Bitmap bitmap){

????float[] pos = {

????????????0f, 0f, 10f,

? ? ? ? ? ? 0f, 0f, 0f,

? ? ? ? ? ? 0f, 10f, 10f,

? ? ? ? ? ? 0f, 10f, 0f

? ? };

? ? textureModel.setDrawPosition(pos);

? ? textureModel.setBitmap(bitmap);

}

運行起來看看效果:

運行效果

咦?怎么是白底的呢橄抹,難道生成的位圖就是白底的靴迫?打個斷點看看

斷點調試

從斷點來看,生成的bitmap是透明的奥ナ摹玉锌??疟羹?那肯定是OpenGLES繪制的問題主守,為什么透明的繪制不出來,變成了白色的呢榄融?

于是参淫,百度一下,還真找到問題了:Android 使用opengles 設置背景透明

在onSurfaceCreated方法增加兩行代碼就搞定愧杯!

@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

????GLES20.glEnable(GLES20.GL_DEPTH_TEST);

? ? //就是下面這兩行

? ? GLES20.glEnable(GLES20.GL_BLEND);

? ? GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

? ? renderFilter.createProgram();

}

再運行起來看看效果涎才,OK,收工A拧c疚!

透明底字符繪制
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末畏邢,一起剝皮案震驚了整個濱河市业扒,隨后出現的幾起案子,更是在濱河造成了極大的恐慌舒萎,老刑警劉巖程储,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異臂寝,居然都是意外死亡章鲤,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門咆贬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來败徊,“玉大人,你說我怎么就攤上這事掏缎≈灞模” “怎么了煤杀?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沪哺。 經常有香客問我沈自,道長,這世上最難降的妖魔是什么辜妓? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任枯途,我火速辦了婚禮,結果婚禮上籍滴,老公的妹妹穿的比我還像新娘酪夷。我一直安慰自己,他們只是感情好孽惰,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布晚岭。 她就那樣靜靜地躺著,像睡著了一般灰瞻。 火紅的嫁衣襯著肌膚如雪腥例。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天酝润,我揣著相機與錄音燎竖,去河邊找鬼。 笑死要销,一個胖子當著我的面吹牛构回,可吹牛的內容都是我干的。 我是一名探鬼主播疏咐,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼纤掸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浑塞?” 一聲冷哼從身側響起借跪,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酌壕,沒想到半個月后掏愁,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡卵牍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年果港,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糊昙。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡辛掠,死狀恐怖,靈堂內的尸體忽然破棺而出释牺,到底是詐尸還是另有隱情萝衩,我是刑警寧澤回挽,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站欠气,受9級特大地震影響厅各,放射性物質發(fā)生泄漏镜撩。R本人自食惡果不足惜预柒,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袁梗。 院中可真熱鬧宜鸯,春花似錦、人聲如沸遮怜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锯梁。三九已至即碗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陌凳,已是汗流浹背剥懒。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留合敦,地道東北人初橘。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像充岛,于是被迫代替她去往敵國和親保檐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內容