NewGFX company colour overlays (and shadows)

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

bobingabout wrote:although i get what you trying to do with the +(255-CR-CG-CB)*BR)/255, i feel that simply *BR/255 would give a cleaner result. but feel free to try either method.
you do realise that the +(255-CR-CG-CB)*BR)/255 is what adds the base colour into it don't you? without it it blends the company colour with the base, but doesn't put the remainder (any company colour not used) as base, it leaves it black.
Your code seems to use just the company colour (* the base) if the total company colour amount is more than 127, but this would make it very dark for a value of 128, because the result could never be more than 128. in reality it should add on 127*base/255 to brighten it up, after all, the company colour map doesn't control the shading.

Plus my code's shorter.

EDIT: oh, and after untangling my edits in the previous post, this is the formulas I was trying to give:
RR=min(255,((CR*C1R+CG*C2R+CB*C3R)*BR)/255/255+max(0,255-CR-CG-CB)*BR/255);
RG=min(255,((CR*C1G+CG*C2G+CB*C3G)*BG)/255/255+max(0,255-CR-CG-CB)*BG/255);
RB=min(255,((CR*C1B+CG*C2B+CB*C3B)*BB)/255/255+max(0,255-CR-CG-CB)*BB/255);

explained:
(CR*C1R+CG*C2R+CB*C3R) multiplies the red channel of each company colour by the company colour map, to get the final company colour for that pixel
/255 to put it back into the range 0-255 instead of 0-65535 (255*255)
*BR/255 to blend with the base colour to add shading
+max(0,255-CR-CG-CB)*BG/255:
255-CR-CG-CB takes the remainder (amount not used in the company colour map)
max(0,255-CR-CG-CB) means that if it goes below 0 it uses 0
*BG/255 multiplies the remainder by the base colour to keep it bright enough. (so company colour map total of 128 (or some other number not 255) at the edge of a region of company colour doesn't darken.)
min(255, ...) means that the result can't go over 255.
(yes I know min and max seem to work backward, but min(255, ... ) takes the smaller number out of 255 and the formula result, meaning that if it goes over 255 it uses 255.)

they can be simplified to the following, but they don't make sense to read:
RR=min(255,((CR*C1R+CG*C2R+CB*C3R)/255+max(0,255-CR-CG-CB))*BR/255);
RG=min(255,((CR*C1G+CG*C2G+CB*C3G)/255+max(0,255-CR-CG-CB))*BG/255);
RB=min(255,((CR*C1B+CG*C2B+CB*C3B)/255+max(0,255-CR-CG-CB))*BB/255);
Last edited by Thief^ on 07 Jul 2005 11:30, edited 1 time in total.
Melt with the Shadows,
Embrace your destiny...
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

yes, i realise that, like i said, best to actually test it...

what would be ideal is if the overlay determined the amount of colour, and the base determined the brightness, your way doesn't apear to do the brightness correctly, but as you say, neither does mine.

i think what is needed is a combination between both of ours.


if (RR+RG+RB>127)
{
if (RR+RG+RB>255)
{
NRR=RR*255/(RR+RG+RB);
NRG=RG*255/(RR+RG+RB);
NRB=RB*255/(RR+RG+RB);
}
else
{
NRR=RR;
NRG=RG;
NRB=RB;
}

R= (CC1R*NRR/255 + CC2R*NRG/255 + CC3R*NRB/255 + (255-CR-CG-CB)*BR/255) *((BR+BG+BB)/765);//765=3*255
G= (CC1G*NRR/255 + CC2G*NRG/255 + CC3G*NRB/255 + (255-CR-CG-CB)*BG/255) *((BR+BG+BB)/765);
B= (CC1B*NRR/255 + CC2B*NRG/255 + CC3B*NRB/255 + (255-CR-CG-CB)*BB/255) *((BR+BG+BB)/765);

if (R>255) R=255;
if (G>255) G=255;
if (B>255) B=255;
}
else
{
R=BR;
G=GR;
B=BR;
}


this way:
"CC1R*NRR/255 + CC2R*NRG/255 + CC3R*NRB/255" gets the company colour
"(255-CR-CG-CB)*BR/255" adds the base colour affsets
and "*((BR+BG+BB)/765)" multiplies by the base to give a final brightness.

imo, this is still wrong. if the overlay colour is 255, then "(255-CR-CG-CB)*BR/255" will have no effect, hence the need for the brighness control of "*((BR+BG+BB)/765)"
but also, if there is a difference, and the base image is considerable darker in parts, doing "*((BR+BG+BB)/765)" will likely increase the effect, making the darker parts too dark.

what we need is further thought, its getting very close.
Last edited by bobingabout on 07 Jul 2005 11:40, edited 1 time in total.
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

I think that should be:
R= (CC1R*NRR/255 + CC2R*NRG/255 + CC3R*NRB/255) *(BR+BG+BB)/765 + (255-CR-CG-CB)*BR/255;
otherwise you're multiplying the base part by the base intensity.
Also, don't bother rescalining the company map total (RR,RG,RB on yours) if it goes over 255 because the difference will be so slight, (it'll only go over 257 if somone does it on perpose (spell?), and the differnce between 255 and 257 is undetectable. Just cap the result (R,G,B) at 255 instead.

In other words:
if (RR+RG+RB>0)
{

R= min(255,(CC1R*RR/255 + CC2R*RG/255 + CC3R*RB/255) *(BR+BG+BB)/765 + max(0,(255-CR-CG-CB))*BR/255); //765=3*255
G= min(255,(CC1G*RR/255 + CC2G*RG/255 + CC3G*RB/255) *(BR+BG+BB)/765 + max(0,(255-CR-CG-CB))*BG/255);
B= min(255,(CC1B*RR/255 + CC2B*RG/255 + CC3B*RB/255) *(BR+BG+BB)/765 + max(0,(255-CR-CG-CB))*BB/255);

else
{
R=BR;
G=GR;
B=BR;
}

of course, if the base image is monochrome, then there's no need to do (BR+BG+BB)/765, just BR/255 is fine.
Last edited by Thief^ on 07 Jul 2005 11:47, edited 1 time in total.
Melt with the Shadows,
Embrace your destiny...
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

Thief^ wrote:I think that should be:
R= (CC1R*NRR/255 + CC2R*NRG/255 + CC3R*NRB/255) *(BR+BG+BB)/765 + (255-CR-CG-CB)*BR/255;
otherwise you're multiplying the base part by the base intensity.
i think i agree
Thief^ wrote:Also, don't bother rescalining the company map total (RR,RG,RB on yours) if it goes over 255 because the difference will be so slight, (it'll only go over 257 if somone does it on perpose (spell?), and the differnce between 255 and 257 is undetectable. Just cap the result (R,G,B) at 255 instead.
you would be assuming people follow the rules. I'm assuming they aren't going to. what if someone actually did R=255 G=127 B=191 because they didn't use the same program as Alltaken and didn't follow the "R+G+B<=255" rule. (either not knowing it, or not caring)
but that last if block could be replaced by a limiting command, i just don't know how to use the limiting commands.)
Thief^ wrote:of course, if the base image is monochrome, then there's no need to do (BR+BG+BB)/765, just BR/255 is fine.
well, the "+ (255-CR-CG-CB)*BR/255" part is assuming its not monochrome, so why should the "*(BR+BG+BB)/765" part assume that it is?
Last edited by bobingabout on 07 Jul 2005 19:42, edited 2 times in total.
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

my point is if they draw the company colour map using only solid red (255,0,0) green (0,255,0) or blue (0,0,255), then it's imposible for a program to put the total at more than 255 (give or take a few for innaccuracy).

If they use a wierd colour the result is their fault, it's not worth slowing the renderer down for. (remember this function is called some 1,000,000 times a frame (worst case))
Melt with the Shadows,
Embrace your destiny...
Alltaken
Tycoon
Tycoon
Posts: 1285
Joined: 03 Dec 2003 06:24
Location: Christchurch, New Zealand
Contact:

Post by Alltaken »

Well after talking to Tron. any kind of multiplication.... would be pretty much out of the question (in terms of CPU usage)

so to overcome this i have come to the comprimise with him.

i will provide him GFX similar to what i have stated now, however their brightness... will be somehow precalculated against the base sprite, to determine the intensity of the company colour.

his patch will then (pre game i presume) load the sprite do the calculations store it as a 10bit colour 6bit alpha image and put this against a colour table (with company colours listed)

the game then does a lookup on the lookup tables for every pixel, and substitutes it in.

it effectivly rules out two things in the game. one is colour gradients i.e. from red-yellow on the side of a building for example. (unless its hard rendered in, or a colour lookup table is done especially for gradients or somthing) and the other is each pixel would onyl be able to be the colour of the company colour (except for alpha show through).

so its all a comprimise on all sides. from coders perspectives and GFX perspectives.

till the GPU is used (hint hint...flamewar :P ) i doubt we can do it like this.

although the method worked well in PS, i don't think its going to be doable CPU wise.

Alltaken
User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

I bet it's fine. Want a demo?
Though it could do with some pre-calculation, like using floats so /255 isn't needed, and pre-storing (255-CR-CG-CB). We'll see won't we?

EDIT: wait, did you just say it would be 10-bit colour? why not use full 32-bit?

EDIT2: perhaps it render the sprites (inc company colour) whenever you change your colour(s)?would save even a lookup table.
Melt with the Shadows,
Embrace your destiny...
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

imo, couldn't you simply render every frame of every vehicle and store it in RAM(you could even export it to a temp PNG file if you wanted to save RAM), then look up the already calculated sprite when you want to display it.

this process would have to be done every time you created a company or changed company colours though...

you could do it as and when vehicles became available.

EDIT: without multiplying, theres not much you can do... think of a way to check if the company colour layer is red without multiplying the red componant by the company colour/255. it would have to use an if block instead, which would most likely take as long as a multiplication. if i remember correctly, an if takes 2 instruction cycles, a comparison, and a jump.
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
CobraA1
Route Supervisor
Route Supervisor
Posts: 480
Joined: 07 Nov 2003 17:52
Location: USA

Post by CobraA1 »

Don't depend on processors to take a certain number of cycles to do anything - after all, processor architectures vary a lot. AMD vs Intel, even older chips vs newer chips. Toss stuff like out-of-order execution, superscaler computing, pipelining, and microcode into the mix, and things get messy very quickly . . .

I say on older video cards, go ahead and pre-compute the sprites so they needn't be re-computed every frame.

On newer cards, take advantage of the extra features such as pixel shaders and video memory.
"If a man does not keep pace with his companions, perhaps it is because he hears a different drummer. Let him step to the music he hears, however measured or far away" --Henry David Thoreau
Alltaken
Tycoon
Tycoon
Posts: 1285
Joined: 03 Dec 2003 06:24
Location: Christchurch, New Zealand
Contact:

Post by Alltaken »

CobraA1 wrote:I say on older video cards, go ahead and pre-compute the sprites so they needn't be re-computed every frame.

On newer cards, take advantage of the extra features such as pixel shaders and video memory.
OTTD uses 100% CPU power on ALL computers. we have no GPU usage at all even on the latest equiptment.

unless of course you want to code OpenGL into the source.

Alltaken
Last edited by Alltaken on 08 Jul 2005 04:35, edited 1 time in total.
CobraA1
Route Supervisor
Route Supervisor
Posts: 480
Joined: 07 Nov 2003 17:52
Location: USA

Post by CobraA1 »

Well, using OpenGL would be ideal, but probably too complex :(.

Oh well, I can dream, can't I? :)
"If a man does not keep pace with his companions, perhaps it is because he hears a different drummer. Let him step to the music he hears, however measured or far away" --Henry David Thoreau
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

also, doesn't openGL not suport duel monitors?

duel monitor suport is something a few of us are hoping for. dragging and extra veiwport out of the game and onto a different screen...
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

Alltaken wrote:OTTD uses 100% CPU power on ALL computers. we have no GPU usage at all even on the latest equiptment.

unless of course you want to code OpenGL into the source.

Alltaken
On my machine openttd rarely registers on cpu usage. And it's only a athlon64 3000, hardly a beast machine.
Melt with the Shadows,
Embrace your destiny...
Mek
TTDPatch Developer
TTDPatch Developer
Posts: 417
Joined: 13 Apr 2004 13:35
Location: Eindhoven, Netherlands
Contact:

Post by Mek »

Thief^ wrote:
Alltaken wrote:OTTD uses 100% CPU power on ALL computers. we have no GPU usage at all even on the latest equiptment.

unless of course you want to code OpenGL into the source.

Alltaken
On my machine openttd rarely registers on cpu usage. And it's only a athlon64 3000, hardly a beast machine.
what alltaken was trying to say is that openttd uses only CPU power, not that it uses all cpu power available
User avatar
Thief^
Route Supervisor
Route Supervisor
Posts: 469
Joined: 10 Oct 2004 00:11

Post by Thief^ »

I see. I feel stupid now.
There are so many games out there though that insist on using 100% of the cpu, running at stupid numbers like 250fps, I thought he meant that openttd was one of those.
Melt with the Shadows,
Embrace your destiny...
}T{Reme [Q_G]
Route Supervisor
Route Supervisor
Posts: 389
Joined: 04 Feb 2004 23:24
Contact:

Post by }T{Reme [Q_G] »

CobraA1 wrote:Splitting up a color range to use it for something it's not designed for is, IMHO, not a good idea. We want to make things easier, not more difficult.
Well its not really designed for it true... but the only thing the PNG encoder would see is a really funky image... its lossless so it will never create any artefacts like for example jpeg would if you for example only use the chroma or luma channel. It should make zero difference. My main concern lies with all these heavy calculations everyone is writing. Do remember that would have to be done for ALL pixels in ALL graphics... that amount goes up really really REALLY fast.

Also as far as I can tell none of you have ever written a game... you do NOT want to do all these calculations "on the fly" while you are running the game. It will severely strain the CPU. Pre-computing all the images will be required, not optional if you plan to actually make it playable. Also if you still insist on all the messy calculations. I suggest to use bitshifting and masking. Its FAR faster than multiplying and dividing. If you do it in a smart way, you can actually compute all 3 RGB channels at the same time with just one opcode (Hint : you can stuff 4 bytes in a 32 bit register). MMX code will also allow you to compute RGB values faster.

(Excluding bobingabout and CobraAI as he knows what Im talking about)



OpenGL indeed supports dualhead, however I'm not sure if it will be effective enough in a 2d tile game. Its not designed for such a thing.

Games regularly use the maximum amount of CPU power available. The main reason behind this is generally physics and smooth graphics. Animation and movement is calculated in steps. The smaller these steps, the fewer glitches will occur. Second reason would be for the power-hungry, people love to show off how many frames they can pump out every second. Third reason would lie with the windows CPU scheduler... its as dumb as the back end of a horse (especially older versions of windows) and basically the only reason to effectively cancel out stuttering or sudden slowdowns is to demand all processing power.

250fps isnt that stupid really... wait till you see values of 60.000 and higher.
Siggy not gonna work unless someone allows javascripting...
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

you only really need 100fps, infact, only 50fps could do the job... but not very well.

bit manipulation! why didn't i think of that, I've been too engrosed in maths, that i forgot my digital electronics... for a true and false of 0 or 255, it would be perfect, not sure how well it would work with non-0/255 values though...

i still think the best thing would be to cache all remapable sprites (vehicles industires, fences and stuff) to either a file or RAM, or use something of the graphics processor, even simply using some graphics RAM would be fine.
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: No registered users and 13 guests