Archived

This topic is now archived and is closed to further replies.

eyesonly_d

Darkening the screen

Recommended Posts

I am using DirectDraw7 and I want to know how I could darken the screen. (Like at a pause screen) Using 256 colors I just modified the palette and went with it, but using 16bit color I am not sure how to go about this. I need to be able to do this both in exclusive mode and in window mode, but I can use two different routines if I need to. Any help, would be appritiated very much.

Share this post


Link to post
Share on other sites
Another way is to lock the back buffer, before flipping, and read in each pixel, break it down in to is RGB components and right shift(>>) by 2 or 3 to darken each colour, then recombine and put it back. It may sound slow, but if the game is paused and no other action or AI is going on, it should be fast. Here''s a sample:

//for clarity, here is the long way.
void DarkenColour(USHORT *colour) {
USHORT red=((*colour)>>11)&&0x1f;
USHORT green=((*colour)>>6)&&0x3f;
USHORT blue=(*colour)&&0x1f;
red=red>>3;
green=green>>3;
blue=blue>>3;
(*colour)=(red<<11) | (green<<6) | blue;
}

//this should be faster because it doesn''t declare three USHORTs
//also you could put this in code instead of calling a funciton
void DarkenColour(USHORT *colour) {
(*colour)=( ((((*colour)>>11)&&0x1f)>>3)<<11 ) | (((((*colour)>>6)&&0x3f)>>3)<<6) | ((*colour)&&0x1f)>>3;
}

With the AP''s method, it looks more like a semi-transparent screen as opposed to a darkening.

---
Make it work.
Make it right.
Make it fast.

Share this post


Link to post
Share on other sites
you dont read from VRAM and then change the contents per pixel every frame. WAY TOO SLOW!

