summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-01-13 11:31:13 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2024-01-13 11:31:13 +0000
commit332355a9f4a4199e0ddb51852546d44ec54e176f (patch)
tree4998cde56004f53a0218dc5f00d578f939ffea08
parentInteger support in persistence (diff)
parentOnly create VAOs for the light type(s) in use (diff)
downloadilt-332355a9f4a4199e0ddb51852546d44ec54e176f.tar.bz2
ilt-332355a9f4a4199e0ddb51852546d44ec54e176f.tar.xz
ilt-332355a9f4a4199e0ddb51852546d44ec54e176f.zip
Merge branch 'model-lights'
-rw-r--r--game/scenary/illuminator.cpp90
-rw-r--r--game/scenary/illuminator.h60
-rw-r--r--game/scenary/light.cpp7
-rw-r--r--game/scenary/light.h19
-rw-r--r--gfx/gl/sceneShader.cpp55
-rw-r--r--gfx/gl/sceneShader.h35
-rw-r--r--gfx/gl/shaders/pointLight.fs8
-rw-r--r--gfx/gl/shaders/pointLight.gs15
-rw-r--r--gfx/gl/shaders/pointLight.vs22
-rw-r--r--gfx/gl/shaders/spotLight.fs10
-rw-r--r--gfx/gl/shaders/spotLight.gs24
-rw-r--r--gfx/gl/shaders/spotLight.vs28
-rw-r--r--res/lights.xml28
-rw-r--r--test/test-assetFactory.cpp32
-rw-r--r--test/test-render.cpp59
15 files changed, 306 insertions, 186 deletions
diff --git a/game/scenary/illuminator.cpp b/game/scenary/illuminator.cpp
new file mode 100644
index 0000000..e3810ec
--- /dev/null
+++ b/game/scenary/illuminator.cpp
@@ -0,0 +1,90 @@
+#include "illuminator.h"
+#include "gfx/gl/sceneShader.h"
+#include "gfx/gl/vertexArrayObject.h"
+#include "gfx/models/texture.h" // IWYU pragma: keep
+
+bool
+Illuminator::SpotLight::persist(Persistence::PersistenceStore & store)
+{
+ return STORE_TYPE && STORE_MEMBER(position) && STORE_MEMBER(direction) && STORE_MEMBER(colour) && STORE_MEMBER(kq)
+ && STORE_MEMBER(arc);
+}
+
+bool
+Illuminator::PointLight::persist(Persistence::PersistenceStore & store)
+{
+ return STORE_TYPE && STORE_MEMBER(position) && STORE_MEMBER(colour) && STORE_MEMBER(kq);
+}
+
+bool
+Illuminator::persist(Persistence::PersistenceStore & store)
+{
+ return STORE_TYPE && STORE_HELPER(bodyMesh, Asset::MeshConstruct)
+ && STORE_HELPER(pointLight, Persistence::Appender<decltype(pointLight)>)
+ && STORE_HELPER(spotLight, Persistence::Appender<decltype(spotLight)>) && Asset::persist(store);
+}
+
+void
+Illuminator::postLoad()
+{
+ if (spotLight.empty() && pointLight.empty()) {
+ throw std::logic_error {"Illuminator has no lights"};
+ }
+ texture = getTexture();
+ bodyMesh->configureVAO(instanceVAO)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(instances.bufferName(), 1);
+ if (!spotLight.empty()) {
+ instancesSpotLightVAO.emplace();
+ VertexArrayObject {*instancesSpotLightVAO}
+ .addAttribs<SpotLightVertex, &SpotLightVertex::position, &SpotLightVertex::direction,
+ &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc>(
+ instancesSpotLight.bufferName(), 0)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(instances.bufferName(), 1);
+ std::transform(
+ spotLight.begin(), spotLight.end(), std::back_inserter(spotLightInstances), [this](const auto & s) {
+ return instancesSpotLight.acquire(*s);
+ });
+ }
+ if (!pointLight.empty()) {
+ instancesPointLightVAO.emplace();
+ VertexArrayObject {*instancesPointLightVAO}
+ .addAttribs<PointLightVertex, &PointLightVertex::position, &PointLightVertex::colour,
+ &PointLightVertex::kq>(instancesPointLight.bufferName(), 0)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(instances.bufferName(), 1);
+ std::transform(
+ pointLight.begin(), pointLight.end(), std::back_inserter(pointLightInstances), [this](const auto & s) {
+ return instancesPointLight.acquire(*s);
+ });
+ }
+}
+
+void
+Illuminator::render(const SceneShader & shader) const
+{
+ if (const auto count = instances.size()) {
+ shader.basicInst.use();
+ if (texture) {
+ texture->bind();
+ }
+ bodyMesh->DrawInstanced(instanceVAO, static_cast<GLsizei>(count));
+ }
+}
+
+void
+Illuminator::lights(const SceneShader & shader) const
+{
+ if (const auto count = instances.size()) {
+ if (const auto scount = instancesSpotLight.size()) {
+ shader.spotLightInst.use();
+ glBindVertexArray(*instancesSpotLightVAO);
+ glDrawArraysInstanced(GL_POINTS, 0, static_cast<GLsizei>(scount), static_cast<GLsizei>(count));
+ }
+ if (const auto pcount = instancesPointLight.size()) {
+ shader.pointLightInst.use();
+ glBindVertexArray(*instancesPointLightVAO);
+ glDrawArraysInstanced(GL_POINTS, 0, static_cast<GLsizei>(pcount), static_cast<GLsizei>(count));
+ }
+
+ glBindVertexArray(0);
+ }
+}
diff --git a/game/scenary/illuminator.h b/game/scenary/illuminator.h
new file mode 100644
index 0000000..893e5c7
--- /dev/null
+++ b/game/scenary/illuminator.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "assetFactory/asset.h"
+#include "gfx/gl/instanceVertices.h"
+#include "gfx/renderable.h"
+
+class SceneShader;
+class Location;
+class Texture;
+
+class Illuminator : public Asset, public Renderable, public StdTypeDefs<Illuminator> {
+ Mesh::Ptr bodyMesh;
+ std::shared_ptr<Texture> texture;
+ glVertexArray instanceVAO;
+ std::optional<glVertexArray> instancesSpotLightVAO, instancesPointLightVAO;
+
+public:
+ struct LightCommonVertex {
+ RelativePosition3D position;
+ RGB colour;
+ RelativeDistance kq;
+ };
+
+ struct SpotLightVertex : LightCommonVertex {
+ Direction3D direction;
+ Angle arc;
+ };
+
+ struct PointLightVertex : LightCommonVertex { };
+
+ struct SpotLight : Persistence::Persistable, SpotLightVertex, StdTypeDefs<SpotLight> {
+ private:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<SpotLight>>;
+ bool persist(Persistence::PersistenceStore & store) override;
+ };
+
+ struct PointLight : Persistence::Persistable, PointLightVertex, StdTypeDefs<PointLight> {
+ private:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<PointLight>>;
+ bool persist(Persistence::PersistenceStore & store) override;
+ };
+
+public:
+ using LocationVertex = std::pair<glm::mat4, GlobalPosition3D>;
+ mutable InstanceVertices<LocationVertex> instances;
+ mutable InstanceVertices<SpotLightVertex> instancesSpotLight;
+ mutable InstanceVertices<PointLightVertex> instancesPointLight;
+ void render(const SceneShader &) const override;
+ void lights(const SceneShader &) const override;
+
+protected:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<Illuminator>>;
+ bool persist(Persistence::PersistenceStore & store) override;
+ void postLoad() override;
+
+ std::vector<SpotLight::Ptr> spotLight;
+ std::vector<PointLight::Ptr> pointLight;
+ std::vector<InstanceVertices<SpotLightVertex>::InstanceProxy> spotLightInstances;
+ std::vector<InstanceVertices<PointLightVertex>::InstanceProxy> pointLightInstances;
+};
diff --git a/game/scenary/light.cpp b/game/scenary/light.cpp
new file mode 100644
index 0000000..6207497
--- /dev/null
+++ b/game/scenary/light.cpp
@@ -0,0 +1,7 @@
+#include "light.h"
+#include "location.h"
+
+Light::Light(std::shared_ptr<const Illuminator> type, const Location & position) :
+ type {std::move(type)}, location {this->type->instances.acquire(position.getRotationTransform(), position.pos)}
+{
+}
diff --git a/game/scenary/light.h b/game/scenary/light.h
new file mode 100644
index 0000000..0b19535
--- /dev/null
+++ b/game/scenary/light.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "game/worldobject.h"
+#include "illuminator.h"
+
+class Location;
+
+class Light : public WorldObject {
+ std::shared_ptr<const Illuminator> type;
+ InstanceVertices<Illuminator::LocationVertex>::InstanceProxy location;
+
+ void
+ tick(TickDuration) override
+ {
+ }
+
+public:
+ Light(std::shared_ptr<const Illuminator> type, const Location & position);
+};
diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp
index ccc1a1d..64bf171 100644
--- a/gfx/gl/sceneShader.cpp
+++ b/gfx/gl/sceneShader.cpp
@@ -1,5 +1,4 @@
#include "sceneShader.h"
-#include <array>
#include <gfx/gl/shaders/fs-landmass.h>
#include <gfx/gl/shaders/fs-material.h>
#include <gfx/gl/shaders/fs-pointLight.h>
@@ -21,15 +20,16 @@
SceneShader::SceneShader() :
basicInst {dynamicPointInst_vs, material_fs}, landmass {fixedPoint_vs, landmass_fs},
- absolute {fixedPoint_vs, material_fs}
+ absolute {fixedPoint_vs, material_fs}, spotLightInst {spotLight_vs, spotLight_gs, spotLight_fs},
+ pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs}
{
}
void
SceneShader::setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const
{
- for (const auto & prog : std::array<const SceneProgram *, 7> {
- &basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) {
+ for (const auto & prog : std::initializer_list<const SceneProgram *> {
+ &basic, &basicInst, &water, &landmass, &absolute, &pointLightInst, &spotLightInst}) {
prog->setViewProjection(viewPoint, viewProjection);
}
}
@@ -37,8 +37,8 @@ SceneShader::setViewProjection(const GlobalPosition3D & viewPoint, const glm::ma
void
SceneShader::setViewPort(const ViewPort & viewPort) const
{
- for (const auto & prog : std::array<const SceneProgram *, 7> {
- &basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) {
+ for (const auto & prog : std::initializer_list<const SceneProgram *> {
+ &basic, &basicInst, &water, &landmass, &absolute, &pointLightInst, &spotLightInst}) {
prog->setViewPort(viewPort);
}
}
@@ -87,46 +87,3 @@ SceneShader::WaterProgram::use(float waveCycle) const
Program::use();
glUniform1f(waveLoc, waveCycle);
}
-
-SceneShader::PointLightShader::PointLightShader() :
- SceneProgram {pointLight_vs, pointLight_gs, pointLight_fs}, colourLoc {*this, "colour"}, kqLoc {*this, "kq"},
- viewPointLoc {*this, "viewPoint"}
-{
- VertexArrayObject {va}.addAttribs<Position3D>(b);
-}
-
-void
-SceneShader::PointLightShader::add(const Position3D & position, const RGB & colour, const float kq) const
-{
- Program::use();
- glBindVertexArray(va);
- glBindBuffer(GL_ARRAY_BUFFER, b);
- glUniform3fv(colourLoc, 1, glm::value_ptr(colour));
- glUniform1f(kqLoc, kq);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW);
- glDrawArrays(GL_POINTS, 0, 1);
-}
-
-SceneShader::SpotLightShader::SpotLightShader() :
- SceneProgram {spotLight_vs, spotLight_gs, spotLight_fs}, directionLoc {*this, "v_direction"},
- colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, arcLoc {*this, "arc"}, viewPointLoc {*this, "viewPoint"}
-
-{
- using v3pair = std::pair<Position3D, Direction3D>;
- VertexArrayObject {va}.addAttribs<v3pair, &v3pair::first, &v3pair::second>(b);
-}
-
-void
-SceneShader::SpotLightShader::add(const Position3D & position, const Direction3D & direction, const RGB & colour,
- const float kq, const float arc) const
-{
- Program::use();
- glBindVertexArray(va);
- glBindBuffer(GL_ARRAY_BUFFER, b);
- glUniform3fv(colourLoc, 1, glm::value_ptr(colour));
- glUniform3fv(directionLoc, 1, glm::value_ptr(direction));
- glUniform1f(kqLoc, kq);
- glUniform1f(arcLoc, arc);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW);
- glDrawArrays(GL_POINTS, 0, 1);
-}
diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h
index 7ffaacd..813c1bf 100644
--- a/gfx/gl/sceneShader.h
+++ b/gfx/gl/sceneShader.h
@@ -51,45 +51,12 @@ class SceneShader {
RequiredUniformLocation waveLoc;
};
- class PointLightShader : public SceneProgram {
- public:
- PointLightShader();
-
- void add(const Position3D & position, const RGB & colour, const float kq) const;
-
- private:
- UniformLocation colourLoc;
- UniformLocation kqLoc;
- UniformLocation viewPointLoc;
- glVertexArray va;
- glBuffer b;
- };
-
- class SpotLightShader : public SceneProgram {
- public:
- SpotLightShader();
-
- void add(const Position3D & position, const Direction3D & direction, const RGB & colour, const float kq,
- const float arc) const;
-
- private:
- UniformLocation directionLoc;
- UniformLocation colourLoc;
- UniformLocation kqLoc;
- UniformLocation arcLoc;
- UniformLocation viewPointLoc;
- glVertexArray va;
- glBuffer b;
- };
-
public:
SceneShader();
BasicProgram basic;
WaterProgram water;
- AbsolutePosProgram basicInst, landmass, absolute;
- PointLightShader pointLight;
- SpotLightShader spotLight;
+ AbsolutePosProgram basicInst, landmass, absolute, spotLightInst, pointLightInst;
void setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const;
void setViewPort(const ViewPort & viewPort) const;
diff --git a/gfx/gl/shaders/pointLight.fs b/gfx/gl/shaders/pointLight.fs
index ba327b6..7531d3e 100644
--- a/gfx/gl/shaders/pointLight.fs
+++ b/gfx/gl/shaders/pointLight.fs
@@ -6,9 +6,9 @@ out vec3 FragColor;
layout(binding = 0) uniform isampler2D gPosition;
layout(binding = 1) uniform sampler2D gNormal;
uniform ivec4 viewPort;
-uniform vec3 colour;
-uniform float kq;
-in vec4 geo_centre;
+flat in vec4 geo_centre;
+flat in vec3 geo_colour;
+flat in float geo_kq;
void
main()
@@ -26,5 +26,5 @@ main()
if (normalDot < 0) {
discard;
}
- FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2)));
+ FragColor = (geo_colour * normalDot) / (1 + (geo_kq * pow(lightDist / 1000.0, 2)));
}
diff --git a/gfx/gl/shaders/pointLight.gs b/gfx/gl/shaders/pointLight.gs
index 9c41ed4..fc1d7c3 100644
--- a/gfx/gl/shaders/pointLight.gs
+++ b/gfx/gl/shaders/pointLight.gs
@@ -20,19 +20,24 @@ const vec3[] cube = vec3[]( // http://www.cs.umd.edu/gvil/papers/av_ts.pdf
);
uniform mat4 viewProjection;
uniform ivec3 viewPoint;
-
-in vec3 centre[];
-in float size[];
+flat in vec3 position[];
+flat in vec3 colour[];
+flat in float size[];
+flat in float kq[];
layout(points) in;
layout(triangle_strip, max_vertices = cube.length()) out;
-out vec4 geo_centre;
+flat out vec4 geo_centre;
+flat out vec3 geo_colour;
+flat out float geo_kq;
void
doVertex(int idx)
{
gl_Position = viewProjection * (gl_in[0].gl_Position + vec4(cube[idx] * size[0], 1));
- geo_centre = vec4(centre[0], size[0]);
+ geo_centre = vec4(position[0], size[0]);
+ geo_colour = colour[0];
+ geo_kq = kq[0];
EmitVertex();
}
diff --git a/gfx/gl/shaders/pointLight.vs b/gfx/gl/shaders/pointLight.vs
index 00a34a3..c538207 100644
--- a/gfx/gl/shaders/pointLight.vs
+++ b/gfx/gl/shaders/pointLight.vs
@@ -1,18 +1,24 @@
#version 330 core
-layout(location = 0) in vec3 position;
+layout(location = 0) in vec3 v_position;
+layout(location = 1) in vec3 v_colour;
+layout(location = 2) in float v_kq;
+layout(location = 3) in mat4 model;
+layout(location = 7) in ivec3 modelPos;
-uniform vec3 colour;
-uniform float kq;
uniform ivec3 viewPoint;
-out vec3 centre;
-out float size;
+flat out vec3 position;
+flat out vec3 colour;
+flat out float size;
+flat out float kq;
void
main()
{
- centre = position;
- size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
- gl_Position = vec4(centre - viewPoint, 0);
+ position = modelPos + ivec3(mat3(model) * v_position);
+ kq = v_kq;
+ size = (8000 * sqrt(max(max(v_colour.r, v_colour.g), v_colour.b))) / sqrt(v_kq);
+ colour = v_colour;
+ gl_Position = vec4(position - viewPoint, 0);
}
diff --git a/gfx/gl/shaders/spotLight.fs b/gfx/gl/shaders/spotLight.fs
index 937f922..ad33458 100644
--- a/gfx/gl/shaders/spotLight.fs
+++ b/gfx/gl/shaders/spotLight.fs
@@ -6,10 +6,10 @@ out vec3 FragColor;
layout(binding = 0) uniform isampler2D gPosition;
layout(binding = 1) uniform sampler2D gNormal;
uniform ivec4 viewPort;
-uniform vec3 colour;
-uniform float kq;
-in vec4 geo_centre;
-in vec4 geo_direction;
+flat in vec4 geo_centre;
+flat in vec4 geo_direction;
+flat in vec3 geo_colour;
+flat in float geo_kq;
void
main()
@@ -30,5 +30,5 @@ main()
if (normalDot < 0) {
discard;
}
- FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2)));
+ FragColor = (geo_colour * normalDot) / (1 + (geo_kq * pow(lightDist / 1000.0, 2)));
}
diff --git a/gfx/gl/shaders/spotLight.gs b/gfx/gl/shaders/spotLight.gs
index b58c169..194812a 100644
--- a/gfx/gl/shaders/spotLight.gs
+++ b/gfx/gl/shaders/spotLight.gs
@@ -11,17 +11,19 @@ const vec3[] pyramid = vec3[]( // four-sided
);
uniform mat4 viewProjection;
uniform ivec3 viewPoint;
-uniform float arc;
-
-in vec3 position[];
-in vec3 direction[];
-in float size[];
-in float cosarc[];
+flat in ivec3 position[];
+flat in vec3 direction[];
+flat in vec3 colour[];
+flat in float size[];
+flat in float kq[];
+flat in vec2 arc[];
layout(points) in;
layout(triangle_strip, max_vertices = 8) out;
-out vec4 geo_centre;
-out vec4 geo_direction;
+flat out vec4 geo_centre;
+flat out vec4 geo_direction;
+flat out vec3 geo_colour;
+flat out float geo_kq;
vec3
perp(vec3 a)
@@ -36,14 +38,16 @@ doVertex(vec4 ndcpos)
{
gl_Position = ndcpos;
geo_centre = vec4(position[0], size[0]);
- geo_direction = vec4(direction[0], cosarc[0]);
+ geo_direction = vec4(direction[0], arc[0].x);
+ geo_colour = colour[0];
+ geo_kq = kq[0];
EmitVertex();
}
void
main()
{
- const float base = size[0] * tan(arc / 2);
+ const float base = size[0] * arc[0].y;
const vec3 offx = perp(direction[0]);
const vec3 offy = cross(direction[0], offx);
vec4 out_py[pyramid.length()];
diff --git a/gfx/gl/shaders/spotLight.vs b/gfx/gl/shaders/spotLight.vs
index ac1d1db..eed8778 100644
--- a/gfx/gl/shaders/spotLight.vs
+++ b/gfx/gl/shaders/spotLight.vs
@@ -1,24 +1,30 @@
#version 330 core
layout(location = 0) in vec3 v_position;
+layout(location = 1) in vec3 v_direction;
+layout(location = 2) in vec3 v_colour;
+layout(location = 3) in float v_kq;
+layout(location = 4) in float v_arc;
+layout(location = 5) in mat4 model;
+layout(location = 9) in ivec3 modelPos;
-uniform vec3 v_direction;
-uniform vec3 colour;
-uniform float kq;
-uniform float arc;
uniform ivec3 viewPoint;
-out vec3 position;
-out vec3 direction;
-out float size;
-out float cosarc;
+flat out ivec3 position;
+flat out vec3 direction;
+flat out float size;
+flat out vec2 arc; // cos,tan (v_arc/2)
+flat out vec3 colour;
+flat out float kq;
void
main()
{
- position = v_position;
- direction = normalize(v_direction);
+ position = modelPos + ivec3(mat3(model) * v_position);
+ direction = normalize(mat3(model) * v_direction);
+ colour = v_colour;
+ kq = v_kq;
size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq);
- cosarc = cos(arc / 2);
+ arc = vec2(cos(v_arc / 2), tan(v_arc / 2));
gl_Position = vec4(position - viewPoint, 0);
}
diff --git a/res/lights.xml b/res/lights.xml
new file mode 100644
index 0000000..8b25599
--- /dev/null
+++ b/res/lights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<ilt p.id="assetFactory">
+ <asset p.typeid="Illuminator" id="r-light" name="r-light">
+ <bodyMesh id="body">
+ <use type="cylinder" scale="0.12,0.12,1" colour="lightslategray"/>
+ <use type="cylinder" scale="0.07,0.07,3" position="0,0,1" colour="lightslategray"/>
+ <use type="cylinder" scale="0.05,0.05,1.5" position="0,-0.1,4" rotation="-1.5,0,0" colour="lightslategray"/>
+ <use type="cuboid" position="0,1.400,4.060" scale=".14,.3,0.07" colour="lightslategray"/>
+ </bodyMesh>
+ <spotLight position="0,1400,4100" direction="0,0.1,-1" colour=".9,.9,.9" kq="0.3" arc="1.8"/>
+ </asset>
+ <asset p.typeid="Illuminator" id="old-lamp" name="old-lamp">
+ <bodyMesh id="body">
+ <use type="cylinder" scale="0.13,0.13,.5" colour="#222222"/>
+ <use type="cylinder" scale="0.06,0.06,1.5" position="0,0,.5" colour="#222222"/>
+ <use type="cuboid" scale="0.3,0.02,0.02" position="0,0,1.8" colour="#222222"/>
+ <use type="cuboid" scale="0.2,0.2,0.4" position="0,0,2" colour="#dddddd"/>
+ <use type="cuboid" scale="0.1,0.1,0.1" position="0,0,2.4" colour="#222222"/>
+ </bodyMesh>
+ <pointLight position="0,0,2200" colour=".9,.9,.6" kq="0.3"/>
+ </asset>
+ <!-- yes I'm hacking some floor to light up as though its a bush -->
+ <asset p.typeid="Foliage" id="floor" name="floor">
+ <bodyMesh id="body">
+ <use type="plane" scale="10,10,0" colour="#aaaaaa"/>
+ </bodyMesh>
+ </asset>
+</ilt>
diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp
index c8183df..8341fbf 100644
--- a/test/test-assetFactory.cpp
+++ b/test/test-assetFactory.cpp
@@ -9,6 +9,8 @@
#include "assetFactory/object.h"
#include "assetFactory/texturePacker.h"
#include "game/scenary/foliage.h"
+#include "game/scenary/illuminator.h"
+#include "game/scenary/light.h"
#include "game/scenary/plant.h"
#include "game/vehicles/railVehicle.h"
#include "game/vehicles/railVehicleClass.h"
@@ -46,7 +48,7 @@ public:
void
lights(const SceneShader & shader) const override
{
- shader.pointLight.add({-3, 1, 5}, {1, 1, 1}, .1F);
+ objects.apply(&Renderable::lights, shader);
}
void
@@ -125,6 +127,34 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5))
render(6000);
}
+BOOST_AUTO_TEST_CASE(lights, *boost::unit_test::timeout(5))
+{
+ auto mf = AssetFactory::loadXML(RESDIR "/lights.xml");
+ BOOST_REQUIRE(mf);
+ auto rlight = mf->assets.at("r-light");
+ BOOST_REQUIRE(rlight);
+ auto oldlamp = mf->assets.at("old-lamp");
+ BOOST_REQUIRE(oldlamp);
+ auto rlight_f = std::dynamic_pointer_cast<Illuminator>(rlight);
+ BOOST_REQUIRE(rlight_f);
+ auto oldlamp_f = std::dynamic_pointer_cast<Illuminator>(oldlamp);
+ BOOST_REQUIRE(oldlamp_f);
+
+ auto light1 = std::make_shared<Light>(oldlamp_f, Location {{0, 0, 0}, {0, 0, 0}});
+ auto light2 = std::make_shared<Light>(rlight_f, Location {{-4000, 0, 0}, {0, 2, 0}});
+ auto light3 = std::make_shared<Light>(rlight_f, Location {{-4000, -4000, 0}, {0, 1, 0}});
+ auto light4 = std::make_shared<Light>(oldlamp_f, Location {{3000, 4600, 0}, {0, 2, 0}});
+ objects.objects.push_back(rlight_f);
+ objects.objects.push_back(oldlamp_f);
+
+ // yes I'm hacking some floor to light up as though its a bush
+ auto floorf = std::dynamic_pointer_cast<Foliage>(mf->assets.at("floor"));
+ auto floor = std::make_shared<Plant>(floorf, Location {});
+ objects.objects.push_back(floorf);
+
+ render(6000);
+}
+
BOOST_AUTO_TEST_SUITE_END();
BOOST_AUTO_TEST_CASE(loadall)
diff --git a/test/test-render.cpp b/test/test-render.cpp
index 66b4d46..41731dd 100644
--- a/test/test-render.cpp
+++ b/test/test-render.cpp
@@ -158,63 +158,4 @@ BOOST_AUTO_TEST_CASE(terrain)
Texture::save(outImage, "/tmp/terrain.tga");
}
-BOOST_AUTO_TEST_CASE(pointlight)
-{
- SceneRenderer ss {size, output};
- ss.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
-
- class PointLightScene : public TestScene {
- public:
- void
- environment(const SceneShader &, const SceneRenderer & r) const override
- {
- r.setAmbientLight({0.2F, 0.2F, 0.2F});
- r.setDirectionalLight({0.2F, 0.2F, 0.2F}, west + down, *this);
- }
-
- void
- lights(const SceneShader & shader) const override
- {
- for (int x = 50000; x < 100000; x += 20000) {
- for (int y = 50000; y < 2000000; y += 20000) {
- shader.pointLight.add({x, y, 4000}, {1.0, 1.0, 1.0}, 0.1F);
- }
- }
- }
- };
-
- const PointLightScene scene;
- ss.render(scene);
- Texture::save(outImage, "/tmp/pointlight.tga");
-}
-
-BOOST_AUTO_TEST_CASE(spotlight)
-{
- SceneRenderer ss {size, output};
- ss.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F}));
-
- class PointLightScene : public TestScene {
- public:
- void
- environment(const SceneShader &, const SceneRenderer & r) const override
- {
- r.setAmbientLight({0.2F, 0.2F, 0.2F});
- r.setDirectionalLight({0.2F, 0.2F, 0.2F}, west + down, *this);
- }
-
- void
- lights(const SceneShader & shader) const override
- {
- shader.spotLight.add({50000, 50000, 15000}, down, {1.0, 1.0, 1.0}, 0.01F, 1);
- shader.spotLight.add({51000, 59500, 1000}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
- shader.spotLight.add({53000, 59500, 1000}, north, {1.0, 1.0, 1.0}, 0.001F, .5);
- shader.spotLight.add({60000, 50000, 3000}, north + east, {1.0, 1.0, 1.0}, 0.0001F, .7F);
- }
- };
-
- const PointLightScene scene;
- ss.render(scene);
- Texture::save(outImage, "/tmp/spotlight.tga");
-}
-
BOOST_AUTO_TEST_SUITE_END();