allegro 4 to allegro 5 issue
The Master

hey, i use a custom sprite animation architecture making use of allegro datafiles and properties.

Now I realise that Allegro 5 doesn't have datafiles, which is fine, since you can use .zip files. but it now means I can't use my animation architecture.

I still want to use the animation architecture, so i'm developing a little utility that'll extract the sprite frames and properties from the datafile and pack them into a nice little binary file that can be loaded from the zip. Progress is being made, but I have a bottleneck i need to get around.

This is how the utility saves the bitmap data:

#SelectExpand
1 for( iX = 0; iX < pBitmap->w; iX++ ) { 2 3 for( iY = 0; iY < pBitmap->h; iY++ ) { 4 5 iPix = getpixel( pBitmap, iX, iY ); 6 r = getr( iPix ); 7 g = getg( iPix ); 8 b = getb( iPix ); 9 a = geta( iPix ); 10 pStream->write( (const char*)&r, sizeof( int ) ); 11 pStream->write( (const char*)&g, sizeof( int ) ); 12 pStream->write( (const char*)&b, sizeof( int ) ); 13 pStream->write( (const char*)&a, sizeof( int ) ); 14 15 } 16 17 }

Just so you know, the pStream variable is a pointer to a std::ofstream instance.

That seems to work. But now I'm working on the allegro 5 code to load these files. But all it displays is a black box. The allegro 5 reverse code is shown below:

#SelectExpand
1 m_pSpriteData = al_create_bitmap( m_iWidth, m_iHeight ); 2 al_set_target_bitmap( m_pSpriteData ); 3 for( iX = 0; iX < m_iWidth * m_dwFrameCount; iX++ ) { 4 5 for( iY = 0; iY < m_iHeight; iY++ ) { 6 7 pInput->read( (char*)&r, sizeof( int ) ); 8 pInput->read( (char*)&g, sizeof( int ) ); 9 pInput->read( (char*)&b, sizeof( int ) ); 10 pInput->read( (char*)&a, sizeof( int ) ); 11 al_draw_pixel( iX, iY, al_map_rgba( r, g, b, a ) ); 12 13 } 14 15 } 16 17 al_set_target_bitmap( pBmp );

Obviously this doesn't work. Is there another way? Help would be appreciated.

Matthew Leverton

A) Why are you writing chars with the length of an integer? (Or are r,g,b,a actually integers?)

B) You probably want to lock the bitmap and use al_put_pixel to copy the data as-is without any blending.

The Master

update:
i fixed the problem. It wasn't a problem with my loading code, it was with my drawing code. i had to set up alpha-blending properly.

but there's still an issue.

i do the animation in the form of a filmstrip, and i draw each frame as a segment of the bitmap. But al_draw_bitmap_region doesn't seem to have the same properties as blit, since it doesn't draw a region of the bitmap as much as it draws the strip sequentially across the screen. also, it doesn't mask pink colour. am i doing something wrong?

this is the drawing code.

