A simple, robust and extendible postprocessing class
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.
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.
Thanks.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)
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, big thanks for this
EDIT:
Works like a charm...
(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
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)
(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)
Yeah, I have been testing them and they don't look quite the same.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.
Maybe this helps with the pen and ink effect.
multum in parvo
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:
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
EDIT2: Yes, I am including the headers.
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
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
EDIT2: Yes, I am including the headers.
-
- Posts: 914
- Joined: Fri Aug 03, 2007 12:43 pm
- Location: South Africa
- Contact:
Isn't it enough to add the source in include paths?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
Going to try direct adding stuff into project.
EDIT: Yup, it is working, thanks
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 ^^
I have been trying to get antialiasing in my game using the above ^Direct (a way of getting anti-aliasing - combine these to get 2x, 4x, 8x, etc.)
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);
btw What exactly does PP_DIRECT do?
multum in parvo
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:
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);
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.
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);
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);
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.
ok, well i finally got around to testing the code you posted. This is what my code looks like now:
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?
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();
}
}
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
ok, i think i fixed it. It seems my graphics card doesn't support 8x antialiasing.
This is what my code looks like now:
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
-
- Posts: 20
- Joined: Wed Sep 09, 2009 11:54 pm
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.
Edit: thanks for clarifying that Adler1337.
Last edited by Stratosphere on Sat Oct 24, 2009 9:09 pm, edited 1 time in total.