'How to properly use glTexImage2D to render an object each frame?

This is the code for a ground object that gets rendered every frame in a game I'm making with c++ and openGl.

Ground::Ground() {
    this->loadedObject = loadObject("ground.obj");
    this->vertices = getVerticesFromLoadedObject(this->loadedObject);
    this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);
    
    this->textureData = loadTexture("ground.jpg");
    glGenTextures(1, &this->textureId);
    glBindTexture(GL_TEXTURE_2D, this->textureId);
}

void Ground::draw() {
    glEnable(GL_TEXTURE_2D);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);

    tinyobj::shape_t shape = this->loadedObject.shape;
    unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
    glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
    glVertexPointer(3, GL_FLOAT, 0, this->vertices);
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
    glDisable(GL_TEXTURE_2D);

}

Even though this works, calling glTexImage2D every frame causes a memory leak, but I can't get the texture to show otherwise, I tried doing the call in Ground's constructor but it doesn't load the image at all. How do I load the image just once to avoid the memory leak?

Update: with glTexImage2D in the constructor

Ground::Ground() {
    this->loadedObject = loadObject("ground.obj");
    this->vertices = getVerticesFromLoadedObject(this->loadedObject);
    this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);

    this->textureData = loadTexture("ground.jpg");
    glGenTextures(1, &this->textureId);
    glBindTexture(GL_TEXTURE_2D, this->textureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
}

void Ground::draw() {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, this->textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);

    tinyobj::shape_t shape = this->loadedObject.shape;
    unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
    glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
    glVertexPointer(3, GL_FLOAT, 0, this->vertices);
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
    glDisable(GL_TEXTURE_2D);
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source