VN Textbox can now be any size

This commit is contained in:
2022-11-06 11:45:10 -08:00
parent db90bd1476
commit 6f4ab49caa
23 changed files with 1493 additions and 1317 deletions

View File

@ -1,195 +1,195 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TrueTypeFont.hpp"
#ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#endif
using namespace Dawn;
void TrueTypeFont::bakeQuad(truetypequad_t *quad,float_t *x,float_t *y,char c){
stbtt_GetBakedQuad(
this->characterData,
this->texture.getWidth(), this->texture.getHeight(),
((int32_t)c) - TRUETYPE_FIRST_CHAR,
x, y, quad,
TRUETYPE_FILL_MODE
);
}
float_t TrueTypeFont::getScale(float_t scale) {
return scale / this->fontSize;
}
float_t TrueTypeFont::getSpaceSize(float_t fontSize) {
return mathRoundFloat(this->fontSize * 0.3f);
}
float_t TrueTypeFont::getInitialLineHeight(float_t fontSize) {
return 8.0f;
}
void TrueTypeFont::buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh &mesh,
struct FontMeasure *info
) {
auto stringLength = text.length();
if(stringLength == 0) {
info->length = 0;
info->realLength = 0;
info->lines.clear();
info->height = 0;
info->width = 0;
info->height = 0.0f;
info->lineHeight = 0.0f;
mesh.createBuffers(0, 0);
return;
}
auto quads = new truetypequad_t[stringLength];
// Get the font scale
auto scale = this->getScale(fontSize);
// Adjust the max width to match the scale, and allow "no max width".
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
// Which index in the original text var is the current word from
int32_t wordStart = 0;
// Setup Scales
info->length = 0;
info->realLength = 0;
info->lines.clear();
info->lineHeight = this->getLineHeight(fontSize) * scale;
// Prepare the line counters
info->addLine(0, 0);
// Reset Dimensions
info->width = info->height = 0;
// Setup the initial loop state, and X/Y coords for the quad.
int32_t i = 0;
float_t x = 0;
float_t y = this->getInitialLineHeight(fontSize);
float_t wordX = 0;
char c;
while(c = text[i++]) {
info->length++;
// When space, start of new word about to begin
if(c == FONT_SPACE) {
x += this->getSpaceSize(fontSize);
// Did this space cause a newline?
if(x > maxWidth) {
info->addLine(info->realLength, 0);
y += this->getLineHeight(fontSize);
x = 0;
}
wordX = x;
wordStart = info->realLength;
continue;
}
// New line.
if(c == FONT_NEWLINE) {
info->addLine(info->realLength, 0);
wordStart = info->realLength;
y += this->getLineHeight(fontSize);
x = 0;
continue;
}
// Generate the quad.
auto quad = quads + info->realLength;
this->bakeQuad(quad, &x, &y, c);
// Now measure the width of the line (take the right side of that quad)
if(quad->x1 > maxWidth) {
// We've exceeded the edge, go back to the start of the word and newline.
x = quad->x1 - wordX;
for(auto j = wordStart; j <= info->realLength; j++) {
quad = quads + j;
quad->x0 -= wordX;
quad->x1 -= wordX;
quad->y0 += this->getLineHeight(fontSize);
quad->y1 += this->getLineHeight(fontSize);
}
// Go back to the previous (still current) line and remove the chars
info->lines[info->lines.size() - 1].length -= info->realLength - wordStart;
// Next line begins with this word
y += this->getLineHeight(fontSize);
info->addLine(wordStart, info->realLength-wordStart);
wordX = 0;
}
info->lines[info->lines.size() - 1].length++;
info->realLength++;
}
// Initialize primitive
mesh.createBuffers(
QUAD_VERTICE_COUNT * info->realLength,
QUAD_INDICE_COUNT * info->realLength
);
for(auto j = 0; j < info->realLength; j++) {
auto quad = quads + j;
// Scale the Quad
if(scale != 1.0) {
quad->x0 *= scale;
quad->x1 *= scale;
quad->y0 *= scale;
quad->y1 *= scale;
}
// Update the dimensions.
info->width = mathMax<float_t>(info->width, quad->x1);
info->height = mathMax<float_t>(info->height, quad->y1);
// Buffer the quad.
QuadMesh::bufferQuadMesh(&mesh,
glm::vec2(quad->x0, quad->y0), glm::vec2(quad->s0, quad->t0),
glm::vec2(quad->x1, quad->y1), glm::vec2(quad->s1, quad->t1),
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
);
}
delete quads;
}
Texture & TrueTypeFont::getTexture() {
return this->texture;
}
void TrueTypeFont::draw(Mesh &mesh, int32_t startchar, int32_t length) {
mesh.draw(
MESH_DRAW_MODE_TRIANGLES,
startchar * QUAD_INDICE_COUNT,
length == -1 ? length : length * QUAD_INDICE_COUNT
);
}
float_t TrueTypeFont::getLineHeight(float_t fontSize) {
return 13.0f;
}
float_t TrueTypeFont::getDefaultFontSize() {
return (float_t)this->fontSize;
}
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TrueTypeFont.hpp"
#ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#endif
using namespace Dawn;
void TrueTypeFont::bakeQuad(truetypequad_t *quad,float_t *x,float_t *y,char c){
stbtt_GetBakedQuad(
this->characterData,
this->texture.getWidth(), this->texture.getHeight(),
((int32_t)c) - TRUETYPE_FIRST_CHAR,
x, y, quad,
TRUETYPE_FILL_MODE
);
}
float_t TrueTypeFont::getScale(float_t scale) {
return scale / this->fontSize;
}
float_t TrueTypeFont::getSpaceSize(float_t fontSize) {
return mathRoundFloat(this->fontSize * 0.3f);
}
float_t TrueTypeFont::getInitialLineHeight(float_t fontSize) {
return 8.0f;
}
void TrueTypeFont::buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh &mesh,
struct FontMeasure *info
) {
auto stringLength = text.length();
if(stringLength == 0) {
info->length = 0;
info->realLength = 0;
info->lines.clear();
info->height = 0;
info->width = 0;
info->height = 0.0f;
info->lineHeight = 0.0f;
mesh.createBuffers(0, 0);
return;
}
auto quads = new truetypequad_t[stringLength];
// Get the font scale
auto scale = this->getScale(fontSize);
// Adjust the max width to match the scale, and allow "no max width".
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
// Which index in the original text var is the current word from
int32_t wordStart = 0;
// Setup Scales
info->length = 0;
info->realLength = 0;
info->lines.clear();
info->lineHeight = this->getLineHeight(fontSize) * scale;
// Prepare the line counters
info->addLine(0, 0);
// Reset Dimensions
info->width = info->height = 0;
// Setup the initial loop state, and X/Y coords for the quad.
int32_t i = 0;
float_t x = 0;
float_t y = this->getInitialLineHeight(fontSize);
float_t wordX = 0;
char c;
while(c = text[i++]) {
info->length++;
// When space, start of new word about to begin
if(c == FONT_SPACE) {
x += this->getSpaceSize(fontSize);
// Did this space cause a newline?
if(x > maxWidth) {
info->addLine(info->realLength, 0);
y += this->getLineHeight(fontSize);
x = 0;
}
wordX = x;
wordStart = info->realLength;
continue;
}
// New line.
if(c == FONT_NEWLINE) {
info->addLine(info->realLength, 0);
wordStart = info->realLength;
y += this->getLineHeight(fontSize);
x = 0;
continue;
}
// Generate the quad.
auto quad = quads + info->realLength;
this->bakeQuad(quad, &x, &y, c);
// Now measure the width of the line (take the right side of that quad)
if(quad->x1 > maxWidth) {
// We've exceeded the edge, go back to the start of the word and newline.
x = quad->x1 - wordX;
for(auto j = wordStart; j <= info->realLength; j++) {
quad = quads + j;
quad->x0 -= wordX;
quad->x1 -= wordX;
quad->y0 += this->getLineHeight(fontSize);
quad->y1 += this->getLineHeight(fontSize);
}
// Go back to the previous (still current) line and remove the chars
info->lines[info->lines.size() - 1].length -= info->realLength - wordStart;
// Next line begins with this word
y += this->getLineHeight(fontSize);
info->addLine(wordStart, info->realLength-wordStart);
wordX = 0;
}
info->lines[info->lines.size() - 1].length++;
info->realLength++;
}
// Initialize primitive
mesh.createBuffers(
QUAD_VERTICE_COUNT * info->realLength,
QUAD_INDICE_COUNT * info->realLength
);
for(auto j = 0; j < info->realLength; j++) {
auto quad = quads + j;
// Scale the Quad
if(scale != 1.0) {
quad->x0 *= scale;
quad->x1 *= scale;
quad->y0 *= scale;
quad->y1 *= scale;
}
// Update the dimensions.
info->width = mathMax<float_t>(info->width, quad->x1);
info->height = mathMax<float_t>(info->height, quad->y1);
// Buffer the quad.
QuadMesh::bufferQuadMesh(&mesh,
glm::vec2(quad->x0, quad->y0), glm::vec2(quad->s0, quad->t0),
glm::vec2(quad->x1, quad->y1), glm::vec2(quad->s1, quad->t1),
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
);
}
delete quads;
}
Texture & TrueTypeFont::getTexture() {
return this->texture;
}
void TrueTypeFont::draw(Mesh &mesh, int32_t startchar, int32_t length) {
mesh.draw(
MESH_DRAW_MODE_TRIANGLES,
startchar * QUAD_INDICE_COUNT,
length == -1 ? length : length * QUAD_INDICE_COUNT
);
}
float_t TrueTypeFont::getLineHeight(float_t fontSize) {
return 13.0f;
}
float_t TrueTypeFont::getDefaultFontSize() {
return (float_t)this->fontSize;
}

