PDA

View Full Version : Text rendering class does not draw text



th0masr0ss
01-23-2015, 09:10 PM
I'm writing a text rendering class based on this guide (https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01). For some reason it does not render the text and I am completely stumped.

Here's my code:

TextRenderer.hpp

#ifndef TEXTRENDERER_HPP

#include <iostream>

#include <GL/glew.h>

#include <ft2build.h>
#include FT_FREETYPE_H

struct point
{
GLfloat x;
GLfloat y;
GLfloat s;
GLfloat t;
};

class TextRenderer
{
public:
void renderText(const char *text, int x, int y, int scaleX, int scaleY);
void setColor(int r, int g, int b, int a);
TextRenderer(FT_Face face, int fontSize);
GLfloat color[4];
private:
void setup();
void shutdown();
int fontSize;
GLint coordIndex, texIndex, colorIndex;
GLuint program;
GLuint vbo;
FT_Face face;
};
#define TEXTRENDERER_HPP
#endif

TextRenderer.cpp


#include "TextRenderer.hpp"
#include "ShaderHandler.hpp"

#include <iostream>

#include <GL/glew.h>

#include <ft2build.h>
#include FT_FREETYPE_H

TextRenderer::TextRenderer(FT_Face face, int fontSize = 10)
{
this->face = face;
this->program = ShaderHandler::loadShader("TextShader.vglsl", "TextShader.fglsl");
this->fontSize = fontSize;
this->setColor(1, 1, 1, 0);
}

void TextRenderer::setColor(int r, int g, int b, int a)
{
this->color[0] = r;
this->color[1] = g;
this->color[2] = b;
this->color[3] = a;
}

void TextRenderer::setup()
{
glUseProgram(this->program);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FT_Set_Pixel_Sizes(this->face, 0, this->fontSize);
this->coordIndex = ShaderHandler::getAttribIndex(this->program, "coord");
this->texIndex = ShaderHandler::getUniformIndex(this->program, "tex");
this->colorIndex = ShaderHandler::getUniformIndex(this->program, "color");

glGenBuffers(1, &this->vbo);

glUniform4fv(this->colorIndex, 1, this->color);
}

void TextRenderer::shutdown()
{

}

void TextRenderer::renderText(const char *text, int x, int y, int scaleX, int scaleY)
{
this->setup();
FT_GlyphSlot glyph = this->face->glyph;
const char *c;
GLuint tex;

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(this->texIndex, 0);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenBuffers(1, &vbo);

glEnableVertexAttribArray(this->coordIndex);
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
glVertexAttribPointer(this->coordIndex, 4, GL_FLOAT, GL_FALSE, 0, 0);

for (c = text; *c; c++)
{
//std::cout << c << std::endl;
if (FT_Load_Char(this->face, *c, FT_LOAD_RENDER))
{
continue;
}

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glyph->bitmap.width, glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer);

float x2 = x + glyph->bitmap_left * scaleX;
float y2 = -y - glyph->bitmap_top * scaleY;
float width = glyph->bitmap.width * scaleX;
float height = glyph->bitmap.rows * scaleY;

point box[4][4] =
{
{ x2, -y2, 0, 0 },
{ x2 + width, -y2, 1, 0 },
{ x2, -y2 - height, 0, 1 },
{ x2 + width, -y2 - height, 1, 1 },
};

glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

x += (glyph->advance.x >> 6) * scaleX;
y += (glyph->advance.y >> 6) * scaleY;

}
glDisableVertexAttribArray(this->coordIndex);
glDeleteTextures(1, &tex);
}

TextShader.fglsl (Fragment shader)


#version 330

varying vec2 texpos;
uniform sampler2D tex;
uniform vec4 color;
out vec4 outColor;

void main(void)
{
outColor = vec4( 1, 1, 1, texture( tex, texpos ).r) * color;
}

TextShader.vglsl (Vertex shader)


#version 330

attribute vec4 coord;
varying vec2 texpos;
out vec4 pos;

void main(void)
{
pos = vec4(coord.xy, 0, 1);
texpos = coord.zw;
}

Then I just call this to init the TextRenderer:

TextRenderer tRenderer = TextRenderer(sans, 10);
Then this in the game loop:



int sx = width / 2.0;
int sy = height / 2.0;
tRenderer.renderText("hi there", -1 + 8 * sx, 1 - 50 * sy, sx, sy);