Немедленный режим текстурирования странный вывод

Я пытаюсь просто нарисовать изображение с функциями немедленного режима OpenGL. Тем не менее, мой вывод довольно странный. Я попробовал несколько параметров текстуры, но получил тот же результат, иногда с другими цветами. Я не могу понять проблему, но я думаю, что это либо загрузка изображения, либо настройка текстуры. Я перейду к делу, вот как я генерирую свою текстуру (в классе Texture2D):

glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

Далее следует вызов glTexImage2D, например: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);, где данные представляют собой массив unsigned char со значением 255, белого цвета. Затем я загружаю файл PNG с помощью CImg, например:

CImg<unsigned char> image(_filename.c_str());
image.resize(m_Width, m_Height);
glBindTexture(GL_TEXTURE_2D, m_ID);
if(image.spectrum() == 4)
{
    unsigned char* data = image.data();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_Width, m_Height, GL_RGBA,   GL_UNSIGNED_BYTE, data);
}
else if(image.spectrum() == 3)
{
    unsigned char* data = image.data();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_Width, m_Height, GL_RGB, GL_UNSIGNED_BYTE, data);
}
glBindTexture(GL_TEXTURE_2D, 0);

Но когда я пытаюсь нарисовать текстуру в непосредственном режиме, как это (начало находится в верхнем левом углу, обратите внимание, что красный прямоугольник вокруг текстуры сделан намеренно):

void SimpleRenderer::drawTexture(Texture2D* _texture, float _x, float _y, float _width, float _height)
{
    _texture->setActive(0);
    glBegin(GL_QUADS);
      glTexCoord2f(0.0f, 0.0f);
      glVertex2f(_x, _y);

      glTexCoord2f(1.0f, 0.0f);
      glVertex2f(_x + _width, _y);

      glTexCoord2f(1.0f, 1.0f);
      glVertex2f(_x + _width, _y + _height);

      glTexCoord2f(0.0f, 1.0f);
      glVertex2f(_x, _y + _height);
    glEnd();

    glBindTexture(GL_TEXTURE_2D, 0);

    glColor3ub(strokeR, strokeG, strokeB);
    glBegin(GL_LINE_LOOP);
      glVertex2f((GLfloat)_x, (GLfloat)_y);
      glVertex2f((GLfloat)_x+_width, (GLfloat)_y);
      glVertex2f((GLfloat)_x+_width, (GLfloat)_y+_height);
      glVertex2f((GLfloat)_x, (GLfloat)_y+_height);
    glEnd();
}

Я ожидаю такой вывод внутри прямоугольника (отладка того же PNG в той же программе/потоке с помощью CImg):

Ожидается Марио

Но я получаю это:

Марио актуален

Может ли кто-нибудь обнаружить проблему с моим кодом?


person tubberd    schedule 08.04.2016    source источник


Ответы (2)


Из Как данные пикселей хранятся в CImg:

Значения не чередуются и упорядочены сначала по осям X, Y, Z и V соответственно (в соответствии с шириной, высотой, глубиной, затемненными размерами), начиная с верхнего левого пикселя до нижнего правого пикселя. мгновенное изображение с классическим запуском строки развертки. Таким образом, цветное изображение с затемнением = 3 и глубиной = 1 будет храниться в памяти как: R1R2R3R4R5R6......G1G2G3G4G5G6.......B1B2B3B4B5B6.... (т.е. следуя «плоской» структуре), а не как R1G1B1R2G2B2R3G3B3... (чередующиеся каналы),

OpenGL не работает с планарными данными, он ожидает чередующиеся пиксельные данные. Самое простое решение — использовать библиотеку, отличную от CImg.

Это не устраняет проблемы с масштабированием, но это хорошее место для начала.

person Dietrich Epp    schedule 08.04.2016
comment
отличный. Но CImg так прост в использовании и работе :( и я настроил для него все свои зависимости... Думаю, в следующий раз мне следует более внимательно прочитать документацию. - person tubberd; 09.04.2016
comment
Существует тонна библиотек для загрузки изображений. SDL_Image, DevIL, ПОЧВА и т. д. - person Dietrich Epp; 09.04.2016
comment
Я сейчас смотрю на эти. Я отклонил SDL_Image, так как не хочу использовать SDL (пожалуйста, не спрашивайте, почему :D), у меня проблемы с попыткой скомпилировать DevIL с MinGW 5.1, а SOIL, похоже, загружается только непосредственно в текстуры OpenGL, что для меня неприемлемо. . - person tubberd; 09.04.2016
comment
Звучит так, будто вы намеренно пытаетесь потерпеть неудачу... просто скачайте бинарные файлы DevIL, если не можете их скомпилировать, или используйте SDL, даже если вам это не нравится. - person Dietrich Epp; 09.04.2016
comment
Что ж, я не пытаюсь намеренно потерпеть неудачу, но попытка настроить DevIL с помощью CMAKE просто выдает ошибки проекта, и, как следствие, генерация не создает никаких Makefile ^^ Ну, я думаю, тогда мне придется использовать большую библиотеку. Вроде понравился CImg, особенно с его встроенными функциями обработки изображений. - person tubberd; 09.04.2016
comment
Предоставляет ли CImg какие-либо функции для извлечения данных в чередующемся формате? Не могу проверить документацию прямо сейчас, я также думаю, что мог бы просто преобразовать формат изображения самостоятельно. Не должно быть слишком сложно. - person tubberd; 09.04.2016
comment
Вы используете OpenGL, который в сто раз лучше, чем CImg для обработки изображений. Если вам нужна библиотека меньшего размера, вы можете использовать WinCodec, но это будет работать только в Windows. - person Dietrich Epp; 09.04.2016
comment
Ну да, но тогда мне придется самому писать алгоритмы xD - person tubberd; 09.04.2016

Используйте CImg<T>::permute_axes() для преобразования буфера изображения в чередующийся формат, например:

CImg<unsigned char> img("imageRGB.png");
img.permute_axes("cxyz"); // Convert to interleaved representation
// Now, use img.data() here as a pointer for OpenGL functions.
img.permute_axes("yzcx");  // Go back to planar representation (if needed).

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

person bvalabas    schedule 09.04.2016
comment
Также будьте осторожны, когда вы применяете CImg<T>::permute_axes() к вашему экземпляру CImg<unsigned char>, это также меняет свои размеры в соответствии с данной перестановкой. Таким образом, img.spectrum() становится img.width() и т. д. (width()->height() и height()->depth()). - person bvalabas; 09.04.2016