Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
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
206void 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}
Central state/object manager and communications hub.
#define TOSTRING(x)
Definition Application.h:57
Game state manager and message-queue provider.
Manager for all visuals belonging to a single actor.
int getInt() const
Definition CVar.h:97
const TerrainPtr & GetTerrain()
void SetRodsVisible(bool visible)
void SetAllMeshesVisible(bool value)
Ogre::RenderTarget * m_render_targets[NUM_FACES]
Ogre::Camera * m_cameras[NUM_FACES]
void UpdateEnvMap(Ogre::Vector3 center, GfxActor *gfx_actor, bool full=false)
Ogre::SceneManager * GetSceneManager()
Definition GfxScene.h:83
SkyManager * getSkyManager()
Definition Terrain.cpp:522
CVar * gfx_envmap_rate
CameraManager * GetCameraManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
GfxScene * GetGfxScene()
CVar * diag_envmap
CVar * gfx_envmap_enabled