2013-12-06 2 views
0

Я создаю класс для управления изображениями с помощью OpenGL. Чтобы загрузить изображение, я использую SOIL для загрузки PNG. Поскольку мне нужно проверить конфликт, я хочу получить прозрачный пиксель. Так я пытаюсь получить данные с помощью: glGetTexImageОшибка переполнения буфера при вызове glGetTexImage несколько раз

Конструктор загружает изображение:

Image::Image(string imagePath, unsigned int flags){ 
    this->imagePath=imagePath; 
    this->pxData=NULL; 
    texture=SOIL_load_OGL_texture 
    (
    imagePath.c_str(), 
    SOIL_LOAD_AUTO, 
    SOIL_CREATE_NEW_ID, 
    flags 
    ); 

    //Use that to subdivide in sprites the texture 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_WIDTH, &textureWidth); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_HEIGHT, &textureHeight); 
    glBindTexture(GL_TEXTURE_2D, this->texture); 
    //cout << "Real Dimensions - " << textureWidth << "-" << textureHeight; 

    loadPixels(); //multiple instances of image generates error here 
} 

нагрузку при LoadPixels внутри моей структуры пиксельные данные.

typedef struct PixelData{ 
    unsigned char r; 
    unsigned char g; 
    unsigned char b; 
    unsigned char a; 
} PixelData; 
PixelData* pxData; 

Тогда в loadPixels я хранить эти данные:

void Image::loadPixels(){ 
    pxData = new PixelData[textureHeight*textureWidth]; 
    glGetTexImage(GL_TEXTURE_2D, 1, GL_RGBA, GL_UNSIGNED_BYTE , pxData); 
} 

Проблема заключается в том, если я создать изображение:

Image img("/Developer/img.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 

Он работает отлично.

Если я создать много образов:

Image img("/Developer/img.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img2("/Developer/img2.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img3("/Developer/img3.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img4("/Developer/img4.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img5("/Developer/img5.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img6("/Developer/img6.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img7("/Developer/img7.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img8("/Developer/img8.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img9("/Developer/img9.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 
    Image img10("/Developer/img10.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT); 

Тогда моя программа выходит из строя:

Ошибка является:

OpenGL Game Engine(35463,0x7fff7b121310) malloc: *** error for object 0x104017808: incorrect checksum for freed object - object was probably modified after being freed. 
*** set a breakpoint in malloc_error_break to debug 

Если я свой комментарий glGetTexImage (GL_TEXTURE_2D, 1, GL_RGBA , GL_UNSIGNED_BYTE, pxData); он работает отлично, поэтому я представляю, что проблема не в распределении.

Мне просто нужно получить данные о пикселях, чтобы сохранить его, я хочу создать некоторые данные, используя эти пиксели, поэтому мне нужно получить пиксель моей текстуры.

Примечание:

Программа останавливается на imagePath.c_str() с sigabort, если я раскомментировать loadPixels, если я комментировать его загружает мелкие все текстуры

Благодаря Одри я получил больше информации.

glGetTexLevelParameteriv(GL_TEXTURE_2D, this->texture, GL_TEXTURE_WIDTH, &textureWidth); 
glGetTexLevelParameteriv(GL_TEXTURE_2D, this->texture, GL_TEXTURE_HEIGHT, &textureHeight); 

Real Dimensions - 128-128 
Real Dimensions - 64-64 
Real Dimensions - 32-32 
Real Dimensions - 16-16 

Это то же изображение, но размеры продолжают уменьшаться.

Я проверил идентификатор, и он действительно создает новый идентификатор каждый раз, так почему размеры становятся беспорядочными?

Есть ли другой способ получить эти данные, что мне здесь не хватает? Другой вопрос, этот метод получает текстуру связывания, есть ли способ получить данные текстуры, используя идентификатор текстуры?

+0

Являются ли 'textureWidth' и' textureHeight' возвращающими то, что вы думаете о них? –

+0

Они возвращают размер текстуры, его ок. Проблема в том, когда я хочу получить данные из glGetTexImage, если я только один раз, когда данные вернутся отлично, но если я вызову много времени, программа сработает – Lefsler

+1

Мне интересно, пытается ли 'getGlTexImage писать слишком много байтов к 'pxData'. Это первое, что я проверил бы. Вы не можете получить ошибку при работе с одним изображением, потому что у вас есть некоторая память за пределами 'pxData', и она повреждена, но вы не заметили, и компьютер не жаловался/segfault. –

ответ

1
glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_HEIGHT, &textureHeight); 

Второй параметр не принимает текстуры ID. Это уровень mipmap. Вам нужно привязать текстуру сначала, а затем вызвать эту функцию с помощью 0, где вы положили текстуру.

В частности, ваши идентификаторы текстур почти наверняка создаются как «0», «1», «2» и т. Д. Каждый раз, когда вы вызывали glGetTexLevelParameteriv с последовательным значением, вы запрашивали меньший уровень mipmap на связанная текстура. Тот факт, что ваш первый звонок не увенчался успехом, заставляет меня подозревать, что SOIL_load_OGL_texture фактически не отвязывает его до его возвращения.

Помните, что почти никакая функция OpenGL не принимает идентификатор текстуры, буфера или шейдера в качестве параметра, а скорее действует на текущий связанный объект. Единственными функциями, которые вы обычно используете с фактическим идентификатором, являются те, которые создают, уничтожают или связывают объект, например glGenTextures, glDeleteTextures и glBindTexture

+0

Изображения точно такие же, я просто сделал копию , похоже, проблема с SOIL, я пытаюсь проверить, что – Lefsler

+0

Да, я просто понял, что неправильно понял вопрос. Я исправил ответ, исходя из вашего комментария на пост Андрея. Вы запрашиваете последовательные уровни mipmap по мере увеличения размера текстуры, поэтому ваши высоты и ширину уменьшаются вдвое с каждой текстурой. – Jherico

+0

Спасибо, это сработало – Lefsler

2

В соответствии с обсуждением в комментариях, похоже, что getGlTexImage переполняет буфер pxData. Если вы опубликуете, какой вывод функций дает вам textureWidth и textureHeight, мы сможем выяснить, что не так. (Например, вы уверены, что совместимость между типом возвращаемой функции геттерной и переменными textureWidth и т.д.?)

Edit: Я хотел бы проверить ваш <Gl.h>, чтобы увидеть подпись функции glGetTexLevelParametersiv.Я немного посмотрел в Интернете, и версия Microsoft WINAPI имеет другую подпись, чем на OpenGL.org, и ни одна из них не согласна с подписью, которую вы используете.

Try переназначения и переписывание этого:

glBindTexture(GL_TEXTURE_2D, this->texture); 
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &textureWidth); 
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &textureHeight); 
+0

Привет, Андрей, да, они используют GLint, что, кажется, происходит каждый раз я вызываю ту же функцию, я не знаю, почему размер делится на 2, исходный размер - 256 на 256, затем я перехожу на 128 на 128 до 0. – Lefsler

Смежные вопросы