Skip to content
Commits on Source (2)
...@@ -206,6 +206,7 @@ ...@@ -206,6 +206,7 @@
<ClInclude Include="include\Uniform.hpp" /> <ClInclude Include="include\Uniform.hpp" />
<ClInclude Include="include\ManagedPtr.hpp" /> <ClInclude Include="include\ManagedPtr.hpp" />
<ClInclude Include="include\Theme.hpp" /> <ClInclude Include="include\Theme.hpp" />
<ClInclude Include="include\Types.ipp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\lib\x64\SDL3.dll"> <None Include="..\lib\x64\SDL3.dll">
......
...@@ -146,6 +146,9 @@ ...@@ -146,6 +146,9 @@
<ClInclude Include="include\Theme.hpp"> <ClInclude Include="include\Theme.hpp">
<Filter>Header Files\GUI</Filter> <Filter>Header Files\GUI</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="include\Types.ipp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\lib\x64\SDL3.dll"> <None Include="..\lib\x64\SDL3.dll">
......
...@@ -5,26 +5,29 @@ ...@@ -5,26 +5,29 @@
template<typename T> template<typename T>
class DynamicBlockBuffer { class DynamicBlockBuffer {
size_t blockSize; size_t blockSize;
std::vector<T> data; std::vector<T> _data;
size_t expectedSize = 0; size_t expectedSize = 0;
public: public:
DynamicBlockBuffer(size_t blockSize = 1024) DynamicBlockBuffer(size_t blockSize = 1024)
: blockSize(blockSize) { : blockSize(blockSize) {
data.reserve(blockSize); _data.reserve(blockSize);
} }
DynamicBlockBuffer(const DynamicBlockBuffer&) = delete; DynamicBlockBuffer(const DynamicBlockBuffer&) = delete;
private: private:
void reserveApply(size_t knownIncrease) { void reserveApply(size_t knownIncrease) {
size_t requiredSize = data.size() + knownIncrease; size_t requiredSize = _data.size() + knownIncrease;
if (expectedSize > requiredSize) requiredSize = expectedSize; if (expectedSize > requiredSize) requiredSize = expectedSize;
size_t newReserveSize = ((requiredSize + blockSize - 1) / blockSize) * blockSize; size_t newReserveSize = ((requiredSize + blockSize - 1) / blockSize) * blockSize;
if (data.capacity() >= newReserveSize) return; if (_data.capacity() >= newReserveSize) return;
data.reserve(newReserveSize); _data.reserve(newReserveSize);
} }
public: public:
T* data() {
return _data.data();
}
void clear() { void clear() {
data.clear(); _data.clear();
expectedSize = 0; expectedSize = 0;
} }
void allocateAppend(size_t sizeIncrease) { void allocateAppend(size_t sizeIncrease) {
...@@ -32,34 +35,34 @@ public: ...@@ -32,34 +35,34 @@ public:
} }
void append(const T& newData) { void append(const T& newData) {
reserveApply(1); reserveApply(1);
data.push_back(newData); _data.push_back(newData);
} }
void append(const T* newData, size_t length) { void append(const T* newData, size_t length) {
reserveApply(length); reserveApply(length);
for (size_t i = 0; i < length; i++) for (size_t i = 0; i < length; i++)
data.push_back(newData[i]); _data.push_back(newData[i]);
} }
void append(const Span<const T>& newData) { void append(const Span<const T>& newData) {
reserveApply(newData.dataSize); reserveApply(newData.dataSize);
for (size_t i = 0; i < newData.dataSize; i++) for (size_t i = 0; i < newData.dataSize; i++)
data.push_back(newData[i]); _data.push_back(newData[i]);
} }
Span<T> appendGetEnd(size_t length) { Span<T> appendGetEnd(size_t length) {
size_t startIndex = data.size(); size_t startIndex = _data.size();
reserveApply(length); reserveApply(length);
data.resize(data.size() + length); _data.resize(_data.size() + length);
return Span<T>(&(data[startIndex]), length); return Span<T>(&(_data[startIndex]), length);
} }
T& operator[](size_t index) { T& operator[](size_t index) {
return data[index]; return _data[index];
} }
const T& operator[](size_t index) const { const T& operator[](size_t index) const {
return data[index]; return _data[index];
} }
Span<T> getSpanAll() { Span<T> getSpanAll() {
return Span<T>(data.data(), data.size()); return Span<T>(_data.data(), _data.size());
} }
size_t size() { size_t size() {
return data.size(); return _data.size();
} }
}; };
\ No newline at end of file
#include "FontRasterizer.hpp" #include "FontRasterizer.hpp"
#include <cassert> #include <cassert>
#include <utility>
#include <vector> #include <vector>
#include "utf8.h" #include "utf8.h"
#include <ft2build.h> #include <ft2build.h>
...@@ -12,11 +13,21 @@ Font::Text::Text(std::string text) { ...@@ -12,11 +13,21 @@ Font::Text::Text(std::string text) {
data.clear(); data.clear();
utf8::utf8to32(text.begin(), text.end(), back_inserter(data)); utf8::utf8to32(text.begin(), text.end(), back_inserter(data));
} }
#ifdef _DEBUG
//#define DEBUG_ATLAS
#endif
size_t Font::Text::size() const { size_t Font::Text::size() const {
#ifdef DEBUG_ATLAS
return data.size() + 1;
#else
return data.size(); return data.size();
#endif
} }
Font::Atlas::Atlas() { }
Font::Atlas::Atlas(Font* font, FontSize fontSize) Font::Atlas::Atlas(Font* font, FontSize fontSize)
: font(font), fontSize(fontSize) { : font(font), fontSize(fontSize) {
assert(font); assert(font);
...@@ -27,6 +38,27 @@ Font::Atlas::Atlas(Font* font, FontSize fontSize) ...@@ -27,6 +38,27 @@ Font::Atlas::Atlas(Font* font, FontSize fontSize)
for (char32_t unicode32 = 0; unicode32 < lookupArr.size(); unicode32++) for (char32_t unicode32 = 0; unicode32 < lookupArr.size(); unicode32++)
requestGlyphs.insert(unicode32); requestGlyphs.insert(unicode32);
} }
Font::Atlas::~Atlas() { }
Font::Atlas::Atlas(Atlas&& that) noexcept {
*this = std::forward<Atlas>(that);
}
Font::Atlas& Font::Atlas::operator=(Atlas&& that) noexcept {
font = that.font;
fontSize = that.fontSize;
glyphs = that.glyphs;
lookupArr = that.lookupArr;
lookupHash = that.lookupHash;
requestGlyphs = that.requestGlyphs;
skyline = that.skyline;
rawTexture = that.rawTexture;
textureSize = that.textureSize;
textureSizePow2 = that.textureSizePow2;
texture = that.texture;
lastUpdate = that.lastUpdate;
return *this;
}
void Font::Atlas::clearAndResize(uint8_t sizePow2) { void Font::Atlas::clearAndResize(uint8_t sizePow2) {
if (textureSizePow2 == sizePow2) if (textureSizePow2 == sizePow2)
goto ONLY_CLEAR; goto ONLY_CLEAR;
...@@ -87,7 +119,7 @@ void Font::Atlas::insertGlyphRaw(const Glyph& glyph, Span<uint8_t> data) { ...@@ -87,7 +119,7 @@ void Font::Atlas::insertGlyphRaw(const Glyph& glyph, Span<uint8_t> data) {
for (size_t Ixy = 0, Oy = glyph.x + glyph.y * textureSize, hi = 0; for (size_t Ixy = 0, Oy = glyph.x + glyph.y * textureSize, hi = 0;
hi < height; hi++, Oy += textureSize) hi < height; hi++, Oy += textureSize)
for (size_t Oxy = Oy, wi = 0; wi < width; wi++, Ixy++, Oxy++) for (size_t Oxy = Oy, wi = 0; wi < width; wi++, Ixy++, Oxy++)
rawTexture[Oxy] = data.data[Ixy]; rawTexture[Oxy] = data.data[Ixy];//(Oxy & 2 ? 255 : 0);
} }
void Font::Atlas::insertGlyph(const Glyph& glyphInput, Span<uint8_t> data) { void Font::Atlas::insertGlyph(const Glyph& glyphInput, Span<uint8_t> data) {
Glyph glyph = glyphInput; Glyph glyph = glyphInput;
...@@ -190,23 +222,35 @@ size_t Font::Atlas::generateInstances(Rect pos, const Text& text, Span<Instance> ...@@ -190,23 +222,35 @@ size_t Font::Atlas::generateInstances(Rect pos, const Text& text, Span<Instance>
Vec2 currentPos = Vec2(pos.x, pos.y); Vec2 currentPos = Vec2(pos.x, pos.y);
size_t index = 0; size_t index = 0;
assert(buffer.size() >= text.size()); assert(buffer.size() >= text.size());
RectU::Position startY = (RectU::Position)currentPos.y + text.size();
for (char32_t unicode32 : text.data) { for (char32_t unicode32 : text.data) {
Glyph glyph = getGlyph(unicode32); Glyph glyph = getGlyph(unicode32);
buffer[index] = Instance(InstanceDataGlyph{ buffer[index] = Instance(InstanceDataGlyph{
.rect = Rect( .rect = RectU(
currentPos.x + glyph.ox, currentPos.y + glyph.oy, glyph.w, glyph.h currentPos.x + glyph.ox, startY - glyph.oy, glyph.w, glyph.h
), ),
.color = text.color, .color = text.color,
.atlas = Rect( .atlas = RectU(
glyph.x, glyph.y, glyph.w, glyph.h glyph.x, glyph.y, glyph.w, glyph.h
) ).scaleNormalize(textureSize)
}, &shaderFlat, 0); }, &shaderGlyph, 1);
buffer[index].uniforms.push_back(ManagedPtr<Uniform>(&texture)); buffer[index].uniforms = Span<Uniform*>(uniforms);
if (glyph.w == 0 || glyph.h == 0) if (glyph.w == 0 || glyph.h == 0)
buffer[index].skip = true; buffer[index].skip = true;
index++; index++;
currentPos.x += glyph.ax; currentPos.x += glyph.ax;
} }
#ifdef DEBUG_ATLAS
buffer[index] = Instance(InstanceDataGlyph{
.rect = (RectU)pos,
.color = text.color,
.atlas = RectU(
0,0,textureSize,textureSize
).scaleNormalize(textureSize)
}, &shaderGlyph, 0);
buffer[index++].uniforms = Span<Uniform*>(uniforms);
#endif
return index; return index;
} }
Font::FontSize Font::Atlas::getFontSize() const { Font::FontSize Font::Atlas::getFontSize() const {
...@@ -224,7 +268,7 @@ Font::Atlas* Font::getAtlas(FontSize fontSize) { ...@@ -224,7 +268,7 @@ Font::Atlas* Font::getAtlas(FontSize fontSize) {
for (Atlas& atlas : atlases) for (Atlas& atlas : atlases)
if (atlas.getFontSize() == fontSize) return &atlas; if (atlas.getFontSize() == fontSize) return &atlas;
size_t newIndex = atlases.size(); size_t newIndex = atlases.size();
atlases.push_back(Atlas(this, fontSize)); atlases.push_back(std::move(Atlas(this, fontSize)));
return &(atlases[newIndex]); return &(atlases[newIndex]);
} }
......
...@@ -58,15 +58,27 @@ public: ...@@ -58,15 +58,27 @@ public:
TextureSize textureSize; TextureSize textureSize;
uint8_t textureSizePow2 = -1; uint8_t textureSizePow2 = -1;
UniformTexture8 texture{ "atlasTexture" }; UniformTexture8 texture{ "atlasTexture" };
Uniform* uniforms[1]{
&texture
};
uint16_t lastUpdate = 0; uint16_t lastUpdate = 0;
Atlas() = delete;
Atlas(Font* font, FontSize fontSize); Atlas(Font* font, FontSize fontSize);
void clearAndResize(uint8_t size); void clearAndResize(uint8_t size);
void upscaleRawTexture(); void upscaleRawTexture();
void insertGlyphRaw(const Glyph& glyph, Span<uint8_t> data); void insertGlyphRaw(const Glyph& glyph, Span<uint8_t> data);
void insertGlyph(const Glyph& glyph, Span<uint8_t> data); void insertGlyph(const Glyph& glyph, Span<uint8_t> data);
public: public:
Atlas();
~Atlas();
Atlas(Atlas&& that) noexcept;
Atlas& operator=(Atlas&& that) noexcept;
Atlas(const Atlas& that) = delete;
Atlas& operator=(const Atlas& that) = delete;
bool generateGlyphs(); bool generateGlyphs();
Glyph getGlyph(char32_t unicode32); Glyph getGlyph(char32_t unicode32);
size_t generateInstances(Rect pos, const Text& text, Span<Instance> buffer); size_t generateInstances(Rect pos, const Text& text, Span<Instance> buffer);
......
...@@ -14,6 +14,8 @@ constexpr const uint8_t DIRTY = 2; ...@@ -14,6 +14,8 @@ constexpr const uint8_t DIRTY = 2;
class GUIElement { class GUIElement {
public: public:
uint8_t dirty = DIRTY; uint8_t dirty = DIRTY;
bool updateOverlaps = false;
Depth depth;
bool hovering = false; bool hovering = false;
bool hasOnRender = false; bool hasOnRender = false;
Rect position, boundsCache[2] = { }; Rect position, boundsCache[2] = { };
...@@ -28,6 +30,8 @@ public: ...@@ -28,6 +30,8 @@ public:
virtual bool handleWheel(Vec2 pos, Vec2 scroll, uint8_t index) = 0; virtual bool handleWheel(Vec2 pos, Vec2 scroll, uint8_t index) = 0;
virtual bool isActive(); virtual bool isActive();
virtual bool onRender(); virtual bool onRender();
void setDepth(Depth depth);
void clearDepth();
protected: protected:
virtual const Rect calculateBounds(bool isRender); virtual const Rect calculateBounds(bool isRender);
enum State : uint8_t { enum State : uint8_t {
......
...@@ -17,7 +17,7 @@ public: ...@@ -17,7 +17,7 @@ public:
ContainerScrollElement scroll0{Rect(300, 20, 300, 300), Vec2(16, 32), 1024, true}; ContainerScrollElement scroll0{Rect(300, 20, 300, 300), Vec2(16, 32), 1024, true};
SliderElement slider1{Rect{20, 10, 256, 16}, Vec2{16, 32}, false}; SliderElement slider1{Rect{20, 10, 256, 16}, Vec2{16, 32}, false};
TextElement text0{Rect(30,30,300,32), Font::Default, 12, Font::Text("Hello world!")}; TextElement text0{Rect(30,30,500,32), Font::Default, 12, Font::Text("Hello world!")};
GUIMain(); GUIMain();
......
...@@ -13,26 +13,27 @@ struct AShader; ...@@ -13,26 +13,27 @@ struct AShader;
template<typename T> class ShaderInstanced; template<typename T> class ShaderInstanced;
struct Instance { struct Instance {
bool skip = false; bool skip = false;
size_t depth = 0; Depth depth = 0;
AShader* shader; AShader* shader;
Span<Uniform*> uniforms;
ManagedPtr<> data{ }; ManagedPtr<> data{ };
std::vector<ManagedPtr<Uniform>> uniforms{ }; //std::vector<ManagedPtr<Uniform>> uniforms{ };
Instance(); Instance();
template<typename I> Instance(I* data, AShader* shader, size_t depth = 0) template<typename I> Instance(I* data, AShader* shader, Depth depth = 0)
: data(data), shader(shader), depth(depth) { }; : data(data), shader(shader), depth(depth) { };
template<typename I> Instance(const I& data, AShader* shader, size_t depth = 0) template<typename I> Instance(const I& data, AShader* shader, Depth depth = 0)
: data(data), shader(shader), depth(depth) { }; : data(data), shader(shader), depth(depth) { };
}; };
struct InstanceDataFlat { struct InstanceDataFlat {
static void constructBuffer(ShaderInstanced<InstanceDataFlat>* shader); static void constructBuffer(ShaderInstanced<InstanceDataFlat>* shader);
Rect rect; RectU rect;
Color color; Color color;
}; };
struct InstanceDataLines { struct InstanceDataLines {
static void constructBuffer(ShaderInstanced<InstanceDataLines>* shader); static void constructBuffer(ShaderInstanced<InstanceDataLines>* shader);
Rect rect; RectU rect;
Color color; Color color;
Vec2 distance; Vec2 distance;
uint16_t size; uint16_t size;
...@@ -40,7 +41,7 @@ struct InstanceDataLines { ...@@ -40,7 +41,7 @@ struct InstanceDataLines {
}; };
struct InstanceDataTriangle { struct InstanceDataTriangle {
static void constructBuffer(ShaderInstanced<InstanceDataTriangle>* shader); static void constructBuffer(ShaderInstanced<InstanceDataTriangle>* shader);
Rect rect; RectU rect;
Color color; Color color;
uint16_t direction; uint16_t direction;
constexpr static const uint16_t FRACT8 = ((uint16_t) - 1) / 8; constexpr static const uint16_t FRACT8 = ((uint16_t) - 1) / 8;
...@@ -55,9 +56,9 @@ struct InstanceDataTriangle { ...@@ -55,9 +56,9 @@ struct InstanceDataTriangle {
}; };
struct InstanceDataGlyph { struct InstanceDataGlyph {
static void constructBuffer(ShaderInstanced<InstanceDataGlyph>* shader); static void constructBuffer(ShaderInstanced<InstanceDataGlyph>* shader);
Rect rect; RectU rect;
Color color; Color color;
Rect atlas; RectU atlas;
}; };
#include "Shader.hpp" #include "Shader.hpp"
\ No newline at end of file
...@@ -14,10 +14,12 @@ class RenderDispatcher { ...@@ -14,10 +14,12 @@ class RenderDispatcher {
static Rect nestedClip; static Rect nestedClip;
struct {
UniformMat4* projection = new UniformMat4("projection"); UniformMat4 projection{"projection"};
UniformUI32* time = new UniformUI32("time"); UniformUI32 time{"time"};
} commonUniforms; Uniform* commonUniforms[2]{
&projection, &time
};
ObjectBuffer quadBuffer; ObjectBuffer quadBuffer;
Vec2 offset; Vec2 offset;
......
...@@ -11,18 +11,24 @@ template<typename T> class ShaderInstanced; ...@@ -11,18 +11,24 @@ template<typename T> class ShaderInstanced;
#include "GLHeaders.hpp" #include "GLHeaders.hpp"
#include "Uniform.hpp" #include "Uniform.hpp"
#include "Instance.hpp" #include "Instance.hpp"
#include "DynamicBlockBuffer.hpp"
struct ObjectBuffer { struct ObjectBuffer {
struct Shader { struct Shader {
GLuint VAO = 0, instanceVBO; GLuint VAO = 0, instanceVBO;
void resizeBuffer(AShader* shader, size_t newBufferSize);
void upscaleBuffer(AShader* shader, size_t minBufferSize);
private:
size_t bufferSize = 0;
}; };
void (*constructVBOAttribs)(GLuint VBO); void (*constructVBOAttribs)(GLuint VBO);
std::unordered_map<GLuint, Shader> shaders; std::unordered_map<GLuint, Shader> shaders;
std::pair<GLuint, Shader> lastFound{-1, Shader{ }}; std::pair<GLuint, Shader*> lastFound{-1, nullptr};
GLsizei size; GLsizei size;
GLuint VBO = 0; GLuint VBO = 0;
Shader getShaderBuffers(AShader* shader); Shader* getShaderBuffers(AShader* shader);
template<size_t SIZE> void setMeshIndices(const uint32_t(&data)[SIZE]); template<size_t SIZE> void setMeshIndices(const uint32_t(&data)[SIZE]);
void setMeshIndices(const uint32_t* data, size_t size); void setMeshIndices(const uint32_t* data, size_t size);
}; };
...@@ -46,7 +52,6 @@ struct AShader { ...@@ -46,7 +52,6 @@ struct AShader {
void setProgram(GLuint program); void setProgram(GLuint program);
virtual void setUniforms(Span<Uniform*> uniforms) = 0; virtual void setUniforms(Span<Uniform*> uniforms) = 0;
virtual void renderInstances(ObjectBuffer* obj, Span<Instance> data) = 0; virtual void renderInstances(ObjectBuffer* obj, Span<Instance> data) = 0;
virtual size_t getInstanceMaxCount() = 0;
virtual size_t getInstanceSize() = 0; virtual size_t getInstanceSize() = 0;
private: private:
virtual void onSetProgram() = 0; virtual void onSetProgram() = 0;
...@@ -62,14 +67,14 @@ template<typename T> class ShaderInstanced : public AShader { ...@@ -62,14 +67,14 @@ template<typename T> class ShaderInstanced : public AShader {
static_assert(has_constructBuffer<T>::value, "T must have static void constructBuffer(Shader<T>*)"); static_assert(has_constructBuffer<T>::value, "T must have static void constructBuffer(Shader<T>*)");
public: public:
std::vector<T> instanceCache; DynamicBlockBuffer<T> instanceCache{ };
//std::vector<T> instanceCache;
ShaderInstanced(size_t instanceCacheSize = 16); ShaderInstanced(size_t instanceCacheSize = 16);
virtual void setUniforms(Span<Uniform*> uniforms); virtual void setUniforms(Span<Uniform*> uniforms);
virtual void renderInstances(ObjectBuffer* obj, Span<Instance> data); virtual void renderInstances(ObjectBuffer* obj, Span<Instance> data);
virtual void renderInstances(ObjectBuffer* obj, Span<T> dataRaw); virtual void renderInstances(ObjectBuffer* obj, Span<T> dataRaw);
virtual size_t getInstanceMaxCount();
virtual size_t getInstanceSize(); virtual size_t getInstanceSize();
template<typename F> void addField(F T::* memberPtr, const char* name, GLenum type, size_t count, bool varying = true, bool normalized = false); template<typename F> void addField(F T::* memberPtr, const char* name, GLenum type, size_t count, bool varying = true, bool normalized = false);
private: private:
......
...@@ -20,22 +20,25 @@ template<typename T> void ShaderInstanced<T>::setUniforms(Span<Uniform*> uniform ...@@ -20,22 +20,25 @@ template<typename T> void ShaderInstanced<T>::setUniforms(Span<Uniform*> uniform
} }
template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb, Span<Instance> data) { template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb, Span<Instance> data) {
ObjectBuffer::Shader obj = objb->getShaderBuffers(this); ObjectBuffer::Shader* obj = objb->getShaderBuffers(this);
assert(obj.VAO != 0); assert(obj->VAO != 0);
assert(obj.instanceVBO != 0); assert(obj->instanceVBO != 0);
instanceCache.clear();
instanceCache.allocateAppend(data.size());
for (size_t i = 0, im = data.size(); i < im; i++) { for (size_t i = 0, im = data.size(); i < im; i++) {
const Instance& inst = data[i]; const Instance& inst = data[i];
const T* data = inst.data.pointerAs<const T>(); const T* data = inst.data.pointerAs<const T>();
instanceCache[i] = *data; instanceCache.append(*data);
} }
obj->resizeBuffer(this, instanceCache.size());
glUseProgram(program); glUseProgram(program);
CheckGLError("glUseProgram"); CheckGLError("glUseProgram");
glBindVertexArray(obj.VAO); glBindVertexArray(obj->VAO);
CheckGLError("glBindVertexArray"); CheckGLError("glBindVertexArray");
glBindBuffer(GL_ARRAY_BUFFER, obj.instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, obj->instanceVBO);
CheckGLError("glBindBuffer"); CheckGLError("glBindBuffer");
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(T) * data.size(), instanceCache.data()); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(T) * data.size(), instanceCache.data());
CheckGLError("glBufferSubData"); CheckGLError("glBufferSubData");
...@@ -44,16 +47,17 @@ template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb ...@@ -44,16 +47,17 @@ template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb
CheckGLError("glDrawArraysInstanced"); CheckGLError("glDrawArraysInstanced");
} }
template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb, Span<T> data) { template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb, Span<T> data) {
ObjectBuffer::Shader obj = objb->getShaderBuffers(this); ObjectBuffer::Shader* obj = objb->getShaderBuffers(this);
assert(obj.VAO != 0); assert(obj->VAO != 0);
assert(obj.instanceVBO != 0); assert(obj->instanceVBO != 0);
obj->upscaleBuffer(this, data.size());
glUseProgram(program); glUseProgram(program);
CheckGLError("glUseProgram"); CheckGLError("glUseProgram");
glBindVertexArray(obj.VAO); glBindVertexArray(obj->VAO);
CheckGLError("glBindVertexArray"); CheckGLError("glBindVertexArray");
glBindBuffer(GL_ARRAY_BUFFER, obj.instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, obj->instanceVBO);
CheckGLError("glBindBuffer"); CheckGLError("glBindBuffer");
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(T) * data.size(), data.data); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(T) * data.size(), data.data);
CheckGLError("glBufferSubData"); CheckGLError("glBufferSubData");
...@@ -62,10 +66,6 @@ template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb ...@@ -62,10 +66,6 @@ template<typename T> void ShaderInstanced<T>::renderInstances(ObjectBuffer* objb
CheckGLError("glDrawArraysInstanced"); CheckGLError("glDrawArraysInstanced");
} }
template<typename T> size_t ShaderInstanced<T>::getInstanceMaxCount() {
return instanceCache.size();
}
template<typename T> size_t ShaderInstanced<T>::getInstanceSize() { template<typename T> size_t ShaderInstanced<T>::getInstanceSize() {
return sizeof(T); return sizeof(T);
} }
...@@ -75,7 +75,7 @@ inline void ShaderInstanced<T>::addField(F T::* memberPtr, const char* name, GLe ...@@ -75,7 +75,7 @@ inline void ShaderInstanced<T>::addField(F T::* memberPtr, const char* name, GLe
Field newField; Field newField;
newField.index = glGetAttribLocation(program, name); newField.index = glGetAttribLocation(program, name);
if (newField.index < 0) { if (newField.index < 0) {
SDL_Log("Shader field '%s' not found", name); SDL_Log("Shader field '%s' not found in %s", name, this->name);
return; return;
} }
newField.varying = varying; newField.varying = varying;
......
...@@ -4,16 +4,28 @@ ...@@ -4,16 +4,28 @@
typedef int16_t Position; typedef int16_t Position;
typedef uint16_t Distance; typedef uint16_t Distance;
typedef uint16_t Depth;
struct Vec2; struct Vec2;
struct Rect { template<typename P, typename D>
Position x, y; struct RectT {
Distance w = 0, h = 0; typedef P Position;
Rect flipAxies() const; typedef D Distance;
P x, y;
D w = 0, h = 0;
RectT<P, D> flipAxies() const;
bool inside(Vec2 point) const; bool inside(Vec2 point) const;
Rect clip(const Rect& that) const; bool overlaps(const RectT<P, D>& that) const;
Rect combine(const Rect& that) const; RectT<P, D> clip(const RectT<P, D>& that) const;
RectT<P, D> combine(const RectT<P, D>& that) const;
void debugPrint() const; void debugPrint() const;
RectT<P, D> scaleNormalize(D scale) const;
template<typename T>
explicit operator T();
}; };
typedef RectT<Position, Distance> Rect;
typedef RectT<uint16_t, uint16_t> RectU;
struct Vec2 { struct Vec2 {
Position x, y; Position x, y;
Vec2 flipAxies(); Vec2 flipAxies();
...@@ -52,3 +64,5 @@ enum class MouseButton : uint8_t { ...@@ -52,3 +64,5 @@ enum class MouseButton : uint8_t {
enum class MouseInput : uint8_t { enum class MouseInput : uint8_t {
PRESS, MOVE, RELEASE, EXIT PRESS, MOVE, RELEASE, EXIT
}; };
#include "Types.ipp"
#include <iostream>
#include "Types.hpp"
template<typename P, typename D>
RectT<P, D> RectT<P, D>::flipAxies() const {
return Rect{x, y, h, w};
}
template<typename P, typename D>
bool RectT<P, D>::inside(Vec2 point) const {
return x <= point.x && x + w >= point.x
&& y <= point.y && y + h >= point.y;
}
template<typename P, typename D>
bool RectT<P, D>::overlaps(const RectT<P, D>& that) const {
if (x + w <= that.x) return false;
if (that.x + that.w <= x) return false;
if (y + h <= that.y) return false;
if (that.y + that.h <= y) return false;
return true;
}
template<typename P, typename D>
RectT<P, D> RectT<P, D>::clip(const RectT<P, D>& that) const {
RectT<P, D> newRect = *this;
int32_t diff;
diff = that.x - newRect.x;
if (diff > newRect.w) return RectT<P, D>();
if (diff > 0) {
newRect.x += diff;
newRect.w -= diff;
}
diff = (newRect.x + newRect.w) - (that.x + that.w);
if (diff > newRect.w) return RectT<P, D>();
if (diff > 0) {
newRect.w -= diff;
}
diff = that.y - newRect.y;
if (diff > newRect.h) return RectT<P, D>();
if (diff > 0) {
newRect.y += diff;
newRect.h -= diff;
}
diff = (newRect.y + newRect.h) - (that.y + that.h);
if (diff > newRect.h) return RectT<P, D>();
if (diff > 0) {
newRect.y -= diff;
}
return newRect;
}
template<typename P, typename D>
RectT<P, D> RectT<P, D>::combine(const RectT<P, D>& that) const {
RectT<P, D> newRect = *this;
int32_t diff;
diff = that.x - newRect.x;
if (diff > 0) {
newRect.x -= diff;
newRect.w += diff;
}
diff = (newRect.x + newRect.w) - (that.x + that.w);
if (diff > 0) {
newRect.w += diff;
}
diff = that.y - newRect.y;
if (diff > 0) {
newRect.y -= diff;
newRect.h += diff;
}
diff = (newRect.y + newRect.h) - (that.y + that.h);
if (diff > 0) {
newRect.y += diff;
}
return newRect;
}
template<typename P, typename D>
void RectT<P, D>::debugPrint() const {
std::cout << "Rect(" << x << ", " << y << ", " << w << ", " << h << ")";
}
template<typename P, typename D>
RectT<P, D> RectT<P, D>::scaleNormalize(D scale) const {
return RectT<P, D>(
(P)((D)-1 * (uint64_t)x / scale),
(P)((D)-1 * (uint64_t)y / scale),
(D)((D)-1 * (uint64_t)w / scale),
(D)((D)-1 * (uint64_t)h / scale)
);
}
template<typename P, typename D>
template<typename T>
RectT<P, D>::operator T() {
typename T::Position newX = (typename T::Position)x;
typename T::Position newY = (typename T::Position)y;
typename T::Distance newW = (typename T::Distance)w;
typename T::Distance newH = (typename T::Distance)h;
return T{ newX, newY, newW, newH };
}
\ No newline at end of file
...@@ -25,6 +25,7 @@ struct UniformUI32 : public Uniform { ...@@ -25,6 +25,7 @@ struct UniformUI32 : public Uniform {
UniformUI32(const char* name, uint32_t value); UniformUI32(const char* name, uint32_t value);
}; };
struct UniformTexture8 : public Uniform { struct UniformTexture8 : public Uniform {
virtual void applyLoc(GLint loc);
uint32_t width = 0, height = 0; uint32_t width = 0, height = 0;
uint8_t index; uint8_t index;
...@@ -32,7 +33,6 @@ struct UniformTexture8 : public Uniform { ...@@ -32,7 +33,6 @@ struct UniformTexture8 : public Uniform {
UniformTexture8(const UniformTexture8& that); UniformTexture8(const UniformTexture8& that);
UniformTexture8(const char* name, uint8_t index = 0); UniformTexture8(const char* name, uint8_t index = 0);
~UniformTexture8(); ~UniformTexture8();
virtual void applyLoc(GLint loc);
void set(const std::vector<uint8_t>& data, uint32_t width, uint32_t height); void set(const std::vector<uint8_t>& data, uint32_t width, uint32_t height);
private: private:
GLuint tex = GL_NONE; GLuint tex = GL_NONE;
......
#version 330 core #version 330 core
uniform sampler2D glyphTexture; uniform sampler2D atlasTexture;
flat in vec4 fragColor; flat in vec4 fragColor;
flat in vec2 fragUV; in vec2 fragUV;
out vec4 finalColor; out vec4 finalColor;
void main() { void main() {
finalColor = fragColor * texture2D(glyphTexture, fragUV).r; float text = texture(atlasTexture, fragUV).r;
finalColor = fragColor * text;
//finalColor = vec4(fract(fragUV.xy * 8.0) * 0.5 + text * 0.5, text,1);
} }
\ No newline at end of file
...@@ -9,11 +9,12 @@ layout(location = 2) in vec4 rectColor; ...@@ -9,11 +9,12 @@ layout(location = 2) in vec4 rectColor;
layout(location = 3) in vec4 atlasXYWH; layout(location = 3) in vec4 atlasXYWH;
flat out vec4 fragColor; flat out vec4 fragColor;
flat out vec2 fragUV; out vec2 fragUV;
const vec2 pos[4] = vec2[4](vec2(0, 1), vec2(0, 0), vec2(1, 0), vec2(1, 1)); const vec2 pos[4] = vec2[4](vec2(0, 1), vec2(0, 0), vec2(1, 0), vec2(1, 1));
void main() { void main() {
fragUV = atlasXYWH.xy + atlasXYWH.zw * pos[vertexIndex]; fragUV = atlasXYWH.xy + atlasXYWH.zw * pos[vertexIndex];
//fragUV = pos[vertexIndex];
fragColor = rectColor; fragColor = rectColor;
vec2 vertexPos = pos[vertexIndex] * rectXYWH.zw + rectXYWH.xy; vec2 vertexPos = pos[vertexIndex] * rectXYWH.zw + rectXYWH.xy;
gl_Position = projection * vec4(vertexPos.x, vertexPos.y, 0.0, 1.0); gl_Position = projection * vec4(vertexPos.x, vertexPos.y, 0.0, 1.0);
......
...@@ -16,14 +16,14 @@ size_t ContainerScrollElement::getInstanceCount() { ...@@ -16,14 +16,14 @@ size_t ContainerScrollElement::getInstanceCount() {
void ContainerScrollElement::populateInstances(Span<Instance> buffer) { void ContainerScrollElement::populateInstances(Span<Instance> buffer) {
setChildrenDirty(); setChildrenDirty();
background.rect = position; background.rect = (RectU)position;
background.color = theme.background[1]; background.color = theme.background[1];
scrollbar.rect = Rect( scrollbar.rect = RectU(
position.x + position.w - handleSize.x, position.y, position.x + position.w - handleSize.x, position.y,
handleSize.x, position.h); handleSize.x, position.h);
scrollbar.color = theme.background[2]; scrollbar.color = theme.background[2];
handle.rect = calculateHandleBounds(0); handle.rect = (RectU)calculateHandleBounds(0);
handle.color = theme.interactableArr[inputState]; handle.color = theme.interactableArr[inputState];
buffer.copyFrom(instances); buffer.copyFrom(instances);
......
...@@ -9,6 +9,15 @@ bool GUIElement::onRender() { ...@@ -9,6 +9,15 @@ bool GUIElement::onRender() {
return false; return false;
} }
void GUIElement::setDepth(Depth depth) {
this->depth = depth;
this->updateOverlaps = true;
}
void GUIElement::clearDepth() {
this->updateOverlaps = false;
}
const Rect GUIElement::calculateBounds(bool isRender) { const Rect GUIElement::calculateBounds(bool isRender) {
return position; return position;
} }
......
...@@ -20,6 +20,9 @@ GUIMain::GUIMain() { ...@@ -20,6 +20,9 @@ GUIMain::GUIMain() {
slider1.maxValue = 32; slider1.maxValue = 32;
slider1.valueStep = 4.0; slider1.valueStep = 4.0;
slider1.fillValue = true; slider1.fillValue = true;
text0.setDepth(0);
scroll0.setDepth(32);
} }
......
...@@ -27,5 +27,5 @@ void InstanceDataTriangle::constructBuffer(ShaderInstanced<InstanceDataTriangle> ...@@ -27,5 +27,5 @@ void InstanceDataTriangle::constructBuffer(ShaderInstanced<InstanceDataTriangle>
void InstanceDataGlyph::constructBuffer(ShaderInstanced<InstanceDataGlyph>* shader) { void InstanceDataGlyph::constructBuffer(ShaderInstanced<InstanceDataGlyph>* shader) {
shader->addField(&InstanceDataGlyph::rect, "rectXYWH", GL_UNSIGNED_SHORT, 4); shader->addField(&InstanceDataGlyph::rect, "rectXYWH", GL_UNSIGNED_SHORT, 4);
shader->addField(&InstanceDataGlyph::color, "rectColor", GL_UNSIGNED_BYTE, 4, true, true); shader->addField(&InstanceDataGlyph::color, "rectColor", GL_UNSIGNED_BYTE, 4, true, true);
shader->addField(&InstanceDataGlyph::atlas, "atlasXYWH", GL_UNSIGNED_SHORT, 4); shader->addField(&InstanceDataGlyph::atlas, "atlasXYWH", GL_UNSIGNED_SHORT, 4, true, true);
} }