Я обнаружил довольно отвратительное поведение glDeleteTexture, удаляющее только части памяти (со стороны графического процессора и по мере восстановления текстур ради скорости в ОЗУ), что в моем случае является ошибкой showtopper, моя программа ест все память.
Я не хочу / не требую, чтобы вы читали весь код, это просто демонстрация, я бы лучше знал, как на самом деле использовать glDeleteTextures, чтобы он не утечка любая память.
В примере кода для компиляции требуется Qt 4.5 или новее:
glleak.pro
QT += opengl
SOURCES += main.cpp \
glleak.cpp
HEADERS += glleak.h
main.cpp
#include <QtOpenGL>
#include <QtGui>
#include "glleak.h"
int main(int argc, char** argv){
QApplication app(argc, argv);
glleak gll(0);
gll.show();
return app.exec();
}
glleak.h
#ifndef GLLEAK_H
#define GLLEAK_H
#include <QGLWidget>
#include <QMouseEvent>
#include <QDebug>
#include <QList>
class glleak : public QGLWidget
{
Q_OBJECT
public:
glleak(QWidget* parent = 0);
virtual ~glleak();
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void drawScene(GLenum mode);
void wheelEvent(QWheelEvent* event);
void hardcoreTexturing();
private:
QList<GLuint> texels;
};
#endif // GLLEAK_H
glleak.cpp
glleak::glleak(QWidget* parent) :
QGLWidget(parent)
{
}
glleak::~glleak()
{
}
void glleak::initializeGL(){
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_MULTISAMPLE);
glLineWidth (1.5f);
glPointSize(4.5f);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void glleak::resizeGL(int w, int h){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2.0, w/2.0, h/2.0, -h/2.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, w, h);
glLoadIdentity();
}
void glleak::paintGL(){
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0f,1.0f,1.0f);
drawScene(GL_RENDER);
glPopMatrix();
}
void glleak::drawScene(GLenum mode){
qDebug() << "drawed #" << texels.count() << " Textures";
hardcoreTexturing();
}
void glleak::hardcoreTexturing(){
glEnable(GL_TEXTURE_2D);
for ( int i(0); i<texels.count(); ++i){
glPushMatrix();
glTranslatef(1.1f*i, 2.2f*i, 0.0f);
glBindTexture(GL_TEXTURE_2D, texels.at(i));
glBegin(GL_QUADS);
{
glTexCoord2i(0,0);
glVertex2i(-128,-128);
glTexCoord2i(0,1);
glVertex2i(-128,128);
glTexCoord2i(1,1);
glVertex2i(128,128);
glTexCoord2i(1,0);
glVertex2i(128,-128);
}
glEnd();
glPopMatrix();
}
glDisable(GL_TEXTURE_2D);
}
void glleak::wheelEvent(QWheelEvent* event){
glEnable(GL_TEXTURE_2D);
int n(50);
if (event->delta()>0){
qDebug() << "gen textures";
for (int i(0); i<n; ++i){
QImage t("./ballmer_peak.png","png");
GLuint tex(0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
texels.append(tex);
}
}
else{
qDebug() << "del textures";
for (QList<GLuint>::iterator i(texels.begin()); i!=texels.end();){
glDeleteTextures(1, &(*i));
i = texels.erase(i);
if (--n <= 0)
break;
}
}
glDisable(GL_TEXTURE_2D);
updateGL();
}
ballmer_peak.png
Изображение для загрузки и рендеринга
Примечание: скомпилируйте демонстрацию: просто поместите все это в папку, переименуйте ваше изображение в ballmer_peak.png , вызовите qmake, make, ./glleak
Примечание: Использование демонстрации: Использование колесика мыши для создания или удаления 50 текстур одновременно
Если я использую glDeleteTextures совершенно неправильно, скажите, пожалуйста, как его использовать.
У меня нет идей, так как мое использование соответствует официальному использованию OpenGL glDeleteTextures .