SDL / OpenGL загруженные цвета изображения инвертированы

Я пытаюсь загрузить изображение в свою игру. Он написан на C ++, с SDL и OpenGL, а также с фреймворком SDL_Image.
Я получил изображение и повернул / перевернул его для своих нужд, но есть две основные проблемы.

Во-первых, цвета изображения полностью инвертированы. (т.е. синий -> красный)
У меня есть формат «GL_RGB» или «GL_RGBA», в зависимости от байтов на пиксель. Я пробовал с PNG, JPEG и BMP, но все равно. Я потерялся!

—Спасибо datenwolf за исправление моих глупых ошибок!

Во-вторых, изображение рисует один раз, и все тут. Он не перерисовывается в другом буфере, он просто отображается один раз, а затем исчезает, как только рисуется следующий кадр.

GLuint loadTexture()
{
SDL_Surface* image = IMG_Load( "/Users/<My name>/Pictures/pacman board.jpeg" );

SDL_DisplayFormatAlpha(image);

unsigned object(0);

glGenTextures(1, &object);

glBindTexture(GL_TEXTURE_2D, object);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);int Mode = NULL;

if(image->format->BytesPerPixel == 3) {Mode = GL_RGB;}
else if(image->format->BytesPerPixel == 4) {Mode = GL_RGBA;}

glTexImage2D(GL_TEXTURE_2D, 0, Mode, image->w, image->h, 0, Mode, GL_UNSIGNED_BYTE, image->pixels);

SDL_FreeSurface(image);
return object;
}

int main(int argc, char * argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_WM_SetCaption("HI", NULL);
SDL_SetVideoMode(600, 600, 32, SDL_OPENGL);

glClearColor(0,0,0,1);
glViewport(0, 0, 600, 600);

glShadeModel(GL_SMOOTH);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

unsigned int pad_texture = 0;
pad_texture = loadTexture();//---MAIN LOOP---\\

bool isRunning = true;
SDL_Event event;
while (isRunning)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) { isRunning = false; }
if (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE) {isRunning = false;}
}glClear(GL_COLOR_BUFFER_BIT);
gluOrtho2D(0, 600, 0, 600); // For some reason, I prefer having '0,0' at the bottom left.

glPushMatrix();

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,pad_texture);

glBegin(GL_QUADS);

glTexCoord2d(0, 1); glVertex2f(0, 0);
glTexCoord2d(1, 1); glVertex2f(600, 0);
glTexCoord2d(1, 0); glVertex2f(600, 600);
glTexCoord2d(0, 0); glVertex2f(0, 600);
glEnd();

glDisable(GL_TEXTURE_2D);

glPopMatrix(); //Stop drawing

SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}

2

Решение

Большинство форматов файлов изображений имеют данные пикселей в порядке BGR или BGRA. Если вы загружаете такие данные изображения, используя порядок RGB, сине-красный канал, конечно, поменяется местами.

OpenGL также предлагает эти форматы пикселей, начиная с версии 1.4. Вам придется либо использовать обертку расширения, такую ​​как GLEW, либо получить и установить текущую glext.h получить доступ к токенам нового формата. Посмотри на http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml для полного списка поддерживаемых форматов в ядре OpenGL-3 и позже. Для более старых OpenGL, а именно с OpenGL-1.4 до OpenGL-2.1, посмотрите на http://www.opengl.org/sdk/docs/man2/xhtml/glTexImage2D.xml

Обновить

То, что ваше изображение показывает только один раз, объясняется следующим:

while (isRunning)
{
/*...*/

glClear(GL_COLOR_BUFFER_BIT);
gluOrtho2D(0, 600, 0, 600); // For some reason, I prefer having '0,0' at the bottom left.

gluOrtho2D умножает сверху на то, что уже на матрице. Который является то, что gluOrtho2D делал в предыдущей итерации. Также вы вышли из режима матрицы в «висячем» состоянии. Как правило, вы всегда должны заново устанавливать все состояние рисования OpenGL (область просмотра, чистый цвет, чистая глубина, все матрицы) в начале каждой итерации чертежа. В твоем случае

while (isRunning)
{
/*...*/

glViewport(0, 0, win_width, win_height);

glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, win_width, 0, win_height, -1, 1); // gluOrtho2D is the most useless wrapper ever..., just put a -1, 1 as additional parameters to glOrtho

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glShadeModel(GL_SMOOTH);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]