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