0

I have an own method to draw images. It uses Vertex and UVBuffers.

I draw like the following:

SpriteBatch.Begin(blendMode) <- sets up blending
SpriteBatch.Draw(parameters) <- add vertices to the list of vertex arrays
SpriteBatch.End() <- Sets up buffers and draw out everything at once

And it works like charm.

However when i try my DrawString method which uses the same Draw method. Texture UV Maps or some buffers get screwed up (everything draws like a solid rectangle with missing pixels).

I use Angelcode Bitmap Font Generator.

I use the same functinality the only difference is that I set textures and UV Maps according to the current character's data.

I will post all my Draw functions just in case I messed up something in other functions.

public void Begin(int Source, int Destination)
{
    GL.glEnable(GL10.GL_BLEND);
    GL.glBlendFunc(Source, Destination);
}

All my buffers and variables (I didn't want to declare in functions)

ArrayList<float[]> vertices = new ArrayList<float[]>();
FloatBuffer vertexBuffer;
ArrayList<short[]> indices = new ArrayList<short[]>();
ShortBuffer indexBuffer;
float minU = 0;
float maxU = 1;
float minV = 0;
float maxV = 1;
ArrayList<GLColor> colors = new ArrayList<GLColor>();
GLColor c_color;
ArrayList<float[]> vertexUVs = new ArrayList<float[]>();
FloatBuffer uvBuffer;
ArrayList<TransformationMatrix> matrices = new ArrayList<TransformationMatrix>();
TransformationMatrix matrix = new TransformationMatrix();
ArrayList<Integer> textures = new ArrayList<Integer>();

Draw Method which accesses main method from DrawString

public void Draw(Texture2D texture, Rectangle destination, Rectangle source, GLColor color)
{
    Draw(texture, destination, source, color, new Vector2(0, 0), 0);
}

Draw Method

public void Draw(Texture2D texture, Rectangle destination, Rectangle source, GLColor color, Vector2 origin, float Rotation)
{
    vertices.add(new float[]{-origin.X, -origin.Y,
            destination.Width - origin.X, -origin.Y,
            destination.Width - origin.X, destination.Height - origin.Y,
                    -origin.X, destination.Height - origin.Y});

    indices.add(new short[]{0, 1, 2, 2, 3, 0});

    //Generate UV of Vertices

    minU = 0;
    maxU = 1;
    minV = 0;
    maxV = 1;

    if (source != null)
    {
        minU = (float)source.X / (float)texture.getWidth();
        maxU = (float)(source.X + source.Width) / (float)texture.getWidth();
        minV = (float)source.Y / (float)texture.getHeight();
        maxV = (float)(source.Y + source.Height) / (float)texture.getHeight();
    }
    vertexUVs.add(new float[]{minU, minV,
                        maxU, minV,
                        maxU, maxV,
                        minU, maxV});

    //Calculate Matrix
    matrix = new TransformationMatrix();
    matrix.Translate(destination.X + origin.X, destination.Y + origin.Y, 0);
    matrix.Rotate(0, 0, Rotation);
    matrices.add(matrix);

    colors.add(color);
    textures.add(texture.ID);
    }

Draw String Method (that causes bugs)

public void DrawString(SpriteFont spriteFont, String Text, Vector2 vector, GLColor color)
{
    int cursorX = (int)vector.X;
    int cursorY = (int)vector.Y;

    for (int i = 0; i < Text.length(); i++)
    {
        char c = Text.charAt(i);
        if (c == '\n') cursorX += spriteFont.LineHeight;
        else
        {
            int index = (int)c;

            //Draw Character
            if (spriteFont.Characters.length <= index)
            {
                Log.d("SpriteFont error", "Character is not presented in SpriteFont!");
                continue;
            }

            CharacterDescriptor cd = spriteFont.Characters[index];

            Rectangle source = new Rectangle(cd.x, cd.y, cd.Width, cd.Height);
            //Draw Character
            Rectangle destination = new Rectangle(cursorX + cd.XOffset, cursorY + cd.YOffset, cd.Width, cd.Height);

            Draw(spriteFont.Pages[cd.Page], destination, source, color);

            cursorX += cd.XAdvance;
        }
    }
}

And finally the ending method:

public void End()
{
    vertexBuffer = ByteBuffer.allocateDirect(vertices.size() * 8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    for (int i = 0; i < vertices.size(); i++)
    {
        vertexBuffer.put(vertices.get(i));
    }
    vertexBuffer.flip();


    //Generate Indices
    indexBuffer = ByteBuffer.allocateDirect(indices.size() * 6 * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
    for (int i = 0; i < vertices.size(); i++)
    {
        indexBuffer.put(indices.get(i));
    }
    indexBuffer.flip();

    //Generate UV of Vertices
    uvBuffer = ByteBuffer.allocateDirect(vertexUVs.size() * 8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    for (int i = 0; i < vertexUVs.size(); i++)
    {
        uvBuffer.put(vertexUVs.get(i));
    }
    uvBuffer.flip();

    //Bind Vertices

    for (int i = 0; i < colors.size(); i++)
    {
        //Bind Pointers
        GL.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        GL.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        GL.glEnable(GL10.GL_TEXTURE_2D);
        vertexBuffer.position(i * 8);
        GL.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
        uvBuffer.position(i * 8);
        GL.glTexCoordPointer(2, GL10.GL_FLOAT, 0, uvBuffer);
        matrix = matrices.get(i);
        c_color = colors.get(i);

        GL.glMatrixMode(GL10.GL_MODELVIEW);
        GL.glLoadIdentity();
        GL.glTranslatef(matrix.TranslationX, matrix.TranslationY, matrix.TranslationZ);
        GL.glRotatef((float)Math.sqrt(matrix.RotationX * matrix.RotationX + matrix.RotationY*matrix.RotationY + matrix.RotationZ*matrix.RotationZ), matrix.RotationX, matrix.RotationY, matrix.RotationZ);
        //Bind Texture
        GL.glBindTexture(GL10.GL_TEXTURE_2D, textures.get(i));
        GL.glColor4f(c_color.R, c_color.G, c_color.B, c_color.A);

        //Draw Elements
        GL.glDrawElements(GL10.GL_TRIANGLES, 8, GL10.GL_UNSIGNED_SHORT, indexBuffer);

        GL.glBindTexture(GL10.GL_TEXTURE_2D, 0);
        GL.glDisable(GL10.GL_TEXTURE_2D);
        GL.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        GL.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    //Disable things
    GL.glDisable(GL10.GL_BLEND);
    colors.clear();
    matrices.clear();
    vertices.clear();
    vertexUVs.clear();
}

I still try to find the solution. I'll also try to post an image to help you understanding this problem. Thanks in advance.

Daniel Sharp
  • 169
  • 1
  • 2
  • 12
  • How is it _"get screwed up"_? It does not show anything? It shows the texture but it is not correctly mapped? Characters are not in the same baseline? Please specify – c.s. Jul 31 '13 at 14:44
  • Everything after drawing string draws like a rectangle with missing pixels. – Daniel Sharp Jul 31 '13 at 15:01
  • The difference with the DrawString is that you calculate different texture coordinates for the bitmap font atlas but from the code above nothing seems wrong. Perhaps some state of the SpriteBatch class get corrupted (it is not clear how origin and destination rectange are used) but it is rather difficult to spot it without the whole code – c.s. Jul 31 '13 at 15:52
  • Destination rectangle is the 4 vertex defined by a rectangle that gets textured. Origin is the point from which the texture gets rotated and the translation is offseted by it. I define it in the rectangle instead using matrices to keep things simple at least for me. I think about something like arbitrary coordinates for the source rectangle can be a problem. But tests show that it is not if I don't use DrawString. But I'll look at the origin I didn't test it yet. – Daniel Sharp Jul 31 '13 at 15:58
  • What I meant is that the class is unknown to me. I can only try to guess without the code. E.g. Your `Draw` is declared: `Draw(Texture2D texture, Rectangle destination, Rectangle source, GLColor color, Vector2 origin, float Rotation)` - 6 parameters, inside `DrawString` you call it like: `Draw(spriteFont.Pages[cd.Page], destination, source, color);` 4 parameters. It seems you have an overriden version of `Draw`? Thinks like that. Just post the whole code so someone might spot something out – c.s. Jul 31 '13 at 16:13
  • Oh, sry it's just basic overload to the main function. Right I forgot add that in the question. I use overloads and pass null or 0 to parameters unknown. I try to approach this like C#'s XNA library. But I Posted the missing code. – Daniel Sharp Jul 31 '13 at 16:16

1 Answers1

0

I feel really ashamed that I answer my questions everytime but I found it out. I didn't clear texture buffer from my Draw buffers. I really don't like I had no real question on this site. But at least it's solved now. I feel really stupid now as always after solving one of my problems. Thanks for your comments though!

Daniel Sharp
  • 169
  • 1
  • 2
  • 12