Reputation: 169
I am trying to create a text class witch has its own vertex array, vertex buffer, index buffer and draw them on a function call. It looks like so:
class Text {
private:
std::string m_FontFilePath;
std::string m_Text;
Texture* m_FontTexture;
VertexBuffer* m_Vbo;
IndexBuffer* m_Ibo;
VertexArray* m_Va;
float* m_TextPos;
unsigned int* m_Index;
unsigned int m_IndexCount;
public:
Text(std::string fontFilePath, std::string text, float posX, float posY);
~Text();
void drawText();
};
void Text::drawText()
{
m_Va->Bind();
glDrawElements(GL_TRIANGLES, m_IndexCount, GL_UNSIGNED_INT, nullptr);
}
This is the constructor that creates everything:
Text::Text(std::string fontFilePath, std::string text, float posX, float posY)
: m_FontFilePath(fontFilePath), m_Text(text)
{
VertexArray va2;
va2.Bind();
m_TextPos = new float[m_Text.size() * 24];
std::cout << posX << " " << posY<<"\n";
float unitH = 0.1f, unitW = 0.1f;
int countNow = 0;
for (auto letter : m_Text)
{
addLetter(m_TextPos, {
// posX posY poZ TextureCoord, TextureIndex
posX, posY, 0, 0.0f, 0.0f, 0.0f,
posX + unitW, posY, 0, 1.0f, 0.0f, 0.0f,
posX + unitW, posY + unitH, 0, 1.0f, 1.0f, 0.0f,
posX, posY + unitH, 0, 0.0f, 1.0f, 0.0f
}, countNow);
posX += unitW;
countNow += 24;
}
// this creates a square for every letter of the word
VertexBuffer vb2(m_TextPos, sizeof(float) * 24 * m_Text.size());
VertexBufferLayout vbl2;
vbl2.Push<float>(3);
vbl2.Push<float>(2);
vbl2.Push<float>(1);
va2.AddBuffer(vb2, vbl2);
m_Index = new unsigned int[m_Text.size() * 6];
for (int i = 0; i < m_Text.size(); i++) {
m_Index[i * 6 + 0] = i * 4 + 0;
m_Index[i * 6 + 1] = i * 4 + 1;
m_Index[i * 6 + 2] = i * 4 + 2;
m_Index[i * 6 + 3] = i * 4 + 2;
m_Index[i * 6 + 4] = i * 4 + 3;
m_Index[i * 6 + 5] = i * 4 + 0;
}
// this creates the m_Index array
IndexBuffer ibo2(m_Index, m_Text.size() * 6);
m_Vbo = &vb2;
m_Ibo = &ibo2;
m_Va = &va2;
m_IndexCount = 6 * m_Text.size();
std::cout << "INDEXES:\n";
for (int i = 0; i < m_Text.size() * 6; i++) {
std::cout << m_Index[i] << " ";
if ((i + 1) % 6 == 0) std::cout << "\n";
}
std::cout << "\nINSIDE VBO:\n";
for (int i = 0; i < 24 * m_Text.size(); i++) {
std::cout << m_TextPos[i] << " ";
if ((i + 1) % 6 == 0)std::cout << "\n";
}
va2.Unbind();
}
The IndexBuffer
and VertexBuffer
have the right data in them(I checked both).
If I take all the data from this class and move it in main.cpp and draw it there it works fine witch I find weird.
The main loop looks like so:
Text test(filePath, "randomText", 0.1f, 0.1f);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
// va = vertex array I created above this while loop, contains
va.Bind(); // 2 squares, it draws good
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr);
test.drawText(); // nothing draws on screen
glfwSwapBuffers(window);
glfwPollEvents();
}
Upvotes: 1
Views: 59
Reputation: 210877
Your buffers objects are local in scope of Text::Text
. The attributes are dangling pointers. You have to create dynamic objects. Remove the local variables va2
, vb2
and ibo2
but allocate dynamic memory and create the objects with the new
operator:
Text::Text(std::string fontFilePath, std::string text, float posX, float posY)
: m_FontFilePath(fontFilePath), m_Text(text)
{
m_Va = new VertexArray();
m_Va->Bind();
// [...]
m_Vbo = new VertexBuffer(m_TextPos, sizeof(float) * 24 * m_Text.size());
// [...]
m_Ibo = new IndexBuffer(m_Index, m_Text.size() * 6);
// [...]
}
Don't forget to delete
the objects in the class's destructor.
Upvotes: 2