Text Rendering class not working

Problems with Canvas, OpenGL, etc...

Text Rendering class not working

Postby Tripphippy » Thu Jul 22, 2010 6:33 pm

HELP!! I can't get anything to show up at all. It's supposed to render text and I'm not getting anything at all.
Any help would be appreciated

The image i'm using for the glyphs is a 16x16 grid of all ascii characters so the ascii code is used to index the texture map.
Image

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class TextRenderer
  2. {
  3.     private GL10 gl;
  4.     private int[] tex;
  5.     private float width;
  6.     private float height;
  7.     private FloatBuffer vertexBuffer;
  8.     private FloatBuffer texBuffer;
  9.     private ByteBuffer indexBuffer;
  10.     public TextRenderer(GL10 _gl, Context ctx)
  11.     {
  12.         float[] texcoords;
  13.         float quad[] =
  14.         {
  15.             0.0f, 0.0f, 0.0f,
  16.             0.0f, 1.0f, 0.0f,
  17.             1.0f, 0.0f, 0.0f,
  18.             1.0f, 1.0f, 0.0f
  19.         };
  20.         byte indices[] =
  21.         {
  22.             0, 1, 2, 3
  23.         };
  24.         gl = _gl;
  25.         tex = new int[1];
  26.         gl.glGenTextures(1, tex, 0);
  27.         Bitmap bmp = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.berlin);
  28.         gl.glBindTexture(GL10.GL_TEXTURE_2D, tex[0]);
  29.         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
  30.         bmp.recycle();
  31.         texcoords = new float[16*16*4*2];//16 by 16 tiles by 4 vertices per quad by 2 coords per vertex
  32.         for(int y = 0; y < 16; y++)
  33.         {
  34.             for(int x = 0; x < 16; x++)
  35.             {
  36.                     texcoords[(x*8)+(y*16*8)] = (float)x / 16.0f;
  37.                     texcoords[(x*8)+(y*16*8)+1] = (float)y / 16.0f;
  38.                     texcoords[(x*8)+(y*16*8)+2] = (float)x / 16.0f;
  39.                     texcoords[(x*8)+(y*16*8)+3] = ((float)y + 1.0f) / 16.0f;
  40.                     texcoords[(x*8)+(y*16*8)+4] = ((float)x + 1.0f) / 16.0f;
  41.                     texcoords[(x*8)+(y*16*8)+5] = (float)y / 16.0f;
  42.                     texcoords[(x*8)+(y*16*8)+6] = ((float)x + 1.0f) / 16.0f;
  43.                     texcoords[(x*8)+(y*16*8)+7] = ((float)y + 1.0f) / 16.0f;
  44.             }
  45.         }
  46.         ByteBuffer vbb = ByteBuffer.allocateDirect(quad.length*4);
  47.         vbb.order(ByteOrder.nativeOrder());
  48.         vertexBuffer = vbb.asFloatBuffer();
  49.         vertexBuffer.put(quad);
  50.         vertexBuffer.position(0);
  51.  
  52.         vbb = ByteBuffer.allocateDirect(texcoords.length * 4);
  53.         vbb.order(ByteOrder.nativeOrder());
  54.         texBuffer = vbb.asFloatBuffer();
  55.         texBuffer.put(texcoords);
  56.         texBuffer.position(0);
  57.  
  58.         indexBuffer = ByteBuffer.allocateDirect(indices.length);
  59.         indexBuffer.put(indices);
  60.         indexBuffer.position(0);
  61.     }
  62.    
  63.     public void drawText(float x, float y, String text)
  64.     {
  65.         gl.glEnable(gl.GL_TEXTURE_2D);
  66.         gl.glMatrixMode(gl.GL_PROJECTION);
  67.         gl.glPushMatrix();
  68.         gl.glLoadIdentity();
  69.         gl.glOrthof(0.0f, 1.0f, 0.0f, 1.0f, 0.1f, 10.0f);
  70.         gl.glMatrixMode(gl.GL_MODELVIEW);
  71.         gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
  72.         gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);
  73.         gl.glVertexPointer(4, gl.GL_FLOAT, 0, vertexBuffer);
  74.         gl.glBindTexture(GL10.GL_TEXTURE_2D, tex[0]);
  75.         gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  76.         float drawx = x;
  77.         float drawy = y;
  78.         for(int i = 0; i < text.length(); i++)
  79.         {
  80.             int ascii = text.codePointAt(i);
  81.             texBuffer.position(ascii*2*4);
  82.             gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, texBuffer);
  83.             gl.glTranslatef(drawx, drawy, 1.0f);
  84.             gl.glDrawElements(gl.GL_TRIANGLE_STRIP, 4, gl.GL_UNSIGNED_BYTE, indexBuffer);
  85.             drawx++;
  86.         }
  87.         gl.glDisable(gl.GL_TEXTURE_2D);
  88.         gl.glMatrixMode(gl.GL_PROJECTION);
  89.         gl.glPopMatrix();
  90.         gl.glMatrixMode(gl.GL_MODELVIEW);
  91.     }
  92.    
  93.     public void resize(float w, float h)
  94.     {
  95.         width = w;
  96.         height = h;
  97.     }
  98. }
  99.  
