#72937 - genfish - Wed Feb 22, 2006 3:18 pm
Hi, I have a TGA file reader which i have used for reading 24bit and 32bit images before. I have modified it to read 16bit TGA's, and made my own fopen and fread functions for gbfs. Would this work to load images onto the main screen in framebuffer mode if i copy the 16bit values from the tga file?
thanks.
_________________
there is no rl only afk
#72954 - genfish - Wed Feb 22, 2006 4:42 pm
ok, i whipped up some test code and i just seem to get a black square where the sprite should be...
(code removed)
in main i have set wait_cr, and called the loadtexture function.
All i can think of is that im doing something wrong with the filreading/gbfs
any input would be appreciated :) thanks
_________________
there is no rl only afk
Last edited by genfish on Fri Mar 03, 2006 4:10 pm; edited 1 time in total
#72969 - Cearn - Wed Feb 22, 2006 6:48 pm
I may have simply missed it in all this code, but it seems like you're never allocating memory for image; it always points to NULL. Putting things in NULL is usually bad.
Also, this ...
Quote: |
Code: | while (count < (w * h))
{
word bpp16;
if (header.pixelDepth != 16)
{
// Unsupported colour depth
//fprintf(stderr, "TGA_Read: Unsupported Pixel Depth", filename);
}
else if (header.pixelDepth == 16)
{
// Read image data from file
fread(&bpp16, 2, 1, fp);
// Move to image variable
image[count] = bpp16;
}
count++;
}
fclose(fp);
|
|
can probably be sped up by a whole lot (something like 10*w times faster, but that's just a guess) by taking the bpp-check out of the loop and copying per scanline instead of per pixel.
Code: |
if(header.pixelDepth == 16)
{
while(h--)
{
fread(image, 2, width, fp);
image += width;
}
}
|
If the TGA doesn't necessarily have the same dimensions as the arguments of load_image() (i.e., if w != header.width or h != header.height), you will have add code for those differences as well.
#73322 - genfish - Fri Feb 24, 2006 7:42 pm
i've made these updates, thanks. Im still getting a black square, think its something to do with the filereading functions, because im trying to test it with a text file and it isn't working either. ill post if i find the solution.
_________________
there is no rl only afk
#74214 - genfish - Fri Mar 03, 2006 4:08 pm
update on this, plus ill remove all the code above.
I now seem to have a purple coloured square where the sprite should be, i have been looking for tga file format specs for how the pixels are arranged. The best i can find is, if u make a photoshop 16bit targe image, and hover over it, it says 'A1R5G5B5'. Assuming this was how the pixels were organised, i did this:
Code: |
image[count] = (uint16)(image[count]<<1);
image[count] = BIT(15);
|
i thought this would sort it out, but nope, still got a purple square. Anyone know why? thanks
_________________
there is no rl only afk
#74235 - Cearn - Fri Mar 03, 2006 7:40 pm
genfish wrote: |
update on this, plus ill remove all the code above.
I now seem to have a purple coloured square where the sprite should be, i have been looking for tga file format specs for how the pixels are arranged. |
Looking 'for' or 'at' specs? If you need something on the TGA format, wotsit has a large collection of file formats including this one.
genfish wrote: |
The best i can find is, if u make a photoshop 16bit targe image, and hover over it, it says 'A1R5G5B5'. |
a1r5g5b5 means that it's the same kind of format as you want, only with the red and blue components switched.
Code: |
// assuming 'image' is the buffer with the a1r5g5b5 formatted pixels:
u32 clr_org, clr_new;
clr_org= image[count];
clr_new =(clr_org>>10)&31; // shift red to lowest 5 bits
clr_new |= clr_org&(31<<5); // add green
clr_new |=(clr_org&31)<<10; // shift blue up
clr_new |= 1<<15;
image[count]= clr_new;
|
Of course, this is going to slow down the TGA loader by a whole lot. Have you considered converting the image on the PC and using that instead?
genfish wrote: |
Assuming this was how the pixels were organised, i did this:
Code: | image[count] = (uint16)(image[count]<<1);
image[count] = BIT(15);
|
|
May I ask why you did this? Because this code doesn't make any kind of sense at all. What is it supposed to do? I'm a little surprised that it oes anything at all with this code
Even with the red-blue swap, this doesn't explain the purple square, though, as purple has equal values for red and blue. A uniformly colored square probably means two things: either you're not updating the counter when loading the pixels, so you always fill VRAM with the first pixel; or if you're using an affine sprite, you forgot to set the affine matrix.
#74246 - tepples - Fri Mar 03, 2006 8:14 pm
Or there could be other problems. A lot of programs use purple for all totally transparent pixels.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#74364 - genfish - Sat Mar 04, 2006 8:20 pm
Cearn wrote: |
genfish wrote: | Assuming this was how the pixels were organised, i did this:
Code: | image[count] = (uint16)(image[count]<<1);
image[count] = BIT(15);
|
|
May I ask why you did this? Because this code doesn't make any kind of sense at all. What is it supposed to do? I'm a little surprised that it oes anything at all with this code
|
i came up with this by thinking about it for a little while. I wanted to shift all the bits left by 1 to eradicate the alpha bit, which i then thought was R5G5B5 and the 1 extra at the end. And i read somewhere that the last bit needs to be set to 1 for it to display, and i took the BIT(15) line from doublec's tutorials, which is explained there to set the last bit in a 16bit variable.
Cearn wrote: |
Looking 'for' or 'at' specs?
|
Well, both, i looked at the TGA file format details from wotsit, and i couldnt find the part with pixel arrangements for 16bit.
Cearn wrote: |
Of course, this is going to slow down the TGA loader by a whole lot. Have you considered converting the image on the PC and using that instead?
|
I'll try putting in the code you suggested, see how it fares. If i were to go about doing this conversion on the pc, what would i do? Write a converter to run the tga's through before i add them to the .gbfs file?
Thanks to everyone for your input by the way, its quite important that i get this right as its for my university dissertation :)
_________________
there is no rl only afk
#74520 - Cearn - Sun Mar 05, 2006 4:37 pm
genfish wrote: |
Cearn wrote: |
genfish wrote: | Assuming this was how the pixels were organised, i did this:
Code: | image[count] = (uint16)(image[count]<<1);
image[count] = BIT(15);
|
|
May I ask why you did this? Because this code doesn't make any kind of sense at all. What is it supposed to do? I'm a little surprised that it oes anything at all with this code
|
i came up with this by thinking about it for a little while. I wanted to shift all the bits left by 1 to eradicate the alpha bit, which i then thought was R5G5B5 and the 1 extra at the end. And i read somewhere that the last bit needs to be set to 1 for it to display, and i took the BIT(15) line from doublec's tutorials, which is explained there to set the last bit in a 16bit variable. |
The first line in the code does indeed get rid of the TGA's alpha bit, (which is indeed bit 15), but by shifting all of it you're also shifting the highest r,g,b bits into alpha, r and g channels, which can't be good. None of that really matters here anyway, though, beause the second line fills the whole pixel with BIT(15) because you're using an assignment instead of inserting the bit.
genfish wrote: |
Cearn wrote: | Looking 'for' or 'at' specs?
| Well, both, i looked at the TGA file format details from wotsit, and i couldnt find the part with pixel arrangements for 16bit.
|
I'll agree that it's hidden a bit, but it's there:
tga.txt wrote: |
Code: | color map data
...
| | | The 2 byte entry is broken down as follows: |
| | | ARRRRRGG GGGBBBBB, where each letter represents a bit. |
| | | But, because of the lo-hi storage order, the first byte |
| | | coming from the file will actually be GGGBBBBB, and the |
| | | second will be ARRRRRGG. "A" represents an attribute bit. |
|
|
In other words, a little-endian halfword, a1r5g5b5, whereas the NDS uses a1b5g5r5.
genfish wrote: |
Cearn wrote: | Of course, this is going to slow down the TGA loader by a whole lot. Have you considered converting the image on the PC and using that instead?
|
I'll try putting in the code you suggested, see how it fares. If i were to go about doing this conversion on the pc, what would i do? Write a converter to run the tga's through before i add them to the .gbfs file? |
Something like that yeah.
First make sure your code can read a TGA properly, by putting it on a screen or converting it to a BMP or something. At least you'll know that that part of the code won't be a problem. If that is ok, you can simply do the conversion to the preferred NDS format (switch red and blue components), then dump the whole thing into a binary file that you then add to the GBFS. Or you could add GBFS capabilities to the converter as well; it's not that hard.
#74537 - genfish - Sun Mar 05, 2006 8:11 pm
Ok cool, i think im getting the hang of it now.
Quote: |
the first byte coming from the file will actually be GGGBBBBB, and the second will be ARRRRRGG. |
Does this mean that i ignore the first byte, or have to read 2 bytes in and swap them for every pixel?
Quote: |
// assuming 'image' is the buffer with the a1r5g5b5 formatted pixels:
u32 clr_org, clr_new;
clr_org= image[count];
clr_new =(clr_org>>10)&31; // shift red to lowest 5 bits
clr_new |= clr_org&(31<<5); // add green
clr_new |=(clr_org&31)<<10; // shift blue up
clr_new |= 1<<15;
image[count]= clr_new; |
Also, i've not done any bit manipulation before, is there a reason this is u32 when we're dealing with 16bit values?
thanks again
_________________
there is no rl only afk
#74540 - Cearn - Sun Mar 05, 2006 8:34 pm
genfish wrote: |
Ok cool, i think im getting the hang of it now.
Quote: | the first byte coming from the file will actually be GGGBBBBB, and the second will be ARRRRRGG. |
Does this mean that i ignore the first byte, or have to read 2 bytes in and swap them for every pixel? |
It means you need to do a little more research on how data is kept in computer memory, in particular endianness. :P
Reading in 2 bytes and swapping may or may not be required; it depends on the platform you are working on. Little endian means that for multi-byte types, the lower bytes appear first. For example, the byte pattern "0x01 0x02" would form 0x0201 on little-endian systems, but 0x0102 on big-endian systems. TGA is little endian, so are intel and GBA/NDS, so that would work out nicely. Open VBA's memory viewer anywhere and switch between byte (u8), halfword (u16) and word (u32) interpretations and look at the differences in notation; the data itself remains the same.
genfish wrote: |
Quote: | // assuming 'image' is the buffer with the a1r5g5b5 formatted pixels:
u32 clr_org, clr_new;
clr_org= image[count];
clr_new =(clr_org>>10)&31; // shift red to lowest 5 bits
clr_new |= clr_org&(31<<5); // add green
clr_new |=(clr_org&31)<<10; // shift blue up
clr_new |= 1<<15;
image[count]= clr_new; |
Also, i've not done any bit manipulation before, is there a reason this is u32 when we're dealing with 16bit values? |
The datatype isn't about bit manipulation. Because the NDS is a 32bit system, 32bit variables are to be preferred. If you use anything else, GCC will have to add extra instructions to keep the values in their datatype boundaries, slowing down the routine. As a general rule, (unsigned) ints are preferable.
Also: this may come in hand if you're new to bit ops.
#74544 - genfish - Sun Mar 05, 2006 8:49 pm
lol i didnt realise it would be THAT complicated:/ maybe i've gone over my head with this one...
do you, or anyone else know a program that converts any popular graphics format into files with raw 16bit values i can directly transfer into a DS framebuffer?
I know about bmp2spr etc but dont they only use 256 colours. I was hoping to utilize a larger palette.
once again thanks for your help... if i find another method ill look into this again when i dont only have 4 weeks to complete the project!
_________________
there is no rl only afk
#74638 - genfish - Mon Mar 06, 2006 6:27 pm
For anyone interested, the way i've decided to go is, make the sprites in photoshop on 16bit canvases, Then convert them to 24 bit so there is 1 byte per channel. I have a working reader for 24bit files so i can then read in a pixel at a time and convert each channel from a 0-255 number to a 0-31 number.
Then im going to have a raw image file full of this 0-31 data which i can then use to get a colour using the RGB function in ndslib. RGB(31,31,31) for example :)
_________________
there is no rl only afk