A simple, robust and extendible postprocessing class

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

New version

Should fix Murloc992's problem - it now tests the version of irrlicht and uses unsigned dimensions in Irrlicht 1.6, which should avoid the conversions it's failing to do.
(This looks like a bug with the dimension2d<s32>=dimension2d<u32> code in the new Irrlicht)

I also added more effects;

* PP_SHARPEN (and PP_HSHARPEN, PP_VSHARPEN)
* PP_POSTERIZE
* PP_WATERCOLOR (doesn't look much like a real watercolour, but it's a start)
* PP_PURENOISE (=PP_NOISE but ignores input - acts as a generator)

There's a new feature too; setFixed( true ); will make the effect render once, then remain static unless preRender is called, or setFixed( false ) is called. This is mainly for PP_PURENOISE to allow a static noise texture to be generated, but could be used with any effect.

Adler1337; well they're not really implemented, that's just me saying how I would approach them with the shaders that are already made. I'm sure the real ones are doing more complex things, but without access to the code I can't be sure what.
Murloc992
Posts: 272
Joined: Mon Apr 13, 2009 2:45 pm
Location: Utena,Lithuania

Post by Murloc992 »

DavidJE13 wrote:New version

Should fix Murloc992's problem - it now tests the version of irrlicht and uses unsigned dimensions in Irrlicht 1.6, which should avoid the conversions it's failing to do.
(This looks like a bug with the dimension2d<s32>=dimension2d<u32> code in the new Irrlicht)
Thanks.

First I got errors from compiling, same errors, but I have changed some bits, so now it is pure success!

The bits I have changed:

Code: Select all

dimension2d<s32> to dimension2d<u32>

Main.cpp/Device Creation

int main( ) {
	// Boring stuff: set up the scene, object & camera as usual
	IrrlichtDevice* device = createDevice( DRIVER, dimension2d<u32>( 640, 480 ), 16, false, false, false, 0 );

dimension2di to dimension2du

lines 72 and 75 in Main.cpp

IPostProc* ppRenderer = new CRendererPostProc( smgr, dimension2du( 1024, 512 ), true, true, SColor( 255u, 100u, 101u, 140u ) ); //still as I see SColor is used by with unsigneds

CEffectPostProc* ppBlur = new CEffectPostProc( ppRenderer, dimension2du( 1024, 512 ), PP_BLUR, 0.01f );

Still, will be trying to get it to work after school, or earlier. Who knows :D

Still, big thanks for this :)

EDIT:

Works like a charm...

Image
(Invert+Blur)

Still, it's kinda annoying to change ALL bits <s32> to u32 and 2di to 2du, but it is pure awesome so I don't mind :D
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

