I am making a text rendering system using freetype library.
I have generated a texture for each character, and now i'd like to draw each character of a string.
Here is my code for the string drawing :
Code: Select all
for (Component *c : _components)
{
TextComponent *text = dynamic_cast<TextComponent*>(c);
if (text == nullptr)
{
debugNetPrintf(INFO, "Null text component...");
continue;
}
auto & shader = _assetsManager.getShader("text");
float x = text->getPosition().x;
float y = text->getPosition().y;
for (int i = 0; i < text->getText().length(); i++)
{
char c = text->getText()[i];
if (_characters.find(c) == _characters.end())
continue ;
Character & ch = _characters[c];
float xpos = x + ch.Bearing.x;
float ypos = y - (ch.Size.y - ch.Bearing.y);
float w = ch.Size.x;
float h = ch.Size.y;
Mesh mesh;
mesh.addVertex(glm::vec3(xpos, ypos + h, 0.0f));
mesh.addVertex(glm::vec3(xpos,ypos, 0.0));
mesh.addVertex(glm::vec3(xpos + w, ypos, 0.0f));
mesh.addVertex(glm::vec3(xpos, ypos + h, 0.0f));
mesh.addVertex(glm::vec3(xpos + w, ypos, 0.0f));
mesh.addVertex(glm::vec3(xpos + w, ypos + h, 0.0f));
mesh.addTexCoord(glm::vec2(0.f, 0.f));
mesh.addTexCoord(glm::vec2(0.f, 1.f));
mesh.addTexCoord(glm::vec2(1.f, 1.f));
mesh.addTexCoord(glm::vec2(0.f, 0.f));
mesh.addTexCoord(glm::vec2(1.f, 1.f));
mesh.addTexCoord(glm::vec2(1.f, 0.f));
for (int i = 0; i < 6; i++)
{
mesh.addIndex(i);
}
mesh.uploadToVram();
shader.bind(_graphics.gxmContext());
shader.setUniformMat4(VERTEX, "projection", _graphics.gxmContext(), _projection);
shader.setUniformVec3(FRAGMENT, "textColor", _graphics.gxmContext(), text->getColor());
shader.setUniformTexture(_graphics.gxmContext(), ch.texture);
mesh.draw(_graphics.gxmContext());
mesh.release();
x += ch.Advance;
}
}
Here is the code for freeing the mesh :
Code: Select all
void Mesh::release()
{
gpu_free(_indicesUid);
gpu_free(_verticesUid);
}
Code: Select all
void gpu_free(SceUID uid)
{
void *mem = nullptr;
if (sceKernelGetMemBlockBase(uid, &mem) != SCE_OK)
{
debugNetPrintf(ERROR, "Error get mem block\n");
return;
}
if (sceGxmUnmapMemory(mem) != SCE_OK)
{
debugNetPrintf(ERROR, "Error sceGxmUnmapMemory\n");
return ;
}
if (sceKernelFreeMemBlock(uid) != SCE_OK)
{
debugNetPrintf(ERROR, "Error sceGxmUnmapMemory\n");
return;
}
}
Code: Select all
void Mesh::draw(SceGxmContext *context)
{
if (_pVertices == nullptr)
{
debugNetPrintf(ERROR, "null verticies...\n");
return ;
}
if (_pIndices == nullptr)
{
debugNetPrintf(ERROR, "null indicies...\n");
return ;
}
sceGxmSetVertexStream(context, 0, _pVertices);
sceGxmDraw(context,
SCE_GXM_PRIMITIVE_TRIANGLES,
SCE_GXM_INDEX_FORMAT_U16,
_pIndices,
_indices.size());
}
Thanks for your help!
PS: this is a quick test, and the code is not optimized at all (I will switch to a font atlas, and one mesh for a string instead of one mesh for a char)
Advertising