Anaglyphic 3D
Posted: Tue Feb 03, 2009 2:43 pm
Well, the super bowl left me with a bunch of cheap 3D glasses, so I thought I would include an anaglyph function. There's lot's of talk on the board about how to do this, but doesn't seem to be a straight forward function anywhere, so here it is.
Of course, I'm not smart enough to come up with this, so thanks to the many that provided the smart stuff, I humbly bring it together into a function.
The super bowl glasses are blue and orange instead of the more traditional cyan/red. Try passing ulREyeKey = 0x000000ff, ulLEyeKey = 0x00ffff00, for those glasses. You'll have to change the key if you have different color lenses. 2 and 1000 are good starting points for fWidth and fFocus respectively. (That's the width between the eyes and the focal point).
*edit*
As to how to use this function, you could replace the following lines in your code with a call to this function.
Of course, I'm not smart enough to come up with this, so thanks to the many that provided the smart stuff, I humbly bring it together into a function.
The super bowl glasses are blue and orange instead of the more traditional cyan/red. Try passing ulREyeKey = 0x000000ff, ulLEyeKey = 0x00ffff00, for those glasses. You'll have to change the key if you have different color lenses. 2 and 1000 are good starting points for fWidth and fFocus respectively. (That's the width between the eyes and the focal point).
Code: Select all
static BOOL DrawAnaglyph( irr::video::IVideoDriver *pDriver,
irr::scene::ISceneManager *pSm,
irr::scene::ICameraSceneNode *pCamera,
irr::video::SColor colBackground,
float fWidth, float fFocus, int nDriverType,
unsigned long ulREyeKey, unsigned long ulLEyeKey )
{
// Right eye
irr::core::vector3df reye = pCamera->getPosition();
// Left eye
irr::core::vector3df v( fWidth, 0, 0 );
irr::core::matrix4 m;
m.setRotationDegrees( pCamera->getRotation() + irr::core::vector3df( 90.f, 0, 0 ) );
m.transformVect( v );
irr::core::vector3df leye = reye + v;
// Eye target
irr::core::vector3df oldt = pCamera->getTarget();
irr::core::vector3df eyet = ( oldt - reye ).normalize() * fFocus;
pCamera->setTarget( eyet );
IDirect3DDevice9 *pDdx9 = NULL;
if ( nDriverType == irr::video::EDT_DIRECT3D9
&& pDriver->getExposedVideoData().D3D9.D3DDev9 )
pDdx9 = pDriver->getExposedVideoData().D3D9.D3DDev9;
// Setup right eye
if ( nDriverType == irr::video::EDT_OPENGL )
{ glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColorMask( 0 != ( ulREyeKey & 0x00ff0000 ),
0 != ( ulREyeKey & 0x0000ff00 ),
0 != ( ulREyeKey & 0x000000ff ),
0 != ( ulREyeKey & 0xff000000 ) );
} // end if
else if ( pDdx9 )
pDdx9->SetRenderState( D3DRS_COLORWRITEENABLE,
( ulREyeKey & 0x00ff0000 ? D3DCOLORWRITEENABLE_RED : 0 )
| ( ulREyeKey & 0x0000ff00 ? D3DCOLORWRITEENABLE_GREEN : 0 )
| ( ulREyeKey & 0x000000ff ? D3DCOLORWRITEENABLE_BLUE : 0 )
| ( ulREyeKey & 0xff000000 ? D3DCOLORWRITEENABLE_ALPHA : 0 ) );
pDriver->beginScene( true, true, colBackground );
pSm->drawAll();
// Left Eye
if ( nDriverType == irr::video::EDT_OPENGL )
{ glClear( GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColorMask( 0 != ( ulLEyeKey & 0x00ff0000 ),
0 != ( ulLEyeKey & 0x0000ff00 ),
0 != ( ulLEyeKey & 0x000000ff ),
0 != ( ulLEyeKey & 0xff000000 ) );
} // end if
else if ( pDdx9 )
{ pDdx9->Clear(0 , 0 , D3DCLEAR_ZBUFFER, 0x000000 , 1.0f , 0);
pDdx9->SetRenderState( D3DRS_COLORWRITEENABLE,
( ulLEyeKey & 0x00ff0000 ? D3DCOLORWRITEENABLE_RED : 0 )
| ( ulLEyeKey & 0x0000ff00 ? D3DCOLORWRITEENABLE_GREEN : 0 )
| ( ulLEyeKey & 0x000000ff ? D3DCOLORWRITEENABLE_BLUE : 0 )
| ( ulLEyeKey & 0xff000000 ? D3DCOLORWRITEENABLE_ALPHA : 0 ) );
} // end else if
pCamera->setPosition( leye );
pCamera->OnRegisterSceneNode();
pSm->drawAll();
pDriver->endScene();
if ( nDriverType == irr::video::EDT_OPENGL )
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
else if ( pDdx9 )
if ( pDdx9 )
pDdx9->SetRenderState( D3DRS_COLORWRITEENABLE,
D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_ALPHA );
// Restore original position
pCamera->setPosition( reye );
pCamera->setTarget( oldt );
return TRUE;
}
As to how to use this function, you could replace the following lines in your code with a call to this function.
Code: Select all
pDriver->beginScene( true, true, colBackground );
pSm->drawAll();
pDriver->endScene();