ah yes, forgot to change main.cpp. Glad it's working now :)
(I've added the fix, will be in the next version)

I've looked at Ogre's postprocessing. There isn't much that isn't already here in some form, though I added a new type of bloom from it (just uses a slightly different formula to find bright spots, but no variable threshold). There are a few other things I'd like to add, like heat vision and halftone but they need special textures and I don't have a way to add reference textures elegantly yet.

In other news, depth of field has finally been converted to Direct3D - again will be in the next release. Just Haze to go now (and water but that's currently quite crappy anyway)
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

well they're not really implemented, that's just me saying how I would approach them with the shaders that are already made. I'm sure the real ones are doing more complex things, but without access to the code I can't be sure what.
Yeah, I have been testing them and they don't look quite the same.
Maybe this helps with the pen and ink effect.
multum in parvo
Murloc992
Posts: 272
Joined: Mon Apr 13, 2009 2:45 pm
Location: Utena,Lithuania

Post by Murloc992 »

Damn, I am error attractor. If Im trying to include any kind of post procesing in other class it keeps spitting me this kind errors:

Code: Select all

1>MenuState.obj : error LNK2019: unresolved external symbol "public: __thiscall CRendererPostProc::CRendererPostProc(class irr::scene::ISceneManager *,class irr::core::dimension2d<unsigned int>,bool,bool,class irr::video::SColor)" (??0CRendererPostProc@@QAE@PAVISceneManager@scene@irr@@V?$dimension2d@I@core@3@_N2VSColor@video@3@@Z) referenced in function "public: virtual void __thiscall MenuState::init(void)" (?init@MenuState@@UAEXXZ)
1>E:\Andriaus\CPP Projektai\Unnamed\Debug\Unnamed.exe : fatal error LNK1120: 1 unresolved externals
And how I am making it?

In MenuState class's header there is only IPostProc*ppRender which is defined in cpp file like in examples(using new). Just a copy paste, which won't work :(

Give me a hand, please.

EDIT: It won't work anywhere but in the main.cpp of example :o
EDIT2: Yes, I am including the headers.
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

it seems like you didnt add the cpp files from the wrapper into your project, the compiler cannot find the ACTUAL function, not just the declaration of it in the header
Murloc992
Posts: 272
Joined: Mon Apr 13, 2009 2:45 pm
Location: Utena,Lithuania

Post by Murloc992 »

FuzzYspo0N wrote:it seems like you didnt add the cpp files from the wrapper into your project, the compiler cannot find the ACTUAL function, not just the declaration of it in the header
Isn't it enough to add the source in include paths? :)

Going to try direct adding stuff into project. :wink:

EDIT: Yup, it is working, thanks :)
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

This depends on how your compiler works, on the setting chosen, of whether you include the cpp in the h/hpp at the end, etc. There's many way to include code, do none and the code isn't found; do 2 and you'll have competition of which is the real one (unless your compiler has settings to prefer one over another), do one and you still must be careful. This is our wonderful profession ^^
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

Direct (a way of getting anti-aliasing - combine these to get 2x, 4x, 8x, etc.)
I have been trying to get antialiasing in my game using the above ^
This is what i have tried:

Code: Select all

IPostProc* ppRenderer = new CRendererPostProc(smgr, dimension2d<u32>( 1024, 512 ), true, true, SColor( 255, 100, 101, 140 ));
 CEffectPostProc* ppDirect1X = new CEffectPostProc(ppRenderer, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect2X = new CEffectPostProc(ppDirect1X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect3X = new CEffectPostProc(ppDirect2X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect4X = new CEffectPostProc(ppDirect3X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect5X = new CEffectPostProc(ppDirect4X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect6X = new CEffectPostProc(ppDirect5X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect7X = new CEffectPostProc(ppDirect6X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
	CEffectPostProc* ppDirect8X = new CEffectPostProc(ppDirect7X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
I'm not sure if i am doing this right. I don't get any errors, but i don't notice any difference between the different levels of antialiasing and no antialiasing. Any ideas?

btw What exactly does PP_DIRECT do?
multum in parvo
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

hi

ok, didn't explain that very well. direct just copies from one texture to another, and because graphics cards apply 2x2 anti-aliasing by default, you can chain them to get high levels of anti-alias.

Note this will be slow for high levels, because it needs large renders and big textures.

For 8x8 anti-aliasing with a screen size of ~ 1024x512:

Code: Select all

IPostProc* ppRenderer = new CRendererPostProc(smgr, dimension2d<u32>( 8192, 4096 ), true, true, SColor( 255, 100, 101, 140 ));
CEffectPostProc* ppDirect4X = new CEffectPostProc(ppRenderer, dimension2d<u32>( 4096, 2048 ), PP_DIRECT);
CEffectPostProc* ppDirect2X = new CEffectPostProc(ppDirect4X, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
CEffectPostProc* ppDirect1X = new CEffectPostProc(ppDirect2X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
Notice that the render is now to a texture of size 8192x4096! This will be slow on most cards, and some can't cope with textures that big at all, so I'd recommend using 4x anti-aliasing (this is usually the top-notch highest allowed anti-aliasing in commercial games);

Code: Select all

IPostProc* ppRenderer = new CRendererPostProc(smgr, dimension2d<u32>( 4096, 2048 ), true, true, SColor( 255, 100, 101, 140 ));
CEffectPostProc* ppDirect2X = new CEffectPostProc(ppRenderer, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
CEffectPostProc* ppDirect1X = new CEffectPostProc(ppDirect2X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
even lower levels are usually acceptable, and certainly 2x will look professional enough.

I'll also note that I'm in the process of re-writing this from scratch, with a new more efficient method and more flexible (not to mention tidier) design - hence the recent quietness on this version. I'll include a built-in anti-aliasing node with it. Should be done in a couple of weeks.
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

Thanks, this helps a lot :D
multum in parvo
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

ok, well i finally got around to testing the code you posted. This is what my code looks like now:

Code: Select all

//____________________________________8X___________________________________________________________________________________
    IPostProc* ppRenderer8X = new CRendererPostProc(smgr, dimension2d<u32>( 8192, 4096 ), true, true, SColor( 255, 100, 101, 140 ));
    CEffectPostProc* ppDirect4X8 = new CEffectPostProc(ppRenderer8X, dimension2d<u32>( 4096, 2048 ), PP_DIRECT);
    CEffectPostProc* ppDirect2X8 = new CEffectPostProc(ppDirect4X8, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
    CEffectPostProc* ppDirect1X8 = new CEffectPostProc(ppDirect2X8, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
//____________________________________4X___________________________________________________________________________________
	IPostProc* ppRenderer4X = new CRendererPostProc(smgr, dimension2d<u32>( 4096, 2048 ), true, true, SColor( 255, 100, 101, 140 ));
    CEffectPostProc* ppDirect2X4 = new CEffectPostProc(ppRenderer4X, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
    CEffectPostProc* ppDirect1X4 = new CEffectPostProc(ppDirect2X4, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
//____________________________________2X___________________________________________________________________________________
	IPostProc* ppRenderer2X = new CRendererPostProc(smgr, dimension2d<u32>( 2048, 1024 ), true, true, SColor( 255, 100, 101, 140 ));
    CEffectPostProc* ppDirect1X2 = new CEffectPostProc(ppRenderer2X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);

	while(device->run())
	{
		if(paused == false)
		{
	
            if(antialiasing == 0)
            {
                driver->beginScene(true, true, SColor(255,100,101,140));
            }
            else
            {
                driver->beginScene(false, driver->getDriverType() == EDT_OPENGL);
            }

            if(antialiasing == 0)
            {
                smgr->drawAll();
            }
            else if(antialiasing == 2)
            {
                ppDirect1X2->render(NULL);
            }
            else if(antialiasing == 4)
            {
                ppDirect1X4->render(NULL);
            }
            else if(antialiasing == 8)
            {
                ppDirect1X8->render(NULL);
            }
			driver->endScene();
		}
	}
I am giving the user the option of choosing between none, 2x, 4x, and 8x. Everything compiles fine, but when i run it, it crashes and shows this in the console window:
FBO format unsupported
FBO error
FBO incomplete
It does this no matter what option I try, even none. Is this happening because my graphics card doesn't support it or is it something else?
multum in parvo
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

ok, i think i fixed it. It seems my graphics card doesn't support 8x antialiasing.
This is what my code looks like now:

Code: Select all

IPostProc* ppRenderer8X = 0;
    IPostProc* ppRenderer4X = 0;
    IPostProc* ppRenderer2X = 0;
    CEffectPostProc* ppDirect4X8 = 0;
    CEffectPostProc* ppDirect2X8 = 0;
    CEffectPostProc* ppDirect1X8 = 0;
    CEffectPostProc* ppDirect2X4 = 0;
    CEffectPostProc* ppDirect1X4 = 0;
    CEffectPostProc* ppDirect1X2 = 0;
//____________________________________8X___________________________________________________________________________________
    if(antialiasing == 8)
    {
        ppRenderer8X = new CRendererPostProc(smgr, dimension2d<u32>( 8192, 4096 ), true, true, SColor( 255, 100, 101, 140 ));
        ppDirect4X8 = new CEffectPostProc(ppRenderer8X, dimension2d<u32>( 4096, 2048 ), PP_DIRECT);
        ppDirect2X8 = new CEffectPostProc(ppDirect4X8, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
        ppDirect1X8 = new CEffectPostProc(ppDirect2X8, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
    }
//____________________________________4X___________________________________________________________________________________
    if(antialiasing == 4)
    {
        ppRenderer4X = new CRendererPostProc(smgr, dimension2d<u32>( 4096, 2048 ), true, true, SColor( 255, 100, 101, 140 ));
        ppDirect2X4 = new CEffectPostProc(ppRenderer4X, dimension2d<u32>( 2048, 1024 ), PP_DIRECT);
        ppDirect1X4 = new CEffectPostProc(ppDirect2X4, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
    }
//____________________________________2X___________________________________________________________________________________
    if(antialiasing == 2)
    {
        ppRenderer2X = new CRendererPostProc(smgr, dimension2d<u32>( 2048, 1024 ), true, true, SColor( 255, 100, 101, 140 ));
        ppDirect1X2 = new CEffectPostProc(ppRenderer2X, dimension2d<u32>( 1024, 512 ), PP_DIRECT);
    }
while(device->run())
	{
		if(paused == false)
		{
if(antialiasing == 0)
            {
                driver->beginScene(true, true, SColor(255,100,101,140));
            }
            else
            {
                driver->beginScene(false, driver->getDriverType() == EDT_OPENGL);
            }

            if(antialiasing == 0)
            {
                smgr->drawAll();
            }
            else if(antialiasing == 2)
            {
                ppDirect1X2->render(NULL);
            }
            else if(antialiasing == 4)
            {
                ppDirect1X4->render(NULL);
            }
            else if(antialiasing == 8)
            {
                ppDirect1X8->render(NULL);
            }
			driver->endScene();
		}
	}
}
multum in parvo
Stratosphere
Posts: 20
Joined: Wed Sep 09, 2009 11:54 pm

Post by Stratosphere »

Wow, thank you for making this! i thought I was going to have to make a bunch of shaders for certain effects myself. But will this work with code blocks ide :?:

Edit: thanks for clarifying that Adler1337.
Last edited by Stratosphere on Sat Oct 24, 2009 9:09 pm, edited 1 time in total.
Adler1337
Posts: 471
Joined: Sat Aug 09, 2008 6:10 pm
Location: In your base.

Post by Adler1337 »

Yeah, it works with CodeBlocks. That's what i am using now.
multum in parvo
Post Reply