渲染到纹理是个很重要的技巧,特别是做海洋,湖泊这种水体渲染的时候.这里在OGRE实现下,到时候我用DX写一个渲染到纹理的例子,那时再讲原理
/*------------------------------------------------------------
main.cpp -- Render to texture demo
(c) Seamanj.2013/8/16
------------------------------------------------------------*/
//phase1 : Add Framework
//phase2 : Add environment ,knot mesh and ogrehead
//phase3 : Add a plane;
//phase4 : add a texture
//phase5 : add frame listener
#define phase1 1
#define phase2 1
#define phase3 1
#define phase4 1
#define phase5 1
#if phase1
#include "ExampleApplication.h"
#include <windows.h>
#if phase5
class MyFrameListener : public ExampleFrameListener
{
protected:
Camera* mReflectCam;
SceneNode* mPlaneNode;
public:
MyFrameListener(RenderWindow* window, Camera* maincam, Camera* reflectCam,
SceneNode* planeSceneNode) : ExampleFrameListener(window, maincam),
mReflectCam(reflectCam), mPlaneNode(planeSceneNode)
{}
bool frameStarted( const FrameEvent& evt )
{
if( ExampleFrameListener::frameStarted( evt ) == false )
return false;
// Make sure reflection camera is updated too
mReflectCam->setOrientation( mCamera->getOrientation());
mReflectCam->setPosition( mCamera->getPosition());
// Rotate plane
/// mPlaneNode->yaw(Degree(30 * evt.timeSinceLastFrame), Node::TS_PARENT);
return true;
}
};
#endif
class MyApplication : public ExampleApplication
#if phase5
, public RenderTargetListener
#endif
{
#if phase3
protected:
MovablePlane* mPlane;
Entity* mPlaneEnt;
SceneNode* mPlaneNode;
#if phase4
Camera* mReflectCam;
#endif
#endif
public:
MyApplication()
#if phase3
: mPlane(0)
#endif
{}
~MyApplication()
{
#if phase3
delete mPlane;
#endif
}
protected:
#if phase5
void preRenderTargetUpdate(const RenderTargetEvent& evt)
{
// Hide plane
mPlaneEnt->setVisible(false);
}
void postRenderTargetUpdate(const RenderTargetEvent& evt)
{
// Show plane
mPlaneEnt->setVisible(true);
}
#endif
void createScene()
{
#if phase2
// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
// Set skybox
mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox");
// Create a light
Light* l = mSceneMgr->createLight("MainLight");
l->setType(Light::LT_DIRECTIONAL);
Vector3 dir(0.5, -1, 0);
dir.normalise();
l->setDirection(dir);
l->setDiffuseColour(1.0f, 1.0f, 0.8f);
l->setSpecularColour(1.0f, 1.0f, 1.0f);
// Create 3 knots
Entity* knotEnt = mSceneMgr->createEntity( "Knot", "knot.mesh" );
knotEnt->setMaterialName("Examples/TextureEffect2");
Entity* cloneEnt;
for(int n = 0; n < 3; n++ )
{
// Create a new node under the root
SceneNode* node = mSceneMgr->createSceneNode();
// Random translate
Vector3 nodePos;
nodePos.x = Math::SymmetricRandom() * 750.0;
nodePos.y = Math::SymmetricRandom() * 100.0 + 25;
nodePos.z = Math::SymmetricRandom() * 750.0;
node->setPosition(nodePos);
mSceneMgr->getRootSceneNode()->addChild(node);
// Clone knot
char cloneName[12];
sprintf(cloneName, "Knot%d", n);
cloneEnt = knotEnt->clone(cloneName);
//Attach to new node
node->attachObject(cloneEnt);
}
// Create an ogrehead
Entity* ogreHead = mSceneMgr->createEntity( "Head", "ogrehead.mesh" );
mSceneMgr->getRootSceneNode()->createChildSceneNode( "Head" )->attachObject( ogreHead );
#if phase3
mPlane = new MovablePlane("ReflectPlane");
mPlane->d = 0;
mPlane->normal = Vector3::UNIT_Y;
MeshManager::getSingleton().createPlane("ReflectionPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
*mPlane, 4000, 4000,1, 1, true, 1, 1, 1, Vector3::UNIT_Z);
mPlaneEnt = mSceneMgr->createEntity( "Plane", "ReflectionPlane");
mPlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mPlaneNode->attachObject(mPlaneEnt);
mPlaneNode->attachObject(mPlane);
mPlaneNode->translate(0, -10, 0);
//mPlaneNode->roll(Degree(5));
#if phase4
TexturePtr texture = TextureManager::getSingleton().createManual( "RttTex",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
RenderTarget *rttTex = texture->getBuffer()->getRenderTarget();
mReflectCam = mSceneMgr->createCamera("ReflectCam");
mReflectCam->setNearClipDistance(mCamera->getNearClipDistance());
mReflectCam->setFarClipDistance(mCamera->getFarClipDistance());
mReflectCam->setAspectRatio((Real)mWindow->getViewport(0)->getActualWidth() /
(Real)mWindow->getViewport(0)->getActualHeight());
Viewport *v = rttTex->addViewport( mReflectCam );
v->setClearEveryFrame( true );
v->setBackgroundColour( ColourValue::Black );
MaterialPtr mat = MaterialManager::getSingleton().create("RttMat",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
//TextureUnitState* t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RustedMetal.jpg");
TextureUnitState* t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");
// Blend with base texture
// t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, ColourValue::White,
// ColourValue::White, 0.25);
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
t->setProjectiveTexturing( true, mReflectCam );
//rttTex->addListener(this);
// set up linked reflection
mReflectCam->enableReflection(mPlane);
// Also clip
mReflectCam->enableCustomNearClipPlane(mPlane);
mPlaneEnt->setMaterialName("RttMat");
#endif
#endif
#endif
}
#if phase5
void createFrameListener()
{
mFrameListener = new MyFrameListener( mWindow, mCamera, mReflectCam, mPlaneNode );
mRoot->addFrameListener( mFrameListener );
}
#endif
};
INT WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
MyApplication app;
try
{
app.go();
}
catch( Exception& e)
{
MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
return 0;
}
#endif