Skip to content

Commit

Permalink
Merge branch '3.2'
Browse files Browse the repository at this point in the history
# Conflicts:
#	include/version.h
  • Loading branch information
codereader committed Aug 21, 2022
2 parents 8836ef1 + 5721b4b commit 8ad503f
Show file tree
Hide file tree
Showing 27 changed files with 640 additions and 90 deletions.
3 changes: 3 additions & 0 deletions include/irender.h
Expand Up @@ -265,6 +265,9 @@ class RendererLight

// Whether this light is allowed to cast shadows
virtual bool isShadowCasting() const = 0;

// Whether this light is using a blend light material
virtual bool isBlendLight() const = 0;
};
typedef std::shared_ptr<RendererLight> RendererLightPtr;

Expand Down
2 changes: 1 addition & 1 deletion include/version.h
Expand Up @@ -4,7 +4,7 @@
#include <config.h>
#define RADIANT_VERSION PACKAGE_VERSION
#else
#define RADIANT_VERSION "3.1.0"
#define RADIANT_VERSION "3.2.0pre1"
#endif

#define RADIANT_APPNAME "DarkRadiant"
Expand Down
30 changes: 30 additions & 0 deletions install/gl/blend_light_fp.glsl
@@ -0,0 +1,30 @@
#version 130

uniform sampler2D u_LightProjectionTexture; // light projection texture
uniform sampler2D u_LightFallOffTexture; // light falloff texture
uniform vec4 u_BlendColour; // light colour

varying vec4 var_tex_atten_xy_z;

void main()
{
// Light texture lookups
vec4 attenuation_xy = vec4(0,0,0,0);

// Discard s/t coords outside the light texture (clamp)
if (var_tex_atten_xy_z.x < 0 || var_tex_atten_xy_z.x > 1 ||
var_tex_atten_xy_z.y < 0 || var_tex_atten_xy_z.y > 1)
{
discard;
}

if (var_tex_atten_xy_z.w > 0.0)
{
attenuation_xy = texture2DProj(u_LightProjectionTexture, var_tex_atten_xy_z.xyw);
}

vec4 attenuation_z = texture2D(u_LightFallOffTexture, vec2(var_tex_atten_xy_z.z, 0.5));

gl_FragColor = u_BlendColour * attenuation_xy * attenuation_z;
}

21 changes: 21 additions & 0 deletions install/gl/blend_light_vp.glsl
@@ -0,0 +1,21 @@
#version 130

in vec4 attr_Position; // bound to attribute 0 in source, in object space

uniform mat4 u_ModelViewProjection; // combined modelview and projection matrix
uniform mat4 u_ObjectTransform; // object transform (object2world)
uniform mat4 u_LightTextureMatrix; // light texture transform (world-to-light-UV)

varying vec4 var_tex_atten_xy_z;

void main()
{
vec4 worldVertex = u_ObjectTransform * attr_Position;

// calc light xy,z attenuation in light space
var_tex_atten_xy_z = u_LightTextureMatrix * worldVertex;

// Apply the supplied object transform to the incoming vertex
// transform vertex position into homogenous clip-space
gl_Position = u_ModelViewProjection * worldVertex;
}
4 changes: 3 additions & 1 deletion radiantcore/CMakeLists.txt
Expand Up @@ -211,22 +211,24 @@ add_library(radiantcore MODULE
patch/PatchTesselation.cpp
Radiant.cpp
rendersystem/backend/GLProgramFactory.cpp
rendersystem/backend/glprogram/BlendLightProgram.cpp
rendersystem/backend/glprogram/CubeMapProgram.cpp
rendersystem/backend/glprogram/DepthFillAlphaProgram.cpp
rendersystem/backend/glprogram/GenericVFPProgram.cpp
rendersystem/backend/glprogram/GLSLProgramBase.cpp
rendersystem/backend/glprogram/InteractionProgram.cpp
rendersystem/backend/glprogram/RegularStageProgram.cpp
rendersystem/backend/glprogram/ShadowMapProgram.cpp
rendersystem/backend/BlendLight.cpp
rendersystem/backend/BuiltInShader.cpp
rendersystem/backend/ColourShader.cpp
rendersystem/backend/InteractingLight.cpp
rendersystem/backend/SceneRenderer.cpp
rendersystem/backend/FullBrightRenderer.cpp
rendersystem/backend/LightingModeRenderer.cpp
rendersystem/backend/ObjectRenderer.cpp
rendersystem/backend/OpenGLShader.cpp
rendersystem/backend/OpenGLShaderPass.cpp
rendersystem/backend/RegularLight.cpp
rendersystem/backend/DepthFillPass.cpp
rendersystem/backend/InteractionPass.cpp
rendersystem/debug/SpacePartitionRenderer.cpp
Expand Down
7 changes: 6 additions & 1 deletion radiantcore/entity/light/LightNode.cpp
@@ -1,6 +1,6 @@
#include "LightNode.h"

#include "itextstream.h"
#include "ishaders.h"
#include "icolourscheme.h"
#include "../EntitySettings.h"
#include <functional>
Expand Down Expand Up @@ -1012,6 +1012,11 @@ bool LightNode::isShadowCasting() const
return EntityNode::isShadowCasting();
}

