#89876 - Onions - Tue Jun 27, 2006 3:23 am
I'm wanting some of my images to have varying levels of opacity, yet, I do not know how to do this and after searching the forums only 1 other post seemed vaguely useful to my situation, although I could not get anything to work based on it.
So, anyway, I'm using images converted from PCX to Binary using a converter called "pcx2tex". I'm also using the following for my video setup, which uses uint16 for my color values...
Code: |
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG_0x6000000);
BG3_CR = BG_BMP16_256x256;
|
I'd like a function where I give it two colors which it can blend based on a 3rd value which represents the 2nd color's opacity. I also wouldn't mind the 3rd value using int as it's type, so that 1 to "whatever" value could represent it's opacity, or another uint16 that takes grayscale as it's opacity value (where white is visable, gray is inbetween, and black means completely transparent).
It's kind of similar to what was said in the already mentioned post I came across, which can be found here...
http://forum.gbadev.org/viewtopic.php?t=5917&highlight=opacity
Any help is appreciated.
#89877 - tepples - Tue Jun 27, 2006 3:43 am
You can write this function yourself: - Separate the source and destination pixels into red, green, and blue components.
- Multiply one pixel's components by gamma and the other's by 16 - gamma, and add them. That is:
dstRed = aRed * gamma + bRed * (16 - gamma); - Divide all components by 16.
- Reassemble the pixel.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#89886 - Onions - Tue Jun 27, 2006 5:01 am
I think my main problem is not knowing how to seperate the color value I get from my image arrays (by using pcx2tex) into seperate color channels.
Also, I don't know the opacity range that can be given to colors, or exactly how that's set up. I believe it was you that showed me the break down in binary of where the opacity bit is located, but I do not understand how you derived a hex based value for it (based on the question I had asked). Yet, something tells me since it was one bit and in binary, that it wasn't the opacity I'm wanting but a simple "is transparent" or "is not transparent" switch. So what I'm talking about here probably is irrelevant... but to continue on this subject (if it matters)... I think the whole bit shifting and working at such a level is beyond me. I probably need to look into this, though, as handheld development seems to use a lot of it.
I will say the most problematic thing I'm running into with developing on DS or GBA (DS mostly) is how to deal with color. I'm currently working on building everything myself based around the simple use of plotting pixels to the screen, so I'm sure other things would be confusing me aswell, but I'm simply not dealing with them (yet atleast).
So anyway, any help is appreciated in telling me how to split my color value found in my image arrays - or where I can go to best learn this - aswell as how to derive an opacity level.
#89889 - tepples - Tue Jun 27, 2006 5:40 am
Onions wrote: |
I think my main problem is not knowing how to seperate the color value I get from my image arrays (by using pcx2tex) into seperate color channels. |
From libnds:
Code: |
#define RGB15(r,g,b) ((r)|((g)<<5)|((b)<<10)) |
So let's reverse that:
Code: |
#define RGB15R(rgb) (((rgb) ) & 0x1F)
#define RGB15G(rgb) (((rgb) >> 5) & 0x1F)
#define RGB15B(rgb) (((rgb) >> 10) & 0x1F) |
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#89935 - Onions - Tue Jun 27, 2006 3:20 pm
What you said seems like it would work, yet I get a blank screen when I do the following test...
Code: |
uint16 red = RGB15R(color);
uint16 green = RGB15G(color);
uint16 blue = RGB15B(color);
color = RGB15(red, green, blue);
*Camera_01[y * 40 + x] = color;
|
It seems the problem lies in the splitting of the colors as I put other values into RGB15 and atleast something came out of it. Any insight into what I may be doing wrong is appreciated.
EDIT: I just tried putting 1 to 2 of the seperate colors into RGB15() and some distorted colors showed up, however, adding a 3rd gives a blank screen. This might help in deducing what's going on perhaps.
#89936 - Mighty Max - Tue Jun 27, 2006 3:25 pm
You are losing bit 15. Which decides about the general visibility on backgrounds which can have transparent pixels.
_________________
GBAMP Multiboot
#89940 - Onions - Tue Jun 27, 2006 3:40 pm
I got the colors to seperate I think, by changing your defines to...
Code: |
#define RGB15R(rgb) (((rgb) ) )
#define RGB15G(rgb) (((rgb) >> 5) )
#define RGB15B(rgb) (((rgb) >> 10) )
|
Doing the following does change the color, although currently it's messed up. I'll keep looking into it though...
Code: |
int gamma = 50;
uint16 aRed = RGB15R(color);
uint16 aGreen = RGB15G(color);
uint16 aBlue = RGB15B(color);
uint16 bRed = RGB15R(color);
uint16 bGreen = RGB15G(color);
uint16 bBlue = RGB15B(color);
uint16 dstRed = aRed * gamma + bRed * (16 - gamma);
uint16 dstGreen = aBlue * gamma + bBlue * (16 - gamma);
uint16 dstBlue = aGreen * gamma + bGreen * (16 - gamma);
dstRed = dstRed / 16;
dstGreen = dstGreen / 16;
dstBlue = dstBlue / 16;
color = RGB15(dstRed, dstGreen, dstBlue);
*Camera_01[y * 40 + x] = color;
|
What value should gamma be giving? I think that's what's messing things up perhaps. Thanks.
#89945 - Mighty Max - Tue Jun 27, 2006 4:10 pm
Onions wrote: |
Code: |
int gamma = 50;
(...)
uint16 dstRed = aRed * gamma + bRed * (16 - gamma);
uint16 dstGreen = aBlue * gamma + bBlue * (16 - gamma);
uint16 dstBlue = aGreen * gamma + bGreen * (16 - gamma);
|
|
Gamma should be between 0 and 16.
_________________
GBAMP Multiboot
#89961 - tepples - Tue Jun 27, 2006 5:20 pm
Onions wrote: |
I got the colors to seperate I think, by changing your defines to...
Code: |
#define RGB15R(rgb) (((rgb) ) )
#define RGB15G(rgb) (((rgb) >> 5) )
#define RGB15B(rgb) (((rgb) >> 10) )
|
|
No, that returns the RGBA, GBA[1], and BA values, not the R, G, and B values. What you need is to define another macro RGBA15() and then use that instead of RGB15():
Code: |
#define RGBA15(r, g, b) ((RGB15(r, g, b)) | 0x8000) |
[1] Green, blue, alpha, not another handheld game system.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
Last edited by tepples on Wed Jun 28, 2006 1:47 am; edited 1 time in total
#89982 - Onions - Tue Jun 27, 2006 7:35 pm
Thanks Tepples, for sticking with me through what is probably a simple matter. I think I'm starting to understand it better now, though. The opacity seems to be working correctly, yet I'm currently having to manually type in the opacity value as an int type.
Since the opacity range is 0 - 16, I assume that's why it takes a u8 type as seen in the other poster's function. Can I use a grayscale image converted with pcx2tex as I've been doing and type cast it to u8 instead of u16 (or uint16) and it work correctly? Or is there something else I should do?
Also (out of curiosity), since each color had 5 bits to represent a color channel's range, and each bit can either be a 1 or 0 (since it's binary) what is the amount of possibilities for those 5 bits, or color channel?
And I'm sure there's a formula for reaching such odds or possibilties for values, so if you could tell me that too I'd appreciate it.
By the way, just so you'll know (if you don't already), I suck at math. I'm more of an artist than a programmer, but over the years I've learnt I've got to do it myself if I ever want to make a game.
So I appreciate you (and any others) trying to help me with even the simplest of things.
#89995 - tepples - Tue Jun 27, 2006 8:55 pm
A single bit can be either on (1) or off (0).
An n-bit field can represent any number from 0 to (1 << n)-1. In the case of a 5-bit field, this is 0 to (1 << 5)-1 = 0 to 32-1 = 0 to 31.
What's << ? It stands for shifting the number to the left. In general, a << b equals a times 2 to the nth power.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#90014 - Onions - Tue Jun 27, 2006 9:58 pm
Quote: |
In the case of a 5-bit field, this is 0 to (1 << 5)-1 = 0 to 32-1 = 0 to 31
|
Given your explanation of the procedure of what << does to the left and right values, I don't see how (1 << 5) can equel 32... can you break this down even further with an equation using these numbers as examples?
#90017 - dXtr - Tue Jun 27, 2006 10:08 pm
here we go:
Code: |
decimal | binary
1 | 00000001
now we shift left 5 times:
1 << 1 = 2 | 00000010
1 << 2 = 4 | 00000100
1 << 3 = 8 | 00001000
1 << 4 = 16 | 00010000
1 << 5 = 32 | 00100000 |
_________________
go back to coding and stop screaming wolf :)
#90128 - Onions - Wed Jun 28, 2006 3:20 pm
So then, it's not an actual mathematical method that determines this number, it's more of a set incremental process. One where each right value to the << operator means double the left that many times.
Why I didn't get how the value was determined is because I was taking both numbers and trying to get some sort of value from it based on an equation. Thanks.
#90138 - Dark Knight ez - Wed Jun 28, 2006 4:10 pm
Not mathematical? The implementation might not be according to you, but shifting to the left n times, would be the same as multiplying by (2 to the power n).
1 << 5 == 1 * (2^5) == 1 * 32 == 32
#90150 - Onions - Wed Jun 28, 2006 5:18 pm
Why it didn't seem mathematical to me is because I didn't see how 32 would come about from 1<<5.
When you say 2^5 (I assume 2 to the 5th power) I would think it equels 50, like so... 5x5 = 25, then 25 x 2 = 50. I couldn't figure out in any mathematical way (that I knew of) of how 32 was the answer.
Was I "squaring" and not putting it to the power of "nth"?
EDIT: Now I'm starting to remember what the "nth" power is...
lets say 3 to the 7th power, that would equel...
1. 3 + 3 = 6
2. 6 + 6 = 12
3. 12 + 12 = 24
4. 24 + 24 = 48
5. 48 + 48 = 96
6. 96 + 96 = 192
7. 192 + 192 = 384
... so 3^7 = 384, correct? (and of course, the above could have used x2, instead of n + n, which is how it's probably meant to be done)
#90152 - Dark Knight ez - Wed Jun 28, 2006 5:30 pm
2 the power of 5 == 2^5
which can be rewritten as: 1 * 2*2*2*2*2
note that 1 is multiplied 5 times by 2.
so 2^0 == 1
and 2^1 == 2
and 2^2 == 2*2 == 4
and 2^3 == 2*2*2 == 8
and 2^4 == 2*2*2*2 == 16
and 2^5 == 2*2*2*2*2 == 32
Basic math.
#90217 - tepples - Wed Jun 28, 2006 10:54 pm
(C) 1 << 5
= (BASIC) 2 ^ 5
= (English) 2 to the 5th power
= 2*2*2*2*2
= 32
(BASIC) 5 ^ 2
= (English) 5 to the 2nd power (or) 5 squared
= 5*5
= 25
(BASIC) 3 ^ 7
= (English) 3 to the 7th power
= 3*3*3*3*3*3*3
= 2187
(C) 3 << 7
= (BASIC) 3 * (2^7)
= (English) 3 times 2 to the 7th power
= 3 * (2*2*2*2*2*2*2)
= 384
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#90246 - Onions - Thu Jun 29, 2006 2:04 am
Alright, now I see. I was wondering what the use of << would be if ^ already does the same.
#90250 - tepples - Thu Jun 29, 2006 2:11 am
In C, in C++, and in Java, the ^ operator performs exclusive or, not exponentiation.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.