所以我试图在本教程之后使用FTGL,GLFW和GLEW库在我的C ++引擎中渲染一些文本:https://www.youtube.com/watch?v=Rsdc6I80aFQ。 但是,当我这样做时,文本应该是字符而不是字符,我得到某种三角形(截图):
我想使用与渲染普通精灵时相同的着色器,因此我将着色器中的模型矩阵设置为单位矩阵,而是使用VBO将字符位置传递到着色器。
这是字体类:
class Font
{
private:
/* Variables */
ftgl::texture_atlas_t* m_atlas;
ftgl::texture_font_t* m_font;
public:
/* Constructors */
Font(const char* filename, const float size)
: m_atlas(ftgl::texture_atlas_new(512, 512, 1)),
m_font(ftgl::texture_font_new_from_file(m_atlas, size, filename))
{}
/* Functions */
void bindFontTexture() const
{
GLcall( glBindTexture(GL_TEXTURE_2D, m_atlas->id) );
}
// Getters
inline ftgl::texture_font_t* getFTGLFont() const { return m_font; }
};
这里是标签类(标签是2D渲染器,在我的引擎中有一些文字):
class Label2D : public Renderable2D
{
protected:
/* Variables */
std::string m_text;
Color m_color;
Font* m_font;
public:
/* Constructors */
Label2D(const std::string& text, const vector2& pos, const vector2& size, Font* font)
: Renderable2D(pos, size), m_text(text), m_font(font)
{}
Label2D(const std::string& text, const vector2& pos, const vector2& size, Font* font, const Color& color)
: Renderable2D(pos, size), m_text(text), m_font(font), m_color(color)
{}
/* Functions */
void bindFontTexture() const
{
m_font->bindFontTexture();
}
// Setters
void setText(const std::string& text)
{
m_text = text;
}
void setColor(const Color& color)
{
m_color = color;
}
void setFont(Font* font)
{
m_font = font;
}
// Getters
inline const std::string& getText() const { return m_text; }
inline const Color& getColor() const { return m_color; }
inline ftgl::texture_font_t* getFTGLFont() const { return m_font->getFTGLFont(); }
};
这是我的文字渲染代码。现在我知道这段代码编写得非常糟糕,因为每次我想要渲染一些文本时都不应该创建VAO和VBO,但我只是为了测试目的而做,我只是想确保库工作正常,然后我将组织代码:
void Layer2D::m_renderLabels(const bool renderLighting)
{
// Uniforms Setup
m_textureShader.start();
m_textureShader.setUniformMatrix4f("u_modelMatrix", matrix4(1.0f));f));
// Rendering Labels from std::vector
for (Label2D* label : m_labels)
{
// Binding
m_textureVAO.bind();
label->bindFontTexture();
// Starting Shader
m_textureShader.start();
// Preparation Stuff
std::vector<float> positions;
std::vector<float> textureCoordinates;
float offsetX = label->getPosition().x;
// Loading Characters
for (unsigned int i = 0; i < label->getText().length(); i++)
{
// Loading Glyph
ftgl::texture_glyph_t* glyph = ftgl::texture_font_get_glyph(label->getFTGLFont(), &label->getText().at(i));
if (glyph != NULL)
{
if (i > 0)
{
float kerning = texture_glyph_get_kerning(glyph, &label->getText().at(i - 1));
offsetX += kerning;
}
// Glyph Position/Offset/Size Calculations
float x0 = offsetX + glyph->offset_x;
float y0 = label->getPosition().y + glyph->offset_y;
float x1 = x0 + glyph->width;
float y1 = y0 - glyph->height;
float u0 = glyph->s0;
float v0 = glyph->t0;
float u1 = glyph->s1;
float v1 = glyph->t1;
positions.push_back(x0);
positions.push_back(y0);
positions.push_back(x0);
positions.push_back(y1);
positions.push_back(x1);
positions.push_back(y1);
positions.push_back(x1);
positions.push_back(y0);
textureCoordinates.push_back(u0);
textureCoordinates.push_back(v0);
textureCoordinates.push_back(u0);
textureCoordinates.push_back(v1);
textureCoordinates.push_back(u1);
textureCoordinates.push_back(v1);
textureCoordinates.push_back(u1);
textureCoordinates.push_back(v0);
offsetX += glyph->advance_x;
}
}
VertexArray textVAO;
VertexBuffer* textPosVBO = new VertexBuffer(&positions[0], positions.size(), 2);
VertexBuffer* textTexCoordsVBO = new VertexBuffer(&textureCoordinates[0], textureCoordinates.size(), 2);
textVAO.addAttribute(textPosVBO, 0);
textVAO.addAttribute(textTexCoordsVBO, 1);
textVAO.bind();
// Rendering
GLcall( glDrawArrays(GL_TRIANGLE_STRIP, 0, 4 * label->getText().length()) );
}
}
最后那是着色器代码: 顶点:
#shader vertex
#version 330 core
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_textureCoordinates;
out vec2 pass_textureCoordinates;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
uniform mat4 u_modelMatrix;
void main()
{
pass_textureCoordinates = in_textureCoordinates;
gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * vec4(in_position, 0.0, 1.0);
}
片段:
#shader fragment
#version 330 core
in vec2 pass_textureCoordinates;
out vec4 out_color;
uniform sampler2D u_textureSampler;
void main()
{
vec4 textureColor = texture2D(u_textureSampler, pass_textureCoordinates);
out_color = textureColor;
out_color = vec4(1.0, 0.0, 0.0, 1.0); //done for test purposes only (it still doesn't work when this line is removed)
}
如果我不够具体,我很抱歉,如果我能提供更多信息来帮助你,请在下面发表评论。
提前致谢!
编辑: 如果您想知道,我会在代码的其他部分设置投影和查看矩阵:
m_textureShader.start();
m_textureShader.setUniformMatrix4f("u_projectionMatrix", m_projectionMatrix);
m_textureShader.setUniformMatrix4f("u_viewMatrix", viewMatrix);
编辑:在交换最后2个顶点后,我现在得到四边形,但仍然不是文本(屏幕截图)四边形不是红色的,因为我从片段着色器中删除了调试行。