Skip to content

Commit

Permalink
Renderer|FX: Working on basic lens flare shader rendering
Browse files Browse the repository at this point in the history
Trying to get a simple white quad to appear on screen. This is not
quite working yet.
  • Loading branch information
skyjake committed Nov 17, 2013
1 parent 15de061 commit d00ca4d
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 3 deletions.
5 changes: 5 additions & 0 deletions doomsday/client/data/shaders.dei
Expand Up @@ -156,6 +156,11 @@ group fx {
}
}

shader lensflares {
path.vertex = "shaders/lensflares.vsh"
path.fragment = "shaders/lensflares.fsh"
}

# Post-processing shaders need to have uFadeInOut (0..1) for
# fading the effect in/out.
group post {
Expand Down
17 changes: 17 additions & 0 deletions doomsday/client/data/shaders/lensflares.fsh
@@ -0,0 +1,17 @@
uniform sampler2D uTex;
varying highp vec2 vUV;

void main(void) {
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
/*
highp vec4 original = texture2D(uTex, vUV);
highp float intens =
(0.2125 * original.r) +
(0.7154 * original.g) +
(0.0721 * original.b);
gl_FragColor = vec4(vec3(intens), 1.0);
if(uFadeInOut < 1.0) {
gl_FragColor = mix(original, gl_FragColor, uFadeInOut);
}
*/
}
11 changes: 11 additions & 0 deletions doomsday/client/data/shaders/lensflares.vsh
@@ -0,0 +1,11 @@
uniform highp mat4 uMvpMatrix;
uniform highp vec2 uViewUnit;
attribute highp vec4 aVertex;
attribute highp vec2 aUV;
attribute highp vec2 aUV2;
varying highp vec2 vUV;

void main(void) {
gl_Position = (uMvpMatrix * aVertex) + vec4(aUV2 * uViewUnit, 0, 0);
vUV = aUV;
}
5 changes: 5 additions & 0 deletions doomsday/client/include/render/fx/lensflares.h
Expand Up @@ -20,6 +20,7 @@
#define DENG_CLIENT_FX_LENSFLARES_H

#include "render/consoleeffect.h"
#include "render/ilightsource.h"

namespace fx {

Expand All @@ -31,9 +32,13 @@ class LensFlares : public ConsoleEffect
public:
LensFlares(int console);

void clearLights();
void markLightPotentiallyVisibleForCurrentFrame(ILightSource const *lightSource);

void glInit();
void glDeinit();

void beginFrame();
void draw();

private:
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/include/render/ilightsource.h
Expand Up @@ -45,7 +45,7 @@ class ILightSource
/**
* RGB color of the emitted light.
*/
typedef de::Vector3f Color;
typedef de::Vector3f Colorf;

public:
virtual ~ILightSource() {}
Expand All @@ -68,7 +68,7 @@ class ILightSource
* not be factored into the color values, but is instead returned separately
* by lightSourceIntensity().
*/
virtual Color lightSourceColor() const = 0;
virtual Colorf lightSourceColorf() const = 0;

/**
* Returns the intensity of the light.
Expand Down
162 changes: 161 additions & 1 deletion doomsday/client/src/render/fx/lensflares.cpp
Expand Up @@ -17,12 +17,17 @@
*/

#include "render/fx/lensflares.h"
#include "render/ilightsource.h"
#include "render/viewports.h"
#include "gl/gl_main.h"

#include <de/concurrency.h>
#include <de/Drawable>
#include <de/Shared>
#include <de/Log>

#include <QHash>

using namespace de;

namespace fx {
Expand All @@ -32,6 +37,8 @@ namespace fx {
*/
struct FlareData
{
AtlasTexture atlas;

FlareData()
{
DENG_ASSERT_IN_MAIN_THREAD();
Expand All @@ -52,30 +59,165 @@ DENG2_PIMPL(LensFlares)
typedef Shared<FlareData> SharedFlareData;
SharedFlareData *res;

Instance(Public *i) : Base(i), res(0)
struct TestLight : public ILightSource
{
public:
LightId lightSourceId() const {
return 1;
}
Origin lightSourceOrigin() const {
return Origin(1055, -3280, 30);
}
dfloat lightSourceRadius() const {
return 10;
}
Colorf lightSourceColorf() const {
return Colorf(1, 1, 1);
}
dfloat lightSourceIntensity(de::Vector3d const &) const {
return 1;
}
};
TestLight testLight;

/**
* Current state of a potentially visible light.
*/
struct PVLight
{
ILightSource const *light;
int seenFrame; // R_FrameCount()

PVLight() : light(0), seenFrame(0)
{}
};

typedef QHash<ILightSource::LightId, PVLight *> PVSet;
PVSet pvs;

typedef GLBufferT<Vertex3Tex3Rgba> VBuf;
VBuf *buffer;
Drawable drawable;
GLUniform uMvpMatrix;
GLUniform uViewUnit;

Instance(Public *i)
: Base(i)
, res(0)
, buffer(0)
, uMvpMatrix("uMvpMatrix", GLUniform::Mat4)
, uViewUnit ("uViewUnit", GLUniform::Vec2)
{}

~Instance()
{
DENG2_ASSERT(res == 0); // should have been deinited
releaseRef(res);
clearPvs();
}

void glInit()
{
// Acquire a reference to the shared flare data.
res = SharedFlareData::hold();

buffer = new VBuf;
drawable.addBuffer(buffer);
self.shaders().build(drawable.program(), "fx.lensflares")
<< uMvpMatrix << uViewUnit;
}

void glDeinit()
{
drawable.clear();
buffer = 0;
clearPvs();
releaseRef(res);
}

void clearPvs()
{
qDeleteAll(pvs);
pvs.clear();
}

void addToPvs(ILightSource const *light)
{
PVSet::iterator found = pvs.find(light->lightSourceId());
if(found == pvs.end())
{
found = pvs.insert(light->lightSourceId(), new PVLight);
}

PVLight *pvl = found.value();
pvl->light = light;
pvl->seenFrame = R_FrameCount();
}

void makeVerticesForPVS()
{
int const thisFrame = R_FrameCount();

// The vertex buffer will contain a number of quads.
VBuf::Vertices verts;
VBuf::Indices idx;
VBuf::Type vtx;

for(PVSet::const_iterator i = pvs.constBegin(); i != pvs.constEnd(); ++i)
{
PVLight const *pvl = i.value();

// Skip lights that are not visible right now.
/// @todo If so, it might be time to purge it from the PVS.
if(pvl->seenFrame != thisFrame) continue;

float radius = .1f;
Rectanglef uvRect;

int const firstIdx = verts.size();

vtx.pos = pvl->light->lightSourceOrigin().xzy();
vtx.rgba = pvl->light->lightSourceColorf();

vtx.texCoord[0] = uvRect.topLeft;
vtx.texCoord[1] = Vector2f(-1, -1) * radius;
verts << vtx;

vtx.texCoord[0] = uvRect.topRight();
vtx.texCoord[1] = Vector2f(1, -1) * radius;
verts << vtx;

vtx.texCoord[0] = uvRect.bottomRight;
vtx.texCoord[1] = Vector2f(1, 1) * radius;
verts << vtx;

vtx.texCoord[0] = uvRect.bottomLeft();
vtx.texCoord[1] = Vector2f(-1, 1) * radius;
verts << vtx;

// Make two triangles.
idx << firstIdx << firstIdx + 2 << firstIdx + 1
<< firstIdx << firstIdx + 2 << firstIdx + 3;
}

buffer->setVertices(verts, gl::Dynamic);
buffer->setIndices(gl::Triangles, idx, gl::Dynamic);
}
};

LensFlares::LensFlares(int console) : ConsoleEffect(console), d(new Instance(this))
{}

void LensFlares::clearLights()
{
d->clearPvs();
}

void LensFlares::markLightPotentiallyVisibleForCurrentFrame(ILightSource const *lightSource)
{
d->addToPvs(lightSource);
}

void LensFlares::glInit()
{
LOG_AS("fx::LensFlares");
Expand All @@ -92,9 +234,27 @@ void LensFlares::glDeinit()
ConsoleEffect::glDeinit();
}

void fx::LensFlares::beginFrame()
{
markLightPotentiallyVisibleForCurrentFrame(&d->testLight); // testing

d->makeVerticesForPVS();
}

void LensFlares::draw()
{
//Rectanglef const rect = viewRect();

d->uViewUnit = Vector2f(1, 1);
d->uMvpMatrix = GL_GetProjectionMatrix();

GLState::push()
.setCull(gl::None)
.setDepthTest(false);

d->drawable.draw();

GLState::pop().apply();
}

} // namespace fx
Expand Down

0 comments on commit d00ca4d

Please sign in to comment.