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
187
188
189
190
191
192
193
194
195
#include "Headers/BloomPreRenderOperator.h"

#include "Platform/Video/Headers/GFXDevice.h"
#include "Core/Headers/ParamHandler.h"
#include "Core/Resources/Headers/ResourceCache.h"
#include "Geometry/Shapes/Headers/Predefined/Quad3D.h"
#include "Rendering/PostFX/Headers/PreRenderStageBuilder.h"

namespace Divide {

BloomPreRenderOperator::BloomPreRenderOperator(Framebuffer* result,
                                               const vec2<U16>& resolution,
                                               SamplerDescriptor* const sampler)
    : PreRenderOperator(PostFXRenderStage::BLOOM, resolution, sampler),
      _outputFB(result),
      _tempHDRFB(nullptr),
      _luminaMipLevel(0)
{
    _luminaFB[0] = nullptr;
    _luminaFB[1] = nullptr;
    _horizBlur = 0;
    _vertBlur = 0;
    _tempBloomFB = GFX_DEVICE.newFB();

    TextureDescriptor tempBloomDescriptor(TextureType::TEXTURE_2D,
                                          GFXImageFormat::RGB8,
                                          GFXDataFormat::UNSIGNED_BYTE);
    tempBloomDescriptor.setSampler(*_internalSampler);

    _tempBloomFB->addAttachment(tempBloomDescriptor, TextureDescriptor::AttachmentType::Color0);
    _outputFB->addAttachment(tempBloomDescriptor, TextureDescriptor::AttachmentType::Color0);
    _outputFB->setClearColor(DefaultColors::BLACK());
    ResourceDescriptor bright("bright");
    bright.setThreadedLoading(false);
    ResourceDescriptor blur("blur");
    blur.setThreadedLoading(false);

    _bright = CreateResource<ShaderProgram>(bright);
    _blur = CreateResource<ShaderProgram>(blur);
    _bright->Uniform("texScreen", ShaderProgram::TextureUsage::UNIT0);
    _bright->Uniform("texExposure", ShaderProgram::TextureUsage::UNIT1);
    _bright->Uniform("texPrevExposure", 2);
    _blur->Uniform("texScreen", ShaderProgram::TextureUsage::UNIT0);
    _blur->Uniform("kernelSize", 10);
    _horizBlur = _blur->GetSubroutineIndex(ShaderType::FRAGMENT, "blurHorizontal");
    _vertBlur = _blur->GetSubroutineIndex(ShaderType::FRAGMENT, "blurVertical");
    reshape(_resolution.width, _resolution.height);
}

BloomPreRenderOperator::~BloomPreRenderOperator() {
    RemoveResource(_bright);
    RemoveResource(_blur);
    MemoryManager::DELETE(_tempBloomFB);
    MemoryManager::DELETE(_luminaFB[0]);
    MemoryManager::DELETE(_luminaFB[1]);
    MemoryManager::DELETE(_tempHDRFB);
}

U32 nextPOW2(U32 n) {
    n--;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    n++;
    return n;
}

void BloomPreRenderOperator::reshape(U16 width, U16 height) {
    assert(_tempBloomFB);
    U16 w = width / 4;
    U16 h = height / 4;
    _tempBloomFB->create(w, h);
    _outputFB->create(width, height);
    if (_genericFlag && _tempHDRFB) {
        _tempHDRFB->create(width, height);
        U16 lumaRez = to_ushort(nextPOW2(width / 3));
        // make the texture square sized and power of two
        _luminaFB[0]->create(lumaRez, lumaRez);
        _luminaFB[1]->create(lumaRez, lumaRez);
        _luminaMipLevel = 0;
        while (lumaRez >>= 1) {
            _luminaMipLevel++;
        }
    }
    _blur->Uniform("size", vec2<F32>(w, h));
}

void BloomPreRenderOperator::operation() {
    if (!_enabled) return;

    if (_inputFB.empty()) {
        Console::errorfn(Locale::get("ERROR_BLOOM_INPUT_FB"));
        return;
    }

    U32 defaultStateHash = GFX_DEVICE.getDefaultStateBlock(true);

    toneMapScreen();

    // render all of the "bright spots"
    _outputFB->begin(Framebuffer::defaultPolicy());
    {
        // screen FB
        _inputFB[0]->bind(to_ubyte(ShaderProgram::TextureUsage::UNIT0));
        GFX_DEVICE.drawTriangle(defaultStateHash, _bright);
    }
    _outputFB->end();

    _blur->bind();
    // Blur horizontally
    _blur->SetSubroutine(ShaderType::FRAGMENT, _horizBlur);
    _tempBloomFB->begin(Framebuffer::defaultPolicy());
    {
        // bright spots
        _outputFB->bind(to_ubyte(ShaderProgram::TextureUsage::UNIT0));
        GFX_DEVICE.drawTriangle(defaultStateHash, _blur);
    }
    _tempBloomFB->end();

    // Blur vertically
    _blur->SetSubroutine(ShaderType::FRAGMENT, _vertBlur);
    _outputFB->begin(Framebuffer::defaultPolicy());
    {
        // horizontally blurred bright spots
        _tempBloomFB->bind(to_ubyte(ShaderProgram::TextureUsage::UNIT0));
        GFX_DEVICE.drawTriangle(defaultStateHash, _blur);
        // clear states
    }
    _outputFB->end();
}

void BloomPreRenderOperator::toneMapScreen() {
    if (!_genericFlag) {
        return;
    }

    if (!_tempHDRFB) {
        _tempHDRFB = GFX_DEVICE.newFB();
        TextureDescriptor hdrDescriptor(TextureType::TEXTURE_2D,
                                        GFXImageFormat::RGBA16F,
                                        GFXDataFormat::FLOAT_16);
        hdrDescriptor.setSampler(*_internalSampler);
        _tempHDRFB->addAttachment(hdrDescriptor, TextureDescriptor::AttachmentType::Color0);
        _tempHDRFB->create(_inputFB[0]->getWidth(), _inputFB[0]->getHeight());

        _luminaFB[0] = GFX_DEVICE.newFB();
        _luminaFB[1] = GFX_DEVICE.newFB();

        SamplerDescriptor lumaSampler;
        lumaSampler.setWrapMode(TextureWrap::CLAMP_TO_EDGE);
        lumaSampler.setMinFilter(TextureFilter::LINEAR_MIPMAP_LINEAR);

        TextureDescriptor lumaDescriptor(TextureType::TEXTURE_2D,
                                         GFXImageFormat::RED16F,
                                         GFXDataFormat::FLOAT_16);
        lumaDescriptor.setSampler(lumaSampler);
        _luminaFB[0]->addAttachment(lumaDescriptor, TextureDescriptor::AttachmentType::Color0);
        U16 lumaRez = to_ushort(nextPOW2(_inputFB[0]->getWidth() / 3));
        // make the texture square sized and power of two
        _luminaFB[0]->create(lumaRez, lumaRez);

        lumaSampler.setFilters(TextureFilter::LINEAR);
        lumaDescriptor.setSampler(lumaSampler);
        _luminaFB[1]->addAttachment(lumaDescriptor, TextureDescriptor::AttachmentType::Color0);

        _luminaFB[1]->create(1, 1);
        _luminaMipLevel = 0;
        while (lumaRez >>= 1) _luminaMipLevel++;
    }

    _bright->Uniform("luminancePass", true);

    _luminaFB[1]->blitFrom(_luminaFB[0]);

    _luminaFB[0]->begin(Framebuffer::defaultPolicy());
    _inputFB[0]->bind(0);
    _luminaFB[1]->bind(2);
    GFX_DEVICE.drawTriangle(GFX_DEVICE.getDefaultStateBlock(true), _bright);

    _bright->Uniform("luminancePass", false);
    _bright->Uniform("toneMap", true);

    _tempHDRFB->blitFrom(_inputFB[0]);

    _inputFB[0]->begin(Framebuffer::defaultPolicy());
    // screen FB
    _tempHDRFB->bind(0);
    // luminance FB
    _luminaFB[0]->bind(1);
    GFX_DEVICE.drawTriangle(GFX_DEVICE.getDefaultStateBlock(true), _bright);
    _bright->Uniform("toneMap", false);
}
};

