// COMPILE:
// g++ main_bug.cpp -lglut -lGLU -lpthread
// RUN: ./a.out
#include <GL/freeglut.h>
#include <vector>
#include <iostream>
using namespace std;
#define IMAGE_SIZE 1024
#define FRAMES_PER_SECOND 10
int mainWindowHD = 0;
// create a new RGBA texture from pData
GLuint manualTex(const unsigned char* pData)
{
GLuint texname;
glGenTextures(1, &texname);
glBindTexture(GL_TEXTURE_2D, texname);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
IMAGE_SIZE, IMAGE_SIZE, 0, GL_RGBA,
GL_UNSIGNED_BYTE, pData);
return texname;
}
int renderLoopCounter = 0; // 0-20
int cnt = 0; // one-up counter
std::vector<GLuint> mTexts; // list of textures i've created
bool done = false;
void Display (int t)
{
cnt++;
if (renderLoopCounter == FRAMES_PER_SECOND)
{
renderLoopCounter = 0;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
// until i've created 50 textures
if (!done && cnt > FRAMES_PER_SECOND*2 && mTexts.size() < 50)
{
// create 10 textures at a time
for (int i=0;i<10;i++)
{
unsigned char* img = new unsigned char[IMAGE_SIZE*IMAGE_SIZE*4];
GLuint tex_id = manualTex(img);
// @note: if i do this right here, there is no apparent memory issue:
// glDeleteTextures(1, &tex_id); tex_id = 0;
// but instead, i add to a list of textures to be deleted later
if (tex_id != 0)
{
mTexts.push_back(tex_id);
cout << "creating texture id=" << tex_id << endl;
}
delete[] img;
}
}
// once i've created 50, delete all the textures at once
if (renderLoopCounter == 0 && mTexts.size() >= 50)
{
for (int i=0;i<mTexts.size();i++)
{
GLuint tex_id = mTexts[i];
cout << "deleting: " << tex_id << endl;
glDeleteTextures(1, &tex_id);
}
mTexts.clear();
done = true;
}
renderLoopCounter++;
glutSwapBuffers();
glutPostRedisplay();
glutTimerFunc(1000/FRAMES_PER_SECOND, Display, 0);
}
main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(1024, 768);
mainWindowHD = glutCreateWindow("Testing screen");
glutTimerFunc(1000/FRAMES_PER_SECOND, Display, 0);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glEnable(GL_NORMALIZE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_FRONT);
glutPostRedisplay();
glutMainLoop();
}