bool LightNode::isBlendLight() const
{
return m_shader.isBlendLight();
}

/* greebo: A light is projected, if the entity keys light_target/light_up/light_right are not empty.
*/
bool LightNode::isProjected() const {
Expand Down
1 change: 1 addition & 0 deletions radiantcore/entity/light/LightNode.h
Expand Up @@ -267,6 +267,7 @@ class LightNode :
Matrix4 getLightTextureTransformation() const override;
Vector3 getLightOrigin() const override;
bool isShadowCasting() const override;
bool isBlendLight() const override;
const ShaderPtr& getShader() const override;
AABB lightAABB() const override;
};
Expand Down
9 changes: 9 additions & 0 deletions radiantcore/entity/light/LightShader.h
Expand Up @@ -2,6 +2,7 @@

#include <string>
#include "irender.h"
#include "shaders/MaterialManager.h"

namespace entity {

Expand Down Expand Up @@ -43,6 +44,14 @@ class LightShader: public sigc::trackable
return _shader;
}

bool isBlendLight() const
{
if (!_shader) return false;

const auto& material = _shader->getMaterial();
return material ? material->isBlendLight() : false;
}

private:

void captureShader()
Expand Down
120 changes: 120 additions & 0 deletions radiantcore/rendersystem/backend/BlendLight.cpp
@@ -0,0 +1,120 @@
#include "BlendLight.h"

#include "OpenGLShader.h"
#include "glprogram/BlendLightProgram.h"

namespace render
{

BlendLight::BlendLight(RendererLight& light, IGeometryStore& store, IObjectRenderer& objectRenderer) :
_light(light),
_store(store),
_objectRenderer(objectRenderer),
_lightBounds(light.lightAABB()),
_objectCount(0)
{}

bool BlendLight::isInView(const IRenderView& view)
{
return view.TestAABB(_lightBounds) != VOLUME_OUTSIDE;
}

void BlendLight::collectSurfaces(const IRenderView& view, const std::set<IRenderEntityPtr>& entities)
{
// Now check all the entities intersecting with this light
for (const auto& entity : entities)
{
entity->foreachRenderableTouchingBounds(_lightBounds,
[&](const IRenderableObject::Ptr& object, Shader* shader)
{
// Skip empty objects and invisible surfaces
if (!object->isVisible() || !shader->isVisible()) return;

// Cull surfaces that are not in view
if (object->isOriented())
{
if (view.TestAABB(object->getObjectBounds(), object->getObjectTransform()) == VOLUME_OUTSIDE)
{
return;
}
}
else if (view.TestAABB(object->getObjectBounds()) == VOLUME_OUTSIDE) // non-oriented AABB test
{
return;
}

auto glShader = static_cast<OpenGLShader*>(shader);

// We only consider materials designated for camera rendering
if (!glShader->isApplicableTo(RenderViewType::Camera))
{
return;
}

// Blend lights only affect materials that interact with lighting
if (!glShader->getInteractionPass())
{
return;
}

_objects.emplace_back(std::ref(*object));

++_objectCount;
});
}
}

void BlendLight::draw(OpenGLState& state, RenderStateFlags globalFlagsMask,
BlendLightProgram& program, const IRenderView& view, std::size_t time)
{
program.setLightTextureTransform(_light.getLightTextureTransformation());
auto lightShader = static_cast<OpenGLShader*>(_light.getShader().get());

std::vector<IGeometryStore::Slot> untransformedObjects;
untransformedObjects.reserve(500);

lightShader->foreachPass([&](OpenGLShaderPass& pass)
{
// Evaluate the stage before deciding whether it's active
pass.evaluateShaderStages(time, &_light.getLightEntity());

if (!pass.stateIsActive()) return;

// Apply our state to the current state object
pass.applyState(state, globalFlagsMask);

// The light textures will be bound by applyState.
// The texture0/texture1 fields were filled in when constructing the pass

program.setBlendColour(pass.state().getColour());

for (const auto& objectRef : _objects)
{
auto& object = objectRef.get();

// We submit all objects with an identity matrix in a single multi draw call
if (!object.isOriented())
{
untransformedObjects.push_back(object.getStorageLocation());
continue;
}

program.setObjectTransform(object.getObjectTransform());

_objectRenderer.submitGeometry(object.getStorageLocation(), GL_TRIANGLES);
++_drawCalls;
}

if (!untransformedObjects.empty())
{
program.setObjectTransform(Matrix4::getIdentity());

_objectRenderer.submitGeometry(untransformedObjects, GL_TRIANGLES);
++_drawCalls;

untransformedObjects.clear();
}
});
}

}
56 changes: 56 additions & 0 deletions radiantcore/rendersystem/backend/BlendLight.h
@@ -0,0 +1,56 @@
#pragma once