Commits for Divide-Framework/trunk/Source Code/Rendering/PostFX/CustomOperators/BloomPreRenderOperator.cpp

Diff revisions: vs.
Revision Author Commited Message
557 Diff Diff IonutCava picture IonutCava Tue 10 Nov, 2015 12:00:20 +0000

[IonutCava]
- Gather all rendering calls from glVertexArray and glGenericVertexData into a single function in glResources: submitRenderCommand.
— This allows both classes to interpret GenericDrawCommands in the same way
- Use unsigned ints for all hasehs instead of size_t to avoid negative number hashes (useful for debugging)

546 Diff Diff IonutCava picture IonutCava Tue 03 Nov, 2015 23:40:35 +0000

[IonutCava]
- Single pass (layered rendering) cascaded shadowmaps including blur
- Naming convention fixes

529 Diff Diff IonutCava picture IonutCava Mon 19 Oct, 2015 20:34:35 +0000

[IonutCava]
- Some alignment fixes
- Removed some redundant shader binds

514 Diff Diff IonutCava picture IonutCava Fri 25 Sep, 2015 16:18:42 +0000

[IonutCava]
- Split fullscreen quad rendering system in two and use the most performant one depending on the situation:
— The old GL_POINTS expanded in Geometry shader method. (e.g. useful for blurs / fxaa)
— Single triangle 2x width and 2xheight of the screen with scaled UVs (e.g. useful for fullscreen rendering)
- Attempt to change line rendering system to support custom start and end widths
- First attempt at splitting vertex specifications from buffers (with glVertexAttribFormat) and use only one VAO per specification instead of one per object
- Code cleanups and small optimizations where appropriate

