diff --git a/CMakeLists.txt b/CMakeLists.txt index 86dec245..b16f4a0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,8 @@ else() target_link_directories(jGL PUBLIC include/vendored/VulkanSDK/Linux/Lib) endif() +target_compile_definitions(jGL PUBLIC MAX_SPRITE_BATCH_BOUND_TEXTURES=4) + if (ANDROID) target_compile_definitions(jGL PUBLIC GLSL_VERSION="300 es") target_link_libraries(jGL PUBLIC ${GLES-lib} ${Vulkan_LIBRARIES} shaderc_combined stduuid freetype glm) @@ -191,6 +193,7 @@ IF (TEST_SUITE) ) target_compile_definitions(glTests PUBLIC GLSL_VERSION="330") + target_compile_definitions(glTests PUBLIC MAX_SPRITE_BATCH_BOUND_TEXTURES=4) if (WINDOWS) target_link_libraries(glTests stduuid glew freetype glm ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES} glfw "winmm") @@ -256,6 +259,7 @@ IF (TEST_SUITE) endif() target_compile_definitions(vkTests PUBLIC GLSL_VERSION="330") + target_compile_definitions(vkTests PUBLIC MAX_SPRITE_BATCH_BOUND_TEXTURES=4) include(CTest) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/tests/cmake/) include(Catch) diff --git a/include/jGL/OpenGL/glSpriteRenderer.h b/include/jGL/OpenGL/glSpriteRenderer.h index efc8da37..bf6bc196 100644 --- a/include/jGL/OpenGL/glSpriteRenderer.h +++ b/include/jGL/OpenGL/glSpriteRenderer.h @@ -6,7 +6,11 @@ #include namespace jGL::GL -{ +{ + /** + * @brief Opengl implementation of SpriteRenderer + * + */ class glSpriteRenderer : public SpriteRenderer { public: diff --git a/include/jGL/spriteRenderer.h b/include/jGL/spriteRenderer.h index 4e4e332e..c2312822 100644 --- a/include/jGL/spriteRenderer.h +++ b/include/jGL/spriteRenderer.h @@ -1,5 +1,5 @@ -#ifndef SPRITERENDERER -#define SPRITERENDERER +#ifndef SPRITERENDERER_H +#define SPRITERENDERER_H #include #include @@ -12,36 +12,82 @@ namespace jGL { + /** + * @brief User name for a Sprite. + * @typedef SpriteId + * */ typedef std::string SpriteId; - /* - - Looks after sprites, and groups for batch rendering - - If two sprites have the same texture (inc. atlas) they will be stored - together for batched rendering - - */ + /** + * @brief Renders sprites in batches, with optional render priority. + * + * @remark Currently there are 4 texture slots loaded at once. + * @remark Keeping to 4 textures is most efficient (1 draw call), atlas textures are useful for this. + * @remark RenderPriority of Sprites may lead to inefficient batching across textures. + * Try to keep similar RenderPriority within the same texture/ group of 4 textures. + */ class SpriteRenderer { public: + + /** + * @brief Largest number of concurrent textures bound for one batch. + * + */ + static const uint8_t MAX_BATCH_BOUND_TEXTURES = MAX_SPRITE_BATCH_BOUND_TEXTURES; + /** + * @brief Construct a new SpriteRenderer. + * + * @param sizeHint Reserve some memory for this many Sprites. + */ SpriteRenderer(size_t sizeHint = 8) { sprites.reserve(sizeHint); - textures.reserve(MAX_TEXTURE_SLOTS); + textures.reserve(MAX_BATCH_BOUND_TEXTURES); } Sprite & getSprite(SpriteId id); const Transform & getTransform(SpriteId id) { return getSprite(id).transform; } - const TextureOffset getTextureOffset(SpriteId id) { return getSprite(id).getTextureOffset(); } + /** + * @brief Get a Sprites TextureOffset + * @remark In pixel units, see TextureOffset::getTextureOffset() + * + * @param id + * @param normalised Return in normalised units. + * @return const TextureOffset + */ + const TextureOffset getTextureOffset(SpriteId id, bool normalised = false) { return getSprite(id).getTextureOffset(normalised); } + + /** + * @brief Draw with overriding render priority and shader. + * + * @param shader An OpenGL Shader to draw all the Sprites with. + * @param ids Render priorities for the Sprites. + */ virtual void draw(std::shared_ptr shader, std::multimap ids) = 0; + + /** + * @brief Draw with overriding render priority. + * + * @param ids Render priorities for the Sprites. + */ virtual void draw(std::multimap ids) = 0; + /** + * @brief Draw with overriding shader. + * + * @param shader An OpenGL Shader to draw all the Sprites with. + */ virtual void draw(std::shared_ptr shader) { draw(shader, ids); } + + /** + * @brief Draw with default shader and priority. + * + */ virtual void draw() { draw(ids); } virtual void add(Sprite s, SpriteId id, RenderPriority priority = 0); @@ -86,7 +132,6 @@ namespace jGL protected: - static const uint8_t MAX_TEXTURE_SLOTS = 4; std::vector> textures; std::unordered_map sprites; @@ -99,4 +144,4 @@ namespace jGL }; } -#endif /* SPRITERENDERER */ +#endif /* SPRITERENDERER_H */ diff --git a/src/jGL/OpenGL/glSpriteRenderer.cpp b/src/jGL/OpenGL/glSpriteRenderer.cpp index 489073a3..2e535356 100644 --- a/src/jGL/OpenGL/glSpriteRenderer.cpp +++ b/src/jGL/OpenGL/glSpriteRenderer.cpp @@ -29,7 +29,7 @@ namespace jGL::GL bool newTexture = std::find(batch.begin(), batch.end(), textureIndex) == batch.end(); if (newTexture) { - if (batch.size() == MAX_TEXTURE_SLOTS) + if (batch.size() == MAX_BATCH_BOUND_TEXTURES) { batches.push_back(std::pair(i, batch)); batch.clear(); @@ -65,7 +65,7 @@ namespace jGL::GL while (b < batches.size()) { biter = batches[b].second.cbegin(); - for (unsigned slot = 0; slot < MAX_TEXTURE_SLOTS; slot++) + for (unsigned slot = 0; slot < MAX_BATCH_BOUND_TEXTURES; slot++) { if (biter == batches[b].second.cend()) { break; } textures[*biter]->bind(slot);