#include "irender.h"

namespace render
{

class OpenGLState;
class IGeometryStore;
class IObjectRenderer;
class BlendLightProgram;

/**
* BlendLights are non-shadowcasting lights performing a simple blend operation
* on any surfaces they intersect with.
* The type of blend operation is defined in the stages of the light material.
*
* Instances only live through the course of a single render pass, therefore direct
* references without ref-counting are used.
*/
class BlendLight
{
private:
RendererLight& _light;
IGeometryStore& _store;
IObjectRenderer& _objectRenderer;
AABB _lightBounds;

using ObjectList = std::vector<std::reference_wrapper<IRenderableObject>>;
ObjectList _objects;

std::size_t _objectCount;
std::size_t _drawCalls;

public:
BlendLight(RendererLight& light, IGeometryStore& store, IObjectRenderer& objectRenderer);
BlendLight(BlendLight&& other) = default;

bool isInView(const IRenderView& view);
void collectSurfaces(const IRenderView& view, const std::set<IRenderEntityPtr>& entities);

std::size_t getObjectCount() const
{
return _objectCount;
}

std::size_t getDrawCalls() const
{
return _drawCalls;
}

void draw(OpenGLState& state, RenderStateFlags globalFlagsMask, BlendLightProgram& program,
const IRenderView& view, std::size_t renderTime);
};

}
2 changes: 2 additions & 0 deletions radiantcore/rendersystem/backend/GLProgramFactory.cpp
Expand Up @@ -6,6 +6,7 @@
#include "glprogram/GenericVFPProgram.h"
#include "glprogram/ShadowMapProgram.h"
#include "glprogram/RegularStageProgram.h"
#include "glprogram/BlendLightProgram.h"

#include "itextstream.h"
#include "iregistry.h"
Expand All @@ -30,6 +31,7 @@ GLProgramFactory::GLProgramFactory()
_builtInPrograms[ShaderProgram::CubeMap] = std::make_shared<CubeMapProgram>();
_builtInPrograms[ShaderProgram::ShadowMap] = std::make_shared<ShadowMapProgram>();
_builtInPrograms[ShaderProgram::RegularStage] = std::make_shared<RegularStageProgram>();
_builtInPrograms[ShaderProgram::BlendLight] = std::make_shared<BlendLightProgram>();
}

GLProgram* GLProgramFactory::getBuiltInProgram(ShaderProgram builtInProgram)
Expand Down
1 change: 1 addition & 0 deletions radiantcore/rendersystem/backend/GLProgramFactory.h
Expand Up @@ -19,6 +19,7 @@ enum class ShaderProgram
CubeMap,
ShadowMap,
RegularStage,
BlendLight,
};

/**
Expand Down

0 comments on commit 8ad503f

Please sign in to comment.