summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assetFactory/assimp.cpp2
-rw-r--r--assetFactory/factoryMesh.cpp11
-rw-r--r--game/network/network.h13
-rw-r--r--game/scenary/foliage.h4
-rw-r--r--game/scenary/illuminator.h4
-rw-r--r--game/terrain.h8
-rw-r--r--game/vehicles/railVehicleClass.h5
-rw-r--r--game/water.h8
-rw-r--r--gfx/gl/program.cpp19
-rw-r--r--gfx/gl/program.h5
-rw-r--r--gfx/gl/shader.cpp65
-rw-r--r--gfx/gl/shader.h8
-rw-r--r--gfx/gl/shaders/commonPoint.glsl15
-rw-r--r--gfx/gl/shaders/commonShadowPoint.glsl5
-rw-r--r--gfx/gl/shaders/commonShadowPoint.gs8
-rw-r--r--gfx/gl/shaders/directionalLight.fs6
-rw-r--r--gfx/gl/shaders/dynamicPoint.vs2
-rw-r--r--gfx/gl/shaders/dynamicPointInst.vs2
-rw-r--r--gfx/gl/shaders/fixedPoint.vs2
-rw-r--r--gfx/gl/shaders/getMaterialDetail.glsl12
-rw-r--r--gfx/gl/shaders/material.fs36
-rw-r--r--gfx/gl/shaders/materialCommon.glsl33
-rw-r--r--gfx/gl/shaders/materialDetail.glsl5
-rw-r--r--gfx/gl/shaders/materialInterface.glsl20
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInstWithTextures.fs8
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInstWithTextures.vs14
-rw-r--r--gfx/models/texture.h5
-rw-r--r--glsl.jam22
-rw-r--r--lib/embed-glsl.cpp.m42
-rw-r--r--lib/msgException.h23
-rw-r--r--lib/stdTypeDefs.h12
-rw-r--r--res/shapespark-low-poly-plants-kit.fbxbin20264540 -> 20407788 bytes
-rw-r--r--test/test-render.cpp8
-rw-r--r--thirdparty/Jamfile.jam3
34 files changed, 260 insertions, 135 deletions
diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp
index 1e11eda..e33783a 100644
--- a/assetFactory/assimp.cpp
+++ b/assetFactory/assimp.cpp
@@ -84,8 +84,8 @@ public:
for (auto idx = f.mIndices; const auto fheh : mesh.fh_range(fh)) {
const auto ouv = !amesh->mTextureCoords[0][*idx++];
mesh.set_texcoord2D(fheh, ouv);
- mesh.property(mesh.materialFaceProperty, fh) = material;
}
+ mesh.property(mesh.materialFaceProperty, fh) = material;
}
}
}
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
index bf4706e..eb9d525 100644
--- a/assetFactory/factoryMesh.cpp
+++ b/assetFactory/factoryMesh.cpp
@@ -25,11 +25,12 @@ FactoryMesh::createMesh() const
std::vector<unsigned int> faceIndices;
for (const auto & heh : mesh.fh_range(face)) {
const auto & vertex = mesh.to_vertex_handle(heh);
- const auto & textureUV = mesh.texcoord2D(heh);
- const auto & point = mesh.point(vertex);
- const auto & normal = useVertexNormals ? mesh.property(mesh.vertex_normals_pph(), vertex)
- : mesh.property(mesh.face_normals_pph(), face);
- Vertex outVertex {point * 1000.F, textureUV, normal, colour, material};
+ Vertex outVertex {.pos = mesh.point(vertex) * 1000.F,
+ .texCoord = mesh.texcoord2D(heh),
+ .normal = useVertexNormals ? mesh.property(mesh.vertex_normals_pph(), vertex)
+ : mesh.property(mesh.face_normals_pph(), face),
+ .colour = colour,
+ .material = material};
if (const auto existingItr = std::find(vertices.rbegin(), vertices.rend(), outVertex);
existingItr != vertices.rend()) {
faceIndices.push_back(static_cast<unsigned int>(std::distance(existingItr, vertices.rend()) - 1));
diff --git a/game/network/network.h b/game/network/network.h
index 5725360..ca17581 100644
--- a/game/network/network.h
+++ b/game/network/network.h
@@ -1,19 +1,18 @@
#pragma once
+#include "collection.h"
#include "gfx/gl/instanceVertices.h"
+#include "gfx/models/texture.h"
+#include "gfx/renderable.h"
#include "link.h"
-#include <collection.h>
-#include <gfx/renderable.h>
+#include "sorting.h"
+#include "special_members.h"
#include <glm/glm.hpp>
#include <memory>
#include <set>
-#include <sorting.h>
-#include <special_members.h>
#include <string>
#include <utility>
-#include <variant>
-class Texture;
class SceneShader;
template<typename> class Ray;
@@ -56,7 +55,7 @@ protected:
using Nodes = std::set<Node::Ptr, PtrMemberSorter<Node::Ptr, &Node::pos>>;
Nodes nodes;
- std::shared_ptr<Texture> texture;
+ Texture::Ptr texture;
};
template<typename LinkType> class NetworkLinkHolder {
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index 3beda89..0a4261c 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -2,16 +2,16 @@
#include "assetFactory/asset.h"
#include "gfx/gl/instanceVertices.h"
+#include "gfx/models/texture.h"
#include "gfx/renderable.h"
class SceneShader;
class ShadowMapper;
class Location;
-class Texture;
class Foliage : public Asset, public Renderable, public StdTypeDefs<Foliage> {
Mesh::Ptr bodyMesh;
- std::shared_ptr<Texture> texture;
+ Texture::Ptr texture;
glVertexArray instanceVAO;
public:
diff --git a/game/scenary/illuminator.h b/game/scenary/illuminator.h
index cd6073c..44bd583 100644
--- a/game/scenary/illuminator.h
+++ b/game/scenary/illuminator.h
@@ -2,15 +2,15 @@
#include "assetFactory/asset.h"
#include "gfx/gl/instanceVertices.h"
+#include "gfx/models/texture.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;
+ Texture::Ptr texture;
glVertexArray instanceVAO;
std::optional<glVertexArray> instancesSpotLightVAO, instancesPointLightVAO;
diff --git a/game/terrain.h b/game/terrain.h
index d088f89..1c79d19 100644
--- a/game/terrain.h
+++ b/game/terrain.h
@@ -4,12 +4,12 @@
#include "collection.h"
#include "config/types.h"
#include "game/worldobject.h"
-#include <gfx/models/mesh.h>
-#include <gfx/renderable.h>
+#include "gfx/models/mesh.h"
+#include "gfx/models/texture.h"
+#include "gfx/renderable.h"
#include <memory>
class SceneShader;
-class Texture;
class GeoData;
class Terrain : public WorldObject, public Renderable {
@@ -32,5 +32,5 @@ private:
std::shared_ptr<GeoData> geoData;
Collection<MeshT<Vertex>, false> meshes;
- std::shared_ptr<Texture> grass;
+ Texture::Ptr grass;
};
diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h
index 9d9d4c2..88f08c5 100644
--- a/game/vehicles/railVehicleClass.h
+++ b/game/vehicles/railVehicleClass.h
@@ -3,14 +3,13 @@
#include "assetFactory/asset.h"
#include "gfx/gl/instanceVertices.h"
#include "gfx/models/mesh.h"
+#include "gfx/models/texture.h"
#include "gfx/renderable.h"
#include <array>
#include <memory>
-#include <string>
class SceneShader;
class ShadowMapper;
-class Texture;
class Location;
class RailVehicleClass : public Renderable, public Asset {
@@ -25,7 +24,7 @@ public:
std::array<Mesh::Ptr, 2> bogies;
Mesh::Ptr bodyMesh;
- std::shared_ptr<Texture> texture;
+ Texture::Ptr texture;
float wheelBase;
float length;
float maxSpeed;
diff --git a/game/water.h b/game/water.h
index ceb7bd2..ba46703 100644
--- a/game/water.h
+++ b/game/water.h
@@ -4,12 +4,12 @@
#include "collection.h"
#include "config/types.h"
#include "game/worldobject.h"
-#include <gfx/models/mesh.h>
-#include <gfx/renderable.h>
+#include "gfx/models/mesh.h"
+#include "gfx/models/texture.h"
+#include "gfx/renderable.h"
#include <memory>
class SceneShader;
-class Texture;
class GeoData;
class Water : public WorldObject, public Renderable {
@@ -30,5 +30,5 @@ private:
std::shared_ptr<GeoData> geoData;
Collection<MeshT<Vertex>, false> meshes;
- std::shared_ptr<Texture> water;
+ Texture::Ptr water;
};
diff --git a/gfx/gl/program.cpp b/gfx/gl/program.cpp
index 7287fde..fdd4c6f 100644
--- a/gfx/gl/program.cpp
+++ b/gfx/gl/program.cpp
@@ -10,10 +10,10 @@ void
Program::linkAndValidate() const
{
glLinkProgram(m_program);
- Shader::CheckShaderError(m_program, GL_LINK_STATUS, true, "Error linking shader program");
+ checkProgramError(m_program, GL_LINK_STATUS, "Error linking shader program");
glValidateProgram(m_program);
- Shader::CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "Invalid shader program");
+ checkProgramError(m_program, GL_VALIDATE_STATUS, "Invalid shader program");
}
void
@@ -22,6 +22,21 @@ Program::use() const
glUseProgram(m_program);
}
+void
+Program::checkProgramError(GLuint program, GLuint flag, std::string_view errorMessage) const
+{
+ GLint success = 0;
+
+ glGetProgramiv(program, flag, &success);
+
+ if (success == GL_FALSE) {
+ std::array<GLchar, 1024> error {};
+ glGetProgramInfoLog(program, error.size(), nullptr, error.data());
+
+ throw std::runtime_error {std::format("{}: '{}'", errorMessage, error.data())};
+ }
+}
+
Program::UniformLocation::UniformLocation(GLuint program, const char * name) :
location {glGetUniformLocation(program, name)}
{
diff --git a/gfx/gl/program.h b/gfx/gl/program.h
index 1a1c306..c89a128 100644
--- a/gfx/gl/program.h
+++ b/gfx/gl/program.h
@@ -1,6 +1,6 @@
#pragma once
-#include "shader.h"
+#include "shader.h" // IWYU pragma: export
#include <glRef.h>
#include <glad/gl.h>
#include <glm/mat4x4.hpp>
@@ -12,6 +12,8 @@ using ProgramRef = glRef<GLuint, &glCreateProgram, &glDeleteProgram>;
class Program {
public:
+ Program() = delete;
+
template<typename... S> explicit Program(const S &... srcs)
{
(glAttachShader(m_program, srcs.compile()), ...);
@@ -47,6 +49,7 @@ public:
}
protected:
+ void checkProgramError(GLuint program, GLuint flag, std::string_view errorMessage) const;
void use() const;
void linkAndValidate() const;
ProgramRef m_program;
diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp
index 0bc127a..931c372 100644
--- a/gfx/gl/shader.cpp
+++ b/gfx/gl/shader.cpp
@@ -1,4 +1,5 @@
#include "shader.h"
+#include "msgException.h"
#include <algorithm>
#include <array>
#include <format>
@@ -18,6 +19,39 @@ namespace {
constexpr std::array<std::tuple<std::string_view, GLenum, LookUpFunction>, 1> LOOKUPS {{
{"GL_MAX_GEOMETRY_OUTPUT_VERTICES", GL_MAX_GEOMETRY_OUTPUT_VERTICES, getInt},
}};
+
+ struct ShaderCompileError : public MsgException<std::invalid_argument> {
+ explicit ShaderCompileError(GLuint shader, Shader::Source src) :
+ MsgException<std::invalid_argument> {"Error compiling shader"}, shader {shader}, source {src},
+ msg {getShaderText(GL_INFO_LOG_LENGTH, glGetShaderInfoLog)}
+ {
+ }
+
+ [[nodiscard]] std::string
+ getMsg() const noexcept override
+ {
+ return std::format("Error compiling shader: '{}'\nSource:\n{}",
+ getShaderText(GL_INFO_LOG_LENGTH, glGetShaderInfoLog), source);
+ }
+
+ private:
+ std::string
+ getShaderText(GLenum param, auto getTextFunc) const
+ {
+ std::string text;
+ text.resize_and_overwrite(static_cast<size_t>(Shader::getShaderParam(shader, param)),
+ [this, getTextFunc](auto buf, auto len) {
+ GLsizei outLen {};
+ getTextFunc(shader, static_cast<GLsizei>(len), &outLen, buf);
+ return outLen;
+ });
+ return text;
+ }
+
+ const GLuint shader;
+ const Shader::Source source;
+ const std::string msg;
+ };
}
Shader::ShaderRef
@@ -46,31 +80,22 @@ Shader::compile() const
}
glCompileShader(shader);
- CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error compiling shader!");
+ checkShaderError(shader);
return shader;
}
void
-Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage)
+Shader::checkShaderError(GLuint shader) const
{
- GLint success = 0;
-
- if (isProgram) {
- glGetProgramiv(shader, flag, &success);
+ if (getShaderParam(shader, GL_COMPILE_STATUS) == GL_FALSE) {
+ throw ShaderCompileError {shader, text};
}
- else {
- glGetShaderiv(shader, flag, &success);
- }
-
- if (success == GL_FALSE) {
- std::array<GLchar, 1024> error {};
- if (isProgram) {
- glGetProgramInfoLog(shader, error.size(), nullptr, error.data());
- }
- else {
- glGetShaderInfoLog(shader, error.size(), nullptr, error.data());
- }
+}
- throw std::runtime_error {std::format("{}: '{}'", errorMessage, error.data())};
- }
+GLint
+Shader::getShaderParam(GLuint shader, GLenum pname)
+{
+ GLint pvalue {};
+ glGetShaderiv(shader, pname, &pvalue);
+ return pvalue;
}
diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h
index c6b45af..ce97734 100644
--- a/gfx/gl/shader.h
+++ b/gfx/gl/shader.h
@@ -7,6 +7,7 @@
class Shader {
public:
+ using Source = std::basic_string_view<GLchar>;
using ShaderRef = glRef<GLuint, &glCreateShader, &glDeleteShader>;
constexpr Shader(const GLchar * text, GLuint type) :
@@ -15,10 +16,13 @@ public:
}
[[nodiscard]] ShaderRef compile() const;
- static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage);
+
+ [[nodiscard]] static GLint getShaderParam(GLuint shader, GLenum pname);
private:
- const std::basic_string_view<GLchar> text;
+ void checkShaderError(GLuint shader) const;
+
+ const Source text;
GLuint type;
bool lookups;
};
diff --git a/gfx/gl/shaders/commonPoint.glsl b/gfx/gl/shaders/commonPoint.glsl
index 2d9e388..dc534d5 100644
--- a/gfx/gl/shaders/commonPoint.glsl
+++ b/gfx/gl/shaders/commonPoint.glsl
@@ -1,17 +1,4 @@
-layout(binding = 1) uniform usampler2DRect materialData;
-
-MaterialDetail
-getMaterialDetail(uint midx)
-{
- if (midx > 0u) {
- const vec4 sPosSize = texture(materialData, uvec2(0, midx - 1u));
- const uvec4 sMode = texture(materialData, uvec2(1, midx - 1u));
- const uint mapmodeU = sMode.x & 0xFu;
- const uint mapmodeV = (sMode.x & 0xF0u) >> 1;
- return MaterialDetail(sPosSize.xy, sPosSize.zw, uvec2(mapmodeU, mapmodeV));
- }
- return MaterialDetail(vec2(0, 0), vec2(0, 0), uvec2(0, 0));
-}
+include(`getMaterialDetail.glsl')
void
main()
diff --git a/gfx/gl/shaders/commonShadowPoint.glsl b/gfx/gl/shaders/commonShadowPoint.glsl
index c4ea827..9910d46 100644
--- a/gfx/gl/shaders/commonShadowPoint.glsl
+++ b/gfx/gl/shaders/commonShadowPoint.glsl
@@ -1,11 +1,10 @@
out vec4 vworldPos;
-ifdef(`TEXTURES', out vec2 vtexCoord;);
-
void
main()
{
vec3 worldPos = model * position;
vworldPos = vec4(worldPos - viewPoint + modelPos, 1);
- ifdef(`TEXTURES', vtexCoord = texCoord;);
+ ifdef(`TEXTURES', TexCoords = texCoord;);
+ ifdef(`TEXTURES', Material = getMaterialDetail(material););
}
diff --git a/gfx/gl/shaders/commonShadowPoint.gs b/gfx/gl/shaders/commonShadowPoint.gs
index b99bd20..2413cc0 100644
--- a/gfx/gl/shaders/commonShadowPoint.gs
+++ b/gfx/gl/shaders/commonShadowPoint.gs
@@ -1,13 +1,16 @@
#version 330 core
#extension GL_ARB_viewport_array : enable
+ifdef(`TEXTURES', include(`materialDetail.glsl'))
+
uniform mat4 viewProjection[4];
uniform int viewProjections;
in vec4 vworldPos[];
layout(triangles) in;
layout(triangle_strip, max_vertices = 12) out;
-ifdef(`TEXTURES', in vec2 vtexCoord[]; out vec2 texCoord;);
+ifdef(`TEXTURES', in vec2 TexCoords[]; out vec2 texCoord;)
+ifdef(`TEXTURES', flat in MaterialDetail Material[]; flat out MaterialDetail material;)
void
main()
@@ -17,7 +20,8 @@ main()
gl_Position = viewProjection[vp] * vworldPos[v];
gl_Position.z = max(gl_Position.z, -1);
gl_Layer = vp;
- ifdef(`TEXTURES', texCoord = vtexCoord[v];);
+ ifdef(`TEXTURES', texCoord = TexCoords[v];)
+ ifdef(`TEXTURES', material = Material[v];)
EmitVertex();
}
EndPrimitive();
diff --git a/gfx/gl/shaders/directionalLight.fs b/gfx/gl/shaders/directionalLight.fs
index 24457b8..86447ec 100644
--- a/gfx/gl/shaders/directionalLight.fs
+++ b/gfx/gl/shaders/directionalLight.fs
@@ -34,10 +34,10 @@ isShaded(vec4 Position)
const float inside = insideShadowCube(PositionInLightSpace);
if (inside > 0) {
const float lightSpaceDepth = texture(shadowMap, vec3(PositionInLightSpace.xy, m)).r;
- return step(lightSpaceDepth, PositionInLightSpace.z);
+ return step(PositionInLightSpace.z, lightSpaceDepth + 0.001);
}
}
- return 0;
+ return 1;
}
void
@@ -46,5 +46,5 @@ main()
const vec4 Position = vec4(texture(gPosition, TexCoords).xyz - lightPoint, 1);
const vec3 Normal = texture(gNormal, TexCoords).rgb;
const float shaded = isShaded(Position);
- FragColor = (1 - shaded) * max(dot(-lightDirection, Normal) * lightColour, 0);
+ FragColor = shaded * max(dot(-lightDirection, Normal) * lightColour, 0);
}
diff --git a/gfx/gl/shaders/dynamicPoint.vs b/gfx/gl/shaders/dynamicPoint.vs
index 7551688..97d2983 100644
--- a/gfx/gl/shaders/dynamicPoint.vs
+++ b/gfx/gl/shaders/dynamicPoint.vs
@@ -1,6 +1,8 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
+layout(binding = 1) uniform usampler2DRect materialData;
+
include(`meshIn.glsl')
include(`materialInterface.glsl')
diff --git a/gfx/gl/shaders/dynamicPointInst.vs b/gfx/gl/shaders/dynamicPointInst.vs
index 69eab0c..a85f9c9 100644
--- a/gfx/gl/shaders/dynamicPointInst.vs
+++ b/gfx/gl/shaders/dynamicPointInst.vs
@@ -1,6 +1,8 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
+layout(binding = 1) uniform usampler2DRect materialData;
+
include(`meshIn.glsl')
include(`materialInterface.glsl')
diff --git a/gfx/gl/shaders/fixedPoint.vs b/gfx/gl/shaders/fixedPoint.vs
index 5cfe9b3..435b3d1 100644
--- a/gfx/gl/shaders/fixedPoint.vs
+++ b/gfx/gl/shaders/fixedPoint.vs
@@ -1,6 +1,8 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
+layout(binding = 1) uniform usampler2DRect materialData;
+
include(`meshIn.glsl')
include(`materialInterface.glsl')
diff --git a/gfx/gl/shaders/getMaterialDetail.glsl b/gfx/gl/shaders/getMaterialDetail.glsl
new file mode 100644
index 0000000..f819fb2
--- /dev/null
+++ b/gfx/gl/shaders/getMaterialDetail.glsl
@@ -0,0 +1,12 @@
+MaterialDetail
+getMaterialDetail(uint midx)
+{
+ if (midx > 0u) {
+ const vec4 sPosSize = texture(materialData, uvec2(0, midx - 1u));
+ const uvec4 sMode = texture(materialData, uvec2(1, midx - 1u));
+ const uint mapmodeU = sMode.x & 0xFu;
+ const uint mapmodeV = (sMode.x & 0xF0u) >> 1;
+ return MaterialDetail(sPosSize.xy, sPosSize.zw, uvec2(mapmodeU, mapmodeV));
+ }
+ return MaterialDetail(vec2(0, 0), vec2(0, 0), uvec2(0, 0));
+}
diff --git a/gfx/gl/shaders/material.fs b/gfx/gl/shaders/material.fs
index 5b93707..37f2e27 100644
--- a/gfx/gl/shaders/material.fs
+++ b/gfx/gl/shaders/material.fs
@@ -1,41 +1,11 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
+layout(binding = 0) uniform sampler2D textureAlbedo;
+
include(`materialInterface.glsl')
include(`materialOut.glsl')
-
-layout(binding = 0) uniform sampler2D texture0;
-
-float map(uint mapmode, float value)
-{
- switch (mapmode) {
- case 0u: // Repeat
- return fract(value);
- case 1u: // Clamp to edge
- return clamp(0.0, 1.0, value);
- case 2u: // Mirror
- discard;
- case 3u: // Decal
- if (value != clamp(0.0, 1.0, value)) {
- discard;
- }
- }
- return 0;
-}
-
-vec2 map(uvec2 mapmode, vec2 value)
-{
- return vec2(map(mapmode.x, value.x), map(mapmode.y, value.y));
-}
-
-vec4 getTextureColour(MaterialDetail mat, vec2 uv)
-{
- if (mat.textureSize.x > 0) {
- const vec2 tSize = textureSize(texture0, 0);
- uv = (mat.textureOrigin + mat.textureSize * map(mat.mapmode, uv)) / tSize;
- }
- return texture(texture0, uv);
-}
+include(`materialCommon.glsl')
void
main()
diff --git a/gfx/gl/shaders/materialCommon.glsl b/gfx/gl/shaders/materialCommon.glsl
new file mode 100644
index 0000000..3fe2237
--- /dev/null
+++ b/gfx/gl/shaders/materialCommon.glsl
@@ -0,0 +1,33 @@
+float
+map(uint mapmode, float value)
+{
+ switch (mapmode) {
+ case 0u: // Repeat
+ return fract(value);
+ case 1u: // Clamp to edge
+ return clamp(0.0, 1.0, value);
+ case 2u: // Mirror
+ discard;
+ case 3u: // Decal
+ if (value != clamp(0.0, 1.0, value)) {
+ discard;
+ }
+ }
+ return 0;
+}
+
+vec2
+map(uvec2 mapmode, vec2 value)
+{
+ return vec2(map(mapmode.x, value.x), map(mapmode.y, value.y));
+}
+
+vec4
+getTextureColour(MaterialDetail mat, vec2 uv)
+{
+ if (mat.textureSize.x > 0) {
+ const vec2 tSize = textureSize(textureAlbedo, 0);
+ uv = (mat.textureOrigin + mat.textureSize * map(mat.mapmode, uv)) / tSize;
+ }
+ return texture(textureAlbedo, uv);
+}
diff --git a/gfx/gl/shaders/materialDetail.glsl b/gfx/gl/shaders/materialDetail.glsl
new file mode 100644
index 0000000..a208d50
--- /dev/null
+++ b/gfx/gl/shaders/materialDetail.glsl
@@ -0,0 +1,5 @@
+struct MaterialDetail {
+ vec2 textureOrigin;
+ vec2 textureSize;
+ uvec2 mapmode;
+};
diff --git a/gfx/gl/shaders/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl
index 3a4796b..f2ca297 100644
--- a/gfx/gl/shaders/materialInterface.glsl
+++ b/gfx/gl/shaders/materialInterface.glsl
@@ -1,13 +1,9 @@
-struct MaterialDetail {
- vec2 textureOrigin;
- vec2 textureSize;
- uvec2 mapmode;
-};
+include(`materialDetail.glsl')
-ifelse(TYPE, .fs, in, out) vec3 FragPos;
-ifelse(TYPE, .fs, in, out) vec2 TexCoords;
-ifelse(TYPE, .fs, in, out) vec3 Normal;
-ifelse(TYPE, .fs, in, out) vec4 Colour;
-flat
-ifelse(TYPE, .fs, in, out)
-MaterialDetail Material;
+define(INOUT, ifelse(TYPE, .fs, in, out));
+
+INOUT vec3 FragPos;
+INOUT vec2 TexCoords;
+INOUT vec3 Normal;
+INOUT vec4 Colour;
+flat INOUT MaterialDetail Material;
diff --git a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.fs b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.fs
index 90519e3..47ce9c0 100644
--- a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.fs
+++ b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.fs
@@ -1,14 +1,18 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
-layout(binding = 3) uniform sampler2D texture0;
+layout(binding = 3) uniform sampler2D textureAlbedo;
+
+include(`materialInterface.glsl')
+include(`materialCommon.glsl')
in vec2 texCoord;
+flat in MaterialDetail material;
void
main()
{
- if (texture(texture0, texCoord).a < 0.5) {
+ if (getTextureColour(material, texCoord).a < 0.5) {
discard;
}
gl_FragDepth = gl_FragCoord.z;
diff --git a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vs b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vs
index 27ad9d7..a76c87f 100644
--- a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vs
+++ b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vs
@@ -1,3 +1,15 @@
+#version 330 core
+#extension GL_ARB_shading_language_420pack : enable
+
+layout(binding = 4) uniform usampler2DRect materialData;
+
define(`TEXTURES', 1)
+include(`materialInterface.glsl')
+include(`getMaterialDetail.glsl')
+include(`meshIn.glsl')
+
+uniform ivec3 viewPoint;
+layout(location = 5) in mat3 model;
+layout(location = 8) in ivec3 modelPos;
-include(`shadowDynamicPointInst.vs')
+include(`commonShadowPoint.glsl')
diff --git a/gfx/models/texture.h b/gfx/models/texture.h
index 689d378..8cb8128 100644
--- a/gfx/models/texture.h
+++ b/gfx/models/texture.h
@@ -1,8 +1,9 @@
#pragma once
#include "config/types.h"
+#include "glArrays.h"
+#include "stdTypeDefs.h"
#include <filesystem>
-#include <glArrays.h>
#include <glm/fwd.hpp>
class Image;
@@ -20,7 +21,7 @@ struct TextureOptions {
static GLint glMapMode(MapMode);
};
-class Texture {
+class Texture : public StdTypeDefs<Texture> {
public:
virtual ~Texture() = default;
DEFAULT_MOVE_NO_COPY(Texture);
diff --git a/glsl.jam b/glsl.jam
index eeeb340..a2a08c6 100644
--- a/glsl.jam
+++ b/glsl.jam
@@ -8,12 +8,13 @@ type.register GL_TESS_CONTROL_SHADER : tcs ;
type.register GL_TESS_EVALUATION_SHADER : tes ;
type.register GL_GEOMETRY_SHADER : gs ;
type.register GL_FRAGMENT_SHADER : fs ;
+type.register GL_GENERIC_SHADER : glsl ;
-generators.register-standard glsl.embed : GL_VERTEX_SHADER : CPP(vs-%) H(vs-%) ;
-generators.register-standard glsl.embed : GL_TESS_CONTROL_SHADER : CPP(tcs-%) H(tcs-%) ;
-generators.register-standard glsl.embed : GL_TESS_EVALUATION_SHADER : CPP(tes-%) H(tes-%) ;
-generators.register-standard glsl.embed : GL_GEOMETRY_SHADER : CPP(gs-%) H(gs-%) ;
-generators.register-standard glsl.embed : GL_FRAGMENT_SHADER : CPP(fs-%) H(fs-%) ;
+generators.register-standard glsl.embed : GL_VERTEX_SHADER : CPP(vs-%) H(vs-%) GL_GENERIC_SHADER(vs-%) ;
+generators.register-standard glsl.embed : GL_TESS_CONTROL_SHADER : CPP(tcs-%) H(tcs-%) GL_GENERIC_SHADER(tcs-%) ;
+generators.register-standard glsl.embed : GL_TESS_EVALUATION_SHADER : CPP(tes-%) H(tes-%) GL_GENERIC_SHADER(tes-%) ;
+generators.register-standard glsl.embed : GL_GEOMETRY_SHADER : CPP(gs-%) H(gs-%) GL_GENERIC_SHADER(gs-%) ;
+generators.register-standard glsl.embed : GL_FRAGMENT_SHADER : CPP(fs-%) H(fs-%) GL_GENERIC_SHADER(fs-%) ;
class m4-scanner : common-scanner {
rule pattern ( ) {
@@ -31,12 +32,17 @@ type.set-scanner GL_FRAGMENT_SHADER : m4-scanner ;
actions glsl.embed
{
- m4 -I$(2:D) -DNAME=$(2:B) -DTYPE=$(2:S) > $(1[2]) lib/embed-glsl.h.m4
- m4 -I$(2:D) -DSOURCE=$(2) -DNAME=$(2:B) -DTYPE=$(2:S) -DGLTYPE=$(OPTIONS) > $(1[1]) lib/embed-glsl.cpp.m4
+ m4 -I$(2:D) -DSOURCE=$(2) -DOUTPUT=$(1[3]) -DNAME=$(2:B) -DTYPE=$(2:S) -DGLTYPE=$(OPTIONS) $(2) > $(1[3])
+ clang-format -i $(1[3])
+ m4 -I$(2:D) -DSOURCE=$(1[3]) -DOUTPUT=$(1[3]) -DNAME=$(2:B) -DTYPE=$(2:S) -DGLTYPE=$(OPTIONS) lib/embed-glsl.h.m4 > $(1[2])
+ m4 -I$(2:D) -DSOURCE=$(1[3]) -DOUTPUT=$(1[3]) -DNAME=$(2:B) -DTYPE=$(2:S) -DGLTYPE=$(OPTIONS) lib/embed-glsl.cpp.m4 > $(1[1])
+ clang-format -i $(1[1]) $(1[2])
}
rule glsl.embed ( targets * : sources * : properties * )
{
- DEPENDS $(targets) : lib/embed-glsl.h.m4 lib/embed-glsl.cpp.m4 ;
+ NOUPDATE $(targets[2]) ;
+ DEPENDS $(targets[2]) : lib/embed-glsl.h.m4 ;
+ DEPENDS $(targets[1]) $(targets[3]) : lib/embed-glsl.cpp.m4 ;
OPTIONS on $(targets) = [ type.type $(sources) ] ;
}
diff --git a/lib/embed-glsl.cpp.m4 b/lib/embed-glsl.cpp.m4
index 9fe0b41..ecae004 100644
--- a/lib/embed-glsl.cpp.m4
+++ b/lib/embed-glsl.cpp.m4
@@ -5,5 +5,5 @@ changecom() dnl
#include <glad/gl.h>
constexpr Shader NAME`_'substr(TYPE,1) {
- R"GLSL-EMBED(dnl
+ R"GLSL-EMBED(// OUTPUT
include(SOURCE))GLSL-EMBED", GLTYPE };
diff --git a/lib/msgException.h b/lib/msgException.h
new file mode 100644
index 0000000..660738d
--- /dev/null
+++ b/lib/msgException.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <optional>
+#include <string>
+
+template<typename BaseException> class MsgException : public BaseException {
+protected:
+ using BaseException::BaseException;
+ [[nodiscard]] virtual std::string getMsg() const noexcept = 0;
+
+public:
+ [[nodiscard]] const char *
+ what() const noexcept override
+ {
+ if (!msg) {
+ msg.emplace(getMsg());
+ }
+ return msg->c_str();
+ }
+
+private:
+ mutable std::optional<std::string> msg;
+};
diff --git a/lib/stdTypeDefs.h b/lib/stdTypeDefs.h
index beab630..38ebe0b 100644
--- a/lib/stdTypeDefs.h
+++ b/lib/stdTypeDefs.h
@@ -28,6 +28,18 @@ template<typename T> struct AnyPtr {
return *ptr;
}
+ // NOLINTNEXTLINE(hicpp-explicit-conversions)
+ operator bool() const
+ {
+ return ptr != nullptr;
+ }
+
+ bool
+ operator!() const
+ {
+ return ptr == nullptr;
+ }
+
private:
T * ptr;
};
diff --git a/res/shapespark-low-poly-plants-kit.fbx b/res/shapespark-low-poly-plants-kit.fbx
index fe87c0c..7457adb 100644
--- a/res/shapespark-low-poly-plants-kit.fbx
+++ b/res/shapespark-low-poly-plants-kit.fbx
Binary files differ
diff --git a/test/test-render.cpp b/test/test-render.cpp
index 2c4efea..b9a809e 100644
--- a/test/test-render.cpp
+++ b/test/test-render.cpp
@@ -9,6 +9,8 @@
#include <assetFactory/assetFactory.h>
#include <game/geoData.h>
#include <game/network/rail.h>
+#include <game/scenary/foliage.h>
+#include <game/scenary/plant.h>
#include <game/terrain.h>
#include <game/vehicles/railVehicle.h>
#include <game/vehicles/railVehicleClass.h>
@@ -25,7 +27,10 @@
class TestScene : public SceneProvider {
const RailVehicleClassPtr brush47rvc = std::dynamic_pointer_cast<RailVehicleClass>(
AssetFactory::loadXML(RESDIR "/brush47.xml")->assets.at("brush-47"));
+ const std::shared_ptr<Foliage> tree021f
+ = std::dynamic_pointer_cast<Foliage>(AssetFactory::loadXML(RESDIR "/foliage.xml")->assets.at("Tree-02-1"));
std::shared_ptr<RailVehicle> train1, train2;
+ std::shared_ptr<Plant> plant1;
RailLinks rail;
std::shared_ptr<GeoData> gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1));
@@ -43,6 +48,7 @@ public:
train2->location.setPosition({52000, 30000, 2000});
train2->bogies.front().setPosition(train2->bogies.front().position() + train2->location.position());
train2->bogies.back().setPosition(train2->bogies.back().position() + train2->location.position());
+ plant1 = std::make_shared<Plant>(tree021f, Location {{40000, 60000, 1}, {}});
rail.addLinksBetween({42000, 50000, 1000}, {65000, 50000, 1000});
rail.addLinksBetween({65000, 50000, 1000}, {75000, 45000, 2000});
}
@@ -53,6 +59,7 @@ public:
terrain.render(shader);
water.render(shader);
brush47rvc->render(shader);
+ tree021f->render(shader);
rail.render(shader);
}
@@ -66,6 +73,7 @@ public:
{
terrain.shadows(shadowMapper);
brush47rvc->shadows(shadowMapper);
+ tree021f->shadows(shadowMapper);
}
};
diff --git a/thirdparty/Jamfile.jam b/thirdparty/Jamfile.jam
index 7a47589..b6ed163 100644
--- a/thirdparty/Jamfile.jam
+++ b/thirdparty/Jamfile.jam
@@ -14,12 +14,13 @@ lib stb : stb_image.c :
;
lib imguisdl2 :
- [ glob imgui/imgui*.cpp : imgui/imgui_demo.cpp ]
+ [ glob imgui/imgui*.cpp imgui/misc/cpp/*.cpp : imgui/imgui_demo.cpp ]
imgui/backends/imgui_impl_sdl2.cpp
imgui/backends/imgui_impl_opengl3.cpp
:
<link>static
<include>imgui
+ <include>imgui/misc/cpp
<use>..//sdl2
<cflags>-fPIC
<warnings>off