Ticket #721: water_ro_r2.patch
File water_ro_r2.patch, 38.2 KB (added by , 13 years ago) |
---|
-
source/renderer/PatchRData.h
44 44 void RenderSides(); 45 45 void RenderPriorities(); 46 46 47 void RenderFancyWater(GLint waterDepth); 48 void RenderSimpleWater(); 49 50 // Check if there is water on this patch 51 bool HasWaterVisible(); 52 bool FullyEmerged(); 53 bool EntirelyUnderWater(); 47 54 private: 48 55 struct SSplat { 49 56 SSplat() : m_Texture(0), m_IndexCount(0) {} … … 117 124 118 125 // splats used in blend pass 119 126 std::vector<SSplat> m_BlendSplats; 127 128 // Simple water vertex description data structure 129 struct SSimpleWaterVertex { 130 // vertex position 131 CVector3D m_Position; 132 // vertex uvs for texture 0 133 float m_UVs[2]; 134 // vertex 3d for texture 1 == vertex position so removed 135 // CVector3D m_PosTex1; 136 // Color TODO: Try to use packed colors? (here:floats) 137 RGBAColor m_Color; 138 }; 139 140 // Fancy water vertex description data structure 141 struct SWaterVertex { 142 // vertex position 143 CVector3D m_Position; 144 // vertex uvs for normal map texture 145 float m_UVs[2]; 146 // water depth (varying for shader) 147 float m_Depth; 148 }; 149 150 void BuildSimpleWaterVertices(); 151 void BuildFancyWaterVertices(); 152 153 void BuildWaterVertexData(); // Common to simple and fancy water 154 155 // Water vertex buffer 156 CVertexBuffer::VBChunk* m_VBWater; 157 158 // Water indices into buffer 159 // NB: Indices are identical for fancy or regular water (same path) 160 void BuildWaterIndices(); 161 162 // 256*256 seems to be enough 163 std::vector<unsigned short> m_WaterIndices; 164 165 // Build data for fancy water or reference data for 166 // computing simple water 167 std::vector<SWaterVertex> m_WaterVertexData; 168 169 // maximum and minimum depth of water at all vertices on the patch 170 // signed value: can be negative (if vertex emerges of water) 171 float max_wdepth; 172 float min_wdepth; 120 173 }; 121 174 122 175 -
source/renderer/TerrainRenderer.h
75 75 */ 76 76 bool HaveSubmissions(); 77 77 78 /* 79 * HasWaterVisible: indicate if one of the patches currently visible 80 * has water visible. 81 */ 82 bool HasWaterVisible(); 83 84 78 85 /** 79 86 * RenderTerrain: Render textured terrain (including blends between 80 87 * different terrain types). … … 84 91 * 85 92 * @param shadow A prepared shadow map, in case rendering with shadows is enabled. 86 93 */ 87 void RenderTerrain(ShadowMap* shadow); 94 enum RenderTerrainMode { // Offer the ability to skip some patches (reflections, refractions) 95 NORMAL, 96 NOT_UNDERWATER, 97 NOT_EMERGED, 98 }; 99 void RenderTerrain(ShadowMap* shadow, RenderTerrainMode mode = NORMAL); 88 100 89 101 /** 90 102 * RenderPatches: Render all patches un-textured as polygons. … … 118 130 119 131 private: 120 132 TerrainRendererInternals* m; 133 134 /* 135 * RenderFancyWater: internal rendering method for fancy water 136 */ 137 bool RenderFancyWater(); 138 /* 139 * RenderSimpleWater: internal rendering method for water 140 */ 141 void RenderSimpleWater(); 121 142 }; 122 143 123 144 #endif // INCLUDED_TERRAINRENDERER -
source/renderer/Renderer.cpp
1084 1084 // Render sky, terrain and models 1085 1085 m->skyManager.RenderSky(); 1086 1086 ogl_WarnIfError(); 1087 RenderPatches(); 1087 // RenderPatches(); 1088 // Directly call terrain renderer without underwater patches 1089 // render all the patches, including blend pass 1090 m->terrainRenderer->RenderTerrain((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0, TerrainRenderer::NOT_UNDERWATER); 1091 1088 1092 ogl_WarnIfError(); 1089 1093 RenderModels(); 1090 1094 ogl_WarnIfError(); … … 1150 1154 glDepthFunc(GL_GEQUAL); 1151 1155 1152 1156 // Render terrain and models 1153 RenderPatches(); 1157 // RenderPatches(); 1158 // Directly call terrain renderer without fully emerged (out of water) patches 1159 // render all the patches, including blend pass 1160 m->terrainRenderer->RenderTerrain((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0, TerrainRenderer::NOT_EMERGED); 1154 1161 ogl_WarnIfError(); 1155 1162 RenderModels(); 1156 1163 ogl_WarnIfError(); … … 1213 1220 1214 1221 ogl_WarnIfError(); 1215 1222 1216 if (m_WaterManager->m_RenderWater && m_WaterManager->WillRenderFancyWater() )1223 if (m_WaterManager->m_RenderWater && m_WaterManager->WillRenderFancyWater() && m->terrainRenderer->HasWaterVisible()) 1217 1224 { 1218 1225 // render reflected and refracted scenes, then re-clear the screen 1219 1226 RenderReflections(); … … 1250 1257 ogl_WarnIfError(); 1251 1258 1252 1259 // render water 1253 if (m_WaterManager->m_RenderWater && g_Game) 1260 PROFILE_START("render water"); 1261 if (m_WaterManager->m_RenderWater && g_Game && m->terrainRenderer->HasWaterVisible()) 1254 1262 { 1255 1263 m->terrainRenderer->RenderWater(); 1256 1264 ogl_WarnIfError(); … … 1267 1275 // turning the water off. On the other hand every user will have water 1268 1276 // on all the time, so it might not be worth worrying about. 1269 1277 } 1278 PROFILE_END("render water"); 1270 1279 1271 1280 // Clean up texture blend mode so particles and other things render OK 1272 1281 // (really this should be cleaned up by whoever set it) -
source/renderer/PatchRData.cpp
54 54 /////////////////////////////////////////////////////////////////// 55 55 // CPatchRData constructor 56 56 CPatchRData::CPatchRData(CPatch* patch) : 57 m_Patch(patch), m_VBBase(0), m_VBSides(0), m_VBBlends(0), m_Vertices(0) 57 m_Patch(patch), m_VBBase(0), m_VBSides(0), m_VBBlends(0), m_Vertices(0), 58 m_VBWater(0), max_wdepth(-FLT_MAX), min_wdepth(FLT_MAX) 58 59 { 59 60 debug_assert(patch); 60 61 Build(); … … 561 562 BuildSides(); 562 563 BuildIndices(); 563 564 BuildBlends(); 565 566 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 567 if (WaterMgr->WillRenderFancyWater()) { 568 // TODO: Switch on fancy or not fancy water 569 BuildFancyWaterVertices(); 570 } else { 571 BuildSimpleWaterVertices(); 572 } 573 BuildWaterIndices(); 564 574 } 565 575 566 576 void CPatchRData::Update() … … 574 584 BuildIndices(); 575 585 BuildBlends(); 576 586 587 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 588 if (WaterMgr->WillRenderFancyWater()) { 589 // TODO: Switch on fancy or not fancy water 590 BuildFancyWaterVertices(); 591 } else { 592 BuildSimpleWaterVertices(); 593 } 594 577 595 m_UpdateFlags=0; 578 596 } 579 597 } … … 708 726 g_Renderer.m_Stats.m_BlendSplats++; 709 727 g_Renderer.m_Stats.m_TerrainTris+=splat.m_IndexCount/2; 710 728 } 711 712 729 CVertexBuffer::Unbind(); 713 730 } 714 731 … … 799 816 } 800 817 } 801 818 } 819 820 // 821 // Water build and rendering 822 // 823 824 // Build vertex buffer for water vertices over our patch 825 void CPatchRData::BuildWaterVertexData() 826 { 827 // number of vertices in each direction in each patch 828 const ssize_t vsize=PATCH_SIZE+1; 829 830 m_WaterVertexData.resize(vsize*vsize); 831 832 // We need to use this to access the water manager or we may not have the 833 // actual values but some compiled-in defaults 834 CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 835 836 // TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults 837 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 838 const float repeatPeriod = WaterMgr->m_RepeatPeriod; 839 #if 0 840 // With non fancy water, period is a constant? TODO: Check 841 const float repeatPeriod = 16.0f; 842 #endif 843 844 845 CPatch* patch = m_Patch; 846 CTerrain* terrain = patch->m_Parent; 847 848 max_wdepth = -FLT_MAX; 849 min_wdepth = FLT_MAX; 850 // build vertices, uv, and shader varying 851 for (ssize_t j=0;j<vsize;j++) 852 { 853 for (ssize_t i=0;i<vsize;i++) 854 { 855 ssize_t ix=(patch->m_X*PATCH_SIZE)+i; 856 ssize_t iz=(patch->m_Z*PATCH_SIZE)+j; 857 ssize_t v=(j*vsize)+i; 858 859 // calculate vertex data like for base vertices 860 terrain->CalcPosition(ix,iz,m_WaterVertexData[v].m_Position); 861 // at this step, Y is still terrainHeight 862 const float waterHeight = (cmpWaterManager.null()) ? 0.0f : cmpWaterManager->GetExactWaterLevel(ix,iz); 863 const float wdepth = waterHeight - m_WaterVertexData[v].m_Position.Y; 864 m_WaterVertexData[v].m_Depth = wdepth; 865 // replaces Y by water height 866 m_WaterVertexData[v].m_Position.Y = waterHeight; 867 // calculates U/V (TODO: could be done in shader? would be beneficial?) 868 m_WaterVertexData[v].m_UVs[0] = m_WaterVertexData[v].m_Position.X / repeatPeriod; 869 m_WaterVertexData[v].m_UVs[1] = m_WaterVertexData[v].m_Position.Z / repeatPeriod; 870 // update min and max depth over patch 871 if (wdepth > max_wdepth) max_wdepth = wdepth; 872 if (wdepth < min_wdepth) min_wdepth = wdepth; 873 } 874 } 875 } 876 877 // Build all that can be done at build time for simple water 878 void CPatchRData::BuildSimpleWaterVertices() 879 { 880 BuildWaterVertexData(); 881 // overall depth around patch is ready now 882 // so, if we are fully emerged, we can get rid of things 883 if (FullyEmerged()) // i.e.: (max_wdepth < 0.0f) 884 { 885 if (m_VBWater) { 886 g_VBMan.Release(m_VBWater); 887 } 888 } 889 else 890 { 891 // allocate vertex buffer (only: update is done at render time) 892 if (!m_VBWater) { 893 m_VBWater=g_VBMan.Allocate(sizeof(SSimpleWaterVertex),m_WaterVertexData.size(),true); 894 } 895 debug_assert(m_VBWater->m_Index < 65536); 896 } 897 898 // The vertex buffer must be ready for indices calculation 899 BuildWaterIndices(); 900 } 901 902 void CPatchRData::BuildFancyWaterVertices() 903 { 904 BuildWaterVertexData(); 905 // overall depth around patch is ready now 906 // so, if we are fully emerged, we can get rid of things 907 if (FullyEmerged()) // i.e.: (max_wdepth < 0.0f) 908 { 909 if (m_VBWater) { 910 g_VBMan.Release(m_VBWater); 911 } 912 } 913 else 914 { 915 // we directly use the vertex data for rendering 916 // upload to vertex buffer 917 if (!m_VBWater) { 918 m_VBWater=g_VBMan.Allocate(sizeof(SWaterVertex),m_WaterVertexData.size(),true); 919 } 920 m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater,&m_WaterVertexData[0]); 921 debug_assert(m_VBWater->m_Index < 65536); 922 } 923 // The vertex buffer must be ready for indices calculation 924 BuildWaterIndices(); 925 926 // We directly use the vertex buffer in rendering, so we 927 // can clear the data buffer for space 928 m_WaterVertexData.clear(); 929 } 930 931 932 void CPatchRData::BuildWaterIndices() 933 { 934 // release existing indices 935 m_WaterIndices.clear(); 936 937 if (FullyEmerged()) 938 return; 939 940 // must have allocated some vertices before trying to build corresponding indices 941 debug_assert(m_VBWater); 942 943 CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 944 945 CPatch* patch = m_Patch; 946 CTerrain* terrain = patch->m_Parent; 947 948 // build indices for water 949 // TODO: Adapt method for non fancy water! 950 size_t base_indice=m_VBWater->m_Index; 951 952 for(ssize_t dx=0; dx<PATCH_SIZE; dx++) 953 { 954 for(ssize_t dz=0; dz<PATCH_SIZE; dz++) 955 { 956 ssize_t x = (patch->m_X*PATCH_SIZE + dx); 957 ssize_t z = (patch->m_Z*PATCH_SIZE + dz); 958 959 // Some offsets used to go around counterclockwise while keeping code concise 960 const int DX[] = {1,1,0,0}; 961 const int DZ[] = {0,1,1,0}; 962 963 const float waterHeight = (cmpWaterManager.null()) ? 0.0f : cmpWaterManager->GetExactWaterLevel(x,z); 964 965 // NB: I do not reuse the values already computed for building the vertex buffer/data 966 // here, even though it would probably be more readable, because it allows to 967 // use the same function for building indices for fancy and non-fancy water (which 968 // have different vertex buffer elements). 969 // But reference visibility info. is for vertices. 970 971 // is any corner of the tile below the water height? if not, no point rendering it 972 bool shouldRender = false; 973 for (int j = 0; j < 4; j++) 974 { 975 const float terrainHeight = terrain->GetVertexGroundLevel(x + DX[j], z + DZ[j]); 976 if (terrainHeight < waterHeight) 977 { 978 shouldRender = true; 979 break; 980 } 981 } 982 if (!shouldRender) 983 continue; 984 for (int j=0; j<4; j++) 985 { 986 ssize_t ix = dx + DX[j]; 987 ssize_t iz = dz + DZ[j]; 988 ssize_t v=(iz*(PATCH_SIZE+1))+ix; 989 m_WaterIndices.push_back(u16(v)+base_indice); 990 debug_assert((u16(v)+base_indice) < 65535); 991 } 992 } 993 } 994 } 995 996 const float EPSILON = 1e-12; 997 998 // if there is a positive water depth there is water on the patch 999 bool CPatchRData::HasWaterVisible() 1000 { 1001 return (max_wdepth > EPSILON); 1002 } 1003 // if the maximum water size is negative, the patch is entirely emerged 1004 bool CPatchRData::FullyEmerged() 1005 { 1006 return (max_wdepth < EPSILON); 1007 } 1008 // if the minimum water size is still positive, the patch is entirely under water 1009 bool CPatchRData::EntirelyUnderWater() 1010 { 1011 return (min_wdepth > -EPSILON); 1012 } 1013 1014 void CPatchRData::RenderSimpleWater() 1015 { 1016 debug_assert(m_UpdateFlags==0); 1017 1018 if (FullyEmerged()) 1019 return; 1020 1021 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 1022 1023 // This is probably changing so vertices need update! 1024 const CCamera& camera = g_Renderer.GetViewCamera(); 1025 CVector3D camPos = camera.m_Orientation.GetTranslation(); 1026 1027 std::vector<SSimpleWaterVertex> vertices; 1028 vertices.reserve(m_WaterVertexData.size()); 1029 1030 // build vertex buffer with adequate alpha 1031 for (unsigned int i=0; i < m_WaterVertexData.size(); i++) // TODO: Use iterators 1032 { 1033 SSimpleWaterVertex vertex; 1034 // Copy data identical to build time 1035 vertex.m_Position = m_WaterVertexData[i].m_Position; 1036 vertex.m_UVs[0] = m_WaterVertexData[i].m_UVs[0]; 1037 vertex.m_UVs[1] = m_WaterVertexData[i].m_UVs[1]; 1038 // We use the same pointer/data in array for saving space 1039 // vertex.m_PosTex1 = m_WaterVertexData[i].m_Position; 1040 1041 const float alpha = clamp( (m_WaterVertexData[i].m_Depth) / WaterMgr->m_WaterFullDepth 1042 + WaterMgr->m_WaterAlphaOffset, 1043 WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 1044 1045 // (Crappy) fresnel effect 1046 CVector3D CamFaceVertex=CVector3D(vertex.m_Position.X,WaterMgr->m_WaterHeight,vertex.m_Position.Z)-camPos; 1047 // Note: WaterMgr->m_WaterHeight is also vertex.m_Position.Y I think... 1048 CamFaceVertex.Normalize(); 1049 float FresnelScalar = CamFaceVertex.Dot(CVector3D(0.0f, -1.0f, 0.0f)); 1050 // Invert and set boundaries 1051 FresnelScalar = 1.f - (FresnelScalar * 0.6); 1052 // Set Color 1053 vertex.m_Color.m_X = WaterMgr->m_WaterColor.r; 1054 vertex.m_Color.m_Y = WaterMgr->m_WaterColor.g; 1055 vertex.m_Color.m_Z = WaterMgr->m_WaterColor.b; 1056 vertex.m_Color.m_W = alpha * FresnelScalar; 1057 1058 // save the finalized vertex built 1059 vertices.push_back(vertex); 1060 } 1061 // upload to vertex buffer 1062 m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater,&vertices[0]); 1063 1064 SSimpleWaterVertex *base=(SSimpleWaterVertex *)m_VBWater->m_Owner->Bind(); 1065 1066 // setup data pointers 1067 GLsizei stride = sizeof(SSimpleWaterVertex); 1068 glColorPointer(4, GL_FLOAT, stride, &base->m_Color[0]); 1069 glVertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]); 1070 pglClientActiveTextureARB(GL_TEXTURE0); 1071 glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs[0]); // render 1072 pglClientActiveTextureARB(GL_TEXTURE1); 1073 glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position[0]); // (same data as vertex) 1074 // glTexCoordPointer(3, GL_FLOAT, stride, &base->m_PosTex1[0]); 1075 1076 if (!g_Renderer.m_SkipSubmit) { 1077 glDrawElements(GL_QUADS, (GLsizei) m_WaterIndices.size(), 1078 GL_UNSIGNED_SHORT, &m_WaterIndices[0]); 1079 } 1080 // bump stats 1081 g_Renderer.m_Stats.m_DrawCalls++; 1082 // TODO: Water stats? 1083 1084 CVertexBuffer::Unbind(); 1085 } 1086 1087 void CPatchRData::RenderFancyWater(GLint waterDepth) 1088 { 1089 debug_assert(m_UpdateFlags==0); 1090 1091 if (FullyEmerged()) 1092 return; 1093 1094 SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind(); 1095 1096 // setup data pointers 1097 GLsizei stride = sizeof(SWaterVertex); 1098 glVertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]); 1099 pglClientActiveTextureARB(GL_TEXTURE0); 1100 glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs[0]); 1101 pglVertexAttribPointerARB(waterDepth, 1, GL_FLOAT, GL_FALSE, /* not to be normalized */ 1102 stride, &base->m_Depth); 1103 // render 1104 if (!g_Renderer.m_SkipSubmit) { 1105 glDrawElements(GL_QUADS, (GLsizei) m_WaterIndices.size(), 1106 GL_UNSIGNED_SHORT, &m_WaterIndices[0]); 1107 } 1108 // bump stats 1109 g_Renderer.m_Stats.m_DrawCalls++; 1110 // TODO: Water stats? 1111 1112 CVertexBuffer::Unbind(); 1113 1114 } 1115 -
source/renderer/TerrainRenderer.cpp
149 149 } 150 150 151 151 152 bool TerrainRenderer::HasWaterVisible() 153 { 154 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 155 { 156 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 157 if (patchdata->HasWaterVisible()) 158 return true; 159 } 160 return false; 161 } 162 152 163 /////////////////////////////////////////////////////////////////// 153 164 // Full-featured terrain rendering with blending and everything 154 void TerrainRenderer::RenderTerrain(ShadowMap* shadow )165 void TerrainRenderer::RenderTerrain(ShadowMap* shadow, RenderTerrainMode mode) 155 166 { 167 PROFILE("render terrain"); 168 156 169 debug_assert(m->phase == Phase_Render); 157 170 171 #if 0 172 // Debug Savings evaluation 173 int c = 0; 174 int d = 0; 175 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 176 { 177 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 178 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) c++; 179 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) d++; 180 } 181 if (mode == NOT_UNDERWATER) 182 std::cout << " Saving under=" << c << " patchrendering on frame" << std::endl; 183 else if (mode == NOT_EMERGED) 184 std::cout << " Saving emerged=" << d << " patchrendering on frame" << std::endl; 185 #endif 186 158 187 // render the solid black sides of the map first 159 188 g_Renderer.BindTexture(0, 0); 160 189 glEnableClientState(GL_VERTEX_ARRAY); … … 162 191 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 163 192 { 164 193 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 194 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) continue; 195 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) continue; 165 196 patchdata->RenderSides(); 166 197 } 167 198 … … 187 218 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 188 219 { 189 220 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 221 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) continue; 222 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) continue; 190 223 patchdata->RenderBase(); 191 224 } 192 225 … … 219 252 for(size_t i = 0; i < m->visiblePatches.size(); ++i) 220 253 { 221 254 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 255 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) continue; 256 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) continue; 222 257 patchdata->RenderBlends(); 223 258 } 224 259 … … 415 450 for (size_t i = 0; i < m->visiblePatches.size(); ++i) 416 451 { 417 452 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 453 if ((mode == NOT_UNDERWATER) && (patchdata->EntirelyUnderWater())) continue; 454 if ((mode == NOT_EMERGED) && (patchdata->FullyEmerged())) continue; 418 455 patchdata->RenderStreams(streamflags); 419 456 } 420 457 … … 499 536 glDisableClientState(GL_VERTEX_ARRAY); 500 537 } 501 538 502 503 /////////////////////////////////////////////////////////////////// 504 // Render water that is part of the terrain 505 void TerrainRenderer::RenderWater() 539 // Render fancy water 540 bool TerrainRenderer::RenderFancyWater() 506 541 { 507 PROFILE( "render water" );542 PROFILE( "render fancy water" ); 508 543 509 544 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 510 545 511 bool fancy = WaterMgr->WillRenderFancyWater(); 512 513 // If we're using fancy water, make sure its shader is loaded 514 if(fancy && !m->fancyWaterShader) 546 // We're using fancy water, make sure its shader is loaded 547 if(!m->fancyWaterShader) 515 548 { 516 549 Handle h = ogl_program_load(g_VFS, L"shaders/water_high.xml"); 517 550 if (h < 0) 518 551 { 519 552 LOGERROR(L"Failed to load water shader. Falling back to non-fancy water.\n"); 520 553 g_Renderer.m_Options.m_FancyWater = false; 521 fancy =false;554 return false; 522 555 } 523 556 else 524 557 { 525 558 m->fancyWaterShader = h; 526 559 } 527 560 } 528 CTerrain* terrain = g_Game->GetWorld()->GetTerrain();529 561 530 562 CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); 531 563 … … 539 571 double period = 1.6; 540 572 int curTex = (int)(time*60/period) % 60; 541 573 542 if(fancy) 543 { 544 WaterMgr->m_NormalMap[curTex]->Bind(); 545 } 546 else 547 { 548 WaterMgr->m_WaterTexture[curTex]->Bind(); 549 } 574 WaterMgr->m_NormalMap[curTex]->Bind(); 550 575 551 576 // Shift the texture coordinates by these amounts to make the water "flow" 552 577 float tx = -fmod(time, 81.0)/81.0; 553 578 float ty = -fmod(time, 34.0)/34.0; 554 579 555 if(!fancy) 556 { 557 // Perform the shifting by modifying the texture matrix 558 glMatrixMode(GL_TEXTURE); 559 glLoadIdentity(); 560 glTranslatef(tx, ty, 0); 580 // Set the proper LOD bias 581 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 561 582 562 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 563 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 564 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 565 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 566 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 567 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 568 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 569 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 570 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 571 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 583 const CCamera& camera = g_Renderer.GetViewCamera(); 584 CVector3D camPos = camera.m_Orientation.GetTranslation(); 572 585 573 // Multiply by LOS texture 574 losTexture.BindTexture(1); 575 pglClientActiveTextureARB(GL_TEXTURE1); 576 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 586 // Bind reflection and refraction textures on texture units 1 and 2 587 pglActiveTextureARB( GL_TEXTURE1_ARB ); 588 glEnable( GL_TEXTURE_2D ); 589 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture ); 590 pglActiveTextureARB( GL_TEXTURE2_ARB ); 591 glEnable( GL_TEXTURE_2D ); 592 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture ); 577 593 578 glLoadMatrixf(losTexture.GetTextureMatrix());594 losTexture.BindTexture(3); 579 595 580 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 581 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 582 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 583 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 584 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 585 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 586 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 587 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 588 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 589 } 596 // Bind water shader and set arguments 597 ogl_program_use( m->fancyWaterShader ); 590 598 591 // Set the proper LOD bias 592 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 599 GLint ambient = ogl_program_get_uniform_location( m->fancyWaterShader, "ambient" ); 600 GLint sunDir = ogl_program_get_uniform_location( m->fancyWaterShader, "sunDir" ); 601 GLint sunColor = ogl_program_get_uniform_location( m->fancyWaterShader, "sunColor" ); 602 GLint cameraPos = ogl_program_get_uniform_location( m->fancyWaterShader, "cameraPos" ); 603 GLint shininess = ogl_program_get_uniform_location( m->fancyWaterShader, "shininess" ); 604 GLint specularStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "specularStrength" ); 605 GLint waviness = ogl_program_get_uniform_location( m->fancyWaterShader, "waviness" ); 606 GLint murkiness = ogl_program_get_uniform_location( m->fancyWaterShader, "murkiness" ); 607 GLint fullDepth = ogl_program_get_uniform_location( m->fancyWaterShader, "fullDepth" ); 608 GLint tint = ogl_program_get_uniform_location( m->fancyWaterShader, "tint" ); 609 GLint reflectionTint = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTint" ); 610 GLint reflectionTintStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTintStrength" ); 611 GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" ); 612 GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" ); 613 GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" ); 614 GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" ); 615 GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" ); 616 GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" ); 617 GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" ); 618 GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" ); 593 619 594 const CCamera& camera = g_Renderer.GetViewCamera(); 595 CVector3D camPos = camera.m_Orientation.GetTranslation(); 620 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 621 pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X ); 622 pglUniform3fvARB( sunDir, 1, &lightEnv.GetSunDir().X ); 623 pglUniform3fvARB( sunColor, 1, &lightEnv.m_SunColor.X ); 624 pglUniform1fARB( shininess, WaterMgr->m_Shininess ); 625 pglUniform1fARB( specularStrength, WaterMgr->m_SpecularStrength ); 626 pglUniform1fARB( waviness, WaterMgr->m_Waviness ); 627 pglUniform1fARB( murkiness, WaterMgr->m_Murkiness ); 628 pglUniform1fARB( fullDepth, WaterMgr->m_WaterFullDepth ); 629 pglUniform3fvARB( tint, 1, WaterMgr->m_WaterTint.FloatArray() ); 630 pglUniform1fARB( reflectionTintStrength, WaterMgr->m_ReflectionTintStrength ); 631 pglUniform3fvARB( reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray() ); 632 pglUniform4fARB( translation, tx, ty, 0, 0 ); 633 pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 ); 634 pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 ); 635 pglUniformMatrix4fvARB( losMatrix, 1, false, losTexture.GetTextureMatrix() ); 636 pglUniform1iARB( normalMap, 0 ); // texture unit 0 637 pglUniform1iARB( reflectionMap, 1 ); // texture unit 1 638 pglUniform1iARB( refractionMap, 2 ); // texture unit 2 639 pglUniform1iARB( losMap, 3 ); // texture unit 3 640 pglUniform3fvARB( cameraPos, 1, &camPos.X ); 596 641 597 GLint vertexDepth = 0; // water depth attribute, if using fancy water 642 // glActiveTexture(GL_TEXTURE0); 598 643 599 if(fancy) 644 glEnableClientState(GL_VERTEX_ARRAY); 645 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 646 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 647 648 // water depth attribute, when using fancy water 649 GLint vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" ); 650 pglEnableVertexAttribArrayARB(vertexDepth); 651 652 for(size_t i=0; i<m->visiblePatches.size(); i++) 600 653 { 601 // Bind reflection and refraction textures on texture units 1 and 2 602 pglActiveTextureARB( GL_TEXTURE1_ARB ); 603 glEnable( GL_TEXTURE_2D ); 604 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture ); 605 pglActiveTextureARB( GL_TEXTURE2_ARB ); 606 glEnable( GL_TEXTURE_2D ); 607 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture ); 654 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 655 patchdata->RenderFancyWater(vertexDepth); 656 } 608 657 609 losTexture.BindTexture(3); 658 pglDisableVertexAttribArrayARB(vertexDepth); 659 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 660 glDisableClientState(GL_VERTEX_ARRAY); 610 661 611 // Bind water shader and set arguments 612 ogl_program_use( m->fancyWaterShader ); 662 // Unbind the LOS/refraction/reflection textures and the shader 663 g_Renderer.BindTexture(3, 0); 664 g_Renderer.BindTexture(2, 0); 665 g_Renderer.BindTexture(1, 0); 666 pglActiveTextureARB(GL_TEXTURE0_ARB); 667 ogl_program_use(0); 613 668 614 GLint ambient = ogl_program_get_uniform_location( m->fancyWaterShader, "ambient" ); 615 GLint sunDir = ogl_program_get_uniform_location( m->fancyWaterShader, "sunDir" ); 616 GLint sunColor = ogl_program_get_uniform_location( m->fancyWaterShader, "sunColor" ); 617 GLint cameraPos = ogl_program_get_uniform_location( m->fancyWaterShader, "cameraPos" ); 618 GLint shininess = ogl_program_get_uniform_location( m->fancyWaterShader, "shininess" ); 619 GLint specularStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "specularStrength" ); 620 GLint waviness = ogl_program_get_uniform_location( m->fancyWaterShader, "waviness" ); 621 GLint murkiness = ogl_program_get_uniform_location( m->fancyWaterShader, "murkiness" ); 622 GLint fullDepth = ogl_program_get_uniform_location( m->fancyWaterShader, "fullDepth" ); 623 GLint tint = ogl_program_get_uniform_location( m->fancyWaterShader, "tint" ); 624 GLint reflectionTint = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTint" ); 625 GLint reflectionTintStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTintStrength" ); 626 GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" ); 627 GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" ); 628 GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" ); 629 GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" ); 630 GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" ); 631 GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" ); 632 GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" ); 633 GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" ); 669 glMatrixMode(GL_MODELVIEW); 670 glDisable(GL_BLEND); 671 glDisable(GL_TEXTURE_2D); 634 672 635 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 636 pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X ); 637 pglUniform3fvARB( sunDir, 1, &lightEnv.GetSunDir().X ); 638 pglUniform3fvARB( sunColor, 1, &lightEnv.m_SunColor.X ); 639 pglUniform1fARB( shininess, WaterMgr->m_Shininess ); 640 pglUniform1fARB( specularStrength, WaterMgr->m_SpecularStrength ); 641 pglUniform1fARB( waviness, WaterMgr->m_Waviness ); 642 pglUniform1fARB( murkiness, WaterMgr->m_Murkiness ); 643 pglUniform1fARB( fullDepth, WaterMgr->m_WaterFullDepth ); 644 pglUniform3fvARB( tint, 1, WaterMgr->m_WaterTint.FloatArray() ); 645 pglUniform1fARB( reflectionTintStrength, WaterMgr->m_ReflectionTintStrength ); 646 pglUniform3fvARB( reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray() ); 647 pglUniform4fARB( translation, tx, ty, 0, 0 ); 648 pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 ); 649 pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 ); 650 pglUniformMatrix4fvARB( losMatrix, 1, false, losTexture.GetTextureMatrix() ); 651 pglUniform1iARB( normalMap, 0 ); // texture unit 0 652 pglUniform1iARB( reflectionMap, 1 ); // texture unit 1 653 pglUniform1iARB( refractionMap, 2 ); // texture unit 2 654 pglUniform1iARB( losMap, 3 ); // texture unit 3 655 pglUniform3fvARB( cameraPos, 1, &camPos.X ); 673 return true; 674 } 656 675 657 vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" ); 658 } 676 void TerrainRenderer::RenderSimpleWater() 677 { 678 PROFILE( "render simple water" ); 679 680 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 681 682 CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); 659 683 660 float repeatPeriod = (fancy ? WaterMgr->m_RepeatPeriod : 16.0f); 684 glEnable(GL_BLEND); 685 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 686 glEnable(GL_DEPTH_TEST); 687 glDepthFunc(GL_LEQUAL); 661 688 662 glBegin(GL_QUADS);689 double time = WaterMgr->m_WaterTexTimer; 663 690 664 for(size_t i=0; i<m->visiblePatches.size(); i++) 665 { 666 CPatch* patch = m->visiblePatches[i]; 691 double period = 1.6; 692 int curTex = (int)(time*60/period) % 60; 667 693 668 for(ssize_t dx=0; dx<PATCH_SIZE; dx++) 669 { 670 for(ssize_t dz=0; dz<PATCH_SIZE; dz++) 671 { 672 ssize_t x = (patch->m_X*PATCH_SIZE + dx); 673 ssize_t z = (patch->m_Z*PATCH_SIZE + dz); 694 WaterMgr->m_WaterTexture[curTex]->Bind(); 674 695 675 // Some offsets used to go around counterclockwise while keeping code concise676 const int DX[] = {1,1,0,0};677 const int DZ[] = {0,1,1,0};696 // Shift the texture coordinates by these amounts to make the water "flow" 697 float tx = -fmod(time, 81.0)/81.0; 698 float ty = -fmod(time, 34.0)/34.0; 678 699 679 // is any corner of the tile below the water height? if not, no point rendering it 680 bool shouldRender = false; 681 for (int j = 0; j < 4; j++) 682 { 683 float terrainHeight = terrain->GetVertexGroundLevel(x + DX[j], z + DZ[j]); 684 if (terrainHeight < WaterMgr->m_WaterHeight) 685 { 686 shouldRender = true; 687 break; 688 } 689 } 690 if (!shouldRender) 691 continue; 700 // Perform the shifting by modifying the texture matrix 701 glMatrixMode(GL_TEXTURE); 702 glLoadIdentity(); 703 glTranslatef(tx, ty, 0); 692 704 693 for (int j=0; j<4; j++) 694 { 695 ssize_t ix = x + DX[j]; 696 ssize_t iz = z + DZ[j]; 705 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 706 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 707 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 708 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 709 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 710 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 711 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 712 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 713 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 714 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 697 715 698 float vertX = ix * CELL_SIZE; 699 float vertZ = iz * CELL_SIZE; 716 // Multiply by LOS texture 717 losTexture.BindTexture(1); 718 pglClientActiveTextureARB(GL_TEXTURE1); 719 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 700 720 701 float terrainHeight = terrain->GetVertexGroundLevel(ix, iz);721 glLoadMatrixf(losTexture.GetTextureMatrix()); 702 722 703 if (fancy) 704 { 705 pglVertexAttrib1fARB(vertexDepth, WaterMgr->m_WaterHeight - terrainHeight); 706 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 707 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 708 } 709 else 710 { 711 float alpha = clamp( (WaterMgr->m_WaterHeight - terrainHeight) / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, 712 WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 723 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 724 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 725 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 726 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 727 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 728 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 729 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 730 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 731 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 713 732 714 // (Crappy) fresnel effect715 CVector3D CamFaceVertex=CVector3D(vertX,WaterMgr->m_WaterHeight,vertZ)-camPos;716 CamFaceVertex.Normalize();717 float FresnelScalar = CamFaceVertex.Dot(CVector3D(0.0f, -1.0f, 0.0f));718 // Invert and set boundaries719 FresnelScalar = 1.f - (FresnelScalar * 0.6);720 733 721 glColor4f(WaterMgr->m_WaterColor.r, 722 WaterMgr->m_WaterColor.g, 723 WaterMgr->m_WaterColor.b, 724 alpha * FresnelScalar); 725 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 726 pglMultiTexCoord3fARB(GL_TEXTURE1, vertX, WaterMgr->m_WaterHeight, vertZ); 727 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 728 } 734 // Set the proper LOD bias 735 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 729 736 730 } 731 } //end of x loop 732 } //end of z loop 733 } 734 glEnd(); 737 glEnableClientState(GL_VERTEX_ARRAY); 738 glEnableClientState(GL_COLOR_ARRAY); 739 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 740 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 735 741 736 if (fancy)742 for(size_t i=0; i<m->visiblePatches.size(); i++) 737 743 { 738 // Unbind the LOS/refraction/reflection textures and the shader 744 CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData(); 745 patchdata->RenderSimpleWater(); 746 } 739 747 740 g_Renderer.BindTexture(3, 0); 741 g_Renderer.BindTexture(2, 0); 742 g_Renderer.BindTexture(1, 0); 748 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 749 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 750 glDisableClientState(GL_COLOR_ARRAY); 751 glDisableClientState(GL_VERTEX_ARRAY); 743 752 744 pglActiveTextureARB(GL_TEXTURE0_ARB); 753 g_Renderer.BindTexture(1, 0); 754 pglClientActiveTextureARB(GL_TEXTURE1_ARB); 755 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 745 756 746 ogl_program_use(0); 747 } 757 glLoadIdentity(); 748 758 749 if (!fancy) 750 { 751 g_Renderer.BindTexture(1, 0); 752 pglClientActiveTextureARB(GL_TEXTURE1_ARB); 753 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 759 pglActiveTextureARB(GL_TEXTURE0_ARB); 760 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 754 761 755 glLoadIdentity(); 762 // Clean up the texture matrix and blend mode 763 glLoadIdentity(); 764 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 756 765 757 pglActiveTextureARB(GL_TEXTURE0_ARB);758 pglClientActiveTextureARB(GL_TEXTURE0_ARB);759 760 // Clean up the texture matrix and blend mode761 glLoadIdentity();762 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);763 }764 765 766 glMatrixMode(GL_MODELVIEW); 766 767 glDisable(GL_BLEND); 767 768 glDisable(GL_TEXTURE_2D); 768 769 } 769 770 771 772 /////////////////////////////////////////////////////////////////// 773 // Render water that is part of the terrain 774 void TerrainRenderer::RenderWater() 775 { 776 // PROFILE is defined in one of the sub functions 777 778 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 779 780 bool fancy = WaterMgr->WillRenderFancyWater(); 781 782 if (fancy) { 783 bool r = RenderFancyWater(); 784 if (r) return; 785 } 786 RenderSimpleWater(); 787 } 788 770 789 void TerrainRenderer::RenderPriorities() 771 790 { 772 791 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();