三个Entity的material所在文件
ogrenew\Samples\Media\materials\scripts\Example.material
// 铁效果的
material Examples/TextureEffect1
{
technique
{
pass
{
ambient 0.75 0.75 0.75
cull_hardware none
cull_software none
texture_unit
{
texture BumpyMetal.jpg
rotate_anim 0.2
wave_xform scale_x sine 1 0.1 0 5
wave_xform scale_y sine 0.5 0.2 0.5 3
}
}
}
}
// 绳结
material Examples/TextureEffect2
{
technique
{
pass
{
texture_unit
{
texture Water02.jpg
scroll_anim 0.5 0
}
}
}
}
// 水平面
material Examples/TextureEffect3
{
technique
{
pass
{
ambient 0.7 0.7 0.7
cull_hardware none
cull_software none
texture_unit
{
texture Water01.jpg
scroll_anim -0.25 0.1
}
texture_unit
{
texture Water01.jpg
colour_op_ex add src_texture src_current
colour_op_multipass_fallback one one
scroll_anim -0.1 0.25
}
}
}
}
截图:
ogrenew\Samples\Media\materials\textures\BumpyMetal.jpg 如下:
/**
\file
TextureFX.h
\brief
Shows OGRE's ability to handle different types of texture effects.
*/
#include "ExampleApplication.h"
class TextureEffectsApplication : public ExampleApplication
{
public:
TextureEffectsApplication() {}
protected:
void createScalingPlane()
{
// Set up a material for the plane
// Create a prefab plane
Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE);
// Give the plane a texture
planeEnt->setMaterialName("Examples/TextureEffect1");
SceneNode* node =
mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-250,-40,-100));
node->attachObject(planeEnt);
}
void createScrollingKnot()
{
Entity *ent = mSceneMgr->createEntity("knot", "knot.mesh");
ent->setMaterialName("Examples/TextureEffect2");
// Add entity to the root scene node
SceneNode* node =
mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,50,150));
node->attachObject(ent);
}
void createWateryPlane()
{
// Create a prefab plane
Entity *planeEnt = mSceneMgr->createEntity("WaterPlane", SceneManager::PT_PLANE);
// Give the plane a texture
planeEnt->setMaterialName("Examples/TextureEffect3");
mSceneMgr->getRootSceneNode()->attachObject(planeEnt);
}
// Just override the mandatory create scene method
void createScene(void)
{
// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
// Create a point light
Light* l = mSceneMgr->createLight("MainLight");
// Accept default settings: point light, white diffuse, just set position
// NB I could attach the light to a SceneNode if I wanted it to move automatically with
// other objects, but I don't
l->setPosition(20,80,50);
createScalingPlane();
createScrollingKnot();
createWateryPlane();
// Set up a material for the skydome
MaterialPtr skyMat = MaterialManager::getSingleton().create("SkyMat",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
// Perform no dynamic lighting on the sky
skyMat->setLightingEnabled(false);
// Use a cloudy sky
TextureUnitState* t = skyMat->getTechnique(0)->getPass(0)->createTextureUnitState("clouds.jpg");
// Scroll the clouds
t->setScrollAnimation(0.15, 0);
// System will automatically set no depth write
// Create a skydome
mSceneMgr->setSkyDome(true, "SkyMat", -5, 2);
}
};
提出问题,然后解决问题!解决的问题多了看OGRE就很通透了!吼吼!Q:
渲染流程是怎样?A:一图解千言!看图吧!
Q:
ViewPort到底是什么?有些地图编辑器里面有几个渲染小窗口,比如像3D Max那种四个视图,这四个视图是什么?四个ViewPort?A:
/** An abstraction of a viewport, i.e. a rendering region on a render
target.
@remarks
A viewport is the meeting of a camera and a rendering surface -
the camera renders the scene from a viewpoint, and places its
results into some subset of a rendering target, which may be the
whole surface or just a part of the surface. Each viewport has a
single camera as source and a single target as destination. A
camera only has 1 viewport, but a render target may have several.
A viewport also has a Z-order, i.e. if there is more than one
viewport on a single render target and they overlap, one must
obscure the other in some predetermined way.
*/
class _OgreExport Viewport
说得再明白也不如改改代码看效果来得直接易懂,看效果
爽吧!哈哈!
改动的代码(红色的部分):
ExampleApplicaton.h里面的话就是所有的Demo都变成4个ViewPort,所以最好在自己的Demo里面override这个成员函数,这样子就只有这一个demo是4个ViewPort。
virtual void createViewports(void)
{
// Create one viewport, entire window
Viewport* vp = mWindow->addViewport(mCamera, 0, 0.5f, 0.0f, 0.5f, 0.5f);
vp->setBackgroundColour(ColourValue(0,0,0));
mWindow->addViewport(mCamera, 2, 0.0f, 0.0f, 0.5f, 0.5f);
mWindow->addViewport(mCamera, 3, 0.0f, 0.5f, 0.5f, 0.5f);
mWindow->addViewport(mCamera, 4, 0.5f, 0.5f, 0.5f, 0.5f);
// Alter the camera aspect ratio to match the viewport
mCamera->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}
我们继续YY!让每个ViewPort的Camera都不一样!也就是每个ViewPort里面看到的是不一样的(不同的观察方向等)!直观点说,就是放了多个摄像机在拍冠希柏芝,不同的角度而已!
改动的代码:
virtual void createViewports(void)
{
// Create the first viewport
Viewport* vp = mWindow->addViewport(mCamera, 0, 0.5f, 0.0f, 0.5f, 0.5f);
vp->setBackgroundColour(ColourValue(0,0,0));
// Alter the camera aspect ratio to match the viewport
mCamera->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
// Create the second viewport
vp = mWindow->addViewport(mCamera1, 1, 0.0f, 0.0f, 0.5f, 0.5f);
mCamera1->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
// Create the third viewport
vp = mWindow->addViewport(mCamera2, 2, 0.0f, 0.5f, 0.5f, 0.5f);
mCamera2->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
// Create the fourth viewport
vp = mWindow->addViewport(mCamera3, 3, 0.5f, 0.5f, 0.5f, 0.5f);
mCamera2->setAspectRatio(
Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}
virtual void createCamera(void)
{
// Create the first camera
mCamera = mSceneMgr->createCamera("PlayerCam");
// Position it at 500 in Z direction
mCamera->setPosition(Vector3(0,0,500));
// Look back along -Z
mCamera->lookAt(Vector3(0,0,-300));
mCamera->setNearClipDistance(5);
// Create the second camera
mCamera1 = mSceneMgr->createCamera("PlayerCam1");
// Position it at 500 in Z direction
mCamera1->setPosition(Vector3(0,100,500));
// Look back along -Z
mCamera1->lookAt(Vector3(0,100,-300));
mCamera1->setNearClipDistance(5);
// Create the third camera
mCamera2 = mSceneMgr->createCamera("PlayerCam2");
// Position it at 500 in Z direction
mCamera2->setPosition(Vector3(0,-100,500));
// Look back along -Z
mCamera2->lookAt(Vector3(0,-100,-300));
mCamera2->setNearClipDistance(5);
// Create the fouth camera
mCamera3 = mSceneMgr->createCamera("PlayerCam3");
// Position it at 500 in Z direction
mCamera3->setPosition(Vector3(100,0,500));
// Look back along -Z
mCamera3->lookAt(Vector3(100,0,-300));
mCamera3->setNearClipDistance(5);
}
自己定义三个camera:
private:
Camera* mCamera1;
Camera* mCamera2;
Camera* mCamera3;
上面的改动之后,只有第一象限的ViewPort里的摄像机能随鼠标动,我们来让其他三个ViewPort的摄像机也能随鼠标动。同时动,不是每个ViewPort单独动!
virtual void createFrameListener(void)
{
mFrameListener = new ExampleFrameListener(mWindow, mCamera);
mFrameListener1 = new ExampleFrameListener(mWindow, mCamera1);
mFrameListener2 = new ExampleFrameListener(mWindow, mCamera2);
mFrameListener3 = new ExampleFrameListener(mWindow, mCamera3);
mFrameListener->showDebugOverlay(true);
mFrameListener1->showDebugOverlay(true);
mFrameListener2->showDebugOverlay(true);
mFrameListener3->showDebugOverlay(true);
mRoot->addFrameListener(mFrameListener);
mRoot->addFrameListener(mFrameListener1);
mRoot->addFrameListener(mFrameListener2);
mRoot->addFrameListener(mFrameListener3);
}
新加三个成员变量:
ExampleFrameListener* mFrameListener1;
ExampleFrameListener* mFrameListener2;
ExampleFrameListener* mFrameListener3;
构造和析构:
TextureEffectsApplication()
: mFrameListener1(0)
, mFrameListener2(0)
, mFrameListener3(0)
{
}
~TextureEffectsApplication()
{
if (mFrameListener1)
{
delete mFrameListener1;
}
if (mFrameListener2)
{
delete mFrameListener2;
}
if (mFrameListener3)
{
delete mFrameListener3;
}
}
每个ViewPort里面不同的render mode可不可以不同呢?当然可以!
这儿还用到CEGUI了,改动还挺多!
添加了一个按钮RenderMode,点击时切换渲染模式。不过只能切换第一象限的,不能区分点击的是哪个象限的按钮!放四个按钮吧,分别控制四个象限。
界面配置文件
ogrenew\Samples\Media\gui\ogregui.lyl.layout:
<?xml version="1.0" ?>
<GUILayout>
<Window Type="DefaultGUISheet" Name="root">
<Window Type="DefaultGUISheet" Name="OgreGuiDemo">
<Property Name="UnifiedSize" Value="{{0.25,0},{1,0}}" />
<Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton0">
<Property Name="UnifiedPosition" Value="{{0.0,0},{0.0,0}}" />
<Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
<Property Name="Text" Value="RenderMode0" />
</Window>
<Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton1">
<Property Name="UnifiedPosition" Value="{{0.0,0},{0.05,0}}" />
<Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
<Property Name="Text" Value="RenderMode1" />
</Window>
<Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton2">
<Property Name="UnifiedPosition" Value="{{0.0,0},{0.1,0}}" />
<Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
<Property Name="Text" Value="RenderMode2" />
</Window>
<Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton3">
<Property Name="UnifiedPosition" Value="{{0.0,0},{0.15,0}}" />
<Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
<Property Name="Text" Value="RenderMode3" />
</Window>
</Window>
</Window>
</GUILayout>
如何使用CEGUI?
1.声明两个成员变量:
CEGUI::OgreCEGUIRenderer* mGUIRenderer;
CEGUI::System* mGUISystem;
2.创建实例,载入配置文件
// setup GUI system
mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow,
Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
mGUISystem = new CEGUI::System(mGUIRenderer);
CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
// load scheme and set up defaults
CEGUI::SchemeManager::getSingleton().loadScheme(
(CEGUI::utf8*)"TaharezLookSkin.scheme");
mGUISystem->setDefaultMouseCursor(
(CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");
CEGUI::Window* sheet =
CEGUI::WindowManager::getSingleton().loadWindowLayout(
(CEGUI::utf8*)"ogregui.lyl.layout");
mGUISystem->setGUISheet(sheet);
3.配置事件处理器
void setupEventHandlers(void)
{
CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton0")
->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode0, this));
wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton1")
->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode1, this));
wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton2")
->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode2, this));
wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton3")
->subscribeEvent(
CEGUI::PushButton::EventClicked,
CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode3, this));
}
4.listener中把OIS的事件转成CEGUI的
//----------------------------------------------------------------//
bool mouseMoved( const OIS::MouseEvent &arg )
{
CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
return true;
}
//----------------------------------------------------------------//
bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
return true;
}
//----------------------------------------------------------------//
bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
return true;
}
//----------------------------------------------------------------//
bool keyPressed( const OIS::KeyEvent &arg )
{
if( arg.key == OIS::KC_ESCAPE )
mShutdownRequested = true;
CEGUI::System::getSingleton().injectKeyDown( arg.key );
CEGUI::System::getSingleton().injectChar( arg.text );
return true;
}
//----------------------------------------------------------------//
bool keyReleased( const OIS::KeyEvent &arg )
{
CEGUI::System::getSingleton().injectKeyUp( arg.key );
return true;
}
Q:
material文件是如何解析的?A:还是看调用堆栈好了
Q:
material文件中各个参数都是他妈的干什么鸟用的,为什么这么简单的几个参数一调就搞出这么牛B的效果?A: 嗯,这个就要查下
每天花30分钟看OGRE--(8) 《Pro OGRE 3D Programming》 Appendix B : Script Attribute Reference
material technique pass都有一堆参数,这个要慢慢领会!
posted on 2008-04-22 22:12
七星重剑 阅读(4105)
评论(5) 编辑 收藏 引用 所属分类:
Game Graphics 、
OGRE