RigsofRods
Soft-body Physics Simulation
EnvironmentMap.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2005-2012 Pierre-Michel Ricordel
4  Copyright 2007-2012 Thomas Fischer
5 
6  For more information, see http://www.rigsofrods.org/
7 
8  Rigs of Rods is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License version 3, as
10  published by the Free Software Foundation.
11 
12  Rigs of Rods is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "EnvironmentMap.h"
22 
23 #include "Application.h"
24 #include "CameraManager.h"
25 #include "GameContext.h"
26 #include "GfxActor.h"
27 #include "GfxScene.h"
28 #include "GUIManager.h"
29 #include "SkyManager.h"
30 #include "Terrain.h"
31 
32 #include <OgreOverlaySystem.h>
33 #include <OgreOverlayManager.h>
34 #include <OgreOverlay.h>
35 
37  m_update_round(0)
38 {
39  memset(m_cameras, 0, sizeof(m_cameras));
40  memset(m_render_targets, 0, sizeof(m_render_targets));
41 }
42 
44 {
45  m_rtt_texture = Ogre::TextureManager::getSingleton().getByName("EnvironmentTexture");
46 
47  for (int face = 0; face < NUM_FACES; face++)
48  {
49  m_render_targets[face] = m_rtt_texture->getBuffer(face)->getRenderTarget();
50  m_cameras[face] = App::GetGfxScene()->GetSceneManager()->createCamera("EnvironmentCamera-" + TOSTRING(face));
51  m_cameras[face]->setAspectRatio(1.0);
52  m_cameras[face]->setProjectionType(Ogre::PT_PERSPECTIVE);
53  m_cameras[face]->setFixedYawAxis(false);
54  m_cameras[face]->setFOVy(Ogre::Degree(90));
55  m_cameras[face]->setNearClipDistance(0.1f);
56  m_cameras[face]->setFarClipDistance(App::GetCameraManager()->GetCamera()->getFarClipDistance());
57 
58  Ogre::Viewport* v = m_render_targets[face]->addViewport(m_cameras[face]);
59  v->setOverlaysEnabled(false);
60  v->setClearEveryFrame(true);
61  v->setBackgroundColour(App::GetCameraManager()->GetCamera()->getViewport()->getBackgroundColour());
62  m_render_targets[face]->setAutoUpdated(false);
63  }
64 
65  m_cameras[0]->setDirection(+Ogre::Vector3::UNIT_X);
66  m_cameras[1]->setDirection(-Ogre::Vector3::UNIT_X);
67  m_cameras[2]->setDirection(+Ogre::Vector3::UNIT_Y);
68  m_cameras[3]->setDirection(-Ogre::Vector3::UNIT_Y);
69  m_cameras[4]->setDirection(-Ogre::Vector3::UNIT_Z);
70  m_cameras[5]->setDirection(+Ogre::Vector3::UNIT_Z);
71 
72  if (App::diag_envmap->getBool())
73  {
74  // create fancy mesh for debugging the envmap
75  Ogre::Overlay* overlay = Ogre::OverlayManager::getSingleton().create("EnvMapDebugOverlay");
76  if (overlay)
77  {
78  Ogre::Vector3 position = Ogre::Vector3::ZERO;
79  float scale = 1.0f;
80 
81  Ogre::MeshPtr mesh = Ogre::MeshManager::getSingletonPtr()->createManual("cubeMapDebug", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
82  // create sub mesh
83  Ogre::SubMesh* sub = mesh->createSubMesh();
84 
85  // Initialize render operation
86  sub->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
87  //
88  sub->useSharedVertices = true;
89  mesh->sharedVertexData = new Ogre::VertexData;
90  sub->indexData = new Ogre::IndexData;
91 
92  // Create vertex declaration
93  size_t offset = 0;
94  mesh->sharedVertexData->vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
95  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
96  mesh->sharedVertexData->vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES);
97 
98  // Create and bind vertex buffer
99  mesh->sharedVertexData->vertexCount = 14;
100  Ogre::HardwareVertexBufferSharedPtr vertexBuffer =
101  Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
102  mesh->sharedVertexData->vertexDeclaration->getVertexSize(0),
103  mesh->sharedVertexData->vertexCount,
104  Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
105  mesh->sharedVertexData->vertexBufferBinding->setBinding(0, vertexBuffer);
106 
107  // Vertex data
108  static const float vertexData[] = {
109  // Position Texture coordinates // Index
110  0.0, 2.0, -1.0, 1.0, 1.0, // 0
111  0.0, 1.0, -1.0, -1.0, 1.0, // 1
112  1.0, 2.0, -1.0, 1.0, -1.0, // 2
113  1.0, 1.0, -1.0, -1.0, -1.0, // 3
114  2.0, 2.0, 1.0, 1.0, -1.0, // 4
115  2.0, 1.0, 1.0, -1.0, -1.0, // 5
116  3.0, 2.0, 1.0, 1.0, 1.0, // 6
117  3.0, 1.0, 1.0, -1.0, 1.0, // 7
118  4.0, 2.0, -1.0, 1.0, 1.0, // 8
119  4.0, 1.0, -1.0, -1.0, 1.0, // 9
120  1.0, 3.0, -1.0, 1.0, 1.0, // 10
121  2.0, 3.0, 1.0, 1.0, 1.0, // 11
122  1.0, 0.0, -1.0, -1.0, 1.0, // 12
123  2.0, 0.0, 1.0, -1.0, 1.0, // 13
124  };
125 
126  // Fill vertex buffer
127  float* pData = static_cast<float*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
128  for (size_t vertex = 0, i = 0; vertex < mesh->sharedVertexData->vertexCount; vertex++)
129  {
130  // Position
131  *pData++ = position.x + scale * vertexData[i++];
132  *pData++ = position.y + scale * vertexData[i++];
133  *pData++ = 0.0;
134 
135  // Texture coordinates
136  *pData++ = vertexData[i++];
137  *pData++ = vertexData[i++];
138  *pData++ = vertexData[i++];
139  }
140  vertexBuffer->unlock();
141 
142  // Create index buffer
143  sub->indexData->indexCount = 36;
144  Ogre::HardwareIndexBufferSharedPtr indexBuffer =
145  Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
146  Ogre::HardwareIndexBuffer::IT_16BIT,
147  sub->indexData->indexCount,
148  Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
149  sub->indexData->indexBuffer = indexBuffer;
150 
151  // Index data
152  static const Ogre::uint16 indexData[] = {
153  // Indices // Face
154  0, 1, 2, // 0
155  2, 1, 3, // 1
156  2, 3, 4, // 2
157  4, 3, 5, // 3
158  4, 5, 6, // 4
159  6, 5, 7, // 5
160  6, 7, 8, // 6
161  8, 7, 9, // 7
162  10, 2, 11, // 8
163  11, 2, 4, // 9
164  3, 12, 5, // 10
165  5, 12, 13, // 11
166  };
167 
168  // Fill index buffer
169  indexBuffer->writeData(0, indexBuffer->getSizeInBytes(), indexData, true);
170 
171  mesh->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
172  mesh->_setBoundingSphereRadius(10);
173  mesh->load();
174 
175  Ogre::Entity* e = App::GetGfxScene()->GetSceneManager()->createEntity(mesh->getName());
176  e->setCastShadows(false);
177  e->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - 1);
178  e->setVisible(true);
179 
180  e->setMaterialName("tracks/EnvMapDebug");
181  Ogre::SceneNode* mDebugSceneNode = new Ogre::SceneNode(App::GetGfxScene()->GetSceneManager());
182  mDebugSceneNode->attachObject(e);
183  mDebugSceneNode->setPosition(Ogre::Vector3(0, 0, -5));
184  mDebugSceneNode->setFixedYawAxis(true, Ogre::Vector3::UNIT_Y);
185  mDebugSceneNode->setVisible(true);
186  mDebugSceneNode->_update(true, true);
187  mDebugSceneNode->_updateBounds();
188  overlay->add3D(mDebugSceneNode);
189  overlay->show();
190  }
191  }
192 }
193 
195 {
196  for (int face = 0; face < NUM_FACES; face++)
197  {
198  if (m_cameras[face] != nullptr)
199  {
200  App::GetGfxScene()->GetSceneManager()->destroyCamera(m_cameras[face]);
201  m_render_targets[face]->removeAllViewports();
202  }
203  }
204 }
205 
206 void RoR::GfxEnvmap::UpdateEnvMap(Ogre::Vector3 center, GfxActor* gfx_actor, bool full/*=false*/)
207 {
208  // how many of the 6 render planes to update at once? Use cvar 'gfx_envmap_rate', unless instructed to do full render.
209  const int update_rate = full ? NUM_FACES : App::gfx_envmap_rate->getInt();
210 
211  if (!App::gfx_envmap_enabled->getBool())
212  {
213  return;
214  }
215 
216  if (App::GetGuiManager()->FlexbodyDebug.IsHideOtherElementsModeActive())
217  {
218  return; // Prevent showing meshes hidden by the diagnostic UI.
219  }
220 
221  if (!full && update_rate == 0)
222  {
223  return;
224  }
225 
226  for (int i = 0; i < NUM_FACES; i++)
227  {
228  m_cameras[i]->setPosition(center);
229  }
230 
231  if (gfx_actor != nullptr)
232  {
233  gfx_actor->SetAllMeshesVisible(false);
234  gfx_actor->SetRodsVisible(false);
235  }
236 
237  for (int i = 0; i < update_rate; i++)
238  {
239 #ifdef USE_CAELUM
240  // caelum needs to know that we changed the cameras
241  if (App::GetGameContext()->GetTerrain()->getSkyManager())
242  {
243  App::GetGameContext()->GetTerrain()->getSkyManager()->NotifySkyCameraChanged(m_cameras[m_update_round]);
244  }
245 #endif // USE_CAELUM
246  m_render_targets[m_update_round]->update();
247  m_update_round = (m_update_round + 1) % NUM_FACES;
248  }
249 #ifdef USE_CAELUM
251  {
252  App::GetGameContext()->GetTerrain()->getSkyManager()->NotifySkyCameraChanged(App::GetCameraManager()->GetCamera());
253  }
254 #endif // USE_CAELUM
255 
256  if (gfx_actor != nullptr)
257  {
258  gfx_actor->SetRodsVisible(true);
259  gfx_actor->SetAllMeshesVisible(true);
260  }
261 }
GameContext.h
Game state manager and message-queue provider.
RoR::App::gfx_envmap_rate
CVar * gfx_envmap_rate
Definition: Application.cpp:233
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::App::GetGuiManager
GUIManager * GetGuiManager()
Definition: Application.cpp:269
RoR::GfxEnvmap::~GfxEnvmap
~GfxEnvmap()
Definition: EnvironmentMap.cpp:194
SkyManager.h
EnvironmentMap.h
RoR::Terrain::getSkyManager
SkyManager * getSkyManager()
Definition: Terrain.cpp:513
RoR::GfxEnvmap::GfxEnvmap
GfxEnvmap()
Definition: EnvironmentMap.cpp:36
CameraManager.h
GUIManager.h
RoR::GfxScene::GetSceneManager
Ogre::SceneManager * GetSceneManager()
Definition: GfxScene.h:64
RoR::GfxEnvmap::SetupEnvMap
void SetupEnvMap()
Definition: EnvironmentMap.cpp:43
TOSTRING
#define TOSTRING(x)
Definition: Application.h:56
RoR::GfxActor::SetRodsVisible
void SetRodsVisible(bool visible)
Definition: GfxActor.cpp:1706
GfxScene.h
Application.h
Central state/object manager and communications hub.
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::App::gfx_envmap_enabled
CVar * gfx_envmap_enabled
Definition: Application.cpp:232
RoR::GfxEnvmap::UpdateEnvMap
void UpdateEnvMap(Ogre::Vector3 center, GfxActor *gfx_actor, bool full=false)
Definition: EnvironmentMap.cpp:206
Terrain.h
RoR::GfxActor
Definition: GfxActor.h:52
GfxActor.h
Manager for all visuals belonging to a single actor.
RoR::App::diag_envmap
CVar * diag_envmap
Definition: Application.cpp:138
RoR::CVar::getInt
int getInt() const
Definition: CVar.h:97
RoR::GfxEnvmap::m_cameras
Ogre::Camera * m_cameras[NUM_FACES]
Definition: EnvironmentMap.h:47
RoR::GfxActor::SetAllMeshesVisible
void SetAllMeshesVisible(bool value)
Definition: GfxActor.cpp:3281
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:276
RoR::GfxEnvmap::m_render_targets
Ogre::RenderTarget * m_render_targets[NUM_FACES]
Definition: EnvironmentMap.h:48
RoR::GameContext::GetTerrain
const TerrainPtr & GetTerrain()
Definition: GameContext.h:117