Сценарии Compositor, по-видимому, предназначены только для полноэкранных (или, точнее, для всего окна просмотра) эффектов.
Рендеринг в текстуру - это путь. Это не обязательно выполняется с помощью скриптов композитора.
Эта тема моего обсуждения на форумах огров более детальна;
Ogre::Root r(...);
Ogre::RenderWindow* window = r.createRenderWindow(...);
//...
Ogre::SceneManager* sm = r.createSceneManager(Ogre::ST_GENERIC, "sm");
//...
//Main scene camera
Ogre::Camera* c = sm->createCamera("camera");
{
c->setNearClipDistance(5);
Ogre::Viewport* v = window->addViewport(c);
v->setBackgroundColour (Ogre::ColourValue(0, 0, 0));
c->setAspectRatio (static_cast<double> (v->getActualWidth ()) / v->getActualHeight ());
}
//RTT
Ogre::TexturePtr ptrTexture = Ogre::TextureManager::getSingleton().createManual(
"RttTex",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D,
512,//window->getWidth(),
512,//window->getHeight(),
0, //MIP_DEFAULT?
Ogre::PF_R8G8B8,
Ogre::TU_RENDERTARGET,
0
);
Ogre::RenderTexture* renderTexture = ptrTexture->getBuffer()->getRenderTarget();
renderTexture->setAutoUpdated(true);
//Create material to use with rect
{
//You should replace this with the material you wish to render to texture
//It can be defined in c++ (as this is) or in a material script
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Technique* tech = material->createTechnique();
tech->createPass();
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
material->getTechnique(0)->getPass(0)->createTextureUnitState("my_square_texture.dds");
}
//Create rect2D in yz plane to which we will draw our textures
//Most likely you'll wish to reposition the node so it's offscreen
const static float r_dimension = 1000.0;
Ogre::SceneNode* rect_node = sm->getRootSceneNode()->createChildSceneNode("rect_node");
{
Ogre::ManualObject *rect = sm->createManualObject("rect");
rect->begin("material", Ogre::RenderOperation::OT_TRIANGLE_FAN);
rect->position(0, r_dimension, r_dimension);
rect->textureCoord(0,0);
rect->normal(0, 1, 0);
rect->position(0, -r_dimension, r_dimension);
rect->textureCoord(0,1);
rect->normal(0, 1, 0);
rect->position(0, -r_dimension, -r_dimension);
rect->textureCoord(1,1);
rect->normal(0, 1, 0);
rect->position(0, r_dimension, -r_dimension);
rect->textureCoord(1,0);
rect->normal(0, 1, 0);
rect->end();
rect_node->attachObject(rect);
}
//Create camera, make it look at this rect2D
Ogre::Camera* rtt_cam = sm->createCamera("rtt_cam");
//Use same FOV as main camera
Ogre::Radian fov_y = c->getFOVy();
rtt_cam->setFOVy(fov_y);
//Position the camera such that the texture fills the viewpoint
{
//Angle from normal (ie, "vector origin->camera") to to top of tecture is FOV/2
//Distance origin to top of texture is r_dimension
double cam_to_rect_distance = r_dimension/tan((fov_y.valueRadians())/2);
rtt_cam->setPosition(cam_to_rect_distance, 0, 0);
rtt_cam->lookAt(rect_node->getPosition());
}
//Debug using main window
//window->addViewport(rtt_cam);
//Write to RTT
Ogre::Viewport* v = renderTexture->addViewport(rtt_cam);
v->setClearEveryFrame(true); //You may wish to set this to false and render only when your material updates/changes
v->setBackgroundColour(Ogre::ColourValue::Blue); //Debug colour. If we see blue border in RTT our cam position is wrong.
v->setOverlaysEnabled(false); //We don't want overlays to show up on the RTT
//TEMP Create debug screen (lifted from Ogre Tutorial 7)
//Draws the result of RTT onscreen picture-in-picture
{
Ogre::Rectangle2D *miniScreen = new Ogre::Rectangle2D(true);
miniScreen->setCorners(0.5f, -0.5f, 1.0f, -1.0f);
//miniScreen->setBoundingBox(Ogre::AxisAlignedBox(-100000.0f * Ogre::Vector3::UNIT_SCALE, 100000.0f * Ogre::Vector3::UNIT_SCALE));
Ogre::SceneNode* miniScreenNode = sm->getRootSceneNode()->createChildSceneNode("MiniScreenNode");
miniScreenNode->attachObject(miniScreen);
//Create material to read result of Rtt, purely for debug purposes
Ogre::MaterialPtr screenMaterial = Ogre::MaterialManager::getSingleton().create("ScreenMatt", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Technique* screenTechnique = screenMaterial->createTechnique();
screenTechnique->createPass();
screenMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
screenMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");
miniScreen->setMaterial("ScreenMatt");
//TODO ideally we'd have render target listeners call setVisible(false) on pre update and setVisible(true) post update,
//so we don't get the infinite line picture-in-picture-in-picture in the preview window.
}
//Now you can bind your shader's material script to the rtt
{
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName("your_material_name");
Ogre::Technique *technique = material->getTechnique(0);
Ogre::Pass *pass = technique->getPass(0);
Ogre::TextureUnitState *tunit = pass->getTextureUnitState("your_materials_tunit_name");
tunit->setTextureName("Rtt");
}
//...
while (! window->isClosed ()) {
//...
r.renderOneFrame();
}