summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-04-13 23:06:39 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-04-13 23:06:39 +0100
commit1c8e84d9503237e7a308107a0a44fbc7f188c700 (patch)
tree60e80d7f4e91621bc62cb5fb2f6c61aae631b4d9
parentLoad assimp textures in parallel (diff)
parentFix typo in name SceneCPtr (diff)
downloadilt-1c8e84d9503237e7a308107a0a44fbc7f188c700.tar.bz2
ilt-1c8e84d9503237e7a308107a0a44fbc7f188c700.tar.xz
ilt-1c8e84d9503237e7a308107a0a44fbc7f188c700.zip
Merge branch 'materials' into assimp
-rw-r--r--Jamroot.jam24
-rw-r--r--assetFactory/asset.h4
-rw-r--r--assetFactory/assetFactory.cpp26
-rw-r--r--assetFactory/assetFactory.h4
-rw-r--r--assetFactory/assimp.cpp16
-rw-r--r--assetFactory/factoryMesh.cpp3
-rw-r--r--assetFactory/modelFactoryMesh.cpp1
-rw-r--r--assetFactory/modelFactoryMesh.h2
-rw-r--r--assetFactory/style.cpp9
-rw-r--r--game/scenary/foliage.h1
-rw-r--r--gfx/gl/shaders/basicShader.fs31
-rw-r--r--gfx/gl/shaders/basicShader.vs12
-rw-r--r--gfx/gl/shaders/geometryOut.glsl3
-rw-r--r--gfx/gl/shaders/landmassShader.fs9
-rw-r--r--gfx/gl/shaders/landmassShader.vs12
-rw-r--r--gfx/gl/shaders/lightingShader.vs2
-rw-r--r--gfx/gl/shaders/materialInterface.glsl7
-rw-r--r--gfx/gl/shaders/meshIn.glsl5
-rw-r--r--gfx/gl/shaders/shadowDynamicPoint.vs2
-rw-r--r--gfx/gl/shaders/shadowFixedPoint.vs2
-rw-r--r--gfx/gl/shaders/waterShader.fs9
-rw-r--r--gfx/gl/shaders/waterShader.vs9
-rw-r--r--gfx/gl/vertexArrayObject.hpp2
-rw-r--r--gfx/models/mesh.cpp3
-rw-r--r--gfx/models/texture.cpp32
-rw-r--r--gfx/models/texture.h19
-rw-r--r--gfx/models/vertex.hpp9
-rw-r--r--glsl.jam36
-rw-r--r--lib/gl_traits.hpp45
29 files changed, 207 insertions, 132 deletions
diff --git a/Jamroot.jam b/Jamroot.jam
index ebe97a6..2275dd6 100644
--- a/Jamroot.jam
+++ b/Jamroot.jam
@@ -1,12 +1,10 @@
using gcc ;
using pkg-config ;
import pkg-config ;
-import type : register ;
-import type : type ;
-import generators : register-standard ;
import testing ;
import lex ;
import sequence ;
+import glsl ;
pkg-config.import sdl2 ;
pkg-config.import glew ;
@@ -50,26 +48,6 @@ project : requirements
<toolset>tidy:<define>TIDY
;
-type.register GL_VERTEX_SHADER : vs ;
-type.register GL_GEOMETRY_SHADER : gs ;
-type.register GL_FRAGMENT_SHADER : fs ;
-
-generators.register-standard embed.glsl : GL_VERTEX_SHADER : CPP(vs-%) H(vs-%) ;
-generators.register-standard embed.glsl : GL_GEOMETRY_SHADER : CPP(gs-%) H(gs-%) ;
-generators.register-standard embed.glsl : GL_FRAGMENT_SHADER : CPP(fs-%) H(fs-%) ;
-
-actions embed.glsl
-{
- m4 -DNAME=$(2:B) -DTYPE=$(2:S) > $(1[2]) lib/embed-glsl.h.m4
- m4 -DSOURCE=$(2) -DNAME=$(2:B) -DTYPE=$(2:S) -DGLTYPE=$(OPTIONS) > $(1[1]) lib/embed-glsl.cpp.m4
-}
-rule embed.glsl ( targets * : sources * : properties * )
-{
- DEPENDS $(targets) : lib/embed-glsl.h.m4 lib/embed-glsl.cpp.m4 ;
- OPTIONS on $(targets) = [ type.type $(sources) ] ;
-}
-IMPORT $(__name__) : embed.glsl : : embed.glsl ;
-
exe iliketrains :
application/main.cpp
:
diff --git a/assetFactory/asset.h b/assetFactory/asset.h
index 30f40cd..dba4974 100644
--- a/assetFactory/asset.h
+++ b/assetFactory/asset.h
@@ -4,11 +4,11 @@
#include "persistence.h"
#include <stdTypeDefs.hpp>
-class Texture;
+class TextureAtlas;
class Asset : public Persistence::Persistable, public StdTypeDefs<Asset> {
public:
- using TexturePtr = std::shared_ptr<Texture>;
+ using TexturePtr = std::shared_ptr<TextureAtlas>;
std::string id;
std::string name;
diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp
index 917edfe..46b4642 100644
--- a/assetFactory/assetFactory.cpp
+++ b/assetFactory/assetFactory.cpp
@@ -80,17 +80,11 @@ AssetFactory::parseColour(std::string_view in) const
throw std::runtime_error("No such asset factory colour");
}
-AssetFactory::TextureFragmentCoords
-AssetFactory::getTextureCoords(std::string_view id) const
+GLuint
+AssetFactory::getMaterialIndex(std::string_view id) const
{
createTexutre();
- const auto & fragmentUV = textureFragmentPositions.at(id);
- return {
- fragmentUV.xy(),
- fragmentUV.zy(),
- fragmentUV.zw(),
- fragmentUV.xw(),
- };
+ return textureFragmentPositions.at(id);
}
Asset::TexturePtr
@@ -103,7 +97,7 @@ AssetFactory::getTexture() const
void
AssetFactory::createTexutre() const
{
- if (!textureFragments.empty() && (!texture || textureFragmentPositions.empty())) {
+ if (!textureFragments.empty() && !texture) {
// * layout images
std::vector<TexturePacker::Image> imageSizes;
std::transform(
@@ -112,18 +106,14 @@ AssetFactory::createTexutre() const
});
const auto [layout, outSize] = TexturePacker {imageSizes}.pack();
// * create texture
- texture = std::make_shared<Texture>(outSize.x, outSize.y, TextureOptions {.wrap = GL_CLAMP_TO_EDGE});
+ texture = std::make_shared<TextureAtlas>(outSize.x, outSize.y, layout.size());
std::transform(textureFragments.begin(), textureFragments.end(),
std::inserter(textureFragmentPositions, textureFragmentPositions.end()),
- [position = layout.begin(), size = imageSizes.begin(), outSize = glm::vec2 {outSize}](
- const auto & tf) mutable {
- const auto positionFraction = glm::vec4 {*position, *position + *size} / outSize.xyxy();
- glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(position->x), static_cast<GLint>(position->y),
- static_cast<GLint>(size->x), static_cast<GLint>(size->y), GL_RGBA, GL_UNSIGNED_BYTE,
- tf.second->image->data.data());
+ [position = layout.begin(), size = imageSizes.begin(), this](const auto & tf) mutable {
+ const auto m = texture->add(*position, *size, tf.second->image->data.data());
position++;
size++;
- return decltype(textureFragmentPositions)::value_type {tf.first, positionFraction};
+ return decltype(textureFragmentPositions)::value_type {tf.first, m};
});
}
}
diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h
index 7843d44..9e5d205 100644
--- a/assetFactory/assetFactory.h
+++ b/assetFactory/assetFactory.h
@@ -23,7 +23,7 @@ public:
AssetFactory();
[[nodiscard]] static std::shared_ptr<AssetFactory> loadXML(const std::filesystem::path &);
[[nodiscard]] ColourAlpha parseColour(std::string_view) const;
- [[nodiscard]] TextureFragmentCoords getTextureCoords(std::string_view) const;
+ [[nodiscard]] GLuint getMaterialIndex(std::string_view) const;
[[nodiscard]] Asset::TexturePtr getTexture() const;
Shapes shapes;
@@ -42,5 +42,5 @@ private:
void createTexutre() const;
mutable Asset::TexturePtr texture;
- mutable std::map<std::string_view, glm::vec4, std::less<>> textureFragmentPositions;
+ mutable std::map<std::string_view, GLuint, std::less<>> textureFragmentPositions;
};
diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp
index 0c6cb86..878e7e7 100644
--- a/assetFactory/assimp.cpp
+++ b/assetFactory/assimp.cpp
@@ -29,12 +29,12 @@ operator!(const aiVector3t<T> & v)
(parent)->m##member, (parent)->mNum##member \
}
-using ScemeCPtr = std::shared_ptr<const aiScene>;
+using SceneCPtr = std::shared_ptr<const aiScene>;
class AssImpNode : public Shape {
public:
- AssImpNode(ScemeCPtr scene, const aiNode * node) : scene(std::move(scene)), node(node) { }
+ AssImpNode(SceneCPtr scene, const aiNode * node) : scene(std::move(scene)), node(node) { }
- ScemeCPtr scene;
+ SceneCPtr scene;
const aiNode * node;
CreatedFaces
@@ -64,11 +64,11 @@ public:
};
const auto & m = *scene->mMaterials[amesh->mMaterialIndex];
- AssetFactory::TextureFragmentCoords tfc;
+ GLuint material {};
if (auto mf = Persistence::ParseBase::getShared<AssetFactory>("assetFactory")) {
aiString path;
m.Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path);
- tfc = mf->getTextureCoords(path.C_Str());
+ material = mf->getMaterialIndex(path.C_Str());
}
for (const auto & f : AIRANGE(amesh, Faces)) {
@@ -79,8 +79,8 @@ public:
if (amesh->HasTextureCoords(0)) {
for (auto idx = f.mIndices; const auto fheh : mesh.fh_range(fh)) {
const auto ouv = !amesh->mTextureCoords[0][*idx++];
- const auto uv = glm::mix(tfc[0], tfc[2], ouv);
- mesh.set_texcoord2D(fheh, uv);
+ mesh.set_texcoord2D(fheh, ouv);
+ mesh.property(mesh.materialFaceProperty, fh) = material;
}
}
}
@@ -90,7 +90,7 @@ public:
void
AssImp::postLoad()
{
- ScemeCPtr scene {
+ SceneCPtr scene {
aiImportFile(Resource::mapPath(path).c_str(), aiProcess_RemoveRedundantMaterials), &aiReleaseImport};
if (!scene) {
throw std::runtime_error("Failed to load asset library: " + path);
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
index 4922936..f7bc7c8 100644
--- a/assetFactory/factoryMesh.cpp
+++ b/assetFactory/factoryMesh.cpp
@@ -18,6 +18,7 @@ FactoryMesh::createMesh() const
for (const auto & face : mesh.faces()) {
const auto & smooth = mesh.property(mesh.smoothFaceProperty, face);
const auto & colour = mesh.color(face);
+ const auto & material = mesh.property(mesh.materialFaceProperty, face);
std::vector<unsigned int> faceIndices;
for (const auto & heh : mesh.fh_range(face)) {
@@ -26,7 +27,7 @@ FactoryMesh::createMesh() const
const auto & point = mesh.point(vertex);
const auto & normal = smooth ? mesh.property(mesh.vertex_normals_pph(), vertex)
: mesh.property(mesh.face_normals_pph(), face);
- Vertex outVertex {point, textureUV, normal, colour};
+ Vertex outVertex {point, textureUV, normal, colour, 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/assetFactory/modelFactoryMesh.cpp b/assetFactory/modelFactoryMesh.cpp
index e640502..3d4b5f3 100644
--- a/assetFactory/modelFactoryMesh.cpp
+++ b/assetFactory/modelFactoryMesh.cpp
@@ -3,6 +3,7 @@
ModelFactoryMesh::ModelFactoryMesh()
{
add_property(smoothFaceProperty);
+ add_property(materialFaceProperty);
add_property(nameFaceProperty);
add_property(nameAdjFaceProperty);
}
diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h
index 8ac2edd..4eac7ee 100644
--- a/assetFactory/modelFactoryMesh.h
+++ b/assetFactory/modelFactoryMesh.h
@@ -1,6 +1,7 @@
#pragma once
#include "modelFactoryMesh_fwd.h"
+#include <GL/glew.h>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/Mesh/Traits.hh>
#include <glm/geometric.hpp>
@@ -47,6 +48,7 @@ struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTra
ModelFactoryMesh();
OpenMesh::FPropHandleT<bool> smoothFaceProperty;
+ OpenMesh::FPropHandleT<GLuint> materialFaceProperty;
OpenMesh::FPropHandleT<std::string> nameFaceProperty;
OpenMesh::HPropHandleT<std::string> nameAdjFaceProperty;
diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp
index 12346a6..ea67fc2 100644
--- a/assetFactory/style.cpp
+++ b/assetFactory/style.cpp
@@ -30,7 +30,14 @@ Style::applyStyle(
else {
mesh.set_color(face, {});
if (auto mf = Persistence::ParseBase::getShared<const AssetFactory>("assetFactory")) {
- auto coords = mf->getTextureCoords(texture);
+ const auto material = mf->getMaterialIndex(texture);
+ mesh.property(mesh.materialFaceProperty, face) = material;
+ static constexpr std::array<ModelFactoryTraits::TexCoord2D, 4> coords {{
+ {0.f, 0.f},
+ {1.f, 0.f},
+ {1.f, 1.f},
+ {0.f, 1.f},
+ }};
auto coord = coords.begin();
// Wild assumption that face is a quad and the texture should apply linearly
for (const auto & heh : mesh.fh_range(face)) {
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index 229bccb..b85aab2 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -5,6 +5,7 @@
class SceneShader;
class ShadowMapper;
class Location;
+class Texture;
class Foliage : public Asset, public StdTypeDefs<Foliage> {
Mesh::Ptr bodyMesh;
diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs
index 24b2791..8a72e6d 100644
--- a/gfx/gl/shaders/basicShader.fs
+++ b/gfx/gl/shaders/basicShader.fs
@@ -1,22 +1,29 @@
#version 330 core
+#extension GL_ARB_shading_language_420pack : enable
-in vec3 FragPos;
-in vec2 TexCoords;
-in vec3 Normal;
-in vec4 Colour;
+include(`materialInterface.glsl')
+include(`geometryOut.glsl')
-out vec4 gPosition;
-out vec4 gNormal;
-out vec4 gAlbedoSpec;
+layout(binding = 0) uniform sampler2D texture0;
+layout(binding = 1) uniform usampler2DRect material;
-uniform sampler2D texture0;
+vec4 getTextureColour(uint midx, vec2 uv)
+{
+ if (midx > 0u) {
+ const vec2 tSize = textureSize(texture0, 0);
+ const vec4 sPosSize = texture(material, uvec2(0, midx - 1u));
+ uv = (sPosSize.xy + sPosSize.zw * fract(uv)) / tSize;
+ }
+ return texture(texture0, uv);
+}
void
main()
{
- vec4 textureColour = texture(texture0, TexCoords);
- float clear = round(mix(textureColour.a, 1, Colour.a));
- gPosition = vec4(FragPos, clear);
- gNormal = vec4(Normal, clear);
+ vec4 textureColour = getTextureColour(Material, TexCoords);
+ float opaque = step(0.5, mix(textureColour.a, 1, Colour.a));
+ gPosition = vec4(FragPos, opaque);
+ gNormal = vec4(Normal, opaque);
+ gl_FragDepth = mix(1.0, gl_FragCoord.z, opaque);
gAlbedoSpec = mix(textureColour, vec4(Colour.rgb, 1), Colour.a);
}
diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs
index ff9a401..e1701ed 100644
--- a/gfx/gl/shaders/basicShader.vs
+++ b/gfx/gl/shaders/basicShader.vs
@@ -1,14 +1,7 @@
#version 330 core
-in vec3 position;
-in vec2 texCoord;
-in vec3 normal;
-in vec4 colour;
-
-out vec3 FragPos;
-out vec2 TexCoords;
-out vec3 Normal;
-out vec4 Colour;
+include(`meshIn.glsl')
+include(`materialInterface.glsl')
uniform mat4 viewProjection;
uniform mat4 model;
@@ -22,6 +15,7 @@ main()
TexCoords = texCoord;
Normal = (model * vec4(normal, 0.0)).xyz;
Colour = colour;
+ Material = material;
gl_Position = viewProjection * worldPos;
}
diff --git a/gfx/gl/shaders/geometryOut.glsl b/gfx/gl/shaders/geometryOut.glsl
new file mode 100644
index 0000000..dc5f8e8
--- /dev/null
+++ b/gfx/gl/shaders/geometryOut.glsl
@@ -0,0 +1,3 @@
+layout(location = 0) out vec4 gPosition;
+layout(location = 1) out vec4 gNormal;
+layout(location = 2) out vec4 gAlbedoSpec;
diff --git a/gfx/gl/shaders/landmassShader.fs b/gfx/gl/shaders/landmassShader.fs
index 7c08e8e..f3cc3e8 100644
--- a/gfx/gl/shaders/landmassShader.fs
+++ b/gfx/gl/shaders/landmassShader.fs
@@ -1,12 +1,7 @@
#version 330 core
-in vec3 FragPos;
-in vec2 TexCoords;
-in vec3 Normal;
-
-layout(location = 0) out vec4 gPosition;
-layout(location = 1) out vec4 gNormal;
-layout(location = 2) out vec4 gAlbedoSpec;
+include(`materialInterface.glsl')
+include(`geometryOut.glsl')
uniform sampler2D texture0;
diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs
index 30c4ef4..0cc8153 100644
--- a/gfx/gl/shaders/landmassShader.vs
+++ b/gfx/gl/shaders/landmassShader.vs
@@ -1,14 +1,7 @@
#version 330 core
-in vec3 position;
-in vec2 texCoord;
-in vec3 normal;
-in vec4 colour;
-
-out vec3 FragPos;
-out vec2 TexCoords;
-out vec3 Normal;
-out vec4 Colour;
+include(`meshIn.glsl')
+include(`materialInterface.glsl')
uniform mat4 viewProjection;
@@ -19,6 +12,7 @@ main()
TexCoords = texCoord;
Normal = normal;
Colour = colour;
+ Material = material;
gl_Position = viewProjection * vec4(position, 1.0);
}
diff --git a/gfx/gl/shaders/lightingShader.vs b/gfx/gl/shaders/lightingShader.vs
index 2271d2e..e07cd0a 100644
--- a/gfx/gl/shaders/lightingShader.vs
+++ b/gfx/gl/shaders/lightingShader.vs
@@ -1,6 +1,6 @@
#version 330 core
-in vec4 position;
+in ivec4 position;
out vec2 TexCoords;
diff --git a/gfx/gl/shaders/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl
new file mode 100644
index 0000000..5735cf9
--- /dev/null
+++ b/gfx/gl/shaders/materialInterface.glsl
@@ -0,0 +1,7 @@
+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)
+uint Material;
diff --git a/gfx/gl/shaders/meshIn.glsl b/gfx/gl/shaders/meshIn.glsl
new file mode 100644
index 0000000..dd84a10
--- /dev/null
+++ b/gfx/gl/shaders/meshIn.glsl
@@ -0,0 +1,5 @@
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec2 texCoord;
+layout(location = 2) in vec3 normal;
+layout(location = 3) in vec4 colour;
+layout(location = 4) in uint material;
diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs
index 6ea352f..531d8de 100644
--- a/gfx/gl/shaders/shadowDynamicPoint.vs
+++ b/gfx/gl/shaders/shadowDynamicPoint.vs
@@ -1,6 +1,6 @@
#version 330 core
-in vec3 position;
+include(`meshIn.glsl')
uniform mat4 viewProjection;
uniform mat4 model;
diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs
index 246890c..c9fa19b 100644
--- a/gfx/gl/shaders/shadowFixedPoint.vs
+++ b/gfx/gl/shaders/shadowFixedPoint.vs
@@ -1,6 +1,6 @@
#version 330 core
-layout(location = 0) in vec3 position;
+include(`meshIn.glsl')
uniform mat4 viewProjection;
diff --git a/gfx/gl/shaders/waterShader.fs b/gfx/gl/shaders/waterShader.fs
index d242566..5936da4 100644
--- a/gfx/gl/shaders/waterShader.fs
+++ b/gfx/gl/shaders/waterShader.fs
@@ -1,13 +1,8 @@
#version 330 core
#extension GL_ARB_shading_language_420pack : enable
-in vec3 FragPos;
-in vec2 TexCoords;
-in vec3 Normal;
-
-out vec4 gPosition;
-out vec4 gNormal;
-out vec4 gAlbedoSpec;
+include(`materialInterface.glsl')
+include(`geometryOut.glsl')
uniform sampler2D texture0;
uniform vec3 waves;
diff --git a/gfx/gl/shaders/waterShader.vs b/gfx/gl/shaders/waterShader.vs
index fe9206f..a21b49f 100644
--- a/gfx/gl/shaders/waterShader.vs
+++ b/gfx/gl/shaders/waterShader.vs
@@ -1,12 +1,7 @@
#version 330 core
-in vec3 position;
-in vec2 texCoord;
-in vec3 normal;
-
-out vec3 FragPos;
-out vec2 TexCoords;
-out vec3 Normal;
+include(`meshIn.glsl')
+include(`materialInterface.glsl')
uniform mat4 viewProjection;
uniform vec3 waves;
diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp
index c0273c0..5b9fc60 100644
--- a/gfx/gl/vertexArrayObject.hpp
+++ b/gfx/gl/vertexArrayObject.hpp
@@ -61,7 +61,7 @@ private:
{
glEnableVertexAttribArray(vertexArrayId);
using traits = gl_traits<T>;
- glVertexAttribPointer(vertexArrayId, traits::size, traits::type, GL_FALSE, sizeof(Vertex), ptr);
+ traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(Vertex), ptr);
}
template<auto Vertex::*attrib>
diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp
index 3db1ad5..2719211 100644
--- a/gfx/models/mesh.cpp
+++ b/gfx/models/mesh.cpp
@@ -7,7 +7,8 @@
Mesh::Mesh(const std::span<const Vertex> vertices, const std::span<const unsigned int> indices, GLenum m) :
m_numIndices {static_cast<GLsizei>(indices.size())}, mode {m}
{
- VertexArrayObject<Vertex>::configure<&Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour>(
+ VertexArrayObject<Vertex>::configure<&Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour,
+ &Vertex::material>(
m_vertexArrayObject, m_vertexArrayBuffers[0], m_vertexArrayBuffers[1], vertices, indices);
}
diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp
index efc76e1..a500fed 100644
--- a/gfx/models/texture.cpp
+++ b/gfx/models/texture.cpp
@@ -85,3 +85,35 @@ Texture::saveNormal(const glTexture & texture, const glm::ivec2 & size, const ch
{
save(texture, GL_BGR, GL_BYTE, size, 3, path, 2);
}
+
+TextureAtlas::TextureAtlas(GLsizei width, GLsizei height, GLuint count) : Texture(width, height, nullptr, {})
+{
+ glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas);
+
+ glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA16UI, 2, static_cast<GLsizei>(count), 0, GL_RGBA_INTEGER,
+ GL_UNSIGNED_BYTE, nullptr);
+}
+
+void
+TextureAtlas::bind(GLenum unit) const
+{
+ Texture::bind(unit);
+ glActiveTexture(unit + 1);
+ glBindTexture(GL_TEXTURE_RECTANGLE, m_atlas);
+}
+
+GLuint
+TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions)
+{
+ glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ struct Material {
+ glm::vec<2, uint16_t> position, size, unused1 {}, unused2 {};
+ } material {position, size};
+ glTextureSubImage2D(m_atlas, 0, 0, static_cast<GLsizei>(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material);
+ return ++used;
+}
diff --git a/gfx/models/texture.h b/gfx/models/texture.h
index ffc9a4a..7900f17 100644
--- a/gfx/models/texture.h
+++ b/gfx/models/texture.h
@@ -16,6 +16,9 @@ struct TextureOptions {
class Texture {
public:
+ virtual ~Texture() = default;
+ DEFAULT_MOVE_NO_COPY(Texture);
+
explicit Texture(const std::filesystem::path & fileName, TextureOptions = {});
explicit Texture(const Image & image, TextureOptions = {});
explicit Texture(GLsizei width, GLsizei height, TextureOptions = {});
@@ -23,17 +26,29 @@ public:
static Cache<Texture, std::filesystem::path> cachedTexture;
- void bind(GLenum unit = GL_TEXTURE0) const;
+ virtual void bind(GLenum unit = GL_TEXTURE0) const;
void save(const glm::ivec2 & size, const char * path) const;
static void save(const glTexture &, const glm::ivec2 & size, const char * path);
static void saveDepth(const glTexture &, const glm::ivec2 & size, const char * path);
static void saveNormal(const glTexture &, const glm::ivec2 & size, const char * path);
-private:
+protected:
static void save(const glTexture &, GLenum, GLenum, const glm::ivec2 & size, unsigned short channels,
const char * path, short tgaFormat);
glTexture m_texture;
GLenum type;
};
+
+class TextureAtlas : public Texture {
+public:
+ TextureAtlas(GLsizei width, GLsizei height, GLuint count);
+
+ void bind(GLenum unit = GL_TEXTURE0) const override;
+ GLuint add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions = {});
+
+private:
+ glTexture m_atlas;
+ GLuint used {};
+};
diff --git a/gfx/models/vertex.hpp b/gfx/models/vertex.hpp
index 64ec3d0..181e7e7 100644
--- a/gfx/models/vertex.hpp
+++ b/gfx/models/vertex.hpp
@@ -1,12 +1,14 @@
#pragma once
+#include <GL/glew.h>
#include <glm/glm.hpp>
class Vertex {
public:
#ifndef __cpp_aggregate_paren_init
- constexpr Vertex(glm::vec3 pos, glm::vec2 texCoord, glm::vec3 normal, glm::vec4 colour = {}) :
- pos {std::move(pos)}, texCoord {std::move(texCoord)}, normal {std::move(normal)}, colour {std::move(colour)}
+ constexpr Vertex(glm::vec3 pos, glm::vec2 texCoord, glm::vec3 normal, glm::vec4 colour = {}, GLuint material = 0) :
+ pos {std::move(pos)}, texCoord {std::move(texCoord)}, normal {std::move(normal)}, colour {std::move(colour)},
+ material {material}
{
}
#endif
@@ -16,5 +18,6 @@ public:
glm::vec3 pos;
glm::vec2 texCoord;
glm::vec3 normal;
- glm::vec4 colour;
+ glm::vec4 colour {};
+ GLuint material {};
};
diff --git a/glsl.jam b/glsl.jam
new file mode 100644
index 0000000..87dee61
--- /dev/null
+++ b/glsl.jam
@@ -0,0 +1,36 @@
+import type : register ;
+import type : type ;
+import generators : register-standard ;
+import scanner : register ;
+
+type.register GL_VERTEX_SHADER : vs ;
+type.register GL_GEOMETRY_SHADER : gs ;
+type.register GL_FRAGMENT_SHADER : fs ;
+
+generators.register-standard glsl.embed : GL_VERTEX_SHADER : CPP(vs-%) H(vs-%) ;
+generators.register-standard glsl.embed : GL_GEOMETRY_SHADER : CPP(gs-%) H(gs-%) ;
+generators.register-standard glsl.embed : GL_FRAGMENT_SHADER : CPP(fs-%) H(fs-%) ;
+
+class m4-scanner : common-scanner {
+ rule pattern ( ) {
+ return "s?include\\(`([^']*)'\\)" ;
+ }
+}
+
+scanner.register m4-scanner : include ;
+
+type.set-scanner GL_VERTEX_SHADER : m4-scanner ;
+type.set-scanner GL_GEOMETRY_SHADER : m4-scanner ;
+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
+}
+
+rule glsl.embed ( targets * : sources * : properties * )
+{
+ DEPENDS $(targets) : lib/embed-glsl.h.m4 lib/embed-glsl.cpp.m4 ;
+ OPTIONS on $(targets) = [ type.type $(sources) ] ;
+}
diff --git a/lib/gl_traits.hpp b/lib/gl_traits.hpp
index d140de9..e2e689d 100644
--- a/lib/gl_traits.hpp
+++ b/lib/gl_traits.hpp
@@ -6,37 +6,50 @@
#include <glm/fwd.hpp>
template<typename T> struct gl_traits;
-template<> struct gl_traits<glm::f32> {
- static constexpr GLenum type {GL_FLOAT};
+struct gl_traits_base {
static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::f64> {
+struct gl_traits_float : public gl_traits_base {
+ static constexpr auto vertexAttribFunc {
+ [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) {
+ glVertexAttribPointer(index, size, type, GL_FALSE, stride, pointer);
+ }};
+};
+struct gl_traits_longfloat : public gl_traits_base {
+ static constexpr auto vertexAttribFunc {
+ [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) {
+ glVertexAttribLPointer(index, size, type, stride, pointer);
+ }};
+};
+struct gl_traits_integer : public gl_traits_base {
+ static constexpr auto vertexAttribFunc {
+ [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) {
+ glVertexAttribIPointer(index, size, type, stride, pointer);
+ }};
+};
+template<> struct gl_traits<glm::f32> : public gl_traits_float {
+ static constexpr GLenum type {GL_FLOAT};
+};
+template<> struct gl_traits<glm::f64> : public gl_traits_longfloat {
static constexpr GLenum type {GL_DOUBLE};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::int8> {
+template<> struct gl_traits<glm::int8> : public gl_traits_integer {
static constexpr GLenum type {GL_BYTE};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::int16> {
+template<> struct gl_traits<glm::int16> : public gl_traits_integer {
static constexpr GLenum type {GL_SHORT};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::int32> {
+template<> struct gl_traits<glm::int32> : public gl_traits_integer {
static constexpr GLenum type {GL_INT};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::uint8> {
+template<> struct gl_traits<glm::uint8> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_BYTE};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::uint16> {
+template<> struct gl_traits<glm::uint16> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_SHORT};
- static constexpr GLint size {1};
};
-template<> struct gl_traits<glm::uint32> {
+template<> struct gl_traits<glm::uint32> : public gl_traits_integer {
static constexpr GLenum type {GL_UNSIGNED_INT};
- static constexpr GLint size {1};
};
template<typename T, std::size_t S> struct gl_traits<std::array<T, S>> : public gl_traits<T> {