0

I'm loading a texture using a class that I've written, as shown below. The aim is to create a new texture, load it with data that is stored in an array, and render it onto the screen. The texture is created without any problem, and loaded as well. However, it's causing memory leaks where the application memory size keeps increasing, despite calling delete in order to invoke the Texture class' destructor to delete the textures.

void renderCurrentGrid(){    

// Get the current grid (custom wrapper class, it's working fine)
Array2D<real_t> currentGrid = m_Continuum->getCurrentGrid();

// load it as a texture
Texture *currentGridTexture = new Texture(GL_TEXTURE_2D);
currentGridTexture->load(currentGrid.sizeWd(), currentGrid.sizeHt(), &currentGrid(0,0));

......

delete currentGridTexture;
}

Texture class' load function:

bool Texture::load(const size_t width, const size_t height, const float *data)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

// Allocate a texture name
glGenTextures(1, &m_TextureObj);

// select current texture
glBindTexture(GL_TEXTURE_2D, m_TextureObj);

// select replace to ensure texture retains each texel's colour
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// if texture wraps over at the edges
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glGenerateMipmap(GL_TEXTURE_2D);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,/* &density(0,0)*/data);

m_Loaded = true;
return true;
}

and the destructor of the Texture class:

Texture::~Texture()
{
glBindTexture(m_TextureTarget, m_TextureObj);
glDeleteTextures(1, &m_TextureObj);
glBindTexture(m_TextureTarget, NULL);
}

Texture class' private data members:

private:
GLenum m_TextureTarget;
GLuint m_TextureObj;

bool m_Loaded;

Here, I've created the new texture, and loaded it using the texture class' load function. The textures render absolutely fine, but the loading causes memory leaks. The application memory size keeps increasing when I check it on task manager.

However, when I comment out the line

currentGridTexture->load(....);

the memory leaks stop. I've omitted the rendering functions,a sit's not relevant to the question.

genpfault
  • 51,148
  • 11
  • 85
  • 139
ccoder83
  • 504
  • 6
  • 15
  • `glDeleteTexture` releases GPU resources, you seem to be leaking CPU memory that's an entirely different problem. – Borgleader Feb 20 '15 at 16:42
  • good point, it is the CPU, where should I be looking in order to try and find the memory leak, as I'm stumped at this point because the memory leak is happening in the load function of the texture class? – ccoder83 Feb 20 '15 at 17:02
  • Unrelated, but worth noting: `glGenerateMipmap (...)` is called in the wrong order with respect to `glTexImage2D (...)`. You need to call that ***after*** you upload an image to texture LOD **0** - otherwise, there is no image to generate the lower resolution mipmap LODs from. _It does not matter right now since you are not using a mipmap minification filter, but it will if you ever change that._ – Andon M. Coleman Feb 21 '15 at 02:33
  • Thanks for pointing that out, @Andon. I was having problems with generating mipmaps, and that's why I was using the `GL_NEAREST` argument. Although my solution below, would have allowed the generation of mipmaps during the second render call, it's a subtle difference I would not have spotted. Switching the order resolved it. – ccoder83 Feb 23 '15 at 12:51

1 Answers1

0

I've managed to solve the question above. In the Texture class' load function, I'm calling

glGenTextures(1, &m_TextureObj)

When calling this function, according to the OpenGL documentation, the second argument specifies an array in which the generated texture names are stored. In order to store the texture, it allocates a certain amount of CPU memory.

The load function was being called every rendering update, hence OpenGL was allocating resources for every time glGenTextures was being called within that function. Although glDeleteTextures was being called by the destructor which in theory should deallocate the resources, according to this link, it's not the case, quote below:

Just because you tell OpenGL that you're done with a texture object doesn't mean that OpenGL must immediately relinquish that memory. Doing that generally requires some pretty heavy-weight operations. So instead, drivers will defer this until later.

As I was creating and deleting a texture every update, I came up with a solution so that I can use the same texture object, and load it with different data to prevent OpenGL allocating resources every update.

I moved the glGenTextures function to the constructor of the Texture class, so that it was being called only once when the Texture object is instantiated. I now create one texture object and load it with new data every update.

To ensure glGenTextures function is called only once, I also moved the instantiation and deletion of the Texture object within the rendering function i.e.

Texture *currentGridTexture = new Texture(GL_TEXTURE_2D);
...
delete currentGridTexture;

and declared currentGridTexture as a private data member of the rendering class, and instantiated it in the constructor, and deleted it in the destructor of that class, such that only one texture object is being created and deleted during the run time of my application, instead of creating and deleting texture objects every update.

Community
  • 1
  • 1
ccoder83
  • 504
  • 6
  • 15