Skip to content
GitLab
Explore
Sign in
Register
Commits on Source (2)
Text rendering!
· 3678622f
Arcane Blackwood
authored
Sep 06, 2025
3678622f
Overlap partial fix
· b85ec35b
Arcane Blackwood
authored
Sep 06, 2025
b85ec35b
Show whitespace changes
Inline
Side-by-side
SDLTest/SDLTest.vcxproj
View file @
b85ec35b
...
...
@@ -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"
>
...
...
SDLTest/SDLTest.vcxproj.filters
View file @
b85ec35b
...
...
@@ -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"
>
...
...
SDLTest/include/DynamicBlockBuffer.hpp
View file @
b85ec35b
...
...
@@ -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
SDLTest/include/FontRasterizer.cpp
View file @
b85ec35b
#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
=
Rect
U
(
currentPos
.
x
+
glyph
.
ox
,
startY
-
glyph
.
oy
,
glyph
.
w
,
glyph
.
h
),
.
color
=
text
.
color
,
.
atlas
=
Rect
(
.
atlas
=
Rect
U
(
glyph
.
x
,
glyph
.
y
,
glyph
.
w
,
glyph
.
h
)
},
&
shader
Flat
,
0
);
buffer
[
index
].
uniforms
.
push_back
(
ManagedPtr
<
Uniform
>
(
&
texture
)
);
)
.
scaleNormalize
(
textureSize
)
},
&
shader
Glyph
,
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
]);
}
...
...
SDLTest/include/FontRasterizer.hpp
View file @
b85ec35b
...
...
@@ -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
);
...
...
SDLTest/include/GUIElement.hpp
View file @
b85ec35b
...
...
@@ -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
{
...
...
SDLTest/include/GUIMain.hpp
View file @
b85ec35b
...
...
@@ -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
,
3
00
,
32
),
Font
::
Default
,
12
,
Font
::
Text
(
"Hello world!"
)};
TextElement
text0
{
Rect
(
30
,
30
,
5
00
,
32
),
Font
::
Default
,
12
,
Font
::
Text
(
"Hello world!"
)};
GUIMain
();
...
...
SDLTest/include/Instance.hpp
View file @
b85ec35b
...
...
@@ -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
;
Rect
U
rect
;
Color
color
;
};
struct
InstanceDataLines
{
static
void
constructBuffer
(
ShaderInstanced
<
InstanceDataLines
>*
shader
);
Rect
rect
;
Rect
U
rect
;
Color
color
;
Vec2
distance
;
uint16_t
size
;
...
...
@@ -40,7 +41,7 @@ struct InstanceDataLines {
};
struct
InstanceDataTriangle
{
static
void
constructBuffer
(
ShaderInstanced
<
InstanceDataTriangle
>*
shader
);
Rect
rect
;
Rect
U
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
;
Rect
U
rect
;
Color
color
;
Rect
atlas
;
Rect
U
atlas
;
};
#include
"Shader.hpp"
\ No newline at end of file
SDLTest/include/RenderDispatcher.hpp
View file @
b85ec35b
...
...
@@ -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
;
...
...
SDLTest/include/Shader.hpp
View file @
b85ec35b
...
...
@@ -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
:
...
...
SDLTest/include/Shaders.ipp
View file @
b85ec35b
...
...
@@ -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;
...
...
SDLTest/include/Types.hpp
View file @
b85ec35b
...
...
@@ -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"
SDLTest/include/Types.ipp
0 → 100644
View file @
b85ec35b
#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
SDLTest/include/Uniform.hpp
View file @
b85ec35b
...
...
@@ -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
;
...
...
SDLTest/resources/shaders/Glyph.fs
View file @
b85ec35b
#
version
330
core
uniform
sampler2D
glyph
Texture
;
uniform
sampler2D
atlas
Texture
;
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
SDLTest/resources/shaders/Glyph.vs
View file @
b85ec35b
...
...
@@ -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
);
...
...
SDLTest/src/ContainerScrollElement.cpp
View file @
b85ec35b
...
...
@@ -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
=
Rect
U
(
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
);
...
...
SDLTest/src/GUIElement.cpp
View file @
b85ec35b
...
...
@@ -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
;
}
...
...
SDLTest/src/GUIMain.cpp
View file @
b85ec35b
...
...
@@ -20,6 +20,9 @@ GUIMain::GUIMain() {
slider1
.
maxValue
=
32
;
slider1
.
valueStep
=
4.0
;
slider1
.
fillValue
=
true
;
text0
.
setDepth
(
0
);
scroll0
.
setDepth
(
32
);
}
...
...
SDLTest/src/Instance.cpp
View file @
b85ec35b
...
...
@@ -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
);
}
Prev
1
2
Next