504 Diff Diff IonutCava picture IonutCava Tue 25 Aug, 2015 16:17:38 +0000

[IonutCava]
- Better caching of draw commands (W.I.P.)
- Remove unused occlusion culling code. Will be replaced with Hi-Z based culling

444 Diff Diff IonutCava picture IonutCava Thu 21 May, 2015 16:06:53 +0000

[Ionut]
- More platform independent code cleanup:
— Moved platform specific defines to their respective header files (e.g. THREAD_LOCAL)
— Moved most preprocessor defines from the VisualC++ projects into source code
— Removed compiler specific code (e.g. warning disables) and fixed most warning resulting from this

417 Diff Diff IonutCava picture IonutCava Thu 30 Apr, 2015 16:27:19 +0000

[Ionut]
- Packed tangent data to a single float and changed color data from a vec4 of unsigned char to a single unsigned int to improve data upload performance from the CPU to the GPU
- Improved the SamplerDescriptor class to automatically detect if mipmaps are needed based on texture filtering.

390 Diff Diff IonutCava picture IonutCava Thu 26 Mar, 2015 22:41:09 +0000

[Ionut]
- Renamed most enum values to shorter names (possible due to enum-class type safety)
- Removed to redundant state change cases (glCullFace when CULL_MODE_NONE was used, and glLineWidth that didn’t have redundancy checks)
- Added a hacky SceneGraphNode render call count to skip the first 3 draw calls so that the data buffers have time to update properly (solves flickering and erroneous rendering when moving camera to include a new node)

371 Diff Diff IonutCava picture IonutCava Sat 14 Mar, 2015 21:18:52 +0000

[Ionut]
- More updates to the DSA style OpenGL API implementation

366 IonutCava picture IonutCava Tue 10 Mar, 2015 16:56:30 +0000

[Ionut]
- More type safe enum replacement