20 #include <glutil/glutil.h> 21 #include "TextObject.h" 22 #include <ShaderProgram.h> 23 #include <FontManager.h> 24 #include <ResourceManager.h> 27 : text(text), font(font), width(width), height(height), x(x), y(-y) {
33 std::vector<std::string> lines;
34 std::vector<int> linesOffsetX;
36 getLines(&lines, &linesOffsetX, &numChars);
38 init(lines,linesOffsetX, numChars);
42 void TextObject::getLines(std::vector<std::string>* lines, std::vector<int>* linesOffsetX,
int* numChars){
44 std::string curLine =
"";
45 std::string word =
"";
47 for(
unsigned char c : text){
48 if (c >
' ' && c < 128){
49 wordLength += font->getCharacter(c).advanceX/64;
53 if (lineLength + wordLength > width){
54 lines->push_back(curLine);
55 linesOffsetX->push_back(getOffsetByLineLength(lineLength));
57 lineLength = wordLength;
59 curLine +=
" " + word;
60 lineLength += font->getCharacter(
' ').advanceX/64 + wordLength;
64 }
else if (c ==
'\r'){
65 if (lineLength + wordLength > width){
66 lines->push_back(curLine);
67 linesOffsetX->push_back(getOffsetByLineLength(lineLength));
69 lineLength = wordLength;
71 curLine +=
" " + word;
72 lineLength += font->getCharacter(
' ').advanceX/64 + wordLength;
74 lines->push_back(curLine);
75 linesOffsetX->push_back(getOffsetByLineLength(lineLength));
82 if (lineLength + wordLength > width){
83 lines->push_back(curLine);
84 linesOffsetX->push_back(getOffsetByLineLength(lineLength));
86 lineLength = wordLength;
88 curLine +=
" " + word;
89 lineLength += font->getCharacter(
' ').advanceX/64 + wordLength;
91 lines->push_back(curLine);
92 linesOffsetX->push_back(getOffsetByLineLength(lineLength));
95 int TextObject::getOffsetByLineLength(
int lineLength) {
96 return (width-lineLength)/2;
99 void TextObject::init(std::vector<std::string> lines, std::vector<int> linesOffsetX,
int numChars) {
102 int y = height/2 - font->getPixelSize();
103 std::vector<GLfloat> data;
105 float atlasWidth = Globals::get(Globals::FONT_TEXTURE_WIDTH),
106 atlasHeight = Globals::get(Globals::FONT_TEXTURE_HEIGHT);
109 for(std::string line : lines) {
110 int lox = linesOffsetX[l++];
111 for (
unsigned char c : line) {
113 gData = font->getCharacter(c);
114 float x2 = x + gData.bitmapLeft + lox;
115 float y2 = -y - gData.bitmapTop;
116 float w = gData.bitmapWidth;
117 float h = gData.bitmapHeight;
118 float ox = gData.offsetX;
121 x += gData.advanceX / 64;
122 y += gData.advanceY / 64;
129 addPoints(&data, {x2 + w, -y2 , 0, (ox + w) / atlasWidth, 0});
130 addPoints(&data, {x2 , -y2 , 0, ox / atlasWidth , 0});
131 addPoints(&data, {x2 , -y2 - h, 0, ox / atlasWidth , h / atlasHeight});
132 addPoints(&data, {x2 + w, -y2 , 0, (ox + w) / atlasWidth, 0});
133 addPoints(&data, {x2 , -y2 - h, 0, ox / atlasWidth , h / atlasHeight});
134 addPoints(&data, {x2 + w, -y2 - h, 0, (ox + w) / atlasWidth, h / atlasHeight});
138 y -= font->getPixelSize();
143 initAndBindBuffers();
144 glBufferData(GL_ARRAY_BUFFER, data.size() *
sizeof(GLfloat), data.data(), GL_STATIC_DRAW);
146 glEnableVertexAttribArray(0);
147 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat), 0);
149 glEnableVertexAttribArray(1);
150 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat), (
void*)(3 *
sizeof(GLfloat)));
153 glBindVertexArray(0);
158 void TextObject::addPoints(std::vector<GLfloat> *data, std::initializer_list<float> elems) {
159 for(
float elem : elems) {
160 data->push_back(elem);
164 void TextObject::initAndBindBuffers() {
166 if (buffersInitiated){
167 glBindVertexArray(vao);
168 glBindBuffer(GL_ARRAY_BUFFER,vbo);
170 glGenVertexArrays(1, &vao);
171 glBindVertexArray(vao);
173 glGenBuffers(1, &vbo);
174 glBindBuffer(GL_ARRAY_BUFFER, vbo);
181 GLint currentDepthFunc;
182 glGetIntegerv(GL_DEPTH_FUNC, ¤tDepthFunc);
184 glDepthFunc(GL_ALWAYS);
186 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
190 shaderProgram->
use();
191 glBindVertexArray(vao);
193 shaderProgram->setUniform1i(
"sprite", 4);
194 shaderProgram->setUniformMatrix4fv(
"modelMatrix", getModelMatrix());
195 shaderProgram->setUniformMatrix4fv(
"projectionMatrix",*projectionMatrix);
196 shaderProgram->setUniform1i(
"isTexture",
false);
197 shaderProgram->setUniform1i(
"isColor",
false);
198 shaderProgram->setUniform1i(
"isFont",
true);
200 glActiveTexture(GL_TEXTURE4);
203 glDrawArrays(GL_TRIANGLES, 0, numVertices);
207 glDepthFunc(currentDepthFunc);
210 glEnable(GL_CULL_FACE);
215 chag::float4x4 TextObject::getModelMatrix() {
216 chag::float3 originalPosition = chag::make_vector((
float)x + width / 2, (
float)y - height /2, 0.0f) - center;
217 return chag::make_translation(originalPosition + relativePosition)
218 * chag::make_rotation_z<chag::float4x4>(rotation)
219 * chag::make_scale<chag::float4x4>(scale)
220 * chag::make_translation(center)
221 * chag::make_identity<chag::float4x4>();
TextObject(std::string text, Font *font, int width, int height, int x, int y)
void restorePreviousShaderProgram()
Class for maintaining OpenGL shader programs.
virtual void setText(std::string text)
static FontManager * getInstance()
virtual void render(ShaderProgram *shaderProgram, chag::float4x4 *projectionMatrix)
void backupCurrentShaderProgram()