Game Development Community

Colour Filter Effect (Night Vision / Colourization)

by Melv May · 02/24/2002 (11:23 am) · 9 comments

Download Code File

Hi Folks,

In an effort to put a few things back into the forum, I thought I would post this simple code snippet which I find useful for all sorts of effects.

Essentially, all I'm doing is using a GUI control to draw a coloured rectangle over the HUD. You can control the filter colour from the editor or script.

The neat bit is the colour mask which uses 'glColorMask' to mask drawing to certain colour channels.

Don't forget to name the HUD element, something like "gFilter1".

You can then use "gFilter1.setFilterColor(red,green,blue,optional)" to set the filter colour.

You can also use "gFilter1.setFilterMask(true,false,true)" to set the RGB filter mask.

The RGB Mask allow you to control exactly which channels will be affected by the overlay effect.

As an example, create three of these controls. Set all with a filter colour of "1,1,1,1" but set the first to mask only red, the second to only green and the third to blue. Now if you position the controls so that they overlay each other slightly you shold see the effect more clearly.

I use it to fade regions of the HUD in/out and other effects. I have another version which uses a texture overlay.

Hope you find it useful. :)

Melv.

// *************************************************************************

Copy the following code into a .cc file and simply add to the engine project. Goto the GUI editor and add a 'GuiFilter' onto your HUD. Use a combination of colours/masks to get the effect you want.

Don't forget that you can change the order of drawing of HUD elements by moving items to the front/back. This means that you can limit the effect to non-hud elements or not!


#include "dgl/dgl.h"
#include "gui/guiControl.h"
#include "console/consoleTypes.h"

class GuiFilter : public GuiControl
{
typedef GuiControl Parent;

ColorF mFilterColor;
bool mMaskRed;
bool mMaskGreen;
bool mMaskBlue;

public:
GuiFilter();

void onRender( Point2I, const RectI &);
static void initPersistFields();

void setFilterColor(ColorF FilterColor);
void setFilterMask(bool RedMask, bool GreenMask, bool BlueMask);

DECLARE_CONOBJECT( GuiFilter );
};

// *************************************************************************

IMPLEMENT_CONOBJECT( GuiFilter );

// *************************************************************************

GuiFilter::GuiFilter()
{
mFilterColor.set(0, 0, 0, 1);

mMaskRed = GL_TRUE;
mMaskGreen = GL_FALSE;
mMaskBlue = GL_TRUE;
}

// *************************************************************************

void GuiFilter::initPersistFields()
{
Parent::initPersistFields();

addField( "FilterColor", TypeColorF, Offset( mFilterColor, GuiFilter ) );
addField( "MaskRed", TypeBool, Offset( mMaskRed, GuiFilter ) );
addField( "MaskGreen", TypeBool, Offset( mMaskGreen, GuiFilter ) );
addField( "MaskBlue", TypeBool, Offset( mMaskBlue, GuiFilter ) );
}

// *************************************************************************

void GuiFilter::onRender(Point2I offset, const RectI &updateRect)
{
glColorMask(mMaskRed, mMaskGreen, mMaskBlue, GL_TRUE);

dglDrawRectFill(updateRect, mFilterColor);

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}

// *************************************************************************

void GuiFilter::setFilterColor(ColorF FilterColor)
{
mFilterColor = FilterColor;
}

// *************************************************************************

void GuiFilter::setFilterMask(bool RedMask, bool GreenMask, bool BlueMask)
{
mMaskRed = RedMask;
mMaskGreen = GreenMask;
mMaskBlue = BlueMask;
}

// *************************************************************************

ConsoleMethod(GuiFilter,setFilterColor,void,5,6,"Sets Filter Color.")
{
F32 r,g,b,a;
ColorF TempColor;

GuiFilter *Filter = static_cast(object);

r = dAtof(argv[2]);
g = dAtof(argv[3]);
b = dAtof(argv[4]);

if (argc == 6)
a = dAtof(argv[5]);
else
a = 1;

TempColor.set(r,g,b,a);

Filter->setFilterColor(TempColor);
}


// *************************************************************************

ConsoleMethod(GuiFilter,setFilterMask,void,5,5,"Sets Filter Masks.")
{
F32 r,g,b;

GuiFilter *Filter = static_cast(object);

r = dAtof(argv[2]);
g = dAtof(argv[3]);
b = dAtof(argv[4]);

Filter->setFilterMask(r,g,b);
}

#1
02/24/2002 (1:56 pm)
I just tested this compared to the process I'm using and it is killing performance.

Full screen, I ended up losing about 85% framerate.

I'm going to continue working with mine, and hopefully the performance problems I'm having (loss of about 30% framerate) are just due to my crappy computer and video card.
#2
02/24/2002 (2:15 pm)
Sorry to hear that Matt but like I said, I'm not using it for the Night-Vision effect, I'm using it for colourisation effects on smaller areas.

On my card, fullscreen, I only drop a handful of frames. I've got a Elsa Gloria III DCC (geForce3) which is a powerful card though.

Melv.
#3
02/24/2002 (5:33 pm)
Yeah, on small areas the framerate loss is minimal. So if there's something (which I can't think of a use) that only needs a small amount of colorization then this should work just fine. Interesting.
#4
02/24/2002 (10:32 pm)
I'll have a think about your Night-Vision problem and see if there is a better/quicker way to do it.

I'm still suprised by the framerate loss, 85% is quite drastic. I had six of these suckers running will no appreciable loss in FPS!

I'm gonna try it out @ work today on a few 'lesser' cards like geForce2, Rage128 etc.

I'll let you know what happens and see if I can come up with an improved solution for you.
#5
02/25/2002 (8:51 am)
Matt,
I tried this on a couple of different cards and there was only a minor performance drop.

Were you simply overlaying the HUD with this control only? What res were you trying it at? Did you try it at 24/32bpp, perhaps you're getting poor performance if you're running in 16bpp?

Let me know because I would like to help.

I added the following code to the "GuiFilter::onRender" function to show me the FPS as I dragged it around. I am loosing around 4-6 fps @ 800x600x32bpp with fullscreen coverage.

ColorF mTextColor(255,255,255);
char buf[256];
dSprintf(buf, sizeof(buf), "FPS: %04f", dAtof(Con::getVariable("fps::virtual")));
dglSetBitmapModulation(mTextColor);
dglDrawText(mProfile->mFont, offset, buf);
dglClearBitmapModulation();

Hope this helps.
#6
02/25/2002 (5:20 pm)
Alright, I just sent this over to a team mate with geforce 3 card and he got similar performance as you.

I'm running on a junk video card (DirectX config thinks i have 2.5 memory on it!) so performance slowdown is multiplied.

I currently have an alternative (only color masks, no filters) that has a much better performance. I'll show it off as soon as I get decent images for what I'm doing. It looks nice, but I guess it's just my video card that are making things seem worse than they really are.
#7
02/03/2003 (11:07 am)
I tried to use the filter to create fade effect but the alpha didn't seem to make any difference.

I noticed the latest Realm Wars has nice fade effect, but with diffenrent code. Its incorporated into canvas object rather than having a seperate control. Is it any better ?

Could you please publish the code for the filter used in RW ?
#8
02/04/2003 (8:59 am)
Melv,

In the HEAD release there is a guiFilter class, but it has completely different functionality. This is rather confusing, and I can't figure out which one (and how)to use.

Could you explain?
#9
03/03/2006 (9:15 pm)
So has anyone used this resource with TGE 1.4? And does it still take a big hit on FPS?