VB:Tutorials:Generic information about RGB
From GPWiki
The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server. However, the GPWiki forums are still active! Come say hello.
[edit] Function: RGBHi there, Most of you allready know about RGB and what its all about. No? Shame on you... ;) RGB (Red Green Blue) is the color combination computers use, hence also us computer programmers. Most of you also know that VB offers very poor functions for handling colors. The best example for this is the RGB function: dim cRed as long cRed = RGB(255, 0, 0) 'eek! Anybody see anything wrong with this picture? Well, the code is solid, but the result is way off. Instead of getting the color "vbRed" we actualy get blue. The VB RGB function reverses the RGB input for some unknown reason, so to get red we have to turn everything upside-down: dim cRed as long cred = RGB(0, 0, 255) 'right! So, my advice to you who deal with RGB values (i know i do), here is an extremely simple function to avoid confusion: Function cRGB(R as Integer, G as Integer, B as Integer) as Long cRGB = RGB(B, G, R) End Function And so we get: dim cRed as long cRed = cRGB(255, 0, 0) 'right! [edit] Converting long colors to RGB valuesNow on to the next problem. VB dont have any built-in function to convert the RGB values back from a long value to 3 integers. Why? We dont know. But neverthenless its simple. The long colors are no unexplainable "voodoo mumbo-jumbo" and even if the value looks alien and unknown, it wont look that fancy when you know the math behind it. cRed = 200 cGreen = 120 cBlue = 35 cColor = cRGB(cRed, cGreen, cBlue) MsgBox cColor '13137955 Here is a typical RGB in a long value. Now, how to retrive the individual values? Well, we'll start by counting how many times "65536" fits in cColor (cRed = int(cColor / 65536)). That should give us the red segment. Now we take cColor - red segment multiplied by 65536 divided by 256 (cGreen = int(cRed * 65536) / 256) Then the rest is the blue segment. Hard nut to chew? Well, it also has its advantages. A single long value is smaller then 3 ints, so it cuts down size alot - specialy when dealing with larger images - then again it requires more speed if you need to retrive the individual values. Enough chatting, lets bring on a snippet to demonstrate - perhaps it will look clearer: shiftRed = 65536 'shiftGreen * shiftGreen (256*256) shiftGreen = 256 'max colors times max colors (256) cRed = 200 cGreen = 120 cBlue = 35 cColor = cRGB(cRed, cGreen, cBlue) msgbox ccolor 'the long color cRed = cint(cColor / shiftRed) cGreen = cint((cColor - cRed * shiftRed) / shiftGreen) cBlue = cColor - int(cRed * shiftRed) - int(cGreen * shiftGreen) msgbox "Red: " & cRed & vbcrlf & "Green: " & cGreen & vbcrlf & "Blue: " & cBlue [edit] Fine, so what do we do with this?Just like turning radians to degrees, we convert long colors to RGB when we need a human readable conversion for manipulating the result. (phew) An example is when you need to blend 2 colors in DirectDraw. Some say it cant be done (bah), others say that the answer is to make a DD/D3D hybrid engine. Well, you can belive what you want to belive - but myself i need to create "shadows" in my C&C clone, so we'l use this as an example. const shadow = 0.65 'lets darken the src by 35% srcColor = point(x, y) srcRed = cint(srcColor / shiftRed) srcGreen = cint((srcColor - srcRed * shiftRed) / shiftGreen) srcBlue = srcColor - int(srcRed * shiftRed) - int(srcGreen * shiftGreen) destColor = cRGB(int(srcRed * shadow), int(srcGreen * shadow), int(srcBlue * shadow)) pset(x, y), destColor [edit] What about alpha blending?I know for a fact that people have problems with alpha blending. Using OpenGL in C its easy enough by just 2-3 lines of code to enable just about any kind of blending - since the blending functions are integrated - but in VB we have to come up with the formula on our own... As we see; finalrgb = a*rgb1 + (1-a)rgb2 Another way to describe the formula is: (taken from wikipedia) Value = Value0(1.0 - Alpha) + Value1(Alpha) This will be slower to do pixel per pixel compared to doing it with alpha quads in a hybrid engine - but the advantage is in detail. We can now very precisely per pixel alpha small segments of images. [edit] OptimizeOur main problem (as always) is speed. The more calculations the lesser speed we have left. I heard some discussion about wether the FPS matters or not, well - if you have a amd64x2 4600+ system and run your game at a "floating" 35 fps - how well do you think it will be running on lesser systems? The first thing id like to point out is not to use VB's builtin point/pset as used in the sample above - but to use DXDD or some similar graphical acceleration. Another tip is to use the byte type for defining individual RGB colors, since they cant go over the value 255 anyway. As a rule - dont pixel-per-pixel plot more than is needed, dxdd7 blt's way faster. Also you should find some more optimized way to retrive the RGB values of long colors, prefferably as a function for reuseability. The above sources are not optimized, but just to basicly show the works. [edit] Sample projectI prepared a demonstration source of alpha blending - i know a few people will thank me for it :-)
[edit] CreditsHope this were interesting :-) Written by: Darksnow 15:06, 22 April 2006 (EDT) |