the best method for this (in dx7) would be:
1. to blit the entire scene to a backbuffer in system memory.
2. darken the buffer. its really easy to just halve the brightness level quickly. or use a better method (just remeber it dont matter if its slow. now that you have the entire scene darkened.
3. now instead of redrawing the scene normally, you woudl just blit the darkened buffer, then blit any animated text or non darkened stuff on top of that. this will keep framerates stupid high and keep cpu usage very low.

also captain jester, ski is 100% correct since when darkening the screen you are just alphablending with a black source, (or vice versa). its a special case of alphablending. in fact your method is just like the aps method. there is no difference except the way the problem is being viewed. (ski is looking ta the more generic way since you can apply his method to d3d, opengl as well as 2d systems).

Askadar, you dont need to darken the scene every frame. since it is paused (which assumes nothing execpt maybe some overlayed text is animated). even then this method can be done in realtime at high res, as long as you got a fast video card iwth bandwidth to spare (agp is good). in fact this method is almost free and is like you are just copying the pixels.

again DONT READ FROM VRAM EVERY FRAME! AND DONT USE PERPIXEL FUNTIONS!

Captain jester, there is an error in your code, you only use a single & when dealing with the and operator. && is for logical and for if blocks. also for grn you only shift by 5 (the size of blue) not 6 (the size of grn).

optimized quick fade blending: (only use for darkening since thats all it will do). this does half fade, you may want more darkening, if so adjust the shifts and the & constants.

WARNING the next section is about 565 systems ONLY. you should be able to adjust this for 555 systems quite easily.
this of course is doing half fade darkening. i am sure you can figure out darker varitions if you need them.

*colour= ((*color)>>1)&0x7BEF; // nice, clean, and efficent
or captain jesters suggest fade amount (which i think is too much):
*colour= ((*color)>>3)&0x18E3; // nice, clean, and efficent

this works because you are shifting everything over (division) which darkens the colors correctly. the spillover problem is handled by using modified constant which represent the new max for each color section.

to solve for the constant.
take the original max for each color
0x1F // red 5bits
0x3F // green 6bits (565 system assumed), adjust for other systems
0x1F // blue 5bits

now those are the max bits per color. shift them to the proper locations and ADD them together and you should get 0xFFFF.
0x1F<<11 = 0xF800 // red in proper location
0x3F<<5 = 0x07E0 // grn in proper location
0x1F = 0x001F // blu in proper location

now add them and you should get 0xFFFF

now you can make your own constant for different levels of fade. just do the shift first to each individual color max, then shift to its proper place and add them all up.

this reduces the entire math to one shift and one AND per pixel.

Math is your friend. if done purly on system to system or system to VRAM (read from sys surface then write to VRAM surface) it is quite fast and can be done in realtime even at 800x600x16 on 400mhz (not sure how fast the framerate would be, but it should be pretty quick). but only if:

1. its not used as a per pixel function like captain jester suggests. a macro is ok.
2. you do not read and write to VRAM. it should either go sys to sys or sys to vid.



Share this post


Link to post
Share on other sites
quote:
Original post by a person
you dont read from VRAM and then change the contents per pixel every frame. WAY TOO SLOW!

the best method for this (in dx7) would be:
1. to blit the entire scene to a backbuffer in system memory.
2. darken the buffer. its really easy to just halve the brightness level quickly. or use a better method (just remeber it dont matter if its slow. now that you have the entire scene darkened.
3. now instead of redrawing the scene normally, you woudl just blit the darkened buffer, then blit any animated text or non darkened stuff on top of that. this will keep framerates stupid high and keep cpu usage very low.


As I said, use the back buffer. Although I did not specify to set it up in system memory. Thanks for pointing that out.

quote:

also captain jester, ski is 100% correct since when darkening the screen you are just alphablending with a black source, (or vice versa). its a special case of alphablending. in fact your method is just like the aps method. there is no difference except the way the problem is being viewed. (ski is looking ta the more generic way since you can apply his method to d3d, opengl as well as 2d systems).


Your right, I was thinking he meant something else.

quote:

again DONT READ FROM VRAM EVERY FRAME! AND DONT USE PERPIXEL FUNTIONS!


Although I forgot about the VRAM slow reads, you can update the darkened screen every frame as most of your loss of speed usually comes from everything non graphical, like AI, updating unit position, updating map position, etc... If you are in pause mode, nothing is going on except to draw the paused screen, which would be very fast, no matter how you do it.


quote:

Captain jester, there is an error in your code, you only use a single & when dealing with the and operator. && is for logical and for if blocks. also for grn you only shift by 5 (the size of blue) not 6 (the size of grn).


OOPS...

quote:

*colour= ((*color)>>1)&0x7BEF; // nice, clean, and efficent
or captain jesters suggest fade amount (which i think is too much):
*colour= ((*color)>>3)&0x18E3; // nice, clean, and efficent


Never even thought of that... thanks. I could use that in the future.

Sorry for all the mistakes in my code. Thanks to 'a person' for all the corrections.

---
Make it work.
Make it right.
Make it fast.

Edited by - CaptainJester on December 17, 2001 3:53:33 PM

Edited by - CaptainJester on December 17, 2001 3:53:47 PM

Share this post


Link to post
Share on other sites
quote:
Original post by Askadar
Nice idea, but try it in realtime in highres, have fun watching the 10 fps or so....


If the card supports 3D acceleration, you can use D3D7 to just draw an alpha-blended quad and it works quite well. I''ve done it and gotten quite decent speeds, though as it''s been pointed out, in this situation your frame rate isn''t important as long as it''s fast enough for a smooth fade. If you don''t care about a smooth fade to the pause, then it matters even less.


Stay Casual,

Ken
Drunken Hyena

Share this post


Link to post
Share on other sites
Cool! I think I know where to go from here (you guys are some mad coders, I cant ever see the level you are on) I''m gonna do some research on the Gamma RAMPS stuff and then try out the idea of creating a seperate ''pause'' surface that is faded. Thanks so much for all your help!

Share this post


Link to post
Share on other sites