Skip to content

Commit

Permalink
Common OpenGL (uS0PRvYIn5) with batched drawing (bT8I6wx1S3), etc...
Browse files Browse the repository at this point in the history
Common OpenGL (uS0PRvYIn5) with batched drawing (bT8I6wx1S3),
Texture Atlas (TQGtvRw14q)
  • Loading branch information
Neko-Box-Coder committed Jul 8, 2023
1 parent 39696fa commit a4a48db
Show file tree
Hide file tree
Showing 42 changed files with 2,296 additions and 1,086 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ function(AddFilesToExecutables folderToExe binSubFolder ideFolderName targetsToL

# For now, skip custom graphics example if we are using SFML backend
STRING(TOLOWER ${ssGUI_MAIN_BACKEND} ssGUI_LOWER_MAIN_BACKEND)
if(CUR_NAME STREQUAL "CustomGraphicsExampleV2" AND NOT ssGUI_LOWER_MAIN_BACKEND MATCHES ".*opengl.*")
if((CUR_NAME STREQUAL "CustomGraphicsExampleV2" OR CUR_NAME STREQUAL "DynamicAtlasTest_Auto") AND NOT ssGUI_LOWER_MAIN_BACKEND MATCHES ".*opengl.*")
continue()
endif()

Expand Down Expand Up @@ -565,6 +565,8 @@ if(ssGUI_BUILD_TESTS)
"ssGUI_Test_NotoColorEmoji"
"${CMAKE_CURRENT_LIST_DIR}/Resources/sd.png"
"ssGUI_Test_sd"
"${CMAKE_CURRENT_LIST_DIR}/Resources/sdTestEdge.png"
"ssGUI_Test_sd_edge"
"${CMAKE_CURRENT_LIST_DIR}/Resources/NotoSans-Bold.ttf"
"ssGUI_Test_NotoSans_Bold")

Expand Down
95 changes: 95 additions & 0 deletions Include/ssGUI/Backend/DynamicImageAtlas.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#ifndef SSGUI_DYNAMIC_IMAGE_ATLAS_HPP
#define SSGUI_DYNAMIC_IMAGE_ATLAS_HPP

#include "ssGUI/HelperClasses/OutputStreamUtil.hpp"

#include "glm/vec2.hpp"
#include "glm/vec3.hpp"
#include <functional>
#include <map>
#include <unordered_map>

namespace ssGUI
{

namespace Backend
{

class DynamicImageAtlas
{
public:
struct ImageAtlasImageInfo
{
glm::ivec3 LocationInPixel;
glm::ivec2 ImageSizeInPixel;
bool HasMipmap;

inline friend std::ostream& operator<< (std::ostream& stream, const ImageAtlasImageInfo& other)
{
stream << SSGUI_OUTPUT_CLASS_NAME(ImageAtlasImageInfo)
<< SSGUI_OUTPUT_VAR(LocationInPixel)
<< SSGUI_OUTPUT_VAR(ImageSizeInPixel)
<< SSGUI_OUTPUT_LAST_VAR(HasMipmap);

return stream;
}
};

private:
typedef int ImageId;
typedef int CellsCount;

struct FreeCellsInfo
{
glm::ivec3 CellsPositionIndex;
glm::ivec2 CellsCountIn2D;
};

const glm::ivec2 CellSizeInPixel;
const glm::ivec2 AtlasSizeInPixel;

glm::ivec2 UsableSizeInPixel;
glm::ivec2 CellsCountInGrid;

ImageId NextImageId;
std::unordered_map<ImageId, ImageAtlasImageInfo> ImageInfos;
std::multimap<CellsCount, FreeCellsInfo> FreeCells;

std::function<bool(void)> OnRequestNewAtlasCallback;
int MaxAtlasIndex = 0;

glm::ivec2 GetAllocatedImageSize(ImageAtlasImageInfo info);

void OccupyCells(std::multimap<CellsCount, FreeCellsInfo>::iterator it, glm::ivec2 occupyCellsCountIn2D);

bool AreCellsOverlapped(FreeCellsInfo info);

void AddCells(CellsCount count, FreeCellsInfo info);

std::multimap<CellsCount, FreeCellsInfo>::iterator FindCells(glm::ivec2 cellsNeeded, int recursiveCount = 0);

bool RequestNewAtlas();

//TODO: Auto refragmenting cells

public:
DynamicImageAtlas(glm::ivec2 atlasSize, glm::ivec2 cellSize, std::function<bool(void)> newAtlasRequestCallback);

//Request Image
bool RequestImage(ImageAtlasImageInfo imgInfo, int& returnId);

//Remove Image
void RemoveImage(int id);

//Get Image Info
bool GetImageInfo(int id, ImageAtlasImageInfo& returnInfo);

void AddOnRequestNewAtlasCallback(std::function<bool(void)> callback);

glm::ivec2 GetAtlasSize();
};
}

}

