From e2edd9f141699ce4be1664f590438369db9573e6 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 18:36:41 +0100 Subject: Split out the glsl embedding jam rules --- Jamroot.jam | 24 +----------------------- glsl.jam | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 glsl.jam 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 tidy: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/glsl.jam b/glsl.jam new file mode 100644 index 0000000..03e93e9 --- /dev/null +++ b/glsl.jam @@ -0,0 +1,23 @@ +import type : register ; +import type : type ; +import generators : register-standard ; + +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-%) ; + +actions glsl.embed +{ + 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 glsl.embed ( targets * : sources * : properties * ) +{ + DEPENDS $(targets) : lib/embed-glsl.h.m4 lib/embed-glsl.cpp.m4 ; + OPTIONS on $(targets) = [ type.type $(sources) ] ; +} -- cgit v1.2.3 From 4d569af26d3bab55e27b3bb9ada14ef088e23f35 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 18:40:18 +0100 Subject: Support m4 includes as a Jam scanner --- glsl.jam | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/glsl.jam b/glsl.jam index 03e93e9..87dee61 100644 --- a/glsl.jam +++ b/glsl.jam @@ -1,6 +1,7 @@ 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 ; @@ -10,10 +11,22 @@ 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 -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 + 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 * ) -- cgit v1.2.3 From 43d8fdb3f6aeb88762c68179d7bb1dc58507bb60 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 18:54:41 +0100 Subject: Move lots of common glsl interface to include files --- gfx/gl/shaders/basicShader.fs | 5 +---- gfx/gl/shaders/basicShader.vs | 6 +----- gfx/gl/shaders/geometryOut.glsl | 3 +++ gfx/gl/shaders/landmassShader.fs | 5 +---- gfx/gl/shaders/landmassShader.vs | 6 +----- gfx/gl/shaders/meshIn.glsl | 4 ++++ gfx/gl/shaders/shadowDynamicPoint.vs | 2 +- gfx/gl/shaders/shadowFixedPoint.vs | 2 +- gfx/gl/shaders/waterShader.fs | 5 +---- gfx/gl/shaders/waterShader.vs | 5 +---- 10 files changed, 15 insertions(+), 28 deletions(-) create mode 100644 gfx/gl/shaders/geometryOut.glsl create mode 100644 gfx/gl/shaders/meshIn.glsl diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 24b2791..0d0b904 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -4,10 +4,7 @@ in vec3 FragPos; in vec2 TexCoords; in vec3 Normal; in vec4 Colour; - -out vec4 gPosition; -out vec4 gNormal; -out vec4 gAlbedoSpec; +include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index ff9a401..a96d478 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -1,10 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; -in vec4 colour; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; 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..5daeeb6 100644 --- a/gfx/gl/shaders/landmassShader.fs +++ b/gfx/gl/shaders/landmassShader.fs @@ -3,10 +3,7 @@ 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(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index 30c4ef4..3eb9aa3 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -1,10 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; -in vec4 colour; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; diff --git a/gfx/gl/shaders/meshIn.glsl b/gfx/gl/shaders/meshIn.glsl new file mode 100644 index 0000000..2b244c1 --- /dev/null +++ b/gfx/gl/shaders/meshIn.glsl @@ -0,0 +1,4 @@ +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texCoord; +layout(location = 2) in vec3 normal; +layout(location = 3) in vec4 colour; 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..d457f27 100644 --- a/gfx/gl/shaders/waterShader.fs +++ b/gfx/gl/shaders/waterShader.fs @@ -4,10 +4,7 @@ in vec3 FragPos; in vec2 TexCoords; in vec3 Normal; - -out vec4 gPosition; -out vec4 gNormal; -out vec4 gAlbedoSpec; +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..6f96c19 100644 --- a/gfx/gl/shaders/waterShader.vs +++ b/gfx/gl/shaders/waterShader.vs @@ -1,9 +1,6 @@ #version 330 core -in vec3 position; -in vec2 texCoord; -in vec3 normal; - +include(`meshIn.glsl') out vec3 FragPos; out vec2 TexCoords; out vec3 Normal; -- cgit v1.2.3 From d0186d81127056ac2647807dcf05b454e234a7cb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 11 Apr 2023 22:54:44 +0100 Subject: Move the vertex/fragment shader interface for materials into an include --- gfx/gl/shaders/basicShader.fs | 5 +---- gfx/gl/shaders/basicShader.vs | 5 +---- gfx/gl/shaders/landmassShader.fs | 4 +--- gfx/gl/shaders/landmassShader.vs | 5 +---- gfx/gl/shaders/materialInterface.glsl | 4 ++++ gfx/gl/shaders/waterShader.fs | 4 +--- gfx/gl/shaders/waterShader.vs | 4 +--- 7 files changed, 10 insertions(+), 21 deletions(-) create mode 100644 gfx/gl/shaders/materialInterface.glsl diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 0d0b904..8bb6350 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -1,9 +1,6 @@ #version 330 core -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; -in vec4 Colour; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index a96d478..4d648f3 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -1,10 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; -out vec4 Colour; +include(`materialInterface.glsl') uniform mat4 viewProjection; uniform mat4 model; diff --git a/gfx/gl/shaders/landmassShader.fs b/gfx/gl/shaders/landmassShader.fs index 5daeeb6..f3cc3e8 100644 --- a/gfx/gl/shaders/landmassShader.fs +++ b/gfx/gl/shaders/landmassShader.fs @@ -1,8 +1,6 @@ #version 330 core -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index 3eb9aa3..cabe39f 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -1,10 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; -out vec4 Colour; +include(`materialInterface.glsl') uniform mat4 viewProjection; diff --git a/gfx/gl/shaders/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl new file mode 100644 index 0000000..3e09c85 --- /dev/null +++ b/gfx/gl/shaders/materialInterface.glsl @@ -0,0 +1,4 @@ +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; diff --git a/gfx/gl/shaders/waterShader.fs b/gfx/gl/shaders/waterShader.fs index d457f27..5936da4 100644 --- a/gfx/gl/shaders/waterShader.fs +++ b/gfx/gl/shaders/waterShader.fs @@ -1,9 +1,7 @@ #version 330 core #extension GL_ARB_shading_language_420pack : enable -in vec3 FragPos; -in vec2 TexCoords; -in vec3 Normal; +include(`materialInterface.glsl') include(`geometryOut.glsl') uniform sampler2D texture0; diff --git a/gfx/gl/shaders/waterShader.vs b/gfx/gl/shaders/waterShader.vs index 6f96c19..a21b49f 100644 --- a/gfx/gl/shaders/waterShader.vs +++ b/gfx/gl/shaders/waterShader.vs @@ -1,9 +1,7 @@ #version 330 core include(`meshIn.glsl') -out vec3 FragPos; -out vec2 TexCoords; -out vec3 Normal; +include(`materialInterface.glsl') uniform mat4 viewProjection; uniform vec3 waves; -- cgit v1.2.3 From 936f54e86f71d8e4af4784ebb32b6518c6fc3a01 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 00:44:20 +0100 Subject: Fix submitting of integer values via vertex arrays --- gfx/gl/shaders/lightingShader.vs | 2 +- gfx/gl/vertexArrayObject.hpp | 2 +- lib/gl_traits.hpp | 45 ++++++++++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 18 deletions(-) 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/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; - glVertexAttribPointer(vertexArrayId, traits::size, traits::type, GL_FALSE, sizeof(Vertex), ptr); + traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(Vertex), ptr); } template 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 template struct gl_traits; -template<> struct gl_traits { - static constexpr GLenum type {GL_FLOAT}; +struct gl_traits_base { static constexpr GLint size {1}; }; -template<> struct gl_traits { +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 : public gl_traits_float { + static constexpr GLenum type {GL_FLOAT}; +}; +template<> struct gl_traits : public gl_traits_longfloat { static constexpr GLenum type {GL_DOUBLE}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_BYTE}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_SHORT}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_INT}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_BYTE}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_SHORT}; - static constexpr GLint size {1}; }; -template<> struct gl_traits { +template<> struct gl_traits : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_INT}; - static constexpr GLint size {1}; }; template struct gl_traits> : public gl_traits { -- cgit v1.2.3 From 1529d37d585ec38aee475519e444d2718a81fda5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:10:44 +0100 Subject: Add TextureAtlas class as an extension of Texture --- gfx/models/texture.cpp | 32 ++++++++++++++++++++++++++++++++ gfx/models/texture.h | 19 +++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) 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(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(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 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 {}; +}; -- cgit v1.2.3 From 259444e842ac4ec546948a8e828b62bec734f659 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:13:20 +0100 Subject: Add material field to vertex and configure it in mesh --- gfx/models/mesh.cpp | 3 ++- gfx/models/vertex.hpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) 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 vertices, const std::span indices, GLenum m) : m_numIndices {static_cast(indices.size())}, mode {m} { - VertexArrayObject::configure<&Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour>( + VertexArrayObject::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/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 #include 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 {}; }; -- cgit v1.2.3 From f16a7df6135262c91fee2a2f6c46ad2f3caa7157 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:15:41 +0100 Subject: Update shaders to use material to conditionally lookup sub-texture in the atlas --- gfx/gl/shaders/basicShader.fs | 16 ++++++++++++++-- gfx/gl/shaders/basicShader.vs | 1 + gfx/gl/shaders/landmassShader.vs | 1 + gfx/gl/shaders/materialInterface.glsl | 3 +++ gfx/gl/shaders/meshIn.glsl | 1 + 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index 8bb6350..ab5e58b 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -1,14 +1,26 @@ #version 330 core +#extension GL_ARB_shading_language_420pack : enable include(`materialInterface.glsl') include(`geometryOut.glsl') -uniform sampler2D texture0; +layout(binding = 0) uniform sampler2D texture0; +layout(binding = 1) uniform usampler2DRect material; + +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); + vec4 textureColour = getTextureColour(Material, TexCoords); float clear = round(mix(textureColour.a, 1, Colour.a)); gPosition = vec4(FragPos, clear); gNormal = vec4(Normal, clear); diff --git a/gfx/gl/shaders/basicShader.vs b/gfx/gl/shaders/basicShader.vs index 4d648f3..e1701ed 100644 --- a/gfx/gl/shaders/basicShader.vs +++ b/gfx/gl/shaders/basicShader.vs @@ -15,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/landmassShader.vs b/gfx/gl/shaders/landmassShader.vs index cabe39f..0cc8153 100644 --- a/gfx/gl/shaders/landmassShader.vs +++ b/gfx/gl/shaders/landmassShader.vs @@ -12,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/materialInterface.glsl b/gfx/gl/shaders/materialInterface.glsl index 3e09c85..5735cf9 100644 --- a/gfx/gl/shaders/materialInterface.glsl +++ b/gfx/gl/shaders/materialInterface.glsl @@ -2,3 +2,6 @@ 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 index 2b244c1..dd84a10 100644 --- a/gfx/gl/shaders/meshIn.glsl +++ b/gfx/gl/shaders/meshIn.glsl @@ -2,3 +2,4 @@ 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; -- cgit v1.2.3 From f709098cd7a5fb7e88b96de18e609a2aebd56644 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:16:39 +0100 Subject: Add missing forward declaration --- game/scenary/foliage.h | 1 + 1 file changed, 1 insertion(+) 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 { Mesh::Ptr bodyMesh; -- cgit v1.2.3 From 1b97b7b4cb126c8b60ac1acbd7e72274f0ddf21f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:20:50 +0100 Subject: Use texture atlas for asset factory --- assetFactory/asset.h | 4 ++-- assetFactory/assetFactory.cpp | 26 ++++++++------------------ assetFactory/assetFactory.h | 4 ++-- assetFactory/assimp.cpp | 8 ++++---- assetFactory/factoryMesh.cpp | 3 ++- assetFactory/modelFactoryMesh.cpp | 1 + assetFactory/modelFactoryMesh.h | 2 ++ assetFactory/style.cpp | 9 ++++++++- 8 files changed, 29 insertions(+), 28 deletions(-) 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 -class Texture; +class TextureAtlas; class Asset : public Persistence::Persistable, public StdTypeDefs { public: - using TexturePtr = std::shared_ptr; + using TexturePtr = std::shared_ptr; 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 imageSizes; std::transform( @@ -112,18 +106,14 @@ AssetFactory::createTexutre() const }); const auto [layout, outSize] = TexturePacker {imageSizes}.pack(); // * create texture - texture = std::make_shared(outSize.x, outSize.y, TextureOptions {.wrap = GL_CLAMP_TO_EDGE}); + texture = std::make_shared(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(position->x), static_cast(position->y), - static_cast(size->x), static_cast(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 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> textureFragmentPositions; + mutable std::map> textureFragmentPositions; }; diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp index 0c6cb86..dd82105 100644 --- a/assetFactory/assimp.cpp +++ b/assetFactory/assimp.cpp @@ -64,11 +64,11 @@ public: }; const auto & m = *scene->mMaterials[amesh->mMaterialIndex]; - AssetFactory::TextureFragmentCoords tfc; + GLuint material {}; if (auto mf = Persistence::ParseBase::getShared("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; } } } 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 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(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 #include #include #include @@ -47,6 +48,7 @@ struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT smoothFaceProperty; + OpenMesh::FPropHandleT materialFaceProperty; OpenMesh::FPropHandleT nameFaceProperty; OpenMesh::HPropHandleT 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("assetFactory")) { - auto coords = mf->getTextureCoords(texture); + const auto material = mf->getMaterialIndex(texture); + mesh.property(mesh.materialFaceProperty, face) = material; + static constexpr std::array 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)) { -- cgit v1.2.3 From 2f5a53d9dfec54bd33609dbe5a0af44c565d8069 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 17:53:38 +0100 Subject: Adjust gl_FragDepth according to texel opacity --- gfx/gl/shaders/basicShader.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index ab5e58b..ff1c822 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -24,5 +24,6 @@ main() float clear = round(mix(textureColour.a, 1, Colour.a)); gPosition = vec4(FragPos, clear); gNormal = vec4(Normal, clear); + gl_FragDepth = mix(1.0, gl_FragCoord.z, clear); gAlbedoSpec = mix(textureColour, vec4(Colour.rgb, 1), Colour.a); } -- cgit v1.2.3 From 31e2bd9b5738498be3d13dc96cc78f48825a8601 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 18:02:28 +0100 Subject: Rename clear to opaque as its 1 for solid --- gfx/gl/shaders/basicShader.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gfx/gl/shaders/basicShader.fs b/gfx/gl/shaders/basicShader.fs index ff1c822..8a72e6d 100644 --- a/gfx/gl/shaders/basicShader.fs +++ b/gfx/gl/shaders/basicShader.fs @@ -21,9 +21,9 @@ void main() { vec4 textureColour = getTextureColour(Material, TexCoords); - float clear = round(mix(textureColour.a, 1, Colour.a)); - gPosition = vec4(FragPos, clear); - gNormal = vec4(Normal, clear); - gl_FragDepth = mix(1.0, gl_FragCoord.z, clear); + 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); } -- cgit v1.2.3 From c51c4c0ca3b19e47d6e75ce4be247a28d412a04c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 20:03:13 +0100 Subject: Fix typo in name SceneCPtr --- assetFactory/assimp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp index dd82105..878e7e7 100644 --- a/assetFactory/assimp.cpp +++ b/assetFactory/assimp.cpp @@ -29,12 +29,12 @@ operator!(const aiVector3t & v) (parent)->m##member, (parent)->mNum##member \ } -using ScemeCPtr = std::shared_ptr; +using SceneCPtr = std::shared_ptr; 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 @@ -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); -- cgit v1.2.3