How do use native OpenGL and Direct3D calls inside Ogre by Assaf Raman- http://www.ogre3d.org/forums/viewtopic.php?f=1&t=43156
Copy to clipboard
/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2006 Torus Knot Software Ltd Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ /** \file NativeRenderSystemCommands.h \brief A sample demonstrating how to add render system specific native code to an existing scene. I based this sample on the SkyDome sample, just added a FrameListener */ #include "..\..\SkyDome\include\SkyDome.h" #include <gl\gl.h> #include <d3d9.h> class RenderSystemCommandsRenderQueueListener : public RenderQueueListener { protected: MovableObject* mObject; const Camera* mCamera; SceneManager* mSceneMgr; RenderWindow* mWindow; virtual void Render() = 0; virtual void PreRender() = 0; virtual void PostRender() = 0; public: RenderSystemCommandsRenderQueueListener(MovableObject* object, const Camera* camera, RenderWindow* window, SceneManager* sceneMgr) : mObject(object), mCamera(camera), mWindow(window), mSceneMgr(sceneMgr) { } virtual void renderQueueStarted(uint8 queueGroupId, const String& invocation, bool& skipThisInvocation) { } virtual void renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation) { // Set wanted render queue here - make sure there are - make sure that something is on // this queue - else you will never pass this if. if (queueGroupId != RENDER_QUEUE_MAIN) return; PreRender(); Render(); PostRender(); } }; class OpenGLRenderSystemCommandsRenderQueueListener : public RenderSystemCommandsRenderQueueListener { protected: virtual void PreRender() { // save matrices glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); //Texture addressing should start out as direct. RenderSystem* renderSystem = mObject->_getManager()->getDestinationRenderSystem(); Node* parentNode = mObject->getParentNode(); renderSystem->_setWorldMatrix(parentNode->_getFullTransform()); renderSystem->_setViewMatrix(mCamera->getViewMatrix()); renderSystem->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); static Pass* clearPass = NULL; if (!clearPass) { MaterialPtr clearMat = MaterialManager::getSingleton().getByName("BaseWhite"); clearPass = clearMat->getTechnique(0)->getPass(0); } //Set a clear pass to give the renderer a clear renderstate mSceneMgr->_setPass(clearPass, true, false); // save attribs glPushAttrib(GL_ALL_ATTRIB_BITS); } virtual void PostRender() { // restore original state glPopAttrib(); // restore matrices glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } public: OpenGLRenderSystemCommandsRenderQueueListener(MovableObject* object, const Camera* camera, RenderWindow* window, SceneManager* sceneMgr) : RenderSystemCommandsRenderQueueListener(object, camera, window, sceneMgr) { } }; class CubeOpenGLRenderSystemCommandsRenderQueueListener : public OpenGLRenderSystemCommandsRenderQueueListener { protected: void Render() { GLboolean depthTestEnabled=glIsEnabled(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST); GLboolean stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glScalef(30.0, 30.0, 30.0); // I took the following sample code from here: http://www.oreillynet.com/network/2000/06/23/magazine/cube.c // OK, let's start drawing our planer quads. glBegin(GL_QUADS); // Bottom Face. Red, 75% opaque, magnified texture glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting glColor4f(0.9,0.2,0.2,.75); // Basic polygon color glTexCoord2f(0.800f, 0.800f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.200f, 0.800f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.200f, 0.200f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(0.800f, 0.200f); glVertex3f(-1.0f, -1.0f, 1.0f); // Top face; offset. White, 50% opaque. glNormal3f( 0.0f, 1.0f, 0.0f); glColor4f(0.5,0.5,0.5,.5); glTexCoord2f(0.005f, 1.995f); glVertex3f(-1.0f, 1.3f, -1.0f); glTexCoord2f(0.005f, 0.005f); glVertex3f(-1.0f, 1.3f, 1.0f); glTexCoord2f(1.995f, 0.005f); glVertex3f( 1.0f, 1.3f, 1.0f); glTexCoord2f(1.995f, 1.995f); glVertex3f( 1.0f, 1.3f, -1.0f); // Far face. Green, 50% opaque, non-uniform texture cooridinates. glNormal3f( 0.0f, 0.0f,-1.0f); glColor4f(0.2,0.9,0.2,.5); glTexCoord2f(0.995f, 0.005f); glVertex3f(-1.0f, -1.0f, -1.3f); glTexCoord2f(2.995f, 2.995f); glVertex3f(-1.0f, 1.0f, -1.3f); glTexCoord2f(0.005f, 0.995f); glVertex3f( 1.0f, 1.0f, -1.3f); glTexCoord2f(0.005f, 0.005f); glVertex3f( 1.0f, -1.0f, -1.3f); // Right face. Blue; 25% opaque glNormal3f( 1.0f, 0.0f, 0.0f); glColor4f(0.2,0.2,0.9,.25); glTexCoord2f(0.995f, 0.005f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.995f, 0.995f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.005f, 0.995f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.005f, 0.005f); glVertex3f( 1.0f, -1.0f, 1.0f); // Front face; offset. Multi-colored, 50% opaque. glNormal3f( 0.0f, 0.0f, 1.0f); glColor4f( 0.9f, 0.2f, 0.2f, 0.5f); glTexCoord2f( 0.005f, 0.005f); glVertex3f(-1.0f, -1.0f, 1.3f); glColor4f( 0.2f, 0.9f, 0.2f, 0.5f); glTexCoord2f( 0.995f, 0.005f); glVertex3f( 1.0f, -1.0f, 1.3f); glColor4f( 0.2f, 0.2f, 0.9f, 0.5f); glTexCoord2f( 0.995f, 0.995f); glVertex3f( 1.0f, 1.0f, 1.3f); glColor4f( 0.1f, 0.1f, 0.1f, 0.5f); glTexCoord2f( 0.005f, 0.995f); glVertex3f(-1.0f, 1.0f, 1.3f); // Left Face; offset. Yellow, varying levels of opaque. glNormal3f(-1.0f, 0.0f, 0.0f); glColor4f(0.9,0.9,0.2,0.0); glTexCoord2f(0.005f, 0.005f); glVertex3f(-1.3f, -1.0f, -1.0f); glColor4f(0.9,0.9,0.2,0.66); glTexCoord2f(0.995f, 0.005f); glVertex3f(-1.3f, -1.0f, 1.0f); glColor4f(0.9,0.9,0.2,1.0); glTexCoord2f(0.995f, 0.995f); glVertex3f(-1.3f, 1.0f, 1.0f); glColor4f(0.9,0.9,0.2,0.33); glTexCoord2f(0.005f, 0.995f); glVertex3f(-1.3f, 1.0f, -1.0f); // All polygons have been drawn. glEnd(); if (depthTestEnabled) { glEnable(GL_DEPTH_TEST); } if (stencilTestEnabled) { glEnable(GL_STENCIL_TEST); } } public: CubeOpenGLRenderSystemCommandsRenderQueueListener(MovableObject* object, const Camera* camera, RenderWindow* window, SceneManager* sceneMgr) : OpenGLRenderSystemCommandsRenderQueueListener(object, camera, window, sceneMgr) { } }; ///////////////////////////////////////// class D3D9RenderSystemCommandsRenderQueueListener : public RenderSystemCommandsRenderQueueListener { protected: virtual void PreRender() { RenderSystem* renderSystem = mObject->_getManager()->getDestinationRenderSystem(); Node* parentNode = mObject->getParentNode(); renderSystem->_setWorldMatrix(parentNode->_getFullTransform()); renderSystem->_setViewMatrix(mCamera->getViewMatrix()); renderSystem->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); static Pass* clearPass = NULL; if (!clearPass) { MaterialPtr clearMat = MaterialManager::getSingleton().getByName("BaseWhite"); clearPass = clearMat->getTechnique(0)->getPass(0); } //Set a clear pass to give the renderer a clear renderstate mSceneMgr->_setPass(clearPass, true, false); } virtual void PostRender() { } public: D3D9RenderSystemCommandsRenderQueueListener(MovableObject* object, const Camera* camera, RenderWindow* window, SceneManager* sceneMgr) : RenderSystemCommandsRenderQueueListener(object, camera, window, sceneMgr) { } }; class CubeD3D9RenderSystemCommandsRenderQueueListener : public D3D9RenderSystemCommandsRenderQueueListener { protected: void Render() { LPDIRECT3DDEVICE9 pd3dDevice = NULL; // Our rendering device LPDIRECT3DVERTEXBUFFER9 pVB = NULL; // Buffer to hold vertices RenderSystem* renderSystem = mObject->_getManager()->getDestinationRenderSystem(); mWindow->getCustomAttribute( "D3DDEVICE", &pd3dDevice ); pd3dDevice->SetRenderState(D3DRS_LIGHTING, false); pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, TVC_DIFFUSE); // A structure for our custom vertex type struct CUSTOMVERTEX { Vector3 pos; // The untransformed, 3D position for the vertex Vector3 normal; // The untransformed, 3D position for the vertex DWORD color; // The vertex color }; // Our custom FVF, which describes our custom vertex structure #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE) #define SCALE_FACTOR 30 // Initialize three vertices for rendering a triangle static const CUSTOMVERTEX cubeVertices[] = { // Bottom Face. { Vector3(-1.0f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, { Vector3( 1.0f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, { Vector3( 1.0f, -1.0f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, { Vector3( 1.0f, -1.0f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, { Vector3(-1.0f, -1.0f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, { Vector3(-1.0f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, -1.0f, 0.0f), 0xff000000, }, // Top Face. { Vector3(-1.0f, 1.3f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, { Vector3(-1.0f, 1.3f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, { Vector3( 1.0f, 1.3f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, { Vector3( 1.0f, 1.3f, 1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, { Vector3( 1.0f, 1.3f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, { Vector3(-1.0f, 1.3f, -1.0f) * SCALE_FACTOR, Vector3( 0.0f, 1.0f, 0.0f), 0xffffff00, }, // Far Face. { Vector3(-1.0f, -1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, { Vector3(-1.0f, 1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, { Vector3( 1.0f, 1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, { Vector3( 1.0f, 1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, { Vector3( 1.0f, -1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, { Vector3(-1.0f, -1.0f, -1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f,-1.0f), 0x00ff0000, }, // Right Face. { Vector3( 1.0f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, { Vector3( 1.0f, 1.0f, -1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, { Vector3( 1.0f, 1.0f, 1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, { Vector3( 1.0f, 1.0f, 1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, { Vector3( 1.0f, -1.0f, 1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, { Vector3( 1.0f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( 1.0f, 0.0f, 0.0f), 0x0000ff00, }, // Front Face. { Vector3(-1.0f, -1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0xff00ff00, }, { Vector3( 1.0f, -1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0x00ffff00, }, { Vector3( 1.0f, 1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0x0000ff00, }, { Vector3( 1.0f, 1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0x0000ff00, }, { Vector3(-1.0f, 1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0xffffff00, }, { Vector3(-1.0f, -1.0f, 1.3f) * SCALE_FACTOR, Vector3( 0.0f, 0.0f, 1.0f), 0xff00ff00, }, // Left Face. { Vector3(-1.3f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, { Vector3(-1.3f, -1.0f, 1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, { Vector3(-1.3f, 1.0f, 1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, { Vector3(-1.3f, 1.0f, 1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, { Vector3(-1.3f, 1.0f, -1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, { Vector3(-1.3f, -1.0f, -1.0f) * SCALE_FACTOR, Vector3( -1.0f, 0.0f, 0.0f), 0xffff0000, }, }; UINT primitiveCount = sizeof(cubeVertices) / sizeof(CUSTOMVERTEX) / 3; // Create the vertex buffer. if( FAILED( pd3dDevice->CreateVertexBuffer( sizeof(cubeVertices), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVB, NULL ) ) ) { return;//E_FAIL; } // Fill the vertex buffer. VOID* pVertices; if( FAILED( pVB->Lock( 0, sizeof(cubeVertices), (void**)&pVertices, 0 ) ) ) return;// E_FAIL; memcpy( pVertices, cubeVertices, sizeof(cubeVertices) ); pVB->Unlock(); // Render the vertex buffer contents pd3dDevice->SetStreamSource( 0, pVB, 0, sizeof(CUSTOMVERTEX) ); pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, primitiveCount ); pVB->Release(); } public: CubeD3D9RenderSystemCommandsRenderQueueListener(MovableObject* object, const Camera* camera, RenderWindow* window, SceneManager* sceneMgr) : D3D9RenderSystemCommandsRenderQueueListener(object, camera, window, sceneMgr) { } }; ///////////////////////////////////////// class NativeRenderSystemCommandsApplication : public SkyDomeApplication { public: NativeRenderSystemCommandsApplication() { } protected: RenderQueueListener * mRenderSystemCommandsRenderQueueListener; // Just override the mandatory create scene method void createScene(void) { SkyDomeApplication::createScene(); ManualObject *manObj; // we will use this Manual Object as a reference point for the native rendering manObj = mSceneMgr->createManualObject("sampleArea"); // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2) mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manObj); String RenderSystemName = mSceneMgr->getDestinationRenderSystem()->getName(); mRenderSystemCommandsRenderQueueListener = NULL; if ("OpenGL Rendering Subsystem" == RenderSystemName) { mRenderSystemCommandsRenderQueueListener = new CubeOpenGLRenderSystemCommandsRenderQueueListener( manObj, mCamera, mWindow, mSceneMgr); mSceneMgr->addRenderQueueListener(mRenderSystemCommandsRenderQueueListener); } if ("Direct3D9 Rendering Subsystem" == RenderSystemName) { mRenderSystemCommandsRenderQueueListener = new CubeD3D9RenderSystemCommandsRenderQueueListener( manObj, mCamera, mWindow, mSceneMgr); mSceneMgr->addRenderQueueListener(mRenderSystemCommandsRenderQueueListener); } } void destroyScene() { if (mRenderSystemCommandsRenderQueueListener) { mSceneMgr->removeRenderQueueListener(mRenderSystemCommandsRenderQueueListener); delete mRenderSystemCommandsRenderQueueListener; mRenderSystemCommandsRenderQueueListener = NULL; } SkyDomeApplication::destroyScene(); } };
Copy to clipboard
/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2006 Torus Knot Software Ltd Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ /** \file NativeRenderSystemCommands.cpp \brief A sample demonstrating how to add render system specific native code to an existing scene. */ #include "NativeRenderSystemCommands.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char *argv[]) #endif { // Create application object NativeRenderSystemCommandsApplication app; try { app.go(); } catch( Ogre::Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; #endif } return 0; } #ifdef __cplusplus } #endif