#endif
82 changes: 9 additions & 73 deletions Include/ssGUI/Backend/Interfaces/BackendDrawingInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,6 @@

#include <iostream>

//From: https://stackoverflow.com/questions/20834838/using-tuple-in-unordered-map
// function has to live in the std namespace
// so that it is picked up by argument-dependent name lookup (ADL).
namespace std
{
namespace
{

// Code from boost
// Reciprocal of the golden ratio helps spread entropy
// and handles duplicates.
// See Mike Seymour in magic-numbers-in-boosthash-combine:
// https://stackoverflow.com/questions/4948780

template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
{
seed ^= hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}

// Recursive template code derived from Matthieu M.
template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
struct HashValueImpl
{
static void apply(size_t& seed, Tuple const& tuple)
{
HashValueImpl<Tuple, Index-1>::apply(seed, tuple);
hash_combine(seed, get<Index>(tuple));
}
};

template <class Tuple>
struct HashValueImpl<Tuple,0>
{
static void apply(size_t& seed, Tuple const& tuple)
{
hash_combine(seed, get<0>(tuple));
}
};
}

template <typename ... TT>
struct hash<std::tuple<TT...>>
{
size_t
operator()(std::tuple<TT...> const& tt) const
{
size_t seed = 0;
HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
return seed;
}

};
}

namespace ssGUI
{

Expand Down Expand Up @@ -94,8 +39,17 @@ namespace Backend

//function: DrawEntities
//Draws the entity based on what is set in the _properties_. Returns true if drawn successfully.
//Depending on the backend this, the entities might be drawn to internal buffer or
// drawn to back buffer directly. For OpenGL backends, it will be drawn to internal buffers.
//<DrawToBackBuffer> can be called to flush the internal buffer to be drawn on the back buffer.
//*Note that if you are not using <ssGUIManager>, you need to call <Render> at the end in order to render it*.
virtual bool DrawEntities(const std::vector<ssGUI::DrawingEntity>& entities) = 0;

//function: DrawToBackBuffer
//This flushes the internal buffer to the back buffer.
//Depending on the backend, this might have no effect as <DrawEntities> can draw to back buffer directly.
//This is also automatically called by <Render>.
virtual void DrawToBackBuffer() = 0;

//function: Render
//Renders every entity that are drawn to the <MainWindow>. This will automatically clear the back buffer.
Expand All @@ -121,24 +75,6 @@ namespace Backend
//You can use the returned handle to modify the cached image.
//If no cache is found, it will return nullptr.
virtual void* GetRawImageCacheHandle(ssGUI::Backend::BackendImageInterface* backendImage) = 0;

protected:
//TODO: Use float for character size
virtual bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::vec2>& texCoords,
const std::vector<glm::u8vec4>& colors,
const uint32_t character,
const ssGUI::Backend::BackendFontInterface& font,
int CharacterSize) = 0;

virtual bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::vec2>& texCoords,
const std::vector<glm::u8vec4>& colors,
const ssGUI::Backend::BackendImageInterface& image) = 0;


virtual bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::u8vec4>& colors) = 0;
};
inline BackendDrawingInterface::~BackendDrawingInterface(){} //Pure virtual destructor needs to be defined
}
Expand Down
22 changes: 4 additions & 18 deletions Include/ssGUI/Backend/Mocks/BackendDrawingMock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ namespace Backend
//See <BackendDrawingInterface::DrawEntities>
bool DrawEntities( const std::vector<ssGUI::DrawingEntity>& entities) override;

//function: DrawToBackBuffer
//See <BackendDrawingInterface::DrawToBackBuffer>
void DrawToBackBuffer() override;

//function: Render
//See <BackendDrawingInterface::Render>
void Render(glm::u8vec3 clearColor) override;
Expand All @@ -84,24 +88,6 @@ namespace Backend
//function: GetRawImageCacheHandle
//See <BackendDrawingInterface::GetRawImageCacheHandle>
void* GetRawImageCacheHandle(ssGUI::Backend::BackendImageInterface* backendImage) override;

//NOTE: These functions are not used in mock
protected:
bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::vec2>& texCoords,
const std::vector<glm::u8vec4>& colors,
const uint32_t character,
const ssGUI::Backend::BackendFontInterface& font,
int characterSize) override;

bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::vec2>& texCoords,
const std::vector<glm::u8vec4>& colors,
const ssGUI::Backend::BackendImageInterface& image) override;


bool DrawShape( const std::vector<glm::vec2>& vertices,
const std::vector<glm::u8vec4>& colors) override;
};
}

Expand Down
Loading

0 comments on commit a4a48db

Please sign in to comment.