#SelectExpand
1int CAnimationController::OnFrameRender( int x, int y, ALLEGRO_BITMAP *pRenderTarget, Color3 litColor, int iAlpha ) { 2 3 ALLEGRO_BITMAP *pSpriteData = m_pSprite->m_pAnimationSets[ m_dwAnimationSetIndex ].m_pAnimations[ m_dwAnimationIndex ].m_pSpriteData; 4 ALLEGRO_BITMAP *pTemp = 0; 5 int w = m_pSprite->m_pAnimationSets[ m_dwAnimationSetIndex ].m_pAnimations[ m_dwAnimationIndex ].GetWidth(); 6 int h = m_pSprite->m_pAnimationSets[ m_dwAnimationSetIndex ].m_pAnimations[ m_dwAnimationIndex ].GetHeight(); 7 int ox = m_pSprite->m_pAnimationSets[ m_dwAnimationSetIndex ].m_pAnimations[ m_dwAnimationIndex ].GetOriginX(); 8 int oy = m_pSprite->m_pAnimationSets[ m_dwAnimationSetIndex ].m_pAnimations[ m_dwAnimationIndex ].GetOriginY(); 9 int px, py; 10 11 if( pRenderTarget ) { 12 13 pTemp = al_get_target_bitmap(); 14 al_set_target_bitmap( pRenderTarget ); 15 16 } 17 18 px = x - ox; 19 py = y - oy; 20 21// al_set_blender( ALLEGRO_ADD, iAlpha, 255 - iAlpha ); 22 23 if( litColor.r != -1 ) 24 al_draw_tinted_bitmap_region( pSpriteData, al_map_rgb( litColor.r, litColor.g, litColor.b ), w * m_dwFrameIndex, 0, w, h, px, py, 0 ); 25 else 26 al_draw_bitmap_region( pSpriteData, w * m_dwFrameIndex, 0, w, h, px, py, 0 ); 27 28 if( pRenderTarget ) 29 al_set_target_bitmap( pTemp ); 30 31 return 0; 32 33}

Edgar Reynaldo

But al_draw_bitmap_region doesn't seem to have the same properties as blit, since it doesn't draw a region of the bitmap as much as it draws the strip sequentially across the screen. also, it doesn't mask pink colour. am i doing something wrong?

What do you mean it draws the strip sequentially across the screen? It should only draw one region at a time, which you specify.

Allegro 5 doesn't understand/use magic pink anymore. You need to use al_convert_mask_to_alpha on your sprite sheets.

Matthew Leverton

What does this mean?

al_set_blender( ALLEGRO_ADD, iAlpha, 255 - iAlpha );

The second and third parameters must be one of:

  • ALLEGRO_ZERO

  • ALLEGRO_ONE

  • ALLEGRO_ALPHA

  • ALLEGRO_INVERSE_ALPHA

The Master

ignore the alpha thing.

What i mean is that, it only draws the first frame of the strip, and tiles it in a line across the screen.

how do the coordinates for al_draw_bitmap_region work? they're float values, so are they fractions or something?

Matthew Leverton

Maybe m_dwFrameIndex is always 0.

Everything that respects the transformations uses floats. If you aren't using any transformations, then they work just like the Allegro 4 coordinates when blitting.

The Master

no the m_dwFrameIndex is incrementing.

the actual argument descriptions for the function are a little ambiguous. I've been tweeking them, and I'm able to stop the thing from tiling, but its not showing the frame indicated by the frame index counter. where is there a concise description for the arguments for drawing bitmap regions?

EDIT:

Problem solved. Thanks guys!

But i have to ask something: how does transparency work in allegro 5? it's not as well described in the documentation as in allegro 4

Edgar Reynaldo

What i mean is that, it only draws the first frame of the strip, and tiles it in a line across the screen.

So you're saying that what it draws is wider and/or taller than the width and height you passed to the al_draw_bitmap_region function? That sounds like something is wrong with the function then. Make sure the width and height values are correct.

where is there a concise description for the arguments for drawing bitmap regions?

al_draw_bitmap_region

The Master

check my last edited post.

i fixed it. there was a problem with my loading code, but it's fixed.

now all i'd like to know is how transparency works in allegro 5.

Matthew Leverton

It uses the alpha channel.

Set the alpha channel to 0 on the pixels you don't want it to draw, and it won't draw them.

The Master

no the masking problem is solved. in allegro 4 i used to be able to draw bitmaps translucently by setting a transparency blender. allegro 5 doesn't seem to have that from my studies of the documentation

Edgar Reynaldo

alpha 0 indicates fully transparent, alpha 255 indicates fully opaque. How bitmaps are drawn depends on the blender in use. A5 uses premultiplied alpha by default, which means you have to scale the rgb values that you pass to functions by the alpha value, or else change the blender.

i used to be able to draw bitmaps translucently by setting a transparency blender. allegro 5 doesn't seem to have that from my studies of the documentation

Use al_draw_tinted_bitmap(bitmap , al_map_rgba_f(1.0f , 1.0f , 1.0f , 0.5f) , x , y , 0); to draw at 50% opacity.

Matthew Leverton

What effect do you want?

If using the default pre-multiplied alpha blender, then something like this will draw at 50%:

al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0);

Thread #606549. Printed from Allegro.cc