Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 167 vs 168 for /trunk/Source Code/Environment/Water/Water.cpp

Diff revisions: vs.
  @@ -10,7 +10,7 @@
10 10
11 11 WaterPlane::WaterPlane() : SceneNode(TYPE_WATER), Reflector(TYPE_WATER_SURFACE,vec2<U16>(1024,1024)),
12 12 _plane(NULL),_texture(NULL), _shader(NULL),_planeTransform(NULL),
13 - _node(NULL),_planeSGN(NULL),_waterLevel(0),_reflectionRendering(false){}
13 + _node(NULL),_planeSGN(NULL),_waterLevel(0),_waterDepth(0),_clippingPlaneID(-1),_reflectionRendering(false){}
14 14
15 15 void WaterPlane::postLoad(SceneGraphNode* const sgn){
16 16 assert(_texture && _shader && _plane);
  @@ -31,25 +31,28 @@
31 31 ///The water doesn't cast shadows, doesn't need ambient occlusion and doesn't have real "depth"
32 32 getSceneNodeRenderState().addToDrawExclusionMask(DEPTH_STAGE);
33 33
34 - _shader->UniformTexture("texWaterReflection", 0);
35 - _shader->UniformTexture("texWaterNoiseNM", 1);
34 + _shader->UniformTexture("texWaterNoiseNM", 0);
35 + _shader->UniformTexture("texWaterReflection", 1);
36 + _shader->UniformTexture("texWaterRefraction", 2);
36 37 }
37 38
38 39 bool WaterPlane::computeBoundingBox(SceneGraphNode* const sgn){
39 40 BoundingBox& bb = _node->getBoundingBox();
40 - if(bb.isComputed()) return true;
41 - _waterLevel = GET_ACTIVE_SCENE()->state()->getWaterLevel();
42 - F32 waterDepth = GET_ACTIVE_SCENE()->state()->getWaterDepth();
43 - bb.set(vec3<F32>(-_farPlane,_waterLevel - waterDepth, -_farPlane),vec3<F32>(_farPlane, _waterLevel, _farPlane));
41 +
42 + if(bb.isComputed())
43 + return true;
44 +
45 + _waterLevel = GET_ACTIVE_SCENE()->state().getWaterLevel();
46 + _waterDepth = GET_ACTIVE_SCENE()->state().getWaterDepth();
47 + _planeTransform->setPositionY(_waterLevel);
48 + _planeDirty = true;
49 + bb.set(vec3<F32>(-_farPlane,_waterLevel - _waterDepth, -_farPlane),
50 + vec3<F32>(_farPlane, _waterLevel, _farPlane));
44 51 _planeSGN->getBoundingBox().Add(bb);
45 52 PRINT_FN(Locale::get("WATER_CREATE_DETAILS_1"), bb.getMax().y)
46 53 PRINT_FN(Locale::get("WATER_CREATE_DETAILS_2"), bb.getMin().y);
47 - bool state = SceneNode::computeBoundingBox(sgn);
48 -
49 - _shader->Uniform("water_bb_min",bb.getMin());
50 - _shader->Uniform("water_bb_max",bb.getMax());
51 54
52 - return state;
55 + return SceneNode::computeBoundingBox(sgn);
53 56 }
54 57
55 58 bool WaterPlane::unload(){
  @@ -58,17 +61,29 @@
58 61 return state;
59 62 }
60 63
61 - void WaterPlane::setParams(F32 shininess, F32 noiseTile, F32 noiseFactor, F32 transparency){
64 + void WaterPlane::setParams(F32 shininess, const vec2<F32>& noiseTile, const vec2<F32>& noiseFactor, F32 transparency){
62 65
63 - _shader->Uniform("water_shininess",shininess );
64 - _shader->Uniform("noise_tile", noiseTile );
65 - _shader->Uniform("noise_factor", noiseFactor);
66 + _shader->Uniform("_waterShininess",shininess );
67 + _shader->Uniform("_noiseFactor", noiseFactor);
68 + _shader->Uniform("_noiseTile", noiseTile );
69 + _shader->Uniform("_transparencyBias", transparency);
66 70 }
67 71
68 72 void WaterPlane::onDraw(const RenderStage& currentStage){
69 - _eyePos = GET_ACTIVE_SCENE()->renderState()->getCamera()->getEye();
70 - BoundingBox& bb = _node->getBoundingBox();
71 - _planeTransform->setPosition(vec3<F32>(_eyePos.x,bb.getMax().y,_eyePos.z));
73 + const vec3<F32>& newEye = GET_ACTIVE_SCENE()->renderState().getCamera().getEye();
74 +
75 + if(newEye != _eyePos){
76 + _eyeDiff.set(_eyePos.xz() - newEye.xz());
77 + _eyePos.set(newEye);
78 + _planeTransform->translateX(_eyeDiff.x);
79 + _planeTransform->translateZ(_eyeDiff.y);
80 + BoundingBox& bb = _node->getBoundingBox();
81 + bb.Translate(vec3<F32>(-_eyeDiff.x,0,-_eyeDiff.y));
82 + _shader->Uniform("water_bb_min", bb.getMin());
83 + _shader->Uniform("water_bb_diff",bb.getMax() - bb.getMin());
84 + _shader->Uniform("underwater",isPointUnderWater(_eyePos));
85 + }
86 +
72 87 }
73 88
74 89 void WaterPlane::postDraw(const RenderStage& currentStage){
  @@ -76,38 +91,36 @@
76 91
77 92 void WaterPlane::prepareMaterial(SceneGraphNode* const sgn){
78 93 //Prepare the main light (directional light only, sun) for now.
79 - if(!GFX_DEVICE.isCurrentRenderStage(DEPTH_STAGE)){
80 - //Find the most influental light for the terrain. Usually the Sun
81 - _lightCount = LightManager::getInstance().findLightsForSceneNode(sgn,LIGHT_TYPE_DIRECTIONAL);
82 - //Update lights for this node
83 - LightManager::getInstance().update();
84 - //Only 1 shadow map for terrains
85 - }
86 - CLAMP<U8>(_lightCount, 0, 1);
94 + //Find the most influental light for the terrain. Usually the Sun
95 + _lightCount = LightManager::getInstance().findLightsForSceneNode(sgn,LIGHT_TYPE_DIRECTIONAL);
96 + //Update lights for this node
97 + LightManager::getInstance().update();
98 + //Only 1 shadow map for terrains
99 +
87 100 if(GFX_DEVICE.isCurrentRenderStage(DISPLAY_STAGE)){
88 - U8 offset = 9;
101 + U8 offset = Config::MAX_TEXTURE_STORAGE;
102 + CLAMP<U8>(_lightCount, 0, 1);
89 103 for(U8 n = 0; n < _lightCount; n++, offset++){
90 104 Light* l = LightManager::getInstance().getLightForCurrentNode(n);
91 105 LightManager::getInstance().bindDepthMaps(l, n, offset);
92 106 }
93 107 }
108 +
94 109 SET_STATE_BLOCK(getMaterial()->getRenderState(FINAL_STAGE));
95 110
96 - _reflectedTexture->Bind(0);
97 - _texture->Bind(1);
111 + _texture->Bind(0);
112 + _reflectedTexture->Bind(1);
113 + //_refractedTexture->Bind(2);
98 114 _shader->bind();
99 - _shader->Uniform("underwater",isPointUnderWater(_eyePos));
100 115 _shader->Uniform("material",getMaterial()->getMaterialMatrix());
101 - _shader->UniformTexture("texWaterReflection", 0);
102 - _shader->UniformTexture("texWaterNoiseNM", 1);
103 116 }
104 117
105 118 void WaterPlane::releaseMaterial(){
106 - _texture->Unbind(1);
107 - _reflectedTexture->Unbind(0);
108 -
119 + //_refractedTexture->Unbind(2);
120 + _reflectedTexture->Unbind(1);
121 + _texture->Unbind(0);
109 122 if(GFX_DEVICE.isCurrentRenderStage(DISPLAY_STAGE)){
110 - U8 offset = (_lightCount - 1) + 9;
123 + U8 offset = (_lightCount - 1) + Config::MAX_TEXTURE_STORAGE;
111 124 for(I32 n = _lightCount - 1; n >= 0; n--,offset--){
112 125 Light* l = LightManager::getInstance().getLightForCurrentNode(n);
113 126 LightManager::getInstance().unbindDepthMaps(l, offset);
  @@ -121,28 +134,40 @@
121 134
122 135 bool WaterPlane::getDrawState(const RenderStage& currentStage) const {
123 136 // Wait for the Reflector to update
124 - if(!_createdFBO){
125 - return false;
126 - }
127 - // Make sure we are not drawing ourself
128 - if((currentStage == REFLECTION_STAGE || _reflectionRendering) && !_updateSelf){
129 - // unless this is desired
130 - return false;
131 - }
137 + if(!_createdFBO) return false;
138 +
139 + // Make sure we are not drawing ourself unless this is desired
140 + if((currentStage == REFLECTION_STAGE || _reflectionRendering) && !_updateSelf) return false;
141 +
132 142 // Else, process normal exclusion
133 143 return SceneNode::getDrawState(currentStage);
134 144 }
135 145
146 + /// update water refraction
147 + //void WaterPlane::updateRefraction(){
148 + // Early out check for render callback
149 + //if(_renderCallback.empty()) return;
150 + //_refractionRendering = true;
151 + // bind the refractive texture
152 + //_refractionTexture->Begin();
153 + // render to the reflective texture
154 + //_renderCallback();
155 + //_refractionTexture->End();
156 + //_refractionRendering = false;
157 + //}
158 +
136 159 /// Update water reflections
137 160 void WaterPlane::updateReflection(){
138 161 // Early out check for render callback
139 162 if(_renderCallback.empty()) return;
163 + //ToDo:: this will cause problems later with multiple reflectors. Fix it! -Ionut
140 164 _reflectionRendering = true;
141 165 // If we are above water, process the plane's reflection. If we are below, we render the scene normally
142 - // Set the correct stage
143 - RenderStage prev = GFX_DEVICE.getRenderStage();
144 - if(!isPointUnderWater(_eyePos)){
166 + bool underwater = isPointUnderWater(_eyePos);
167 +
168 + if(!underwater){
145 169 GFX_DEVICE.setRenderStage(REFLECTION_STAGE);
170 + GFX_DEVICE.enableClipPlane(_clippingPlaneID);
146 171 }
147 172
148 173 // bind the reflective texture
  @@ -151,6 +176,21 @@
151 176 _renderCallback();
152 177 _reflectedTexture->End();
153 178
154 - GFX_DEVICE.setRenderStage(prev);
179 + if(!underwater){
180 + GFX_DEVICE.disableClipPlane(_clippingPlaneID);
181 + GFX_DEVICE.setPreviousRenderStage();
182 + }
155 183 _reflectionRendering = false;
184 + }
185 +
186 + void WaterPlane::updatePlaneEquation(){
187 + _absNormal = _planeSGN->getTransform()->getGlobalOrientation() * WORLD_Y_AXIS;
188 + _absNormal.normalize();
189 + _reflectionPlane.set(_absNormal,_waterLevel);
190 + _reflectionPlane.active(false);
191 + if(_clippingPlaneID == -1){
192 + _clippingPlaneID = GFX_DEVICE.addClipPlane(_reflectionPlane);
193 + }else{
194 + GFX_DEVICE.setClipPlane(_clippingPlaneID,_reflectionPlane);
195 + }
156 196 }