Subversion Repository Public Repository

Divide-Framework

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "stdafx.h"

#include "Headers/Water.h"

#include "Managers/Headers/SceneManager.h"
#include "Managers/Headers/RenderPassManager.h"
#include "Geometry/Material/Headers/Material.h"

namespace Divide {

namespace {
    ClipPlaneIndex g_reflectionClipID = ClipPlaneIndex::CLIP_PLANE_4;
    ClipPlaneIndex g_refractionClipID = ClipPlaneIndex::CLIP_PLANE_5;
};

WaterPlane::WaterPlane(ResourceCache& parentCache, size_t descriptorHash, const stringImpl& name, const vec3<F32>& dimensions)
    : SceneNode(parentCache, descriptorHash, name, SceneNodeType::TYPE_WATER),
      _plane(nullptr),
      _dimensions(dimensions),
      _reflectionCam(nullptr)
{
    // Set water plane to be single-sided
    P32 quadMask;
    quadMask.i = 0;
    quadMask.b[0] = true;

    ResourceDescriptor waterPlane("waterPlane");
    waterPlane.setFlag(true);  // No default material
    waterPlane.setBoolMask(quadMask);
    _plane = CreateResource<Quad3D>(parentCache, waterPlane);

    // The water doesn't cast shadows, doesn't need ambient occlusion and
    // doesn't have real "depth"
    renderState().addToDrawExclusionMask(RenderStage::SHADOW);

    U32 sideLength = nextPOW2(std::max(to_U32(dimensions.width), to_U32(dimensions.height)));

    Console::printfn(Locale::get(_ID("REFRACTION_INIT_FB")), sideLength, sideLength);

    setFlag(UpdateFlag::BOUNDS_CHANGED);

    _reflectionCam = Camera::createCamera(name + "_reflectionCam", Camera::CameraType::FREE_FLY);
}

WaterPlane::~WaterPlane()
{
    Camera::destroyCamera(_reflectionCam);
}

void WaterPlane::postLoad(SceneGraphNode& sgn) {
    static const U32 normalMask = to_base(ComponentType::NAVIGATION) |
                                  to_base(ComponentType::TRANSFORM) |
                                  to_base(ComponentType::BOUNDS) |
                                  to_base(ComponentType::RENDERING) |
                                  to_base(ComponentType::NETWORKING);

    F32 halfWidth = _dimensions.width * 0.5f;
    F32 halfLength = _dimensions.height * 0.5f;

    _plane->setCorner(Quad3D::CornerLocation::TOP_LEFT,     vec3<F32>(-halfWidth, 0, -halfLength));
    _plane->setCorner(Quad3D::CornerLocation::TOP_RIGHT,    vec3<F32>( halfWidth, 0, -halfLength));
    _plane->setCorner(Quad3D::CornerLocation::BOTTOM_LEFT,  vec3<F32>(-halfWidth, 0,  halfLength));
    _plane->setCorner(Quad3D::CornerLocation::BOTTOM_RIGHT, vec3<F32>( halfWidth, 0,  halfLength));
    _plane->setNormal(Quad3D::CornerLocation::CORNER_ALL, WORLD_Y_AXIS);
    _plane->renderState().setDrawState(false);
    
    sgn.addNode(_plane, normalMask, PhysicsGroup::GROUP_STATIC);

    RenderingComponent* renderable = sgn.get<RenderingComponent>();
    renderable->setReflectionCallback(DELEGATE_BIND(&WaterPlane::updateReflection,
                                                    this,
                                                    std::placeholders::_1,
                                                    std::placeholders::_2));
    renderable->setRefractionCallback(DELEGATE_BIND(&WaterPlane::updateRefraction,
                                                    this,
                                                    std::placeholders::_1,
                                                    std::placeholders::_2));

    renderable->setReflectionAndRefractionType(ReflectorType::PLANAR_REFLECTOR);

    SceneNode::postLoad(sgn);
}

void WaterPlane::updateBoundsInternal(SceneGraphNode& sgn) {
    F32 halfWidth = _dimensions.width * 0.5f;
    F32 halfLength = _dimensions.height * 0.5f;

    _boundingBox.set(vec3<F32>(-halfWidth, _dimensions.depth, -halfLength), vec3<F32>(halfWidth, 0, halfLength));

    SceneNode::updateBoundsInternal(sgn);
}

bool WaterPlane::unload() {
    bool state = false;
    state = SceneNode::unload();
    return state;
}

bool WaterPlane::pointUnderwater(const SceneGraphNode& sgn, const vec3<F32>& point) {
    return sgn.get<BoundsComponent>()->getBoundingBox().containsPoint(point);
}

bool WaterPlane::onRender(SceneGraphNode& sgn, 
                          const SceneRenderState& sceneRenderState,
                          const RenderStagePass& renderStagePass) {
    return _plane->onRender(sgn, sceneRenderState, renderStagePass);
}

void WaterPlane::buildDrawCommands(SceneGraphNode& sgn,
                                   const RenderStagePass& renderStagePass,
                                   RenderPackage& pkgInOut) {
    GenericDrawCommand cmd;
    cmd.primitiveType(PrimitiveType::TRIANGLE_STRIP);
    cmd.sourceBuffer(_plane->getGeometryVB());
    cmd.cmd().indexCount = to_U32(_plane->getGeometryVB()->getIndexCount());

    GFX::DrawCommand drawCommand;
    drawCommand._drawCommands.push_back(cmd);
    pkgInOut.addDrawCommand(drawCommand);

    SceneNode::buildDrawCommands(sgn, renderStagePass, pkgInOut);
}

/// update water refraction
void WaterPlane::updateRefraction(RenderCbkParams& renderParams, GFX::CommandBuffer& bufferInOut) {
    // If we are above water, process the plane's refraction.
    // If we are below, we render the scene normally
    bool underwater = pointUnderwater(renderParams._sgn, renderParams._camera->getEye());
    Plane<F32> refractionPlane;
    updatePlaneEquation(renderParams._sgn, refractionPlane, underwater);

    RenderPassManager::PassParams params;
    params.doPrePass = true;
    params.occlusionCull = false;
    params.camera = renderParams._camera;
    params.stage = RenderStage::REFRACTION;
    params.target = renderParams._renderTarget;
    params.drawPolicy = params.doPrePass ? &RenderTarget::defaultPolicyKeepDepth() : &RenderTarget::defaultPolicy();
    params.pass = renderParams._passIndex;
    params.clippingPlanes._planes[to_U32(underwater ? g_reflectionClipID : g_refractionClipID)] = refractionPlane;
    params.clippingPlanes._active[to_U32(g_refractionClipID)] = true;
    renderParams._context.parent().renderPassManager().doCustomPass(params, bufferInOut);
}

/// Update water reflections
void WaterPlane::updateReflection(RenderCbkParams& renderParams, GFX::CommandBuffer& bufferInOut) {
    // If we are above water, process the plane's refraction.
    // If we are below, we render the scene normally
    bool underwater = pointUnderwater(renderParams._sgn, renderParams._camera->getEye());

    Plane<F32> reflectionPlane;
    updatePlaneEquation(renderParams._sgn, reflectionPlane, !underwater);

    // Reset reflection cam
    _reflectionCam->fromCamera(*renderParams._camera);
    if (!underwater) {
        _reflectionCam->setReflection(reflectionPlane);
    }

    RenderPassManager::PassParams params;
    params.doPrePass = true;
    params.occlusionCull = false;
    params.camera = _reflectionCam;
    params.stage = RenderStage::REFLECTION;
    params.target = renderParams._renderTarget;
    params.drawPolicy = params.doPrePass ? &RenderTarget::defaultPolicyKeepDepth() : &RenderTarget::defaultPolicy();
    params.pass = renderParams._passIndex;
    params.clippingPlanes._planes[to_U32(underwater ? g_refractionClipID : g_reflectionClipID)] = reflectionPlane;
    params.clippingPlanes._active[to_U32(g_reflectionClipID)] = true;
    renderParams._context.parent().renderPassManager().doCustomPass(params, bufferInOut);
}

void WaterPlane::updatePlaneEquation(const SceneGraphNode& sgn, Plane<F32>& plane, bool reflection) {
    F32 waterLevel = sgn.get<TransformComponent>()->getPosition().y;
    const Quaternion<F32>& orientation = sgn.get<TransformComponent>()->getOrientation();

    vec3<F32> normal(orientation * (reflection ? WORLD_Y_AXIS : WORLD_Y_NEG_AXIS));
    normal.normalize();
    plane.set(normal, -waterLevel);
}

const vec3<F32>& WaterPlane::getDimensions() const {
    return _dimensions;
}

};

