Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/supertuxkart/stk-code
Browse files Browse the repository at this point in the history
  • Loading branch information
auriamg committed May 4, 2014
2 parents 5acb763 + 849467d commit 6546512
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 25 deletions.
106 changes: 88 additions & 18 deletions data/shaders/pointlight.vert
Expand Up @@ -18,35 +18,105 @@ in vec3 Position;
in float Energy;
in vec3 Color;

in vec2 Corner;

flat out vec3 center;
flat out float energy;
flat out vec3 col;

const float zNear = 1.;

// Code borrowed from https://software.intel.com/en-us/articles/deferred-rendering-for-current-and-future-rendering-pipelines
// Maths explanations are found here http://www.gamasutra.com/view/feature/131351/the_mechanics_of_robust_stencil_.php?page=6

vec2 UpdateClipRegionRoot(float nc, /* Tangent plane x/y normal coordinate (view space) */
float lc, /* Light x/y coordinate (view space) */
float lz, /* Light z coordinate (view space) */
float lightRadius,
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
{
float nz = (lightRadius - nc * lc) / lz;
float pz = (lc * lc + lz * lz - lightRadius * lightRadius) /
(lz - (nz / nc) * lc);

if (pz > 0.) {
float c = -nz * cameraScale / nc;
if (nc > 0.) // Left side boundary
return vec2(c, 1.);
else // Right side boundary
return vec2(-1., c);
}
return vec2(-1., 1.);
}

vec2 UpdateClipRegion(float lc, /* Light x/y coordinate (view space) */
float lz, /* Light z coordinate (view space) */
float lightRadius,
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
{
float rSq = lightRadius * lightRadius;
float lcSqPluslzSq = lc * lc + lz * lz;
float d = rSq * lc * lc - lcSqPluslzSq * (rSq - lz * lz);

// The camera is inside lignt bounding sphere, quad fits whole screen
if (d <= 0.)
return vec2(-1., 1.);

float a = lightRadius * lc;
float b = sqrt(d);
float nx0 = (a + b) / lcSqPluslzSq;
float nx1 = (a - b) / lcSqPluslzSq;

vec2 clip0 = UpdateClipRegionRoot(nx0, lc, lz, lightRadius, cameraScale);
vec2 clip1 = UpdateClipRegionRoot(nx1, lc, lz, lightRadius, cameraScale);
return vec2(max(clip0.x, clip1.x), min(clip0.y, clip1.y));
}

// Returns bounding box [min.x, max.x, min.y, max.y] in clip [-1, 1] space.
vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius)
{
if (lightPosView.z + lightRadius >= zNear) {
vec2 clipX = UpdateClipRegion(lightPosView.x, lightPosView.z, lightRadius, ProjectionMatrix[0][0]);
vec2 clipY = UpdateClipRegion(lightPosView.y, lightPosView.z, lightRadius, ProjectionMatrix[1][1]);

return vec4(clipX, clipY);
}

return vec4(0.);
}


void main(void)
{
// Beyond that value, light is too attenuated
float r = 30 * Energy;
center = Position;
energy = Energy;
float radius = 20. * Energy;
vec4 Center = ViewMatrix * vec4(Position, 1.);
vec4 ProjectedCornerPosition = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.));
float adjustedDepth = ProjectedCornerPosition.z;
if (Center.z > zNear) // Light is in front of the cam
{
adjustedDepth = max(Center.z - r, zNear);
}
else if (Center.z + r > zNear) // Light is behind the cam but in range
Center /= Center.w;

vec2 ProjectedCornerPosition;
vec4 clip = ComputeClipRegion(Center.xyz, radius);
switch (gl_VertexID)
{
adjustedDepth = zNear;
case 0:
ProjectedCornerPosition = clip.xz;
break;
case 1:
ProjectedCornerPosition = clip.xw;
break;
case 2:
ProjectedCornerPosition = clip.yz;
break;
case 3:
ProjectedCornerPosition = clip.yw;
break;
}

ProjectedCornerPosition /= ProjectedCornerPosition.w;
ProjectedCornerPosition.zw = (ProjectionMatrix * vec4(0., 0., adjustedDepth, 1.)).zw;
ProjectedCornerPosition.xy *= ProjectedCornerPosition.w;
// Work out nearest depth for quad Z
// Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped
float quadDepth = max(zNear, Center.z - radius);

// Project quad depth into clip space
vec4 quadClip = ProjectionMatrix * vec4(0., 0., quadDepth, 1.0f);
gl_Position = vec4(ProjectedCornerPosition, quadClip.z / quadClip.w, 1.);

col = Color;
gl_Position = ProjectedCornerPosition;
center = Position;
energy = Energy;
}
5 changes: 5 additions & 0 deletions src/graphics/glwrap.cpp
Expand Up @@ -304,6 +304,11 @@ GLuint getDepthTexture(irr::video::ITexture *tex)

std::set<irr::video::ITexture *> AlreadyTransformedTexture;

void resetTextureTable()
{
AlreadyTransformedTexture.clear();
}

void compressTexture(irr::video::ITexture *tex, bool srgb)
{
if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end())
Expand Down
1 change: 1 addition & 0 deletions src/graphics/glwrap.hpp
Expand Up @@ -159,6 +159,7 @@ GLint LoadProgram(Types ... args)

GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void compressTexture(irr::video::ITexture *tex, bool srgb);
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height);

Expand Down
6 changes: 0 additions & 6 deletions src/graphics/shaders.cpp
Expand Up @@ -1754,7 +1754,6 @@ namespace LightShader
GLuint PointLightShader::attrib_Position;
GLuint PointLightShader::attrib_Color;
GLuint PointLightShader::attrib_Energy;
GLuint PointLightShader::attrib_Corner;
GLuint PointLightShader::uniform_ntex;
GLuint PointLightShader::uniform_dtex;
GLuint PointLightShader::uniform_spec;
Expand All @@ -1773,7 +1772,6 @@ namespace LightShader
attrib_Position = glGetAttribLocation(Program, "Position");
attrib_Color = glGetAttribLocation(Program, "Color");
attrib_Energy = glGetAttribLocation(Program, "Energy");
attrib_Corner = glGetAttribLocation(Program, "Corner");
uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_spec = glGetUniformLocation(Program, "spec");
Expand All @@ -1782,10 +1780,6 @@ namespace LightShader
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo);
glEnableVertexAttribArray(attrib_Corner);
glVertexAttribPointer(attrib_Corner, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, MAXLIGHT * sizeof(PointLightInfo), 0, GL_DYNAMIC_DRAW);
Expand Down
1 change: 0 additions & 1 deletion src/graphics/shaders.hpp
Expand Up @@ -434,7 +434,6 @@ namespace LightShader
public:
static GLuint Program;
static GLuint attrib_Position, attrib_Energy, attrib_Color;
static GLuint attrib_Corner;
static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen;
static GLuint vbo;
static GLuint vao;
Expand Down
3 changes: 3 additions & 0 deletions src/tracks/track.cpp
Expand Up @@ -28,6 +28,7 @@
#include "config/user_config.hpp"
#include "graphics/camera.hpp"
#include "graphics/CBatchingMesh.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/material_manager.hpp"
Expand Down Expand Up @@ -206,6 +207,8 @@ void Track::cleanup()
ItemManager::destroy();

ParticleKindManager::get()->cleanUpTrackSpecificGfx();
// Clear remainder of transformed textures
resetTextureTable();

for(unsigned int i=0; i<m_animated_textures.size(); i++)
{
Expand Down

0 comments on commit 6546512

Please sign in to comment.