Parsed in 0.044 seconds, using GeSHi 1.0.8.4
Tripphippy
Freshman
Freshman
 
Posts: 6
Joined: Thu Jul 22, 2010 6:24 pm

Top

Re: Text Rendering class not working

Postby Tripphippy » Fri Jul 23, 2010 5:24 pm

Ok I fixed it. Feel free to use it to learn or render text in ur app. Let me know if you use it.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. /*
  2.  * To change this template, choose Tools | Templates
  3.  * and open the template in the editor.
  4.  */
  5.  
  6. package org.mgoelz.drakengardmobile;
  7.  
  8. import android.content.Context;
  9. import android.graphics.Bitmap;
  10. import android.graphics.BitmapFactory;
  11. import android.graphics.Color;
  12. import android.opengl.GLUtils;
  13. import java.io.IOException;
  14. import java.io.InputStream;
  15. import java.nio.ByteBuffer;
  16. import java.nio.ByteOrder;
  17. import java.nio.FloatBuffer;
  18. import javax.microedition.khronos.opengles.GL10;
  19.  
  20. /**
  21.  *
  22.  * @author Mike.Goelz
  23.  */
  24. public class TextRenderer
  25. {
  26.     /** The buffer holding the vertices */
  27.     private FloatBuffer vertexBuffer;
  28.     /** The buffer holding the texture coordinates */
  29.     private FloatBuffer textureBuffer;
  30.     /** The buffer holding the indices */
  31.     private ByteBuffer indexBuffer;
  32.  
  33.     /** Our texture pointer */
  34.     private int[] textures = new int[1];
  35.  
  36.     /**
  37.      * The initial vertex definition
  38.      *
  39.      * Note that each face is defined, even
  40.      * if indices are available, because
  41.      * of the texturing we want to achieve
  42.      */
  43.     float[][] texcoords =
  44.     {
  45.         {
  46.             0.0f, 0.0f,
  47.             0.0f, 0.0625f,
  48.             0.0625f, 0.0f,
  49.             0.0625f, 0.0625f
  50.         }
  51.     };
  52.     float quad[] =
  53.     {
  54.         1.0f, 0.0f, 0.0f,
  55.         1.0f, 1.0f, 0.0f,
  56.         0.0f, 0.0f, 0.0f,
  57.         0.0f, 1.0f, 0.0f
  58.     };
  59.     byte indices[] =
  60.     {
  61.         0, 1, 2, 3
  62.     };
  63.  
  64.     private float width;
  65.     private float height;
  66.     float fontsize = 32;
  67.    
  68.     public float getTop()
  69.     {
  70.         return height / fontsize - 1.0f;
  71.     }
  72.    
  73.     public float getRight()
  74.     {
  75.         return width / fontsize - 1.0f;
  76.     }
  77.     public TextRenderer(GL10 gl, Context ctx)
  78.     {
  79.         texcoords = new float[16*16][4*2];//16 by 16 tiles by 4 vertices per quad by 2 coords per vertex
  80.         for(int y = 0; y < 16; y++)
  81.         {
  82.             for(int x = 0; x < 16; x++)
  83.             {
  84.                     texcoords[(x)+(y*16)][0] = ((float)x + 1.0f) / 16.0f;
  85.                     texcoords[(x)+(y*16)][1] = ((float)y + 1.0f) / 16.0f;
  86.                     texcoords[(x)+(y*16)][2] = ((float)x + 1.0f) / 16.0f;
  87.                     texcoords[(x)+(y*16)][3] = (float)y / 16.0f;
  88.                     texcoords[(x)+(y*16)][4] = (float)x / 16.0f;
  89.                     texcoords[(x)+(y*16)][5] = ((float)y + 1.0f) / 16.0f;
  90.                     texcoords[(x)+(y*16)][6] = (float)x / 16.0f;
  91.                     texcoords[(x)+(y*16)][7] = (float)y / 16.0f;
  92.             }
  93.         }
  94.         //
  95.         ByteBuffer byteBuf = ByteBuffer.allocateDirect(quad.length * 4);
  96.         byteBuf.order(ByteOrder.nativeOrder());
  97.         vertexBuffer = byteBuf.asFloatBuffer();
  98.         vertexBuffer.put(quad);
  99.         vertexBuffer.position(0);
  100.  
  101.         //
  102.         byteBuf = ByteBuffer.allocateDirect(texcoords[0].length * 4);
  103.         byteBuf.order(ByteOrder.nativeOrder());
  104.         textureBuffer = byteBuf.asFloatBuffer();
  105.         textureBuffer.put(texcoords[0]);
  106.         textureBuffer.position(0);
  107.  
  108.         //
  109.         indexBuffer = ByteBuffer.allocateDirect(indices.length);
  110.         indexBuffer.put(indices);
  111.         indexBuffer.position(0);
  112.         //Get the texture from the Android resource directory
  113.         InputStream is = ctx.getResources().openRawResource(R.drawable.berlin);
  114.         Bitmap bitmap = null;
  115.         Bitmap alpha = null;
  116.         try {
  117.                 //BitmapFactory is an Android graphics utility for images
  118.                 bitmap = BitmapFactory.decodeStream(is);
  119.                 /*alpha = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ALPHA_8);
  120.                 for(int y = 0; y < bitmap.getHeight(); y++)
  121.                 {
  122.                     for(int x = 0; x < bitmap.getWidth(); x++)
  123.                     {
  124.                         int pix = bitmap.getPixel(x, y);
  125.                         alpha.setPixel(x, y, (Color.red(pix) + Color.green(pix) + Color.blue(pix)) / 3);
  126.                     }
  127.                 }*/
  128.         } finally {
  129.                 //Always clear and close
  130.                 try {
  131.                         is.close();
  132.                         is = null;
  133.                 } catch (IOException e) {
  134.                 }
  135.         }
  136.  
  137.         //Generate one texture pointer...
  138.         gl.glGenTextures(1, textures, 0);
  139.         //...and bind it to our array
  140.         gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
  141.  
  142.         //Create Nearest Filtered Texture
  143.         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
  144.         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
  145.  
  146.         //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
  147.         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
  148.         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
  149.  
  150.         //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
  151.         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
  152.         //GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, gl.GL_ALPHA, bitmap, 0);
  153.  
  154.         //Clean up
  155.         //alpha.recycle();
  156.         bitmap.recycle();
  157.     }
  158.    
  159.     public void drawText(GL10 gl, float x, float y, String text)
  160.     {
  161.         gl.glPushMatrix();//save off the modelview
  162.         gl.glLoadIdentity();//reset modelview
  163.         gl.glMatrixMode(gl.GL_PROJECTION);
  164.         gl.glPushMatrix();//save off the projection
  165.         gl.glLoadIdentity();//reset projection
  166.         gl.glOrthof(0.0f, width / fontsize, 0.0f, height / fontsize, 0.1f, 10.0f);//set to ortho perspective
  167.         gl.glMatrixMode(gl.GL_MODELVIEW);
  168.         //set state for text render
  169.         gl.glEnable(gl.GL_TEXTURE_2D);
  170.         gl.glDisable(gl.GL_DEPTH_TEST);
  171.         gl.glEnable(gl.GL_BLEND);
  172.         gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
  173.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  174.         gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  175.         //Bind our only previously generated texture
  176.         gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
  177.  
  178.         float drawx = x;
  179.         float drawy = y;
  180.         for(int i = 0; i < text.length(); i++)
  181.         {
  182.             int ascii = text.codePointAt(i);
  183.  
  184.             textureBuffer.put(texcoords[ascii]);
  185.             textureBuffer.position(0);
  186.             gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  187.             gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
  188.             gl.glPushMatrix();
  189.             gl.glTranslatef(drawx, drawy, -1.0f);
  190.             gl.glDrawElements(gl.GL_TRIANGLE_STRIP, indices.length, gl.GL_UNSIGNED_BYTE, indexBuffer);
  191.             gl.glPopMatrix();
  192.             drawx += 0.6;
  193.         }
  194.         //Disable the client state before leaving
  195.         gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  196.         gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  197.         //reset rendering
  198.         gl.glDisable(gl.GL_BLEND);
  199.         gl.glEnable(gl.GL_DEPTH_TEST);
  200.         gl.glDisable(gl.GL_TEXTURE_2D);
  201.         gl.glPopMatrix();
  202.         gl.glMatrixMode(gl.GL_PROJECTION);
  203.         gl.glPopMatrix();
  204.         gl.glMatrixMode(gl.GL_MODELVIEW);
  205.     }
  206.    
  207.     public void resize(float w, float h)
  208.     {
  209.         width = w;
  210.         height = h;
  211.     }
  212. }
  213.  