Commits for Divide-Framework/trunk/Source Code/Environment/Water/Water.cpp

Diff revisions: vs.
Revision Author Commited Message
996 Diff Diff IonutCava picture IonutCava Tue 12 Dec, 2017 17:16:54 +0000

[Ionut]
- Update and improve SGN creation and destruction
- Fix cleanup issues
- Fix GPU object memory leaks
- Fix duplicate GUID values being generated
- Misc cleanups and optimizations

994 Diff Diff IonutCava picture IonutCava Mon 11 Dec, 2017 18:01:11 +0000

[Ionut]
- Moved remaining components to new ECS system
- Started cleaning up code that was made redundant by the ECS system

992 Diff Diff IonutCava picture IonutCava Thu 07 Dec, 2017 18:01:51 +0000

[Ionut]
- Split PhysicsComponent into 2, ECS-based, components: TransformComponent and RigidBodyComponent
UNTESTED

949 Diff Diff IonutCava picture IonutCava Thu 19 Oct, 2017 21:48:37 +0000

[Ionut]
- More command buffer refactoring

948 Diff Diff IonutCava picture IonutCava Tue 17 Oct, 2017 22:41:09 +0000

[Ionut]
- Move rendering data caching outside of CommandBuffer and into RenderPackage for better control.

943 Diff Diff IonutCava picture IonutCava Tue 12 Sep, 2017 11:38:52 +0000

