2016-04-08 2 views
0

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

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); 

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

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):

Mario expected

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

Mario actual

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

ответ

1

От How pixel data are stored with CImg:

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

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

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

+0

большой. Но CImg настолько прост в использовании и работает с: (и я установил все мои зависимости для него ... Угадайте, что в следующий раз я должен прочитать документацию. – calcyss

+0

Есть * тонны библиотек загрузки изображений. SDL_Image, DevIL, SOIL и т. Д. –

+0

Я сейчас смотрю на них. Я отклонил SDL_Image, поскольку я не хочу использовать SDL (просьба не спрашивать, почему: D), у меня проблемы с компиляцией DevIL с MinGW 5.1 и Похоже, что SOIL загружается непосредственно в текстуры OpenGL, что неприемлемо для меня. – calcyss

0

Используйте 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 действительно большая библиотека, поэтому все эти виды трансформаций были запланированы в библиотеке.

+0

Также будьте осторожны, чем когда вы применяете 'CImg :: permute_axes()' на вашем экземпляре 'CImg ', это также меняет свои размеры соответственно на данная перестановка. Поэтому 'img.spectrum()' становится 'img.width()' и т. Д. (Width() -> height() и height() -> depth()). – bvalabas