Parsed in 0.057 seconds, using GeSHi 1.0.8.4
Tripphippy
Freshman
Freshman
 
Posts: 6
Joined: Thu Jul 22, 2010 6:24 pm

Re: Text Rendering class not working

Postby pleyas » Fri Aug 13, 2010 2:02 pm

Hi Tripphippy,

I am using part of the code and mixing with what I have done so far.
Became tricky to try to change between the ortho to perspective, one texture to another...
Is important to be careful where the text's algorithm is called for rendering.

But so far seems to work well!
Thank you for the help...
;)
Last edited by pleyas on Fri Aug 13, 2010 2:18 pm, edited 1 time in total.
pleyas
Freshman
Freshman
 
Posts: 3
Joined: Wed Jun 30, 2010 5:45 am

Re: Text Rendering class not working

Postby pleyas » Fri Aug 13, 2010 2:04 pm

Also,
How to figure out the 2d ortho coordinate equivalent to the 3d space?
Let say you wanna draw a text at the end of a 3d line?
So it needs to be converted from one of the 3d vertex of the 3d line to the 2d ortho (screen system equivalent)

Any idea?...
pleyas
Freshman
Freshman
 
Posts: 3
Joined: Wed Jun 30, 2010 5:45 am

Re: Text Rendering class not working

Postby Tripphippy » Tue Aug 17, 2010 6:56 pm

That's much trickier to accomplish and probably can't be done using my text renderer as it is now. The coordinate system used in the ortho projection is funky and doesnt relate to window coordinates in a sensible way. What you probably want to do is skip the ortho perspective and draw the text in 3d using billboarding. If you want the letters to all be the same size regardless of distance then you are going to have a little more work to do. I think you would call gluProject using the 3d coord you want to draw at and then call gluUnProject with the results from project but set winz = 0.0. This should map the 3d coordinate to another 3d coordinate that is on the near clipping plane. From there is is just a simple scaling operation to get the text the right size. I wish I could draw a picture to illustrate better but the thing here is that we are mapping a 3d coordinate to another 3d coordinate that overlaps the same pixel as the first but has a z coord = near clipping plane essentially drawing the text as close as possible to the camera that you can get.
Tripphippy
Freshman
Freshman
 
Posts: 6
Joined: Thu Jul 22, 2010 6:24 pm

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 4 guests