Ticket #2337: Culling.patch
File Culling.patch, 50.3 KB (added by , 10 years ago) |
---|
-
source/graphics/Camera.cpp
126 126 m_ViewFrustum.m_aPlanes[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32; 127 127 m_ViewFrustum.m_aPlanes[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33; 128 128 m_ViewFrustum.m_aPlanes[5].m_Dist = -scissor[0].Z*MatFinal._44 + MatFinal._34; 129 130 for (size_t i = 0; i < 6; ++i) 131 m_ViewFrustum.m_aPlanes[i].Normalize(); 129 132 } 130 133 131 134 void CCamera::ClipFrustum(const CPlane& clipPlane) 132 135 { 133 m_ViewFrustum.AddPlane(clipPlane); 136 CPlane normClipPlane = clipPlane; 137 normClipPlane.Normalize(); 138 m_ViewFrustum.AddPlane(normClipPlane); 134 139 } 135 140 136 141 void CCamera::SetViewPort(const SViewPort& viewport) -
source/graphics/Frustum.cpp
93 93 } 94 94 return false; 95 95 } 96 96 97 bool CFrustum::IsSphereVisible (const CVector3D ¢er, float radius) const 97 98 { 98 for (size_t i =0; i<m_NumPlanes; i++)99 for (size_t i = 0; i < m_NumPlanes; i++) 99 100 { 100 float Dist = m_aPlanes[i].DistanceToPlane (center); 101 102 //is it behind the plane 103 if (Dist < 0) 104 { 105 //if non of it falls in front its outside the 106 //frustum 107 if (-Dist > radius) 108 return false; 109 } 101 float Dist = m_aPlanes[i].DistanceToPlane(center); 102 // If none of the sphere is in front of the plane, then 103 // it is outside the frustum 104 if (-Dist > radius) 105 return false; 110 106 } 111 107 112 108 return true; 113 109 } 114 110 115 116 111 bool CFrustum::IsBoxVisible (const CVector3D &position,const CBoundingBoxAligned &bounds) const 117 112 { 118 113 //basically for every plane we calculate the furthest point -
source/graphics/GameView.cpp
486 486 m->CullCamera.SetProjection(m->ViewNear, m->ViewFar, GetCullFOV()); 487 487 m->CullCamera.UpdateFrustum(); 488 488 } 489 m->ViewCamera.UpdateFrustum(); 489 490 g_Renderer.SetSceneCamera(m->ViewCamera, m->CullCamera); 490 491 491 492 CheckLightEnv(); … … 1055 1056 1056 1057 float CGameView::GetCullFOV() const 1057 1058 { 1058 return m->ViewFOV + DEGTORAD(6.0f); //add 6 degrees to the default FOV for use with the culling frustum; 1059 // XXXX 1060 return m->ViewFOV; 1059 1061 } 1060 1062 1061 1063 void CGameView::SetCameraProjection() -
source/graphics/MapReader.cpp
131 131 RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1200); 132 132 133 133 // read the corresponding XML file 134 RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 5 800);134 RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 50); 135 135 136 // apply data to the world 136 // apply terrain data to the world 137 RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5); 138 139 // read entities 140 RegMemFun(this, &CMapReader::ReadXMLEntities, L"CMapReader::ReadXMLEntities", 5800); 141 142 // apply misc data to the world 137 143 RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5); 138 144 139 145 // load map settings script (must be done after reading map) … … 189 195 // parse RMS results into camera settings 190 196 RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5); 191 197 198 // apply terrain data to the world 199 RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5); 200 192 201 // parse RMS results into entities 193 202 RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000); 194 203 195 // apply data to the world204 // apply misc data to the world 196 205 RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5); 197 206 198 207 // load map settings script (must be done after reading map) … … 264 273 return 0; 265 274 } 266 275 267 // ApplyData: take all the input data, and rebuild the scene from it 268 int CMapReader::ApplyData() 276 int CMapReader::ApplyTerrainData() 269 277 { 270 278 if (m_PatchesPerSide == 0) 271 279 { … … 295 303 } 296 304 } 297 305 } 306 307 CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY); 308 if (cmpTerrain) 309 cmpTerrain->ReloadTerrain(); 310 311 return 0; 312 } 313 314 // ApplyData: take all the input data, and rebuild the scene from it 315 int CMapReader::ApplyData() 316 { 298 317 299 318 // copy over the lighting parameters 300 319 if (pLightEnv) … … 327 346 } 328 347 } 329 348 330 CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);331 if (cmpTerrain)332 cmpTerrain->ReloadTerrain();333 334 349 return 0; 335 350 } 336 351 … … 398 413 399 414 CStr ReadScriptSettings(); 400 415 416 // read everything except for entities 417 void ReadXML(); 418 401 419 // return semantics: see Loader.cpp!LoadFunc. 402 int ProgressiveRead ();420 int ProgressiveReadEntities(); 403 421 404 422 private: 405 423 CXeromyces xmb_file; … … 1071 1089 return 0; 1072 1090 } 1073 1091 1074 int CXMLReader::ProgressiveRead()1092 void CXMLReader::ReadXML() 1075 1093 { 1076 // yield after this time is reached. balances increased progress bar 1077 // smoothness vs. slowing down loading. 1078 const double end_time = timer_Time() + 200e-3; 1079 1080 int ret; 1081 1082 while (node_idx < nodes.Count) 1094 for (int i = 0; i < nodes.Count; ++i) 1083 1095 { 1084 XMBElement node = nodes.Item( node_idx);1096 XMBElement node = nodes.Item(i); 1085 1097 CStr name = xmb_file.GetElementString(node.GetNodeName()); 1086 1098 if (name == "Terrain") 1087 1099 { … … 1097 1109 } 1098 1110 else if (name == "ScriptSettings") 1099 1111 { 1100 // Already loaded - this is to prevent an assertion1112 // Already loaded - this is to prevent an assertion 1101 1113 } 1102 1114 else if (name == "Entities") 1103 1115 { 1104 if (!m_MapReader.m_SkipEntities) 1105 { 1106 ret = ReadEntities(node, end_time); 1107 if (ret != 0) // error or timed out 1108 return ret; 1109 } 1116 // Handled by ProgressiveReadEntities instead 1110 1117 } 1111 1118 else if (name == "Paths") 1112 1119 { … … 1126 1133 debug_printf(L"Invalid XML element in map file: %hs\n", name.c_str()); 1127 1134 debug_warn(L"Invalid map XML data"); 1128 1135 } 1136 } 1137 } 1129 1138 1139 int CXMLReader::ProgressiveReadEntities() 1140 { 1141 // yield after this time is reached. balances increased progress bar 1142 // smoothness vs. slowing down loading. 1143 const double end_time = timer_Time() + 200e-3; 1144 1145 int ret; 1146 1147 while (node_idx < nodes.Count) 1148 { 1149 XMBElement node = nodes.Item(node_idx); 1150 CStr name = xmb_file.GetElementString(node.GetNodeName()); 1151 if (name == "Entities") 1152 { 1153 if (!m_MapReader.m_SkipEntities) 1154 { 1155 ret = ReadEntities(node, end_time); 1156 if (ret != 0) // error or timed out 1157 return ret; 1158 } 1159 } 1130 1160 node_idx++; 1131 1161 } 1132 1162 1133 1163 return 0; 1134 1164 } 1135 1165 … … 1167 1197 return 0; 1168 1198 } 1169 1199 1170 // progressive1171 1200 int CMapReader::ReadXML() 1172 1201 { 1173 1202 if (!xml_reader) 1174 1203 xml_reader = new CXMLReader(filename_xml, *this); 1204 1205 xml_reader->ReadXML(); 1206 1207 return 0; 1208 } 1175 1209 1176 int ret = xml_reader->ProgressiveRead(); 1210 // progressive 1211 int CMapReader::ReadXMLEntities() 1212 { 1213 if (!xml_reader) 1214 xml_reader = new CXMLReader(filename_xml, *this); 1215 1216 int ret = xml_reader->ProgressiveReadEntities(); 1177 1217 // finished or failed 1178 1218 if (ret <= 0) 1179 1219 { -
source/graphics/MapReader.h
79 79 80 80 // ApplyData: take all the input data, and rebuild the scene from it 81 81 int ApplyData(); 82 int ApplyTerrainData(); 82 83 83 // ReadXML: read some other data (entities, etc) in XML format84 // read some misc data from the XML file 84 85 int ReadXML(); 86 87 // read entity data from the XML file 88 int ReadXMLEntities(); 85 89 86 90 // clean up everything used during delayed load 87 91 int DelayLoadFinished(); -
source/graphics/Overlay.h
154 154 CColor m_Color; 155 155 }; 156 156 157 struct SOverlaySphere 158 { 159 SOverlaySphere() : m_Radius(0) { } 160 161 CVector3D m_Center; 162 float m_Radius; 163 CColor m_Color; 164 }; 165 157 166 // TODO: OverlayText 158 167 159 168 #endif // INCLUDED_GRAPHICS_OVERLAY -
source/maths/BoundingBoxAligned.h
54 54 * computing this result, and then taking the axis-aligned bounding boxes from the result again. 55 55 */ 56 56 void Transform(const CMatrix3D& m, CBoundingBoxOriented& result) const; 57 57 58 /** 59 * Translates these bounds by @p v, and writes the result to @p result. 60 */ 61 void Translate(const CVector3D& v, CBoundingBoxAligned& result) const 62 { 63 result.m_Data[0] = m_Data[0] + v; 64 result.m_Data[1] = m_Data[1] + v; 65 } 66 58 67 CVector3D& operator[](int index) { return m_Data[index]; } 59 68 const CVector3D& operator[](int index) const { return m_Data[index]; } 60 69 -
source/ps/CStrInternStatic.h
107 107 X(normalMap) 108 108 X(normalMap2) 109 109 X(objectColor) 110 X(overlay_solid) 110 111 X(particle) 111 112 X(particle_solid) 112 113 X(playerColor) -
source/renderer/OverlayRenderer.cpp
88 88 std::vector<SOverlayTexturedLine*> texlines; 89 89 std::vector<SOverlaySprite*> sprites; 90 90 std::vector<SOverlayQuad*> quads; 91 std::vector<SOverlaySphere*> spheres; 91 92 92 93 QuadBatchMap quadBatchMap; 93 94 … … 223 224 m->quads.push_back(overlay); 224 225 } 225 226 227 void OverlayRenderer::Submit(SOverlaySphere* overlay) 228 { 229 m->spheres.push_back(overlay); 230 } 231 226 232 void OverlayRenderer::EndFrame() 227 233 { 228 234 m->lines.clear(); 229 235 m->texlines.clear(); 230 236 m->sprites.clear(); 231 237 m->quads.clear(); 238 m->spheres.clear(); 239 232 240 // this should leave the capacity unchanged, which is okay since it 233 241 // won't be very large or very variable 234 242 … … 384 392 385 393 RenderTexturedOverlayLines(); 386 394 RenderQuadOverlays(); 395 RenderSphereOverlays(); 387 396 } 388 397 389 398 void OverlayRenderer::RenderTexturedOverlayLines() … … 629 638 glDisable(GL_TEXTURE_2D); 630 639 #endif 631 640 } 641 642 static void TessellateSphereFace(const CVector3D& a, u16 ai, 643 const CVector3D& b, u16 bi, 644 const CVector3D& c, u16 ci, 645 std::vector<float>& vertexes, std::vector<u16>& indexes, int level) 646 { 647 if (level == 0) 648 { 649 indexes.push_back(ai); 650 indexes.push_back(bi); 651 indexes.push_back(ci); 652 } 653 else 654 { 655 CVector3D d = (a + b).Normalized(); 656 CVector3D e = (b + c).Normalized(); 657 CVector3D f = (c + a).Normalized(); 658 int di = vertexes.size() / 3; vertexes.push_back(d.X); vertexes.push_back(d.Y); vertexes.push_back(d.Z); 659 int ei = vertexes.size() / 3; vertexes.push_back(e.X); vertexes.push_back(e.Y); vertexes.push_back(e.Z); 660 int fi = vertexes.size() / 3; vertexes.push_back(f.X); vertexes.push_back(f.Y); vertexes.push_back(f.Z); 661 TessellateSphereFace(a,ai, d,di, f,fi, vertexes, indexes, level-1); 662 TessellateSphereFace(d,di, b,bi, e,ei, vertexes, indexes, level-1); 663 TessellateSphereFace(f,fi, e,ei, c,ci, vertexes, indexes, level-1); 664 TessellateSphereFace(d,di, e,ei, f,fi, vertexes, indexes, level-1); 665 } 666 } 667 668 static void TessellateSphere(std::vector<float>& vertexes, std::vector<u16>& indexes, int level) 669 { 670 /* Start with a tetrahedron, then tessellate */ 671 float s = sqrtf(0.5f); 672 #define VERT(a,b,c) vertexes.push_back(a); vertexes.push_back(b); vertexes.push_back(c); 673 VERT(-s, 0, -s); 674 VERT( s, 0, -s); 675 VERT( s, 0, s); 676 VERT(-s, 0, s); 677 VERT( 0, -1, 0); 678 VERT( 0, 1, 0); 679 #define FACE(a,b,c) \ 680 TessellateSphereFace( \ 681 CVector3D(vertexes[a*3], vertexes[a*3+1], vertexes[a*3+2]), a, \ 682 CVector3D(vertexes[b*3], vertexes[b*3+1], vertexes[b*3+2]), b, \ 683 CVector3D(vertexes[c*3], vertexes[c*3+1], vertexes[c*3+2]), c, \ 684 vertexes, indexes, level); 685 FACE(0,4,1); 686 FACE(1,4,2); 687 FACE(2,4,3); 688 FACE(3,4,0); 689 FACE(1,5,0); 690 FACE(2,5,1); 691 FACE(3,5,2); 692 FACE(0,5,3); 693 #undef FACE 694 #undef VERT 695 } 696 697 void OverlayRenderer::RenderSphereOverlays() 698 { 699 PROFILE3_GPU("overlays (spheres)"); 700 701 if (g_Renderer.GetRenderPath() != CRenderer::RP_SHADER) 702 return; 703 704 if (m->spheres.empty()) 705 return; 706 707 glDisable(GL_TEXTURE_2D); 708 glEnable(GL_BLEND); 709 glDepthMask(0); 710 711 glEnableClientState(GL_VERTEX_ARRAY); 712 713 CShaderProgramPtr shader; 714 CShaderTechniquePtr tech; 715 716 tech = g_Renderer.GetShaderManager().LoadEffect(str_overlay_solid); 717 tech->BeginPass(); 718 shader = tech->GetShader(); 719 720 static std::vector<float> vertexes; 721 static std::vector<u16> indexes; 722 ONCE(TessellateSphere(vertexes, indexes, 3)); 723 724 shader->VertexPointer(3, GL_FLOAT, 0, &vertexes[0]); 725 726 for (size_t i = 0; i < m->spheres.size(); ++i) 727 { 728 SOverlaySphere* sphere = m->spheres[i]; 729 730 CMatrix3D transform; 731 transform.SetIdentity(); 732 transform.Scale(sphere->m_Radius, sphere->m_Radius, sphere->m_Radius); 733 transform.Translate(sphere->m_Center); 734 735 shader->Uniform(str_transform, transform); 736 737 shader->Uniform(str_color, sphere->m_Color); 738 739 glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, &indexes[0]); 740 741 g_Renderer.GetStats().m_DrawCalls++; 742 g_Renderer.GetStats().m_OverlayTris = indexes.size()/3; 743 } 744 745 tech->EndPass(); 746 747 glDisableClientState(GL_VERTEX_ARRAY); 748 749 glDepthMask(1); 750 glDisable(GL_BLEND); 751 } -
source/renderer/OverlayRenderer.h
24 24 struct SOverlayTexturedLine; 25 25 struct SOverlaySprite; 26 26 struct SOverlayQuad; 27 struct SOverlaySphere; 27 28 class CCamera; 28 29 29 30 struct OverlayRendererInternals; … … 74 75 */ 75 76 void Submit(SOverlayQuad* overlay); 76 77 78 void Submit(SOverlaySphere* overlay); 79 77 80 /** 78 81 * Prepare internal data structures for rendering. 79 82 * Must be called after all Submit calls for a frame, and before … … 132 135 */ 133 136 void RenderQuadOverlays(); 134 137 138 void RenderSphereOverlays(); 139 135 140 private: 136 141 OverlayRendererInternals* m; 137 142 }; -
source/renderer/Renderer.cpp
1127 1127 1128 1128 /////////////////////////////////////////////////////////////////////////////////////////////////// 1129 1129 // RenderReflections: render the water reflections to the reflection texture 1130 SScreenRect CRenderer::RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor)1130 void CRenderer::RenderReflections(Scene& scene, const CBoundingBoxAligned& scissor) 1131 1131 { 1132 1132 PROFILE3_GPU("water reflections"); 1133 1133 1134 CShaderDefines context = m->globalContext; 1135 1134 1136 WaterManager& wm = m->waterManager; 1135 1137 1136 1138 // Remember old camera … … 1143 1145 // of the view so we can see wavy reflections of slightly off-screen objects. 1144 1146 m_ViewCamera.m_Orientation.Scale(1, -1, 1); 1145 1147 m_ViewCamera.m_Orientation.Translate(0, 2*wm.m_WaterHeight, 0); 1146 m_ViewCamera.UpdateFrustum(scissor);1147 1148 m_ViewCamera.ClipFrustum(CVector4D(0, 1, 0, -wm.m_WaterHeight)); 1148 1149 1149 1150 SViewPort vp; … … 1152 1153 vp.m_X = 0; 1153 1154 vp.m_Y = 0; 1154 1155 m_ViewCamera.SetViewPort(vp); 1155 m_ViewCamera.SetProjection(normalCamera.GetNearPlane(), normalCamera.GetFarPlane(), normalCamera.GetFOV()*1.05f); // Slightly higher than view FOV1156 1156 CMatrix3D scaleMat; 1157 1157 scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f); 1158 1158 m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat; … … 1162 1162 CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight); 1163 1163 SetObliqueFrustumClipping(camPlane); 1164 1164 1165 // enumerate objects for our frustrum. 1166 m_ViewCamera.UpdateFrustum(); 1167 CFrustum frustum = m_ViewCamera.GetFrustum(); 1168 scene.EnumerateObjects(frustum, this); 1169 m->particleManager.RenderSubmit(*this, frustum); 1170 1171 m->terrainRenderer.PrepareForRendering(); 1172 m->particleRenderer.PrepareForRendering(context); 1173 1174 1165 1175 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1166 1176 wm.m_ReflectionMatrix = m_ViewCamera.GetViewProjection(); 1167 1177 1168 SScreenRect screenScissor; 1169 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width); 1170 screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height); 1171 screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width); 1172 screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height); 1173 1174 if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2) 1175 { 1176 glEnable(GL_SCISSOR_TEST); 1177 glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1178 1179 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1180 1181 glFrontFace(GL_CW); 1178 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1179 1180 // Save the post-processing framebuffer. 1181 GLint fbo; 1182 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo); 1183 1184 GLuint waterBuffer = 0; 1185 pglGenFramebuffersEXT(1, &waterBuffer); 1186 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterBuffer); 1187 1188 glEnable(GL_TEXTURE_2D); 1182 1189 1183 // Render sky, terrain and models 1184 m->skyManager.RenderSky(); 1185 ogl_WarnIfError(); 1186 RenderPatches(context, &m_ViewCamera.GetFrustum()); 1187 ogl_WarnIfError(); 1188 RenderModels(context, &m_ViewCamera.GetFrustum()); 1189 ogl_WarnIfError(); 1190 RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum()); 1191 ogl_WarnIfError(); 1190 glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture); 1191 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_ReflectionTexture, 0); 1192 1193 glFrontFace(GL_CW); 1192 1194 1193 glFrontFace(GL_CCW); 1195 glClearColor(0.5f,0.5f,1.0f,0.0f); 1196 glClear(GL_COLOR_BUFFER_BIT); 1194 1197 1195 glDisable(GL_SCISSOR_TEST); 1198 1199 // Render sky, terrain and models 1200 m->skyManager.RenderSky(); 1201 ogl_WarnIfError(); 1202 RenderPatches(context, &m_ViewCamera.GetFrustum()); 1203 ogl_WarnIfError(); 1204 RenderModels(context, &m_ViewCamera.GetFrustum()); 1205 ogl_WarnIfError(); 1206 RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum()); 1207 ogl_WarnIfError(); 1208 1209 glFrontFace(GL_CCW); 1196 1210 1197 // Copy the image to a texture 1198 pglActiveTextureARB(GL_TEXTURE0); 1199 glEnable(GL_TEXTURE_2D); 1200 glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture); 1201 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1202 screenScissor.x1, screenScissor.y1, 1203 screenScissor.x1, screenScissor.y1, 1204 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1205 } 1211 // rebind post-processing frambuffer. 1212 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 1206 1213 1207 1214 // Reset old camera 1208 1215 m_ViewCamera = normalCamera; 1209 1216 m->SetOpenGLCamera(m_ViewCamera); 1210 1211 return screenScissor;1212 1217 } 1213 1218 1214 1219 1215 1220 /////////////////////////////////////////////////////////////////////////////////////////////////// 1216 1221 // RenderRefractions: render the water refractions to the refraction texture 1217 SScreenRect CRenderer::RenderRefractions(const CShaderDefines& context,const CBoundingBoxAligned &scissor)1222 void CRenderer::RenderRefractions(const CBoundingBoxAligned &scissor) 1218 1223 { 1219 1224 PROFILE3_GPU("water refractions"); 1220 1225 1226 CShaderDefines context = m->globalContext; 1227 1221 1228 WaterManager& wm = m->waterManager; 1222 1229 1223 1230 // Remember old camera … … 1249 1256 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1250 1257 wm.m_RefractionMatrix = m_ViewCamera.GetViewProjection(); 1251 1258 1252 SScreenRect screenScissor; 1253 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width); 1254 screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height); 1255 screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width); 1256 screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height); 1257 if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2) 1258 { 1259 glEnable(GL_SCISSOR_TEST); 1260 glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1261 1262 glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // a neutral gray to blend in with shores 1263 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1264 1265 // Render terrain and models 1266 RenderPatches(context, &m_ViewCamera.GetFrustum()); 1267 ogl_WarnIfError(); 1268 RenderModels(context, &m_ViewCamera.GetFrustum()); 1269 ogl_WarnIfError(); 1270 RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum()); 1271 ogl_WarnIfError(); 1272 1273 glDisable(GL_SCISSOR_TEST); 1274 1275 // Copy the image to a texture 1276 pglActiveTextureARB(GL_TEXTURE0); 1277 glEnable(GL_TEXTURE_2D); 1278 glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture); 1279 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1280 screenScissor.x1, screenScissor.y1, 1281 screenScissor.x1, screenScissor.y1, 1282 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1283 } 1259 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1260 1261 // Save the post-processing framebuffer. 1262 GLint fbo; 1263 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo); 1264 1265 GLuint waterBuffer = 0; 1266 pglGenFramebuffersEXT(1, &waterBuffer); 1267 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterBuffer); 1268 1269 glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture); 1270 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_RefractionTexture, 0); 1271 1272 glClearColor(0.5f,0.5f,1.0f,0.0f); 1273 glClear(GL_COLOR_BUFFER_BIT); 1274 1275 glEnable(GL_TEXTURE_2D); 1276 1277 // Render sky, terrain and models 1278 m->skyManager.RenderSky(); 1279 ogl_WarnIfError(); 1280 RenderPatches(context, &m_ViewCamera.GetFrustum()); 1281 ogl_WarnIfError(); 1282 RenderModels(context, &m_ViewCamera.GetFrustum()); 1283 ogl_WarnIfError(); 1284 RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum()); 1285 ogl_WarnIfError(); 1286 1287 // rebind post-processing frambuffer. 1288 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 1289 glBindTexture(GL_TEXTURE_2D, 0); 1284 1290 1285 1291 // Reset old camera 1286 1292 m_ViewCamera = normalCamera; 1287 1293 m->SetOpenGLCamera(m_ViewCamera); 1288 1289 return screenScissor;1290 1294 } 1291 1295 1292 1296 … … 1429 1433 1430 1434 /////////////////////////////////////////////////////////////////////////////////////////////////// 1431 1435 // RenderSubmissions: force rendering of any batched objects 1432 void CRenderer::RenderSubmissions( )1436 void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor) 1433 1437 { 1434 1438 PROFILE3("render submissions"); 1435 1439 … … 1474 1478 } 1475 1479 1476 1480 ogl_WarnIfError(); 1477 1478 CBoundingBoxAligned waterScissor;1479 if (m_WaterManager->m_RenderWater)1480 {1481 waterScissor = m->terrainRenderer.ScissorWater(m_ViewCamera.GetViewProjection());1482 if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater())1483 {1484 PROFILE3_GPU("water scissor");1485 SScreenRect dirty = { 0, 0, 0, 0 };1486 if (m_Options.m_WaterRefraction && m_Options.m_WaterReflection)1487 {1488 SScreenRect reflectionScissor = RenderReflections(context, waterScissor);1489 SScreenRect refractionScissor = RenderRefractions(context, waterScissor);1490 dirty.x1 = std::min(reflectionScissor.x1, refractionScissor.x1);1491 dirty.y1 = std::min(reflectionScissor.y1, refractionScissor.y1);1492 dirty.x2 = std::max(reflectionScissor.x2, refractionScissor.x2);1493 dirty.y2 = std::max(reflectionScissor.y2, refractionScissor.y2);1494 }1495 else if (m_Options.m_WaterRefraction)1496 {1497 SScreenRect refractionScissor = RenderRefractions(context, waterScissor);1498 dirty.x1 = refractionScissor.x1;1499 dirty.y1 = refractionScissor.y1;1500 dirty.x2 = refractionScissor.x2;1501 dirty.y2 = refractionScissor.y2;1502 }1503 else if (m_Options.m_WaterReflection)1504 {1505 SScreenRect reflectionScissor = RenderReflections(context, waterScissor);1506 dirty.x1 = reflectionScissor.x1;1507 dirty.y1 = reflectionScissor.y1;1508 dirty.x2 = reflectionScissor.x2;1509 dirty.y2 = reflectionScissor.y2;1510 }1511 if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2)1512 {1513 glEnable(GL_SCISSOR_TEST);1514 glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1);1515 glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);1516 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1517 glDisable(GL_SCISSOR_TEST);1518 }1519 }1520 }1521 1522 1481 if (m_Options.m_ShowSky) 1523 1482 { 1524 1483 m->skyManager.RenderSky(); … … 1540 1499 ogl_WarnIfError(); 1541 1500 1542 1501 // render water 1543 if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0 )1502 if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0.0f) 1544 1503 { 1545 1504 // render transparent stuff, but only the solid parts that can occlude block water 1546 1505 RenderTransparentModels(context, TRANSPARENT_OPAQUE); … … 1729 1688 m->overlayRenderer.Submit(overlay); 1730 1689 } 1731 1690 1691 void CRenderer::Submit(SOverlaySphere* overlay) 1692 { 1693 m->overlayRenderer.Submit(overlay); 1694 } 1695 1732 1696 void CRenderer::Submit(CModelDecal* decal) 1733 1697 { 1734 1698 m->terrainRenderer.Submit(decal); … … 1780 1744 1781 1745 m->particleManager.RenderSubmit(*this, frustum); 1782 1746 1747 CBoundingBoxAligned waterScissor; 1748 waterScissor = m->terrainRenderer.ScissorWater(m_ViewCamera.GetViewProjection()); 1749 1783 1750 ogl_WarnIfError(); 1784 1751 1785 RenderSubmissions(); 1752 RenderSubmissions(waterScissor); 1753 1754 RenderRefractions(waterScissor); 1755 1756 // empty lists 1757 m->terrainRenderer.EndFrame(); 1758 m->overlayRenderer.EndFrame(); 1759 m->particleRenderer.EndFrame(); 1760 1761 // Finish model renderers 1762 m->Model.NormalSkinned->EndFrame(); 1763 m->Model.TranspSkinned->EndFrame(); 1764 if (m->Model.NormalUnskinned != m->Model.NormalSkinned) 1765 m->Model.NormalUnskinned->EndFrame(); 1766 if (m->Model.TranspUnskinned != m->Model.TranspSkinned) 1767 m->Model.TranspUnskinned->EndFrame(); 1768 1769 ogl_WarnIfError(); 1770 1771 RenderReflections(scene, waterScissor); 1786 1772 1787 1773 m_CurrentScene = NULL; 1788 1774 } -
source/renderer/Renderer.h
349 349 void Submit(SOverlayQuad* overlay); 350 350 void Submit(CModelDecal* decal); 351 351 void Submit(CParticleEmitter* emitter); 352 void Submit(SOverlaySphere* overlay); 352 353 void SubmitNonRecursive(CModel* model); 353 354 //END: Implementation of SceneCollector 354 355 355 356 // render any batched objects 356 void RenderSubmissions( );357 void RenderSubmissions(const CBoundingBoxAligned& waterScissor); 357 358 358 359 // patch rendering stuff 359 360 void RenderPatches(const CShaderDefines& context, const CFrustum* frustum = 0); … … 370 371 void RenderShadowMap(const CShaderDefines& context); 371 372 372 373 // render water reflection and refraction textures 373 SScreenRect RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor);374 SScreenRect RenderRefractions(const CShaderDefines& context,const CBoundingBoxAligned& scissor);374 void RenderReflections(Scene& scene, const CBoundingBoxAligned& scissor); 375 void RenderRefractions(const CBoundingBoxAligned& scissor); 375 376 376 377 // debugging 377 378 void DisplayFrustum(); -
source/renderer/Scene.h
40 40 struct SOverlayTexturedLine; 41 41 struct SOverlaySprite; 42 42 struct SOverlayQuad; 43 struct SOverlaySphere; 43 44 44 45 class SceneCollector; 45 46 … … 110 111 virtual void Submit(SOverlayQuad* overlay) = 0; 111 112 112 113 /** 114 * Submit a sphere overlay. 115 */ 116 virtual void Submit(SOverlaySphere* overlay) = 0; 117 118 /** 113 119 * Submit a terrain decal. 114 120 */ 115 121 virtual void Submit(CModelDecal* decal) = 0; -
source/simulation2/MessageTypes.h
27 27 28 28 #include "simulation2/components/ICmpPathfinder.h" 29 29 30 #include "maths/Vector3D.h" 31 30 32 #define DEFAULT_MESSAGE_IMPL(name) \ 31 33 virtual int GetType() const { return MT_##name; } \ 32 34 virtual const char* GetScriptHandlerName() const { return "On" #name; } \ … … 258 260 entity_angle_t a; 259 261 }; 260 262 263 class CMessageInterpolatedPositionChanged : public CMessage 264 { 265 public: 266 DEFAULT_MESSAGE_IMPL(InterpolatedPositionChanged) 267 268 CMessageInterpolatedPositionChanged(entity_id_t entity, bool inWorld, const CVector3D& pos0, const CVector3D& pos1) : 269 entity(entity), inWorld(inWorld), pos0(pos0), pos1(pos1) 270 { 271 } 272 273 entity_id_t entity; 274 bool inWorld; 275 CVector3D pos0; 276 CVector3D pos1; 277 }; 278 261 279 /** 262 280 * Sent by CCmpUnitMotion during Update, whenever the motion status has changed 263 281 * since the previous update. … … 277 295 }; 278 296 279 297 /** 298 * Sent when water height has been changed. 299 */ 300 class CMessageWaterChanged : public CMessage 301 { 302 public: 303 DEFAULT_MESSAGE_IMPL(WaterChanged) 304 305 CMessageWaterChanged() 306 { 307 } 308 }; 309 310 /** 280 311 * Sent when terrain (texture or elevation) has been changed. 281 312 */ 282 313 class CMessageTerrainChanged : public CMessage -
source/simulation2/Simulation2.cpp
104 104 componentManager.AddComponent(systemEntity, CID_TemplateManager, noParam); 105 105 106 106 componentManager.AddComponent(systemEntity, CID_CommandQueue, noParam); 107 componentManager.AddComponent(systemEntity, CID_ModelRenderer, noParam); 107 108 componentManager.AddComponent(systemEntity, CID_ObstructionManager, noParam); 108 109 componentManager.AddComponent(systemEntity, CID_ParticleManager, noParam); 109 110 componentManager.AddComponent(systemEntity, CID_Pathfinder, noParam); -
source/simulation2/TypeList.h
42 42 MESSAGE(Destroy) 43 43 MESSAGE(OwnershipChanged) 44 44 MESSAGE(PositionChanged) 45 MESSAGE(InterpolatedPositionChanged) 45 46 MESSAGE(MotionChanged) 46 47 MESSAGE(RangeUpdate) 47 48 MESSAGE(TerrainChanged) 49 MESSAGE(WaterChanged) 48 50 MESSAGE(TerritoriesChanged) 49 51 MESSAGE(PathResult) 50 52 MESSAGE(ValueModification) … … 90 92 INTERFACE(Minimap) 91 93 COMPONENT(Minimap) 92 94 95 INTERFACE(ModelRenderer) 96 COMPONENT(ModelRenderer) 97 93 98 INTERFACE(Motion) 94 99 COMPONENT(MotionBall) 95 100 COMPONENT(MotionScripted) -
source/simulation2/components/CCmpPosition.cpp
43 43 { 44 44 componentManager.SubscribeToMessageType(MT_TurnStart); 45 45 componentManager.SubscribeToMessageType(MT_Interpolate); 46 componentManager.SubscribeToMessageType(MT_TerrainChanged); 47 componentManager.SubscribeToMessageType(MT_WaterChanged); 46 48 47 49 // TODO: if this component turns out to be a performance issue, it should 48 50 // be optimised by creating a new PositionStatic component that doesn't subscribe … … 59 61 UPRIGHT = 0, 60 62 PITCH = 1, 61 63 PITCH_ROLL = 2, 62 ROLL =3,64 ROLL = 3, 63 65 } m_AnchorType; 64 66 65 bool m_Floating;66 67 float m_RotYSpeed; // maximum radians per second, used by InterpolatedRotY to follow RotY 67 68 69 bool m_Floating; 68 70 // Dynamic state: 69 71 70 72 bool m_InWorld; 71 73 // m_LastX/Z contain the position from the start of the most recent turn 72 74 // m_PrevX/Z conatain the position from the turn before that 75 bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height 73 76 entity_pos_t m_X, m_Z, m_LastX, m_LastZ, m_PrevX, m_PrevZ; // these values contain undefined junk if !InWorld 74 77 entity_pos_t m_YOffset, m_LastYOffset; 75 bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height76 78 77 79 entity_angle_t m_RotX, m_RotY, m_RotZ; 78 80 … … 221 223 m_InWorld = false; 222 224 223 225 AdvertisePositionChanges(); 226 AdvertiseInterpolatedPositionChanges(); 224 227 } 225 228 226 229 virtual void MoveTo(entity_pos_t x, entity_pos_t z) … … 237 240 } 238 241 239 242 AdvertisePositionChanges(); 243 AdvertiseInterpolatedPositionChanges(); 240 244 } 241 245 242 246 virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry) … … 254 258 } 255 259 256 260 AdvertisePositionChanges(); 261 AdvertiseInterpolatedPositionChanges(); 257 262 } 258 263 259 264 virtual void JumpTo(entity_pos_t x, entity_pos_t z) … … 268 273 m_LastInterpolatedRotZ = m_InterpolatedRotZ; 269 274 270 275 AdvertisePositionChanges(); 276 AdvertiseInterpolatedPositionChanges(); 271 277 } 272 278 273 279 virtual void SetHeightOffset(entity_pos_t dy) … … 284 290 } 285 291 286 292 AdvertisePositionChanges(); 293 AdvertiseInterpolatedPositionChanges(); 287 294 } 288 295 289 296 virtual entity_pos_t GetHeightOffset() … … 303 310 m_LastYOffset = m_YOffset; 304 311 m_YOffset = y; 305 312 } 313 314 AdvertisePositionChanges(); 315 AdvertiseInterpolatedPositionChanges(); 306 316 } 307 317 308 318 virtual bool IsFloating() … … 495 505 496 506 return m; 497 507 } 508 509 void GetInterpolatedPositions(CVector3D& pos0, CVector3D& pos1) 510 { 511 float baseY0 = 0; 512 float baseY1 = 0; 513 float x0 = m_LastX.ToFloat(); 514 float z0 = m_LastZ.ToFloat(); 515 float x1 = m_X.ToFloat(); 516 float z1 = m_Z.ToFloat(); 517 if (m_RelativeToGround) 518 { 519 CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY); 520 if (cmpTerrain) 521 { 522 baseY0 = cmpTerrain->GetExactGroundLevel(x0, z0); 523 baseY1 = cmpTerrain->GetExactGroundLevel(x1, z1); 524 } 525 526 if (m_Floating) 527 { 528 CmpPtr<ICmpWaterManager> cmpWaterManager(GetSimContext(), SYSTEM_ENTITY); 529 if (cmpWaterManager) 530 { 531 baseY0 = std::max(baseY0, cmpWaterManager->GetExactWaterLevel(x0, z0)); 532 baseY1 = std::max(baseY1, cmpWaterManager->GetExactWaterLevel(x1, z1)); 533 } 534 } 535 } 536 537 float y0 = baseY0 + m_LastYOffset.ToFloat(); 538 float y1 = baseY1 + m_YOffset.ToFloat(); 539 540 pos0 = CVector3D(x0, y0, z0); 541 pos1 = CVector3D(x1, y1, z1); 542 } 498 543 499 544 virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) 500 545 { … … 558 603 559 604 break; 560 605 } 606 case MT_TerrainChanged: 607 case MT_WaterChanged: 608 { 609 AdvertiseInterpolatedPositionChanges(); 610 break; 611 } 561 612 } 562 613 }; 563 614 … … 575 626 GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); 576 627 } 577 628 } 578 629 630 void AdvertiseInterpolatedPositionChanges() 631 { 632 if (m_InWorld) 633 { 634 CVector3D pos0, pos1; 635 GetInterpolatedPositions(pos0, pos1); 636 637 CMessageInterpolatedPositionChanged msg(GetEntityId(), true, pos0, pos1); 638 GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); 639 } 640 else 641 { 642 CMessageInterpolatedPositionChanged msg(GetEntityId(), false, CVector3D(), CVector3D()); 643 GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); 644 } 645 } 646 579 647 void UpdateXZRotation() 580 648 { 581 649 if (!m_InWorld) -
source/simulation2/components/CCmpRangeManager.cpp
1361 1361 return VIS_VISIBLE; 1362 1362 1363 1363 // Fogged if the 'retain in fog' flag is set, and in a non-visible explored region 1364 if (los.IsExplored(i, j ))1364 if (los.IsExplored(i, j, true)) 1365 1365 { 1366 1366 CmpPtr<ICmpVision> cmpVision(ent); 1367 1367 if (forceRetainInFog || (cmpVision && cmpVision->GetRetainInFog())) -
source/simulation2/components/CCmpTerrain.cpp
144 144 virtual void MakeDirty(i32 i0, i32 j0, i32 i1, i32 j1) 145 145 { 146 146 CMessageTerrainChanged msg(i0, j0, i1, j1); 147 GetSimContext().GetComponentManager(). PostMessage(GetEntityId(),msg);147 GetSimContext().GetComponentManager().BroadcastMessage(msg); 148 148 } 149 149 }; 150 150 -
source/simulation2/components/CCmpVisualActor.cpp
23 23 #include "simulation2/MessageTypes.h" 24 24 25 25 #include "ICmpFootprint.h" 26 #include "ICmpModelRenderer.h" 26 27 #include "ICmpOwnership.h" 27 28 #include "ICmpPosition.h" 28 29 #include "ICmpRangeManager.h" … … 40 41 #include "graphics/Unit.h" 41 42 #include "graphics/UnitAnimation.h" 42 43 #include "graphics/UnitManager.h" 44 #include "maths/BoundingSphere.h" 43 45 #include "maths/Matrix3D.h" 44 46 #include "maths/Vector3D.h" 45 47 #include "ps/CLogger.h" … … 54 56 static void ClassInit(CComponentManager& componentManager) 55 57 { 56 58 componentManager.SubscribeToMessageType(MT_Update_Final); 57 componentManager.SubscribeToMessageType(MT_Interpolate); 58 componentManager.SubscribeToMessageType(MT_RenderSubmit); 59 //componentManager.SubscribeToMessageType(MT_Interpolate); 60 componentManager.SubscribeToMessageType(MT_InterpolatedPositionChanged); 61 //componentManager.SubscribeToMessageType(MT_RenderSubmit); 59 62 componentManager.SubscribeToMessageType(MT_OwnershipChanged); 60 componentManager.SubscribeGloballyToMessageType(MT_TerrainChanged); 63 componentManager.SubscribeToMessageType(MT_TerrainChanged); 64 componentManager.SubscribeToMessageType(MT_Destroy); 61 65 } 62 66 63 67 DEFAULT_COMPONENT_ALLOCATOR(VisualActor) … … 92 96 /// Whether the visual actor has been rendered at least once. 93 97 /// Necessary because the visibility update runs on simulation update, 94 98 /// which may not occur immediately if the game starts paused. 95 bool m_PreviouslyRendered; 99 //bool m_PreviouslyRendered; 100 101 bool m_VisibilityDirty; 102 103 ICmpModelRenderer::tag_t m_ModelTag; 96 104 97 105 public: 98 106 static std::string GetSchema() … … 178 186 179 187 virtual void Init(const CParamNode& paramNode) 180 188 { 181 m_PreviouslyRendered = false; 189 // m_PreviouslyRendered = false; 190 m_VisibilityDirty = true; 182 191 m_Unit = NULL; 183 192 m_Visibility = ICmpRangeManager::VIS_HIDDEN; 184 193 m_R = m_G = m_B = fixed::FromInt(1); … … 295 304 Interpolate(msgData.deltaSimTime, msgData.offset); 296 305 break; 297 306 } 298 case MT_RenderSubmit:299 {300 const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);301 RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);302 break;303 }307 //case MT_RenderSubmit: 308 //{ 309 // const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg); 310 // RenderSubmit(msgData.collector, msgData.frustum, msgData.culling); 311 // break; 312 //} 304 313 case MT_OwnershipChanged: 305 314 { 306 315 const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg); … … 313 322 m_Unit->GetModel().SetTerrainDirty(msgData.i0, msgData.j0, msgData.i1, msgData.j1); 314 323 break; 315 324 } 325 case MT_InterpolatedPositionChanged: 326 { 327 const CMessageInterpolatedPositionChanged& msgData = static_cast<const CMessageInterpolatedPositionChanged&> (msg); 328 if (m_ModelTag.valid()) 329 { 330 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 331 cmpModelRenderer->UpdateUnitPos(m_ModelTag, msgData.inWorld, msgData.pos0, msgData.pos1); 332 } 333 break; 334 } 335 case MT_Destroy: 336 { 337 if (m_ModelTag.valid()) 338 { 339 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 340 cmpModelRenderer->RemoveUnit(m_ModelTag); 341 m_ModelTag = ICmpModelRenderer::tag_t(); 342 } 343 break; 344 } 316 345 } 317 346 } 318 347 … … 450 479 m_G = g; 451 480 m_B = b; 452 481 UNUSED2(a); // TODO: why is this even an argument? 482 483 if (m_Unit) 484 { 485 CModelAbstract& model = m_Unit->GetModel(); 486 model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f)); 487 } 453 488 } 454 489 455 490 virtual void SetVariable(std::string name, float value) … … 507 542 void Update(fixed turnLength); 508 543 void UpdateVisibility(); 509 544 void Interpolate(float frameTime, float frameOffset); 510 void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);545 //void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling); 511 546 }; 512 547 513 548 REGISTER_COMPONENT_TYPE(VisualActor) … … 516 551 517 552 void CCmpVisualActor::InitModel(const CParamNode& paramNode) 518 553 { 519 if (GetSimContext().HasUnitManager()) 554 if (!GetSimContext().HasUnitManager()) 555 return; 556 557 std::set<CStr> selections; 558 m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections); 559 if (!m_Unit) 560 return; 561 562 CModelAbstract& model = m_Unit->GetModel(); 563 if (model.ToCModel()) 520 564 { 521 std::set<CStr> selections; 522 m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections); 523 if (m_Unit) 524 { 525 CModelAbstract& model = m_Unit->GetModel(); 526 if (model.ToCModel()) 527 { 528 u32 modelFlags = 0; 529 530 if (paramNode.GetChild("SilhouetteDisplay").ToBool()) 531 modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY; 532 533 if (paramNode.GetChild("SilhouetteOccluder").ToBool()) 534 modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER; 535 536 CmpPtr<ICmpVision> cmpVision(GetEntityHandle()); 537 if (cmpVision && cmpVision->GetAlwaysVisible()) 538 modelFlags |= MODELFLAG_IGNORE_LOS; 539 540 model.ToCModel()->AddFlagsRec(modelFlags); 541 } 542 543 if (paramNode.GetChild("DisableShadows").IsOk()) 544 { 545 if (model.ToCModel()) 546 model.ToCModel()->RemoveShadowsRec(); 547 else if (model.ToCModelDecal()) 548 model.ToCModelDecal()->RemoveShadows(); 549 } 550 551 // Initialize the model's selection shape descriptor. This currently relies on the component initialization order; the 552 // Footprint component must be initialized before this component (VisualActor) to support the ability to use the footprint 553 // shape for the selection box (instead of the default recursive bounding box). See TypeList.h for the order in 554 // which components are initialized; if for whatever reason you need to get rid of this dependency, you can always just 555 // initialize the selection shape descriptor on-demand. 556 InitSelectionShapeDescriptor(paramNode); 565 u32 modelFlags = 0; 566 567 if (paramNode.GetChild("SilhouetteDisplay").ToBool()) 568 modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY; 569 570 if (paramNode.GetChild("SilhouetteOccluder").ToBool()) 571 modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER; 572 573 CmpPtr<ICmpVision> cmpVision(GetEntityHandle()); 574 if (cmpVision && cmpVision->GetAlwaysVisible()) 575 modelFlags |= MODELFLAG_IGNORE_LOS; 576 577 model.ToCModel()->AddFlagsRec(modelFlags); 578 } 557 579 558 m_Unit->SetID(GetEntityId()); 580 if (paramNode.GetChild("DisableShadows").IsOk()) 581 { 582 if (model.ToCModel()) 583 model.ToCModel()->RemoveShadowsRec(); 584 else if (model.ToCModelDecal()) 585 model.ToCModelDecal()->RemoveShadows(); 586 } 587 588 // Initialize the model's selection shape descriptor. This currently relies on the component initialization order; the 589 // Footprint component must be initialized before this component (VisualActor) to support the ability to use the footprint 590 // shape for the selection box (instead of the default recursive bounding box). See TypeList.h for the order in 591 // which components are initialized; if for whatever reason you need to get rid of this dependency, you can always just 592 // initialize the selection shape descriptor on-demand. 593 InitSelectionShapeDescriptor(paramNode); 594 595 m_Unit->SetID(GetEntityId()); 596 597 model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f)); 598 599 if (!m_ModelTag.valid()) 600 { 601 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 602 if (cmpModelRenderer) 603 { 604 // TODO: account for props, animations 605 // TODO: use object bounds 606 CBoundingBoxAligned bounds = m_Unit->GetModel().GetWorldBoundsRec(); 607 CBoundingSphere boundSphere = CBoundingSphere::FromSweptBox(bounds); 608 m_ModelTag = cmpModelRenderer->AddUnit(GetEntityHandle(), m_Unit, boundSphere); 559 609 } 560 610 } 561 611 } … … 636 686 if (!m_Unit) 637 687 return; 638 688 639 std::set<CStr> selections;640 CUnit* newUnit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections);641 642 if (!newUnit)643 return;644 645 689 // Save some data from the old unit 646 690 CColor shading = m_Unit->GetModel().GetShadingColor(); 647 691 player_id_t playerID = m_Unit->GetModel().GetPlayerID(); … … 669 713 m_Unit->GetModel().SetShadingColor(shading); 670 714 671 715 m_Unit->GetModel().SetPlayerID(playerID); 716 717 if (m_ModelTag.valid()) 718 { 719 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 720 CBoundingBoxAligned bounds = m_Unit->GetModel().GetWorldBoundsRec(); 721 CBoundingSphere boundSphere = CBoundingSphere::FromSweptBox(bounds); 722 cmpModelRenderer->UpdateUnit(m_ModelTag, m_Unit, boundSphere); 723 } 672 724 } 673 725 674 726 void CCmpVisualActor::Update(fixed UNUSED(turnLength)) 675 727 { 676 728 if (m_Unit == NULL) 677 729 return; 678 730 731 if (m_ModelTag.valid()) 732 { 733 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 734 if(cmpModelRenderer->isCulled(m_ModelTag)) 735 return; 736 } 679 737 UpdateVisibility(); 680 681 738 // If we're in the special movement mode, select an appropriate animation 682 739 if (!m_AnimRunThreshold.IsZero()) 683 740 { … … 742 799 } 743 800 else 744 801 m_Visibility = ICmpRangeManager::VIS_HIDDEN; 745 746 if (m_Visibility != oldVisibility) 802 803 bool oldHidden = (oldVisibility == ICmpRangeManager::VIS_HIDDEN); 804 bool newHidden = (m_Visibility == ICmpRangeManager::VIS_HIDDEN); 805 if (oldHidden != newHidden) 747 806 { 748 807 // Change the visibility of the visual actor's selectable if it has one. 749 808 CmpPtr<ICmpSelectable> cmpSelectable(GetEntityHandle()); 750 809 if (cmpSelectable) 751 cmpSelectable->SetVisibility(m_Visibility == ICmpRangeManager::VIS_HIDDEN ? false : true); 810 cmpSelectable->SetVisibility(!newHidden); 811 812 if (m_ModelTag.valid()) 813 { 814 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 815 cmpModelRenderer->UpdateUnitVisible(m_ModelTag, !newHidden); 816 } 752 817 } 818 819 m_VisibilityDirty = false; 753 820 } 754 821 755 void CCmpVisualActor::Interpolate(float frameTime, float frameOffset)822 void CCmpVisualActor::Interpolate(float frameTime, float UNUSED(frameOffset)) 756 823 { 757 824 if (m_Unit == NULL) 758 825 return; 759 826 827 if (m_VisibilityDirty) 828 UpdateVisibility(); 829 830 if (m_ModelTag.valid()) 831 { 832 CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY); 833 if(cmpModelRenderer->isCulled(m_ModelTag)) 834 return; 835 } 836 837 m_Unit->UpdateModel(frameTime); 838 839 // If not hidden, then we need to set up some extra state for rendering 840 if (m_Visibility != ICmpRangeManager::VIS_HIDDEN) 841 { 842 m_Unit->GetModel().ValidatePosition(); 843 m_Unit->GetModel().SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f)); 844 } 845 846 /* 760 847 // Disable rendering of the unit if it has no position 761 848 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); 762 849 if (!cmpPosition || !cmpPosition->IsInWorld()) … … 791 878 { 792 879 CVector3D pos = transform.GetTranslation(); 793 880 float ground = cmpTerrain->GetExactGroundLevel(pos.X, pos.Z); 794 dy += std::max(0.f, pos.Y - ground);881 dy = std::max(0.f, pos.Y - ground); 795 882 } 796 883 797 884 transform.Translate(0.0f, (m_ConstructionProgress.ToFloat() - 1.0f) * dy, 0.0f); … … 801 888 CModelAbstract& model = m_Unit->GetModel(); 802 889 803 890 model.SetTransform(transform); 804 m_Unit->UpdateModel(frameTime); 805 806 // If not hidden, then we need to set up some extra state for rendering 807 if (m_Visibility != ICmpRangeManager::VIS_HIDDEN) 808 { 809 model.ValidatePosition(); 810 model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f)); 811 } 891 */ 812 892 } 813 893 894 /* 814 895 void CCmpVisualActor::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling) 815 896 { 816 897 if (m_Unit == NULL) … … 832 913 833 914 collector.SubmitRecursive(&model); 834 915 } 916 */ -
source/simulation2/components/CCmpWaterManager.cpp
103 103 104 104 // Tell the terrain it'll need to recompute its cached render data 105 105 GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES); 106 107 CMessageWaterChanged msg; 108 GetSimContext().GetComponentManager().BroadcastMessage(msg); 106 109 } 107 110 108 111 virtual entity_pos_t GetWaterLevel(entity_pos_t UNUSED(x), entity_pos_t UNUSED(z)) -
source/simulation2/components/ICmpRangeManager.h
252 252 /** 253 253 * Returns whether the given vertex is explored (i.e. was (or still is) within a unit's LOS). 254 254 */ 255 inline bool IsExplored(ssize_t i, ssize_t j )255 inline bool IsExplored(ssize_t i, ssize_t j, bool extended = false) 256 256 { 257 257 if (!(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide)) 258 258 return false; … … 261 261 if ((m_Data[j*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u) 262 262 return true; 263 263 else 264 { 265 if (extended/*m_HighQual*/) // TODO: this should be a setting 266 { 267 if (i > 0 && (m_Data[j*m_VerticesPerSide + i - 1] & m_PlayerMask) & 0x55555555u) 268 return true; 269 if (i < m_VerticesPerSide - 1 && (m_Data[j*m_VerticesPerSide + i + 1] & m_PlayerMask) & 0x55555555u) 270 return true; 271 if (j > 0 && (m_Data[(j-1)*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u) 272 return true; 273 if (j < m_VerticesPerSide - 1 && (m_Data[(j+1)*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u) 274 return true; 275 } 264 276 return false; 277 } 265 278 } 266 279 267 280 /** -
source/simulation2/scripting/MessageTypeConversions.cpp
216 216 217 217 //////////////////////////////// 218 218 219 jsval CMessageInterpolatedPositionChanged::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 220 { 221 LOGWARNING(L"CMessageInterpolatedPositionChanged::ToJSVal not implemented"); 222 return JSVAL_VOID; 223 } 224 225 CMessage* CMessageInterpolatedPositionChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val)) 226 { 227 LOGWARNING(L"CMessageInterpolatedPositionChanged::FromJSVal not implemented"); 228 return NULL; 229 } 230 231 //////////////////////////////// 232 233 219 234 jsval CMessageMotionChanged::ToJSVal(ScriptInterface& scriptInterface) const 220 235 { 221 236 TOJSVAL_SETUP(); … … 256 271 257 272 //////////////////////////////// 258 273 274 jsval CMessageWaterChanged::ToJSVal(ScriptInterface& scriptInterface) const 275 { 276 TOJSVAL_SETUP(); 277 return OBJECT_TO_JSVAL(obj); 278 } 279 280 CMessage* CMessageWaterChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val)) 281 { 282 return new CMessageWaterChanged(); 283 } 284 285 //////////////////////////////// 286 287 259 288 jsval CMessageTerritoriesChanged::ToJSVal(ScriptInterface& scriptInterface) const 260 289 { 261 290 TOJSVAL_SETUP();