Ticket #721: water_ro_r2_r9062.patch
File water_ro_r2_r9062.patch, 38.6 KB (added by , 13 years ago) |
---|
-
source/renderer/PatchRData.h
41 41 void RenderSides(); 42 42 void RenderPriorities(); 43 43 44 void RenderFancyWater(GLint waterDepth); 45 void RenderSimpleWater(); 46 47 // Check if there is water on this patch 48 bool HasWaterVisible(); 49 bool FullyEmerged(); 50 bool EntirelyUnderWater(); 51 44 52 static void RenderBases(const std::vector<CPatchRData*>& patches); 45 53 static void RenderBlends(const std::vector<CPatchRData*>& patches); 46 54 static void RenderStreams(const std::vector<CPatchRData*>& patches, int streamflags); … … 126 134 127 135 // splats used in blend pass 128 136 std::vector<SSplat> m_BlendSplats; 137 138 // Simple water vertex description data structure 139 struct SSimpleWaterVertex { 140 // vertex position 141 CVector3D m_Position; 142 // vertex uvs for texture 0 143 float m_UVs[2]; 144 // vertex 3d for texture 1 == vertex position so removed 145 // CVector3D m_PosTex1; 146 // Color TODO: Try to use packed colors? (here:floats) 147 RGBAColor m_Color; 148 }; 149 150 // Fancy water vertex description data structure 151 struct SWaterVertex { 152 // vertex position 153 CVector3D m_Position; 154 // vertex uvs for normal map texture 155 float m_UVs[2]; 156 // water depth (varying for shader) 157 float m_Depth; 158 }; 159 160 void BuildSimpleWaterVertices(); 161 void BuildFancyWaterVertices(); 162 163 void BuildWaterVertexData(); // Common to simple and fancy water 164 165 // Water vertex buffer 166 CVertexBuffer::VBChunk* m_VBWater; 167 168 // Water indices into buffer 169 // NB: Indices are identical for fancy or regular water (same path) 170 void BuildWaterIndices(); 171 172 // 256*256 seems to be enough 173 std::vector<unsigned short> m_WaterIndices; 174 175 // Build data for fancy water or reference data for 176 // computing simple water 177 std::vector<SWaterVertex> m_WaterVertexData; 178 179 // maximum and minimum depth of water at all vertices on the patch 180 // signed value: can be negative (if vertex emerges of water) 181 float max_wdepth; 182 float min_wdepth; 129 183 }; 130 184 131 185 #endif -
source/renderer/TerrainRenderer.h
71 71 */ 72 72 void EndFrame(); 73 73 74 /* 75 * HasWaterVisible: indicate if one of the patches currently visible 76 * has water visible. 77 */ 78 bool HasWaterVisible(); 79 80 74 81 /** 75 82 * RenderTerrain: Render textured terrain (including blends between 76 83 * different terrain types). … … 80 87 * 81 88 * @param shadow A prepared shadow map, in case rendering with shadows is enabled. 82 89 */ 83 void RenderTerrain(ShadowMap* shadow); 90 enum RenderTerrainMode { // Offer the ability to skip some patches (reflections, refractions) 91 NORMAL, 92 NOT_UNDERWATER, 93 NOT_EMERGED, 94 }; 95 void RenderTerrain(ShadowMap* shadow, RenderTerrainMode mode = NORMAL); 84 96 85 97 /** 86 98 * RenderPatches: Render all patches un-textured as polygons. … … 114 126 115 127 private: 116 128 TerrainRendererInternals* m; 129 130 /* 131 * RenderFancyWater: internal rendering method for fancy water 132 */ 133 bool RenderFancyWater(); 134 /* 135 * RenderSimpleWater: internal rendering method for water 136 */ 137 void RenderSimpleWater(); 117 138 }; 118 139 119 140 #endif // INCLUDED_TERRAINRENDERER -
source/renderer/Renderer.cpp
1102 1102 // Render sky, terrain and models 1103 1103 m->skyManager.RenderSky(); 1104 1104 ogl_WarnIfError(); 1105 RenderPatches(); 1105 // RenderPatches(); 1106 // Directly call terrain renderer without underwater patches 1107 // render all the patches, including blend pass 1108 m->terrainRenderer->RenderTerrain((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0, TerrainRenderer::NOT_UNDERWATER); 1109 1106 1110 ogl_WarnIfError(); 1107 1111 RenderModels(); 1108 1112 ogl_WarnIfError(); … … 1168 1172 glDepthFunc(GL_GEQUAL); 1169 1173 1170 1174 // Render terrain and models 1171 RenderPatches(); 1175 // RenderPatches(); 1176 // Directly call terrain renderer without fully emerged (out of water) patches 1177 // render all the patches, including blend pass 1178 m->terrainRenderer->RenderTerrain((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0, TerrainRenderer::NOT_EMERGED); 1172 1179 ogl_WarnIfError(); 1173 1180 RenderModels(); 1174 1181 ogl_WarnIfError(); … … 1235 1242 1236 1243 ogl_WarnIfError(); 1237 1244 1238 if (m_WaterManager->m_RenderWater && m_WaterManager->WillRenderFancyWater() )1245 if (m_WaterManager->m_RenderWater && m_WaterManager->WillRenderFancyWater() && m->terrainRenderer->HasWaterVisible()) 1239 1246 { 1240 1247 // render reflected and refracted scenes, then re-clear the screen 1241 1248 RenderReflections(); … … 1272 1279 ogl_WarnIfError(); 1273 1280 1274 1281 // render water 1275 if (m_WaterManager->m_RenderWater && g_Game) 1282 PROFILE_START("render water"); 1283 if (m_WaterManager->m_RenderWater && g_Game && m->terrainRenderer->HasWaterVisible()) 1276 1284 { 1277 1285 m->terrainRenderer->RenderWater(); 1278 1286 ogl_WarnIfError(); … … 1289 1297 // turning the water off. On the other hand every user will have water 1290 1298 // on all the time, so it might not be worth worrying about. 1291 1299 } 1300 PROFILE_END("render water"); 1292 1301 1293 1302 // Clean up texture blend mode so particles and other things render OK 1294 1303 // (really this should be cleaned up by whoever set it) -
source/renderer/PatchRData.cpp
56 56 /////////////////////////////////////////////////////////////////// 57 57 // CPatchRData constructor 58 58 CPatchRData::CPatchRData(CPatch* patch) : 59 m_Patch(patch), m_VBSides(0), m_VBBase(0), m_VBBaseIndices(0), m_VBBlends(0), m_VBBlendIndices(0) 59 m_Patch(patch), m_VBSides(0), m_VBBase(0), m_VBBaseIndices(0), m_VBBlends(0), m_VBBlendIndices(0), 60 m_VBWater(0), max_wdepth(-FLT_MAX), min_wdepth(FLT_MAX) 60 61 { 61 62 debug_assert(patch); 62 63 Build(); … … 631 632 BuildSides(); 632 633 BuildIndices(); 633 634 BuildBlends(); 635 636 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 637 if (WaterMgr->WillRenderFancyWater()) { 638 // TODO: Switch on fancy or not fancy water 639 BuildFancyWaterVertices(); 640 } else { 641 BuildSimpleWaterVertices(); 642 } 643 BuildWaterIndices(); 634 644 } 635 645 636 646 void CPatchRData::Update() … … 644 654 BuildIndices(); 645 655 BuildBlends(); 646 656 657 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 658 if (WaterMgr->WillRenderFancyWater()) { 659 // TODO: Switch on fancy or not fancy water 660 BuildFancyWaterVertices(); 661 } else { 662 BuildSimpleWaterVertices(); 663 } 664 647 665 m_UpdateFlags=0; 648 666 } 649 667 } … … 946 964 g_Renderer.m_Stats.m_TerrainTris += std::accumulate(batch.first.begin(), batch.first.end(), 0) / 3; 947 965 } 948 966 } 949 950 967 pglClientActiveTextureARB(GL_TEXTURE0); 951 968 952 969 CVertexBuffer::Unbind(); … … 1045 1062 } 1046 1063 } 1047 1064 } 1065 1066 // 1067 // Water build and rendering 1068 // 1069 1070 // Build vertex buffer for water vertices over our patch 1071 void CPatchRData::BuildWaterVertexData() 1072 { 1073 // number of vertices in each direction in each patch 1074 const ssize_t vsize=PATCH_SIZE+1; 1075 1076 m_WaterVertexData.resize(vsize*vsize); 1077 1078 // We need to use this to access the water manager or we may not have the 1079 // actual values but some compiled-in defaults 1080 CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 1081 1082 // TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults 1083 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 1084 const float repeatPeriod = WaterMgr->m_RepeatPeriod; 1085 #if 0 1086 // With non fancy water, period is a constant? TODO: Check 1087 const float repeatPeriod = 16.0f; 1088 #endif 1089 1090 1091 CPatch* patch = m_Patch; 1092 CTerrain* terrain = patch->m_Parent; 1093 1094 max_wdepth = -FLT_MAX; 1095 min_wdepth = FLT_MAX; 1096 // build vertices, uv, and shader varying 1097 for (ssize_t j=0;j<vsize;j++) 1098 { 1099 for (ssize_t i=0;i<vsize;i++) 1100 { 1101 ssize_t ix=(patch->m_X*PATCH_SIZE)+i; 1102 ssize_t iz=(patch->m_Z*PATCH_SIZE)+j; 1103 ssize_t v=(j*vsize)+i; 1104 1105 // calculate vertex data like for base vertices 1106 terrain->CalcPosition(ix,iz,m_WaterVertexData[v].m_Position); 1107 // at this step, Y is still terrainHeight 1108 const float waterHeight = (cmpWaterManager.null()) ? 0.0f : cmpWaterManager->GetExactWaterLevel(ix,iz); 1109 const float wdepth = waterHeight - m_WaterVertexData[v].m_Position.Y; 1110 m_WaterVertexData[v].m_Depth = wdepth; 1111 // replaces Y by water height 1112 m_WaterVertexData[v].m_Position.Y = waterHeight; 1113 // calculates U/V (TODO: could be done in shader? would be beneficial?) 1114 m_WaterVertexData[v].m_UVs[0] = m_WaterVertexData[v].m_Position.X / repeatPeriod; 1115 m_WaterVertexData[v].m_UVs[1] = m_WaterVertexData[v].m_Position.Z / repeatPeriod; 1116 // update min and max depth over patch 1117 if (wdepth > max_wdepth) max_wdepth = wdepth; 1118 if (wdepth < min_wdepth) min_wdepth = wdepth; 1119 } 1120 } 1121 } 1122 1123 // Build all that can be done at build time for simple water 1124 void CPatchRData::BuildSimpleWaterVertices() 1125 { 1126 BuildWaterVertexData(); 1127 // overall depth around patch is ready now 1128 // so, if we are fully emerged, we can get rid of things 1129 if (FullyEmerged()) // i.e.: (max_wdepth < 0.0f) 1130 { 1131 if (m_VBWater) { 1132 g_VBMan.Release(m_VBWater); 1133 } 1134 } 1135 else 1136 { 1137 // allocate vertex buffer (only: update is done at render time) 1138 if (!m_VBWater) { 1139 m_VBWater=g_VBMan.Allocate(sizeof(SSimpleWaterVertex),m_WaterVertexData.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); 1140 } 1141 debug_assert(m_VBWater->m_Index < 65536); 1142 } 1143 1144 // The vertex buffer must be ready for indices calculation 1145 BuildWaterIndices(); 1146 } 1147 1148 void CPatchRData::BuildFancyWaterVertices() 1149 { 1150 BuildWaterVertexData(); 1151 // overall depth around patch is ready now 1152 // so, if we are fully emerged, we can get rid of things 1153 if (FullyEmerged()) // i.e.: (max_wdepth < 0.0f) 1154 { 1155 if (m_VBWater) { 1156 g_VBMan.Release(m_VBWater); 1157 } 1158 } 1159 else 1160 { 1161 // we directly use the vertex data for rendering 1162 // upload to vertex buffer 1163 if (!m_VBWater) { 1164 m_VBWater=g_VBMan.Allocate(sizeof(SWaterVertex),m_WaterVertexData.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); 1165 } 1166 m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater,&m_WaterVertexData[0]); 1167 debug_assert(m_VBWater->m_Index < 65536); 1168 } 1169 // The vertex buffer must be ready for indices calculation 1170 BuildWaterIndices(); 1171 1172 // We directly use the vertex buffer in rendering, so we 1173 // can clear the data buffer for space 1174 m_WaterVertexData.clear(); 1175 } 1176 1177 1178 void CPatchRData::BuildWaterIndices() 1179 { 1180 // release existing indices 1181 m_WaterIndices.clear(); 1182 1183 if (FullyEmerged()) 1184 return; 1185 1186 // must have allocated some vertices before trying to build corresponding indices 1187 debug_assert(m_VBWater); 1188 1189 CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 1190 1191 CPatch* patch = m_Patch; 1192 CTerrain* terrain = patch->m_Parent; 1193 1194 // build indices for water 1195 // TODO: Adapt method for non fancy water! 1196 size_t base_indice=m_VBWater->m_Index; 1197 1198 for(ssize_t dx=0; dx<PATCH_SIZE; dx++) 1199 { 1200 for(ssize_t dz=0; dz<PATCH_SIZE; dz++) 1201 { 1202 ssize_t x = (patch->m_X*PATCH_SIZE + dx); 1203 ssize_t z = (patch->m_Z*PATCH_SIZE + dz); 1204 1205 // Some offsets used to go around counterclockwise while keeping code concise 1206 const int DX[] = {1,1,0,0}; 1207 const int DZ[] = {0,1,1,0}; 1208 1209 const float waterHeight = (cmpWaterManager.null()) ? 0.0f : cmpWaterManager->GetExactWaterLevel(x,z); 1210 1211 // NB: I do not reuse the values already computed for building the vertex buffer/data 1212 // here, even though it would probably be more readable, because it allows to 1213 // use the same function for building indices for fancy and non-fancy water (which 1214 // have different vertex buffer elements). 1215 // But reference visibility info. is for vertices. 1216 1217 // is any corner of the tile below the water height? if not, no point rendering it 1218 bool shouldRender = false; 1219 for (int j = 0; j < 4; j++) 1220 { 1221 const float terrainHeight = terrain->GetVertexGroundLevel(x + DX[j], z + DZ[j]); 1222 if (terrainHeight < waterHeight) 1223 { 1224 shouldRender = true; 1225 break; 1226 } 1227 } 1228 if (!shouldRender) 1229 continue; 1230 for (int j=0; j<4; j++) 1231 { 1232 ssize_t ix = dx + DX[j]; 1233 ssize_t iz = dz + DZ[j]; 1234 ssize_t v=(iz*(PATCH_SIZE+1))+ix; 1235 m_WaterIndices.push_back(u16(v)+base_indice); 1236 debug_assert((u16(v)+base_indice) < 65535); 1237 } 1238 } 1239 } 1240 } 1241 1242 const float EPSILON = 1e-12; 1243 1244 // if there is a positive water depth there is water on the patch 1245 bool CPatchRData::HasWaterVisible() 1246 { 1247 return (max_wdepth > EPSILON); 1248 } 1249 // if the maximum water size is negative, the patch is entirely emerged 1250 bool CPatchRData::FullyEmerged() 1251 { 1252 return (max_wdepth < EPSILON); 1253 } 1254 // if the minimum water size is still positive, the patch is entirely under water 1255 bool CPatchRData::EntirelyUnderWater() 1256 { 1257 return (min_wdepth > -EPSILON); 1258 } 1259 1260 void CPatchRData::RenderSimpleWater() 1261 { 1262 debug_assert(m_UpdateFlags==0); 1263 1264 if (FullyEmerged()) 1265 return; 1266 1267 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 1268 1269 // This is probably changing so vertices need update! 1270 const CCamera& camera = g_Renderer.GetViewCamera(); 1271 CVector3D camPos = camera.m_Orientation.GetTranslation(); 1272 1273 std::vector<SSimpleWaterVertex> vertices; 1274 vertices.reserve(m_WaterVertexData.size()); 1275 1276 // build vertex buffer with adequate alpha 1277 for (unsigned int i=0; i < m_WaterVertexData.size(); i++) // TODO: Use iterators 1278 { 1279 SSimpleWaterVertex vertex; 1280 // Copy data identical to build time 1281 vertex.m_Position = m_WaterVertexData[i].m_Position; 1282 vertex.m_UVs[0] = m_WaterVertexData[i].m_UVs[0]; 1283 vertex.m_UVs[1] = m_WaterVertexData[i].m_UVs[1]; 1284 // We use the same pointer/data in array for saving space 1285 // vertex.m_PosTex1 = m_WaterVertexData[i].m_Position; 1286 1287 const float alpha = clamp( (m_WaterVertexData[i].m_Depth) / WaterMgr->m_WaterFullDepth 1288 + WaterMgr->m_WaterAlphaOffset, 1289 WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 1290 1291 // (Crappy) fresnel effect 1292 CVector3D CamFaceVertex=CVector3D(vertex.m_Position.X,WaterMgr->m_WaterHeight,vertex.m_Position.Z)-camPos; 1293 // Note: WaterMgr->m_WaterHeight is also vertex.m_Position.Y I think... 1294 CamFaceVertex.Normalize(); 1295 float FresnelScalar = CamFaceVertex.Dot(CVector3D(0.0f, -1.0f, 0.0f)); 1296 // Invert and set boundaries 1297 FresnelScalar = 1.f - (FresnelScalar * 0.6); 1298 // Set Color 1299 vertex.m_Color.m_X = WaterMgr->m_WaterColor.r; 1300 vertex.m_Color.m_Y = WaterMgr->m_WaterColor.g; 1301 vertex.m_Color.m_Z = WaterMgr->m_WaterColor.b; 1302 vertex.m_Color.m_W = alpha * FresnelScalar; 1303 1304 // save the finalized vertex built 1305 vertices.push_back(vertex); 1306 } 1307 // upload to vertex buffer 1308 m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater,&vertices[0]); 1309 1310 SSimpleWaterVertex *base=(SSimpleWaterVertex *)m_VBWater->m_Owner->Bind(); 1311 1312 // setup data pointers 1313 GLsizei stride = sizeof(SSimpleWaterVertex); 1314 glColorPointer(4, GL_FLOAT, stride, &base->m_Color[0]); 1315 glVertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]); 1316 pglClientActiveTextureARB(GL_TEXTURE0); 1317 glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs[0]); // render 1318 pglClientActiveTextureARB(GL_TEXTURE1); 1319 glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position[0]); // (same data as vertex) 1320 // glTexCoordPointer(3, GL_FLOAT, stride, &base->m_PosTex1[0]); 1321 1322 if (!g_Renderer.m_SkipSubmit) { 1323 glDrawElements(GL_QUADS, (GLsizei) m_WaterIndices.size(), 1324 GL_UNSIGNED_SHORT, &m_WaterIndices[0]); 1325 } 1326 // bump stats 1327 g_Renderer.m_Stats.m_DrawCalls++; 1328 // TODO: Water stats? 1329 1330 CVertexBuffer::Unbind(); 1331 } 1332 1333 void CPatchRData::RenderFancyWater(GLint waterDepth) 1334 { 1335 debug_assert(m_UpdateFlags==0); 1336 1337 if (FullyEmerged()) 1338 return; 1339 1340 SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind(); 1341 1342 // setup data pointers 1343 GLsizei stride = sizeof(SWaterVertex); 1344 glVertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]); 1345 pglClientActiveTextureARB(GL_TEXTURE0); 1346 glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs[0]); 1347 pglVertexAttribPointerARB(waterDepth, 1, GL_FLOAT, GL_FALSE, /* not to be normalized */ 1348 stride, &base->m_Depth); 1349 // render 1350 if (!g_Renderer.m_SkipSubmit) { 1351 glDrawElements(GL_QUADS, (GLsizei) m_WaterIndices.size(), 1352 GL_UNSIGNED_SHORT, &m_WaterIndices[0]); 1353 } 1354 // bump stats 1355 g_Renderer.m_Stats.m_DrawCalls++; 1356 // TODO: Water stats? 1357 1358 CVertexBuffer::Unbind(); 1359 1360 } 1361 -
source/renderer/TerrainRenderer.cpp
163 163 164 164 165 165 /////////////////////////////////////////////////////////////////// 166 167 bool TerrainRenderer::HasWaterVisible() 168 { 169 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 170 { 171 CPatchRData* patchdata = m->visiblePatches[i]; 172 if (patchdata->HasWaterVisible()) 173 return true; 174 } 175 return false; 176 } 177 178 /////////////////////////////////////////////////////////////////// 166 179 // Full-featured terrain rendering with blending and everything 167 void TerrainRenderer::RenderTerrain(ShadowMap* shadow )180 void TerrainRenderer::RenderTerrain(ShadowMap* shadow, RenderTerrainMode mode) 168 181 { 182 PROFILE("render terrain"); 183 169 184 debug_assert(m->phase == Phase_Render); 170 185 186 #if 0 187 // Debug Savings evaluation 188 int c = 0; 189 int d = 0; 190 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 191 { 192 CPatchRData* patchdata = m->visiblePatches[i]; 193 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) c++; 194 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) d++; 195 } 196 if (mode == NOT_UNDERWATER) 197 std::cout << " Saving under=" << c << " patchrendering on frame" << std::endl; 198 else if (mode == NOT_EMERGED) 199 std::cout << " Saving emerged=" << d << " patchrendering on frame" << std::endl; 200 #endif 201 202 std::vector<CPatchRData*> patchesToRender; 203 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 204 { 205 CPatchRData* patchdata = m->visiblePatches[i]; 206 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) continue; 207 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) continue; 208 patchesToRender.push_back(patchdata); 209 } 210 171 211 // render the solid black sides of the map first 172 212 g_Renderer.BindTexture(0, 0); 173 213 glEnableClientState(GL_VERTEX_ARRAY); 174 214 glColor3f(0, 0, 0); 175 215 PROFILE_START("render terrain sides"); 176 for (size_t i = 0; i < m->visiblePatches.size(); ++i)177 m->visiblePatches[i]->RenderSides();216 for(size_t i = 0; i < patchesToRender.size(); ++i) 217 patchesToRender[i]->RenderSides(); 178 218 PROFILE_END("render terrain sides"); 179 219 180 220 // switch on required client states … … 197 237 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, one); 198 238 199 239 PROFILE_START("render terrain base"); 200 CPatchRData::RenderBases( m->visiblePatches);240 CPatchRData::RenderBases(patchesToRender); 201 241 PROFILE_END("render terrain base"); 202 242 203 243 // render blends … … 227 267 228 268 // render blend passes for each patch 229 269 PROFILE_START("render terrain blends"); 230 CPatchRData::RenderBlends( m->visiblePatches);270 CPatchRData::RenderBlends(patchesToRender); 231 271 PROFILE_END("render terrain blends"); 232 272 233 273 // Disable second texcoord array … … 444 484 pglClientActiveTextureARB(GL_TEXTURE0); 445 485 446 486 PROFILE_START("render terrain streams"); 447 CPatchRData::RenderStreams( m->visiblePatches, streamflags);487 CPatchRData::RenderStreams(patchesToRender, streamflags); 448 488 PROFILE_END("render terrain streams"); 449 489 450 490 glMatrixMode(GL_TEXTURE); … … 521 561 glDisableClientState(GL_VERTEX_ARRAY); 522 562 } 523 563 524 525 /////////////////////////////////////////////////////////////////// 526 // Render water that is part of the terrain 527 void TerrainRenderer::RenderWater() 564 // Render fancy water 565 bool TerrainRenderer::RenderFancyWater() 528 566 { 529 PROFILE( "render water" );567 PROFILE( "render fancy water" ); 530 568 531 569 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 532 570 533 bool fancy = WaterMgr->WillRenderFancyWater(); 534 535 // If we're using fancy water, make sure its shader is loaded 536 if(fancy && !m->fancyWaterShader) 571 // We're using fancy water, make sure its shader is loaded 572 if(!m->fancyWaterShader) 537 573 { 538 574 Handle h = ogl_program_load(g_VFS, L"shaders/water_high.xml"); 539 575 if (h < 0) 540 576 { 541 577 LOGERROR(L"Failed to load water shader. Falling back to non-fancy water.\n"); 542 578 g_Renderer.m_Options.m_FancyWater = false; 543 fancy =false;579 return false; 544 580 } 545 581 else 546 582 { 547 583 m->fancyWaterShader = h; 548 584 } 549 585 } 550 CTerrain* terrain = g_Game->GetWorld()->GetTerrain();551 586 552 587 CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); 553 588 … … 561 596 double period = 1.6; 562 597 int curTex = (int)(time*60/period) % 60; 563 598 564 if(fancy) 565 { 566 WaterMgr->m_NormalMap[curTex]->Bind(); 567 } 568 else 569 { 570 WaterMgr->m_WaterTexture[curTex]->Bind(); 571 } 599 WaterMgr->m_NormalMap[curTex]->Bind(); 572 600 573 601 // Shift the texture coordinates by these amounts to make the water "flow" 574 602 float tx = -fmod(time, 81.0)/81.0; 575 603 float ty = -fmod(time, 34.0)/34.0; 576 604 577 if(!fancy) 578 { 579 // Perform the shifting by modifying the texture matrix 580 glMatrixMode(GL_TEXTURE); 581 glLoadIdentity(); 582 glTranslatef(tx, ty, 0); 605 // Set the proper LOD bias 606 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 583 607 584 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 585 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 586 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 587 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 588 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 589 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 590 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 591 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 592 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 593 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 608 const CCamera& camera = g_Renderer.GetViewCamera(); 609 CVector3D camPos = camera.m_Orientation.GetTranslation(); 594 610 595 // Multiply by LOS texture 596 losTexture.BindTexture(1); 597 pglClientActiveTextureARB(GL_TEXTURE1); 598 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 611 // Bind reflection and refraction textures on texture units 1 and 2 612 pglActiveTextureARB( GL_TEXTURE1_ARB ); 613 glEnable( GL_TEXTURE_2D ); 614 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture ); 615 pglActiveTextureARB( GL_TEXTURE2_ARB ); 616 glEnable( GL_TEXTURE_2D ); 617 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture ); 599 618 600 glLoadMatrixf(losTexture.GetTextureMatrix());619 losTexture.BindTexture(3); 601 620 602 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 603 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 604 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 605 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 606 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 607 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 608 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 609 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 610 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 611 } 621 // Bind water shader and set arguments 622 ogl_program_use( m->fancyWaterShader ); 612 623 613 // Set the proper LOD bias 614 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 624 GLint ambient = ogl_program_get_uniform_location( m->fancyWaterShader, "ambient" ); 625 GLint sunDir = ogl_program_get_uniform_location( m->fancyWaterShader, "sunDir" ); 626 GLint sunColor = ogl_program_get_uniform_location( m->fancyWaterShader, "sunColor" ); 627 GLint cameraPos = ogl_program_get_uniform_location( m->fancyWaterShader, "cameraPos" ); 628 GLint shininess = ogl_program_get_uniform_location( m->fancyWaterShader, "shininess" ); 629 GLint specularStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "specularStrength" ); 630 GLint waviness = ogl_program_get_uniform_location( m->fancyWaterShader, "waviness" ); 631 GLint murkiness = ogl_program_get_uniform_location( m->fancyWaterShader, "murkiness" ); 632 GLint fullDepth = ogl_program_get_uniform_location( m->fancyWaterShader, "fullDepth" ); 633 GLint tint = ogl_program_get_uniform_location( m->fancyWaterShader, "tint" ); 634 GLint reflectionTint = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTint" ); 635 GLint reflectionTintStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTintStrength" ); 636 GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" ); 637 GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" ); 638 GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" ); 639 GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" ); 640 GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" ); 641 GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" ); 642 GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" ); 643 GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" ); 615 644 616 const CCamera& camera = g_Renderer.GetViewCamera(); 617 CVector3D camPos = camera.m_Orientation.GetTranslation(); 645 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 646 pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X ); 647 pglUniform3fvARB( sunDir, 1, &lightEnv.GetSunDir().X ); 648 pglUniform3fvARB( sunColor, 1, &lightEnv.m_SunColor.X ); 649 pglUniform1fARB( shininess, WaterMgr->m_Shininess ); 650 pglUniform1fARB( specularStrength, WaterMgr->m_SpecularStrength ); 651 pglUniform1fARB( waviness, WaterMgr->m_Waviness ); 652 pglUniform1fARB( murkiness, WaterMgr->m_Murkiness ); 653 pglUniform1fARB( fullDepth, WaterMgr->m_WaterFullDepth ); 654 pglUniform3fvARB( tint, 1, WaterMgr->m_WaterTint.FloatArray() ); 655 pglUniform1fARB( reflectionTintStrength, WaterMgr->m_ReflectionTintStrength ); 656 pglUniform3fvARB( reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray() ); 657 pglUniform4fARB( translation, tx, ty, 0, 0 ); 658 pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 ); 659 pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 ); 660 pglUniformMatrix4fvARB( losMatrix, 1, false, losTexture.GetTextureMatrix() ); 661 pglUniform1iARB( normalMap, 0 ); // texture unit 0 662 pglUniform1iARB( reflectionMap, 1 ); // texture unit 1 663 pglUniform1iARB( refractionMap, 2 ); // texture unit 2 664 pglUniform1iARB( losMap, 3 ); // texture unit 3 665 pglUniform3fvARB( cameraPos, 1, &camPos.X ); 618 666 619 GLint vertexDepth = 0; // water depth attribute, if using fancy water 667 // glActiveTexture(GL_TEXTURE0); 620 668 621 if(fancy) 669 glEnableClientState(GL_VERTEX_ARRAY); 670 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 671 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 672 673 // water depth attribute, when using fancy water 674 GLint vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" ); 675 pglEnableVertexAttribArrayARB(vertexDepth); 676 677 for(size_t i=0; i<m->visiblePatches.size(); i++) 622 678 { 623 // Bind reflection and refraction textures on texture units 1 and 2 624 pglActiveTextureARB( GL_TEXTURE1_ARB ); 625 glEnable( GL_TEXTURE_2D ); 626 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture ); 627 pglActiveTextureARB( GL_TEXTURE2_ARB ); 628 glEnable( GL_TEXTURE_2D ); 629 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture ); 679 CPatchRData* patchdata = m->visiblePatches[i]; 680 patchdata->RenderFancyWater(vertexDepth); 681 } 630 682 631 losTexture.BindTexture(3); 683 pglDisableVertexAttribArrayARB(vertexDepth); 684 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 685 glDisableClientState(GL_VERTEX_ARRAY); 632 686 633 // Bind water shader and set arguments 634 ogl_program_use( m->fancyWaterShader ); 687 // Unbind the LOS/refraction/reflection textures and the shader 688 g_Renderer.BindTexture(3, 0); 689 g_Renderer.BindTexture(2, 0); 690 g_Renderer.BindTexture(1, 0); 691 pglActiveTextureARB(GL_TEXTURE0_ARB); 692 ogl_program_use(0); 635 693 636 GLint ambient = ogl_program_get_uniform_location( m->fancyWaterShader, "ambient" ); 637 GLint sunDir = ogl_program_get_uniform_location( m->fancyWaterShader, "sunDir" ); 638 GLint sunColor = ogl_program_get_uniform_location( m->fancyWaterShader, "sunColor" ); 639 GLint cameraPos = ogl_program_get_uniform_location( m->fancyWaterShader, "cameraPos" ); 640 GLint shininess = ogl_program_get_uniform_location( m->fancyWaterShader, "shininess" ); 641 GLint specularStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "specularStrength" ); 642 GLint waviness = ogl_program_get_uniform_location( m->fancyWaterShader, "waviness" ); 643 GLint murkiness = ogl_program_get_uniform_location( m->fancyWaterShader, "murkiness" ); 644 GLint fullDepth = ogl_program_get_uniform_location( m->fancyWaterShader, "fullDepth" ); 645 GLint tint = ogl_program_get_uniform_location( m->fancyWaterShader, "tint" ); 646 GLint reflectionTint = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTint" ); 647 GLint reflectionTintStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTintStrength" ); 648 GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" ); 649 GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" ); 650 GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" ); 651 GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" ); 652 GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" ); 653 GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" ); 654 GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" ); 655 GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" ); 694 glMatrixMode(GL_MODELVIEW); 695 glDisable(GL_BLEND); 696 glDisable(GL_TEXTURE_2D); 656 697 657 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 658 pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X ); 659 pglUniform3fvARB( sunDir, 1, &lightEnv.GetSunDir().X ); 660 pglUniform3fvARB( sunColor, 1, &lightEnv.m_SunColor.X ); 661 pglUniform1fARB( shininess, WaterMgr->m_Shininess ); 662 pglUniform1fARB( specularStrength, WaterMgr->m_SpecularStrength ); 663 pglUniform1fARB( waviness, WaterMgr->m_Waviness ); 664 pglUniform1fARB( murkiness, WaterMgr->m_Murkiness ); 665 pglUniform1fARB( fullDepth, WaterMgr->m_WaterFullDepth ); 666 pglUniform3fvARB( tint, 1, WaterMgr->m_WaterTint.FloatArray() ); 667 pglUniform1fARB( reflectionTintStrength, WaterMgr->m_ReflectionTintStrength ); 668 pglUniform3fvARB( reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray() ); 669 pglUniform4fARB( translation, tx, ty, 0, 0 ); 670 pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 ); 671 pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 ); 672 pglUniformMatrix4fvARB( losMatrix, 1, false, losTexture.GetTextureMatrix() ); 673 pglUniform1iARB( normalMap, 0 ); // texture unit 0 674 pglUniform1iARB( reflectionMap, 1 ); // texture unit 1 675 pglUniform1iARB( refractionMap, 2 ); // texture unit 2 676 pglUniform1iARB( losMap, 3 ); // texture unit 3 677 pglUniform3fvARB( cameraPos, 1, &camPos.X ); 698 return true; 699 } 678 700 679 vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" ); 680 } 701 void TerrainRenderer::RenderSimpleWater() 702 { 703 PROFILE( "render simple water" ); 704 705 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 706 707 CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); 681 708 682 float repeatPeriod = (fancy ? WaterMgr->m_RepeatPeriod : 16.0f); 709 glEnable(GL_BLEND); 710 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 711 glEnable(GL_DEPTH_TEST); 712 glDepthFunc(GL_LEQUAL); 683 713 684 glBegin(GL_QUADS);714 double time = WaterMgr->m_WaterTexTimer; 685 715 686 for(size_t i=0; i<m->visiblePatches.size(); i++) 687 { 688 CPatch* patch = m->visiblePatches[i]->GetPatch(); 716 double period = 16.0f; 717 int curTex = (int)(time*60/period) % 60; 689 718 690 for(ssize_t dx=0; dx<PATCH_SIZE; dx++) 691 { 692 for(ssize_t dz=0; dz<PATCH_SIZE; dz++) 693 { 694 ssize_t x = (patch->m_X*PATCH_SIZE + dx); 695 ssize_t z = (patch->m_Z*PATCH_SIZE + dz); 719 WaterMgr->m_WaterTexture[curTex]->Bind(); 696 720 697 // Some offsets used to go around counterclockwise while keeping code concise698 const int DX[] = {1,1,0,0};699 const int DZ[] = {0,1,1,0};721 // Shift the texture coordinates by these amounts to make the water "flow" 722 float tx = -fmod(time, 81.0)/81.0; 723 float ty = -fmod(time, 34.0)/34.0; 700 724 701 // is any corner of the tile below the water height? if not, no point rendering it 702 bool shouldRender = false; 703 for (int j = 0; j < 4; j++) 704 { 705 float terrainHeight = terrain->GetVertexGroundLevel(x + DX[j], z + DZ[j]); 706 if (terrainHeight < WaterMgr->m_WaterHeight) 707 { 708 shouldRender = true; 709 break; 710 } 711 } 712 if (!shouldRender) 713 continue; 725 // Perform the shifting by modifying the texture matrix 726 glMatrixMode(GL_TEXTURE); 727 glLoadIdentity(); 728 glTranslatef(tx, ty, 0); 714 729 715 for (int j=0; j<4; j++) 716 { 717 ssize_t ix = x + DX[j]; 718 ssize_t iz = z + DZ[j]; 730 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 731 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 732 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 733 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 734 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 735 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 736 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 737 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 738 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 739 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 719 740 720 float vertX = ix * CELL_SIZE; 721 float vertZ = iz * CELL_SIZE; 741 // Multiply by LOS texture 742 losTexture.BindTexture(1); 743 pglClientActiveTextureARB(GL_TEXTURE1); 744 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 722 745 723 float terrainHeight = terrain->GetVertexGroundLevel(ix, iz);746 glLoadMatrixf(losTexture.GetTextureMatrix()); 724 747 725 if (fancy) 726 { 727 pglVertexAttrib1fARB(vertexDepth, WaterMgr->m_WaterHeight - terrainHeight); 728 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 729 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 730 } 731 else 732 { 733 float alpha = clamp( (WaterMgr->m_WaterHeight - terrainHeight) / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, 734 WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 748 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 749 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 750 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 751 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 752 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 753 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 754 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 755 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 756 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 735 757 736 // (Crappy) fresnel effect737 CVector3D CamFaceVertex=CVector3D(vertX,WaterMgr->m_WaterHeight,vertZ)-camPos;738 CamFaceVertex.Normalize();739 float FresnelScalar = CamFaceVertex.Dot(CVector3D(0.0f, -1.0f, 0.0f));740 // Invert and set boundaries741 FresnelScalar = 1.f - (FresnelScalar * 0.6);742 758 743 glColor4f(WaterMgr->m_WaterColor.r, 744 WaterMgr->m_WaterColor.g, 745 WaterMgr->m_WaterColor.b, 746 alpha * FresnelScalar); 747 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 748 pglMultiTexCoord3fARB(GL_TEXTURE1, vertX, WaterMgr->m_WaterHeight, vertZ); 749 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 750 } 759 // Set the proper LOD bias 760 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 751 761 752 } 753 } //end of x loop 754 } //end of z loop 755 } 756 glEnd(); 762 glEnableClientState(GL_VERTEX_ARRAY); 763 glEnableClientState(GL_COLOR_ARRAY); 764 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 765 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 757 766 758 if (fancy)767 for(size_t i=0; i<m->visiblePatches.size(); i++) 759 768 { 760 // Unbind the LOS/refraction/reflection textures and the shader 769 CPatchRData* patchdata = m->visiblePatches[i]; 770 patchdata->RenderSimpleWater(); 771 } 761 772 762 g_Renderer.BindTexture(3, 0); 763 g_Renderer.BindTexture(2, 0); 764 g_Renderer.BindTexture(1, 0); 773 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 774 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 775 glDisableClientState(GL_COLOR_ARRAY); 776 glDisableClientState(GL_VERTEX_ARRAY); 765 777 766 pglActiveTextureARB(GL_TEXTURE0_ARB); 778 g_Renderer.BindTexture(1, 0); 779 pglClientActiveTextureARB(GL_TEXTURE1_ARB); 780 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 767 781 768 ogl_program_use(0); 769 } 782 glLoadIdentity(); 770 783 771 if (!fancy) 772 { 773 g_Renderer.BindTexture(1, 0); 774 pglClientActiveTextureARB(GL_TEXTURE1_ARB); 775 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 784 pglActiveTextureARB(GL_TEXTURE0_ARB); 785 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 776 786 777 glLoadIdentity(); 787 // Clean up the texture matrix and blend mode 788 glLoadIdentity(); 789 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 778 790 779 pglActiveTextureARB(GL_TEXTURE0_ARB);780 pglClientActiveTextureARB(GL_TEXTURE0_ARB);781 782 // Clean up the texture matrix and blend mode783 glLoadIdentity();784 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);785 }786 787 791 glMatrixMode(GL_MODELVIEW); 788 792 glDisable(GL_BLEND); 789 793 glDisable(GL_TEXTURE_2D); 790 794 } 791 795 796 797 /////////////////////////////////////////////////////////////////// 798 // Render water that is part of the terrain 799 void TerrainRenderer::RenderWater() 800 { 801 // PROFILE is defined in one of the sub functions 802 803 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 804 805 bool fancy = WaterMgr->WillRenderFancyWater(); 806 807 if (fancy) { 808 bool r = RenderFancyWater(); 809 if (r) return; 810 } 811 RenderSimpleWater(); 812 } 813 792 814 void TerrainRenderer::RenderPriorities() 793 815 { 794 816 PROFILE("render priorities"); -
binaries/data/mods/public/shaders/water_high.vs
15 15 waterDepth = vertexDepth; 16 16 gl_TexCoord[0] = gl_MultiTexCoord0 + translation; 17 17 gl_TexCoord[1] = reflectionMatrix * gl_Vertex; // projective texturing 18 gl_TexCoord[2] = ref lectionMatrix * gl_Vertex;18 gl_TexCoord[2] = refractionMatrix * gl_Vertex; 19 19 gl_TexCoord[3] = losMatrix * gl_Vertex; 20 20 w = gl_TexCoord[1].w; 21 21 gl_Position = ftransform();