View File

@ -1,83 +1,83 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Font.hpp"
namespace Dawn {
/** Which character (ASCII) to start the font from */
#define TRUETYPE_FIRST_CHAR 32
/** How many characters (after the first char) to generate */
#define TRUETYPE_NUM_CHARS 96
/** Refer to STBTT docs for OpenGL Fill Mode v d3d Fill Modes */
#define TRUETYPE_FILL_MODE 0
typedef stbtt_bakedchar truetypechar_t;
typedef stbtt_aligned_quad truetypequad_t;
class TrueTypeFont : public Font {
protected:
/**
* Calculate the quad information for a given character.
*
* @param font Font to get the character from.
* @param quad Pointer to the quad to store the quad information in.
* @param x Pointer to the X position for the quad.
* @param y Pointer to the Y position for the quad.
* @param c Character to get the quad and position information for.
*/
void bakeQuad(truetypequad_t *quad, float_t *x, float_t *y, char c);
/**
* Returns the font scale to use for rendering your desired font size at a
* font size that is different than the precompiled font size for this
* true type font. For example, let's say you render your font size at 36
* when you are precompiling it, but rather than creating a new font just
* to add a size 24, you can instead use this method to get the scale to
* use to downscale your font to match.
*
* @param font TrueType font to get the scale of.
* @param fontSize Font size you desire.
* @return The scale used to get the font size that will match.
*/
float_t getScale(float_t fontSize);
/**
* Returns the size of a space character for a given font.
*
* @param fontSize Font size of the font to get the space size for.
* @return The size of the space character.
*/
float_t getSpaceSize(float_t fontSize);
/**
* Returns the initial line height of a font.
*
* @param fontSize Font size for the font to get the line height of.
* @return The line height initial value.
*/
float_t getInitialLineHeight(float_t fontSize);
public:
Texture texture;
int32_t fontSize;
truetypechar_t characterData[TRUETYPE_NUM_CHARS];
void buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh &mesh,
struct FontMeasure *info
) override;
Texture & getTexture() override;
void draw(Mesh &mesh, int32_t startCharacter, int32_t length) override;
float_t getLineHeight(float_t fontSize) override;
float_t getDefaultFontSize() override;
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Font.hpp"
namespace Dawn {
/** Which character (ASCII) to start the font from */
#define TRUETYPE_FIRST_CHAR 32
/** How many characters (after the first char) to generate */
#define TRUETYPE_NUM_CHARS 96
/** Refer to STBTT docs for OpenGL Fill Mode v d3d Fill Modes */
#define TRUETYPE_FILL_MODE 0
typedef stbtt_bakedchar truetypechar_t;
typedef stbtt_aligned_quad truetypequad_t;
class TrueTypeFont : public Font {
protected:
/**
* Calculate the quad information for a given character.
*
* @param font Font to get the character from.
* @param quad Pointer to the quad to store the quad information in.
* @param x Pointer to the X position for the quad.
* @param y Pointer to the Y position for the quad.
* @param c Character to get the quad and position information for.
*/
void bakeQuad(truetypequad_t *quad, float_t *x, float_t *y, char c);
/**
* Returns the font scale to use for rendering your desired font size at a
* font size that is different than the precompiled font size for this
* true type font. For example, let's say you render your font size at 36
* when you are precompiling it, but rather than creating a new font just
* to add a size 24, you can instead use this method to get the scale to
* use to downscale your font to match.
*
* @param font TrueType font to get the scale of.
* @param fontSize Font size you desire.
* @return The scale used to get the font size that will match.
*/
float_t getScale(float_t fontSize);
/**
* Returns the size of a space character for a given font.
*
* @param fontSize Font size of the font to get the space size for.
* @return The size of the space character.
*/
float_t getSpaceSize(float_t fontSize);
/**
* Returns the initial line height of a font.
*
* @param fontSize Font size for the font to get the line height of.
* @return The line height initial value.
*/
float_t getInitialLineHeight(float_t fontSize);
public:
Texture texture;
int32_t fontSize;
truetypechar_t characterData[TRUETYPE_NUM_CHARS];
void buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh &mesh,
struct FontMeasure *info
) override;
Texture & getTexture() override;
void draw(Mesh &mesh, int32_t startCharacter, int32_t length) override;
float_t getLineHeight(float_t fontSize) override;
float_t getDefaultFontSize() override;
};
}

