Gamestudio Links
Zorro Links
Newest Posts
Trading Journey
by howardR. 04/28/24 09:55
Zorro Trader GPT
by TipmyPip. 04/27/24 13:50
Help with plotting multiple ZigZag
by M_D. 04/26/24 20:03
Data from CSV not parsed correctly
by jcl. 04/26/24 11:18
M1 Oversampling
by jcl. 04/26/24 11:12
Why Zorro supports up to 72 cores?
by jcl. 04/26/24 11:09
Eigenwerbung
by jcl. 04/26/24 11:08
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
3 registered members (AndrewAMD, alibaba, Quad), 761 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
Newest Members
wandaluciaia, Mega_Rod, EternallyCurious, howardR, 11honza11
19049 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
bmap_savetga #421231
04/14/13 07:36
04/14/13 07:36
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline OP
Senior Expert
HeelX  Offline OP
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Some users reported that they can't properly save a bitmap as TGA with bmap_save, because the bitmap gets mirrored. This is due the fact that TGA stores a handedness flag that defines if the image origin is in the upper- or lower left corner. --- I found out, that if you set the flag in the TGA, that indicates the origin in the lower left corner, and you write the image upside down into the file, the bitmap is saved correctly and is loaded correctly back into the engine.

So I have written the following function "bmap_savetga" a while ago (inspired by ventilator's C-Script in the wiki) in Lite-C for another project to circumvent the upside-down problem; it also saves the alpha channel in the TGA, if and only if the passed BMAP* has an alpha channel, too; otherwise the TGA just saves RGB data.

Here is the function:

Code:
// Saves a bitmap as tga file
BOOL bmap_savetga (BMAP* b, char* filename)
{
    BOOL bSuccess = false;

    if (b && filename && strlen(filename) > 0)
    {
        var fh = file_open_write(filename);
        if (fh)
        {
            int height = b->height;
            int width = b->width;

            var format = bmap_lock(b, 0);

            // if the bitmap has an alpha channel
            BOOL bAlpha = (((format == 8888) || (format == 1555) || (format == 4444)) && (b->bytespp == 4));

            // header

            int i;
            for (i = 0; i < 2; i++)
                file_asc_write(fh, 0);

            file_asc_write(fh, 2); // uncompressed

            for (i = 0; i < 7; i++)
                file_asc_write(fh, 0);

            // y origin (lower left corner)
            file_asc_write(fh, height & 255);
            file_asc_write(fh, (height >> 8) & 255);

            file_asc_write(fh, width & 255);
            file_asc_write(fh, (width >> 8) & 255);

            file_asc_write(fh, height & 255);
            file_asc_write(fh, (height >> 8) & 255);
            
            int bypp = 24;
            if (bAlpha)
                bypp = 32;

            file_asc_write(fh, bypp); // bypp
            file_asc_write(fh, 0);

            // pixels

            COLOR bgr;
            var alpha;

            int ix, iy;
            for (iy = 0; iy < height; iy++)
            {
                for (ix = 0; ix < width; ix++)
                {
                    // retrieve BGR color and alpha
                    pixel_to_vec(&bgr, &alpha, format, pixel_for_bmap(b, ix, height - 1 - iy));

                    file_asc_write(fh, bgr.blue); // b
                    file_asc_write(fh, bgr.green); // g
                    file_asc_write(fh, bgr.red); // r

                    if (bAlpha)
                        file_asc_write(fh, alpha * 2.55); // a
                }
            }

            // done!
            bmap_unlock(b);
            file_close(fh);

            bSuccess = true;
        }
    }

    return(bSuccess);
}



Here is an example, that creates an RGBA image with a horizontal color gradient and a vertical alpha gradient, saves it and loads it again:

Code:
#include <acknex.h>
#include <default.c>

int main ()
{
    wait(3);
    
    int format = 8888;
    BMAP* b = bmap_createblack(100, 200, format);
    
    bmap_lock(b, 0);
    
    // create red to green gradient from left to right
    // and alpha gradient from translucent to solid from up to bottom
    
    int ix, iy;
    for (ix = 0; ix < b->width; ix++)
    {
        for (iy = 0; iy < b->height; iy++)
        {
            double fx = (double)ix / (double)(b->width-1);
            double fy = (double)iy / (double)(b->height-1);
            
            VECTOR color;
            vec_lerp(&color, COLOR_RED, COLOR_GREEN, fx);
            
            var pixel = pixel_for_vec(&color, 100 * fy, format);
            
            pixel_to_bmap(b, ix, iy, pixel);
        }
    }
    
    bmap_unlock(b);
    
    // save to file
    bmap_savetga(b, "b.tga");
    
    // load from file to compare
    BMAP* bf = bmap_create("b.tga");
    
    video_set(32+b->width+16+bf->width+32, 32+maxv(b->height, bf->height)+32, 0, 2);
    
    while (1)
    {
        draw_text("engine", 32, 32, COLOR_WHITE);
        draw_quad(b, vector(32, 48, 0), NULL, NULL, NULL, NULL, 100, 0);
        
        draw_text("file", 32 + b->width + 16, 32, COLOR_WHITE);
        draw_quad(bf, vector(32 + b->width + 16, 48, 0), NULL, NULL, NULL, NULL, 100, 0);
        
        wait(1);
    }
}



Screenshot:


I hope you find this useful.

Regards,
-Christian

Re: bmap_savetga [Re: HeelX] #421233
04/14/13 08:31
04/14/13 08:31
Joined: Mar 2011
Posts: 3,150
Budapest
sivan Offline
Expert
sivan  Offline
Expert

Joined: Mar 2011
Posts: 3,150
Budapest
useful, I did also something similar based on the wiki script.
just some further info:
- bmap_save works fine with bmap_load (as I remember they are not engine functions, probably directx calls),
- bmap_create results in a flipped image if it was saved by bmap_save (and as I read earlier not planned to be fixed),
- image editors handles fine tga images created by bmap_save


Free world editor for 3D Gamestudio: MapBuilder Editor
Re: bmap_savetga [Re: sivan] #421235
04/14/13 08:45
04/14/13 08:45
Joined: Oct 2004
Posts: 900
Lgh
rojart Offline
User
rojart  Offline
User

Joined: Oct 2004
Posts: 900
Lgh
Yes, I remember some time ago for my Vader's entry contest I used flipped data to get this working, thanks for share it.


Regards, Robert

Quote
Everything should be made as simple as possible, but not one bit simpler.
by Albert Einstein

PhysX Preview of Cloth, Fluid and Soft Body

A8.47.1P
Re: bmap_savetga [Re: rojart] #421279
04/14/13 17:35
04/14/13 17:35
Joined: Nov 2007
Posts: 318
Brasil, Paraná
NeoNeper Offline
Senior Member
NeoNeper  Offline
Senior Member

Joined: Nov 2007
Posts: 318
Brasil, Paraná
Thank you for sharing with us! (^.^)
Very helpful for my project and also learning


Please! Use easy words to be translated. because my English is not very good! Grateful.
_______________________________________________________
Re: bmap_savetga [Re: NeoNeper] #421290
04/15/13 06:25
04/15/13 06:25
Joined: Mar 2006
Posts: 1,993
Karlsruhe
PadMalcom Offline
Serious User
PadMalcom  Offline
Serious User

Joined: Mar 2006
Posts: 1,993
Karlsruhe
This should go to the TUST image lib! laugh

Re: bmap_savetga [Re: PadMalcom] #421291
04/15/13 06:57
04/15/13 06:57
Joined: Mar 2011
Posts: 3,150
Budapest
sivan Offline
Expert
sivan  Offline
Expert

Joined: Mar 2011
Posts: 3,150
Budapest
it could be extended with a bmap_to_format conversion because currently it is not okay for dds images, but not essetnial, as it should be done before pixel manipulations...


Free world editor for 3D Gamestudio: MapBuilder Editor
Re: bmap_savetga [Re: sivan] #423496
05/31/13 04:51
05/31/13 04:51
Joined: May 2008
Posts: 257
D
djfeeler Offline
Member
djfeeler  Offline
Member
D

Joined: May 2008
Posts: 257
Thanks for this contibution ^^


Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1