[IonutCava]
- Rework ThreadPool/Task system for clearer parent<->child relationship between tasks
— Disable Prio pool since it doesn’t work properly with the newest boost libraries
— Modify the C++11 threadpool to remove the boost dependency
- Reduce memory usage by allocating command buffers on use instead of on creation

940 Diff Diff IonutCava picture IonutCava Fri 18 Aug, 2017 16:18:44 +0000

[Ionut]
- Generate GFX::CommandBuffers only from GFX::CommandBufferPools.
— We shouldn’t be allocating any new GFX::CommandBuffers at runtime now.
— ToDo: Add a similar system for Pipelines
- Add 2 command buffer pools to GFXDevice: a primary one used for rendering and a large, secondary one used for command generation

933 Diff Diff IonutCava picture IonutCava Tue 15 Aug, 2017 00:02:05 +0000

[Ionut]
- CommandBuffer Part 2/3: code compiles and splash screen renders and application doesn’t crash (still has drawing issues)

929 Diff Diff IonutCava picture IonutCava Sat 12 Aug, 2017 17:34:44 +0000

[Ionut]
- More work on finishing up new PushConstant / Command buffer rendering system:
— Everything compiles and runs but with graphical and performance issues

895 IonutCava picture IonutCava Wed 21 Jun, 2017 21:10:26 +0000

[IonutCava]
- Reorder and cleanup OpenGL backend a bit.
- Small code cleanup
- Some small profile-guided optimizations