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();
}
CodePudding user response:
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.