View File

@ -1,115 +1,115 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Texture.hpp"
namespace Dawn {
class Material;
enum ShaderParameterType {
SHADER_PARAMETER_TYPE_MATRIX,
SHADER_PARAMETER_TYPE_BOOLEAN,
SHADER_PARAMETER_TYPE_COLOR,
SHADER_PARAMETER_TYPE_VECTOR3,
SHADER_PARAMETER_TYPE_TEXTURE,
SHADER_PARAMETER_TYPE_FLOAT
};
template<typename T>
class IShader {
public:
/**
* Attaches the supplied shader as the current shader.
*/
virtual void bind() = 0;
/**
* Requested by the Material to set the default parameters of the shader.
* Each parameter really should have a default value set so that there is
* no nullptr's or other issues.
*
* @param material Material to set the default parameters on to.
*/
virtual void setDefaultParameters(Material &material) = 0;
/**
* Requested by the render pipeline (typically) to set global level (once
* per frame) parameters.
*
* @param projection Projection matrix of the current viewport.
* @param view View matrix of the current viewport.
*/
virtual void setGlobalParameters(
glm::mat4 projection,
glm::mat4 view
) = 0;
/**
* Requested by the render pipeline (typically) to set mesh-level params.
* This may be performed multiple times per frame.
*
* @param position Matrix of the position of the mesh.
*/
virtual void setMeshParameters(glm::mat4 position) = 0;
/**
* Retreives the list of all parameters that the shader supports. This
* should not include the GLOBAL shader parameters (listed above) since
* those will be modified by the engine directly.
*
* @return Key-Value-Pair of Shader parameters and their type.
*/
virtual std::map<T, enum ShaderParameterType> getParameters() = 0;
/**
* Set's a specific shader parameter to a matrix.
*
* @param parameter parameter on the shader to set.
* @param matrix Matrix to apply.
*/
virtual void setMatrix(T parameter, glm::mat4 matrix) = 0;
/**
* Attaches a boolean to a shader.
*
* @param parameter parameter to set.
* @param value Value to set.
*/
virtual void setBoolean(T parameter, bool_t value) = 0;
/**
* Set a color on to the shader.
*
* @param parameter parameter to set the color to.
* @param color Color to set.
*/
virtual void setColor(T parameter, struct Color color) = 0;
/**
* Set a 3D vector on to the shader.
*
* @param parameter parameter to set the vector to.
* @param vector Vector to set.
*/
virtual void setVector3(T parameter, glm::vec3 vector) = 0;
/**
* Attaches a texture to the currently bound shader.
*
* @param parameter parameter to set the texture on to.
* @param texture Texture to bind to the parameter.
*/
virtual void setTexture(T parameter, Texture *texture) = 0;
/**
* Sets a floating point value to the shader.
*
* @param parameter Paramater to set the float ont o.
* @param float Float to bind.
*/
virtual void setFloat(T parameter, float_t value) = 0;
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Texture.hpp"
namespace Dawn {
class Material;
enum ShaderParameterType {
SHADER_PARAMETER_TYPE_MATRIX,
SHADER_PARAMETER_TYPE_BOOLEAN,
SHADER_PARAMETER_TYPE_COLOR,
SHADER_PARAMETER_TYPE_VECTOR3,
SHADER_PARAMETER_TYPE_TEXTURE,
SHADER_PARAMETER_TYPE_FLOAT
};
template<typename T>
class IShader {
public:
/**
* Attaches the supplied shader as the current shader.
*/
virtual void bind() = 0;
/**
* Requested by the Material to set the default parameters of the shader.
* Each parameter really should have a default value set so that there is
* no nullptr's or other issues.
*
* @param material Material to set the default parameters on to.
*/
virtual void setDefaultParameters(Material &material) = 0;
/**
* Requested by the render pipeline (typically) to set global level (once
* per frame) parameters.
*
* @param projection Projection matrix of the current viewport.
* @param view View matrix of the current viewport.
*/
virtual void setGlobalParameters(
glm::mat4 projection,
glm::mat4 view
) = 0;
/**
* Requested by the render pipeline (typically) to set mesh-level params.
* This may be performed multiple times per frame.
*
* @param position Matrix of the position of the mesh.
*/
virtual void setMeshParameters(glm::mat4 position) = 0;
/**
* Retreives the list of all parameters that the shader supports. This
* should not include the GLOBAL shader parameters (listed above) since
* those will be modified by the engine directly.
*
* @return Key-Value-Pair of Shader parameters and their type.
*/
virtual std::map<T, enum ShaderParameterType> getParameters() = 0;
/**
* Set's a specific shader parameter to a matrix.
*
* @param parameter parameter on the shader to set.
* @param matrix Matrix to apply.
*/
virtual void setMatrix(T parameter, glm::mat4 matrix) = 0;
/**
* Attaches a boolean to a shader.
*
* @param parameter parameter to set.
* @param value Value to set.
*/
virtual void setBoolean(T parameter, bool_t value) = 0;
/**
* Set a color on to the shader.
*
* @param parameter parameter to set the color to.
* @param color Color to set.
*/
virtual void setColor(T parameter, struct Color color) = 0;
/**
* Set a 3D vector on to the shader.
*
* @param parameter parameter to set the vector to.
* @param vector Vector to set.
*/
virtual void setVector3(T parameter, glm::vec3 vector) = 0;
/**
* Attaches a texture to the currently bound shader.
*
* @param parameter parameter to set the texture on to.
* @param texture Texture to bind to the parameter.
*/
virtual void setTexture(T parameter, Texture *texture) = 0;
/**
* Sets a floating point value to the shader.
*
* @param parameter Paramater to set the float ont o.
* @param Float to bind.
*/
virtual void setFloat(T parameter, float_t value) = 0;
};
}