Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw text over sphere in libgdx

Tags:

android

3d

libgdx

I am trying libgdx for rendering some fbx models and I successfully did that, but I am stuck at a point.

I am rendering a basketball fbx file with the help of ModelInstance and now I want to draw a text on that basketball. I am able to draw text on the basketball but its linear which is not looking as a part of that basketball. I want the text in the same curve manner as that ball.

This is how I am drawing text--

batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);

FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("font/Lato-Bold.ttf"));
    FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
    parameter.size = 30;
    parameter.color = com.badlogic.gdx.graphics.Color.WHITE;
    parameter.magFilter = Texture.TextureFilter.Linear; // used for resizing quality
    parameter.minFilter = Texture.TextureFilter.Linear;
    generator.scaleForPixelHeight(3);

    BitmapFont aFont = generator.generateFont(parameter);
    aFont.getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);

aFont.draw(batch, options.get(i), aBound.getCenterX(), aBound.getCenterY() + textHeight / 2);

Where aBound --> BoundingBox of Model (i.e. BasketBall)

like image 976
Vikrant_Dev Avatar asked Apr 21 '17 11:04

Vikrant_Dev


1 Answers

What you are trying to achieve here is slightly complex in libGdx. Your approach, however is incorrect because you are drawing the text as a separate sprite object on top of your ball.

The correct procedure to achieve this is to draw the text onto a texture and then map and bind the texture to the ball.

The procedure can be divided into 4 parts -

  1. Setting up the font generation and the framebuffer object
  2. Setting up the sprite batch
  3. Drawing text, mapping the texture to the model
  4. Rendering the model

As a note, I'd like to mention that any other texture can be used and if you do not want to update the text in real-time, you can easily use a pre-made texture with whatever text that you'd like.

The code is as follows -

Setting up font generation and framebuffer object

//Create a new SpriteBatch object
batch = new SpriteBatch();

//Generate font
FreeTypeFontGenerator generator = new 
FreeTypeFontGenerator(Gdx.files.internal("font/Lato-Bold.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new 
FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = 30;
parameter.color = com.badlogic.gdx.graphics.Color.WHITE;
parameter.magFilter = Texture.TextureFilter.Linear; // used for resizing quality
parameter.minFilter = Texture.TextureFilter.Linear;
generator.scaleForPixelHeight(10);

//Get bitmap font
BitmapFont aFont = generator.generateFont(parameter);
aFont.getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, 
Texture.TextureFilter.Linear);

//Generate new framebuffer object of 128x128 px. This will be our texture
FrameBuffer lFb = new FrameBuffer(Pixmap.Format.RGBA4444,128,128,false);

Setting up the sprite batch

//Set the correct resolution for drawing to the framebuffer
lFb.begin();
Gdx.gl.glViewport(0,0,128,128);
Gdx.gl.glClearColor(1f, 1f, 1f, 1);

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Matrix4 lm = new Matrix4();
//Set the correct projection for the sprite batch
lm.setToOrtho2D(0,0,128,128);
batch.setProjectionMatrix(lm);

Finally draw the text onto the texture

batch.begin();
aFont.draw(batch,"Goal!",64,64);
batch.end();
lFb.end();

Map the texture to the model

//Generate the material to be applied to the ball
//Notice here how we use the FBO's texture as the material base
Material lMaterial = new Material(TextureAttribute.createDiffuse(lFb.getColorBufferTexture()));

//Since I do not have a sphere model, I'll just create one with the newly 
//generated material        
ballModel = mb.createSphere(1.0f,1.0f,1.0f,8,8,lMaterial,
 VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates);

//Finally instantiate an object of the model 
ballInstance = new ModelInstance(ballModel);

Render the model

mBatch.begin(mCamera);
mBatch.render(ballInstance);
mBatch.end();
//Rotate the ball along the y-axis
ballInstance.transform.rotate(0.0f,1.0f,0.0f,0.5f);

Result -

Render text to sphere libGDX

like image 66
Surojit Avatar answered Oct 22 '22 19:10

Surojit