Loading 32-bit PNG with datatypes
-
- Posts: 6
- Joined: Wed Oct 24, 2012 11:56 am
Loading 32-bit PNG with datatypes
I want to load a PNG image with its alpha channel and then blit fragments of this image into window RastPort using BltBitMapTags(). So far I'm unsuccesfull, images are blitted, but without alpha. The first problem is that PDTA_Depth returns me 24 (instead of 32). Do I need some special tag for NewDTObject()?
Re: Loading 32-bit PNG with datatypes
Code: Select all
dto = NewDTObject(filename,
DTA_GroupID, GID_PICTURE,
PDTA_DestMode, PMODE_V43,
PDTA_Remap, FALSE,
TAG_END );
GetDTAttrs(dto, PDTA_BitMapHeader, (ULONG)&bmh, TAG_END );
bufA=AllocVec(bmh->bmh_Width*bmh->bmh_Height*4, MEMF_SHARED);
bpa.pbpa_PixelData = bufA;
bpa.pbpa_PixelFormat = PBPAFMT_ARGB;
bpa.pbpa_PixelArrayMod = bmh->bmh_Width*4;
bpa.pbpa_Left = 0;
bpa.pbpa_Top = 0;
bpa.pbpa_Width = bmh->bmh_Width;
bpa.pbpa_Height = bmh->bmh_Height;
IDoMethodA(dto, (Msg)&bpa);
Maybe the problem come from BltBitMapTags(), but I can't help you, I never used it. Anyway it's simple, just check every 4th byte in your picture buffer.
Re: Loading 32-bit PNG with datatypes
Hi Grzegorz,
Here is my personal function to load images (using datatypes) in the AmiDARK Engine.
It work with PNG using alpha transparency ( RGBA 32bits images ).
MyPicture structure is :
and I setup my image buffer this way :
I use IIntuition->IDoMethodA( dto, bpaptr ) to uncompress the image in my memory buffer as raw RGBA 32 bits pixels maps
it allow me to set how the image is decoded using : bpa.pbpa_PixelFormat = PBPAFMT_RGBA;
I force Depth to 32 in the Buffer allocation in the function AllocPicture32( int Width, int Height ). It ensure that the information is correctly given.
I think you will always get 24 bits for image even if there is an alpha 8 bits channel (it's something I remind to have heard when I worked on DataType system :p)
I'm currently working on understanding bltBitMapTags functions and it seem to be used this way :
if you use 2 bitmap structures for sources & target.
My function is untested because I'm currently working on these bltBitMap functions these days :p
I hope it helped you.
Kindest Regards,
AmiDARK
Here is my personal function to load images (using datatypes) in the AmiDARK Engine.
It work with PNG using alpha transparency ( RGBA 32bits images ).
Code: Select all
struct MyPicture * LoadPicture( APTR FileName ){
struct MyPicture *pt = NULL;
Object *dto = NULL;
ULONG nb;
ULONG * AvailMethod = NULL;
struct BitMapHeader *bmh;
struct pdtBlitPixelArray bpa;
void * bpaptr = &bpa;
if ( !FileName ) return NULL;
dto = IDataTypes->NewDTObject( (STRPTR)FileName,
DTA_SourceType, DTST_FILE,
DTA_GroupID, GID_PICTURE,
PDTA_DestMode, PMODE_V43,
PDTA_Remap, TRUE,
OBP_Precision, PRECISION_EXACT,
TAG_DONE );
if ( dto != 0 ){
nb = IIntuition->GetAttrs( dto, PDTA_BitMapHeader, &bmh, TAG_DONE );
if( nb != 0 ){
int resread;
/* Allocation de la structure Picture et du buffer mémoire */
pt = AllocPicture32( bmh->bmh_Width, bmh->bmh_Height );
if ( pt != NULL ){
bpa.pbpa_PixelData = pt->Pixels;
bpa.pbpa_PixelFormat = PBPAFMT_RGBA;
bpa.pbpa_PixelArrayMod = bmh->bmh_Width * 4;
bpa.pbpa_Left = 0;
bpa.pbpa_Top = 0;
bpa.pbpa_Width = bmh->bmh_Width;
bpa.pbpa_Height = bmh->bmh_Height;
AvailMethod = IDataTypes->GetDTMethods( dto );
if ( IDataTypes->FindMethod( AvailMethod, PDTM_READPIXELARRAY ) != 0 ){
bpa.MethodID = PDTM_READPIXELARRAY;
resread = IIntuition->IDoMethodA( dto, bpaptr );
}else{
DebugMessage( debugDEImage, "Method PDTM_READPIXELARRAY not compatible with object.\n", 0 );
}
}else{
DebugMessage( debugDEImage, "Cannot allocate memory for internal picture structure.\n", 0 );
}
}else{
DebugMessage( debugDEImage, "Informations cannot be read from image file.\n", 0 );
}
IIntuition->DisposeObject( dto );
}else{
DebugMessage( debugDEImage, "Unable to load the image file.\n", 0 );
}
return pt;
Code: Select all
struct MyPicture{
int Width;
int Height;
int Depth;
unsigned char *Pixels;
};
Code: Select all
struct MyPicture * AllocPicture32( int Width, int Height ){
struct MyPicture *pt = NULL;
pt = (struct MyPicture *)MyAllocVec( sizeof( struct MyPicture ), MEMF_ANY|MEMF_CLEAR );
if ( pt ){
pt->Pixels = MyAllocVec( Width * ( Height + 1 ) * 4, MEMF_ANY );
pt->Width = Width;
pt->Height = Height;
pt->Depth = 32;
if ( pt->Pixels == NULL ){
MyFreeVec( pt );
pt = NULL;
}
}
return pt;
}
it allow me to set how the image is decoded using : bpa.pbpa_PixelFormat = PBPAFMT_RGBA;
I force Depth to 32 in the Buffer allocation in the function AllocPicture32( int Width, int Height ). It ensure that the information is correctly given.
I think you will always get 24 bits for image even if there is an alpha 8 bits channel (it's something I remind to have heard when I worked on DataType system :p)
I'm currently working on understanding bltBitMapTags functions and it seem to be used this way :
Code: Select all
void myBltBitMap2BitMap( struct BitMap * srcBitMap, int xStart, int yStart, struct BitMap * tgtBitMap, int xStartT, int yStartT, int Width, int Height, BOOL Transparency ){
IGraphics->BltBitMapTags( BLITA_SrcType, BLITT_BITMAP, BLITA_Source, srcBitMap,
BLITA_SrcX, xStart, BLITA_SrcY, yStart,
BLITA_DestType, BLITT_BITMAP, BLITA_Dest, tgtBitMap,
BLITA_DestX, xStartT, BLITA_DestY, yStartT,
BLITA_Width, Width, BLITA_Height, Height,
BLITA_AlphaMask, Transparency, TAG_END );
}
My function is untested because I'm currently working on these bltBitMap functions these days :p
I hope it helped you.
Kindest Regards,
AmiDARK
Sam440EP - AmigaOS 4.1 Final Edition
-
- Posts: 6
- Joined: Wed Oct 24, 2012 11:56 am
Re: Loading 32-bit PNG with datatypes
I see both of you use PDTM_READPIXELARRAY method. As my code is based on AmigaOS 3.x one, it works differently. After setting PDTA_Mode to v43 (which is the default anyway, as stated it the autodoc), I perform DTM_PROCLAYOUT and then query PDTA_DestBitmap. Finally I allocate my buffer bitmap with friend bitmap set to screen's bitmap and do a blit from datatype's DestBitmap to my buffer. Unfortunately it seems this way I loose alpha information.
Then I will simply separate AmigaOS 4 code from AmigaOS 3 code and use PDTM_READPIXELARRAY. I still will copy this pixel array into my buffer bitmap. When my game runs I do many blits from buffer to the game window, so having game imagery in a bitmap being friend to screen bitmap speeds things up.
Then I have another, loosely related question. How to sync blitting frames of animation with screen refresh? I use WaitBOVP() on both AmigaOS 3 and MorphOS, but on AmigaOS 4 animation is significantly slower. Looks like it synchronizes to every second frame instead of each frame. WaitTOF() would be better? Or there is some AmigaOS 4 specific way?
Then I will simply separate AmigaOS 4 code from AmigaOS 3 code and use PDTM_READPIXELARRAY. I still will copy this pixel array into my buffer bitmap. When my game runs I do many blits from buffer to the game window, so having game imagery in a bitmap being friend to screen bitmap speeds things up.
Then I have another, loosely related question. How to sync blitting frames of animation with screen refresh? I use WaitBOVP() on both AmigaOS 3 and MorphOS, but on AmigaOS 4 animation is significantly slower. Looks like it synchronizes to every second frame instead of each frame. WaitTOF() would be better? Or there is some AmigaOS 4 specific way?
Re: Loading 32-bit PNG with datatypes
Hum, my Os3.x code was really quite the same as the code I showed you, except I used another function than IDoMethodA, but can't remember... Unfortunatelly, I can hardly turn on my 4000T. Are you sure also your PNG datatype support Alpha?
For Os4, I use WaitTOF(), and be sure you have INTERRUPT=YES (or INTERRUPTS=YES, can't remember) in your devs/monitor tooltypes. BTW, screensync give very good visual result, but if you are working on something "heavy" then it's a good idea to make triple buffer and switch/blit from a second process. Vsync in a single process always round down the framerate (60 -> 30 -> 15 -> etc...)
For Os4, I use WaitTOF(), and be sure you have INTERRUPT=YES (or INTERRUPTS=YES, can't remember) in your devs/monitor tooltypes. BTW, screensync give very good visual result, but if you are working on something "heavy" then it's a good idea to make triple buffer and switch/blit from a second process. Vsync in a single process always round down the framerate (60 -> 30 -> 15 -> etc...)
-
- Posts: 6
- Joined: Wed Oct 24, 2012 11:56 am
Re: Loading 32-bit PNG with datatypes
And it worked with OCS/ECS/AGA? I support them too, just in this case the graphics is 4-color IFF ILBM, of course without any alpha.Crisot wrote:Hum, my Os3.x code was really quite the same as the code I showed you,
I have OS 4.1u6 and datatype, which comes with it. I would be surprised if it does not support alpha.Crisot wrote:Unfortunatelly, I can hardly turn on my 4000T. Are you sure also your PNG datatype support Alpha?
It is logical game, so not heavy. Also I do doublebuffering in the only one effect involving larger blits (larger is some 700 x 150 pixels). Other than that animations involve moving 24 x 24 pixels block over background (only one at a time) so I don't think it is heavy.Crisot wrote:BTW, screensync give very good visual result, but if you are working on something "heavy" then it's a good idea to make triple buffer
Re: Loading 32-bit PNG with datatypes
Ah! True! Was CGX/Warp3D code. Not sure it works with classic screenmodes.
Ok, with a simple logic game, you won't have to bother with aynchronous triple buffer ^^
Ok, with a simple logic game, you won't have to bother with aynchronous triple buffer ^^
Re: Loading 32-bit PNG with datatypes
@Grzegorz Kraszewski
Are you supplying BLITA_UseSrcAlpha, TRUE to your BltBitMapTags call?
Are you supplying BLITA_UseSrcAlpha, TRUE to your BltBitMapTags call?
-
- Posts: 6
- Joined: Wed Oct 24, 2012 11:56 am
Re: Loading 32-bit PNG with datatypes
Of course I do. I have read the autodoc of it carefully.chris wrote:Are you supplying BLITA_UseSrcAlpha, TRUE to your BltBitMapTags call?
Code: Select all
BltBitMapTags(
BLITA_Source, ggfx->Bricks,
BLITA_SrcType, BLITT_BITMAP,
BLITA_SrcX, src_x,
BLITA_SrcY, src_y,
BLITA_Dest, win->RPort,
BLITA_DestType, BLITT_RASTPORT,
BLITA_DestX, x,
BLITA_DestY, y,
BLITA_Width, ggfx->BrickWidth,
BLITA_Height, ggfx->BrickHeight,
BLITA_UseSrcAlpha, TRUE,
TAG_END);
- thomasrapp
- Posts: 318
- Joined: Sun Jun 19, 2011 12:22 am
Re: Loading 32-bit PNG with datatypes
Setting PDTA_Remap to TRUE without setting PDTA_Screen also is nonsense. Same applies to OBP_Precision.AmiDARK wrote:Here is my personal function to load images (using datatypes) in the AmiDARK Engine.