LINUX.ORG.RU

SDL в полноэкранном режиме не всегда работает

 sdl linux nvidia


0

1

В общем, у меня Ubuntu 12.04 64-bit LTS. Версия libsdl1.2-dev = 1.2.14-6.4ubuntu3. nVidia - драйвер 310.14, карта GTX465.

Проблема: на компьютере (том что я описал) - не срабатывает вывод изображения в полноэкранном режиме. Иногда да, иногда нет, иногда ровно через раз. Это на домашнем компе. А на работе nVidia 8500GT - с опенсорсным драйвером бывает иногда что не срабатывает, а с проприетарным (current версия, 2** - точно не помню) - всегда срабатывает.

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

Работаю так: по нажатию кнопки в GUI (Qt) - ставлю видео-режим set, затем три секунды жду таймером и затем выводу картинку draw_image, а через 8 секунд после старта - restore т.е. возвращаюсь как было.

(И заодно поинтересуюсь, как задать свой refresh rate в SDL? чтобы ыло например 75 Гц а не 95 и не 60 для того или иного режима)

#include "video_mode.h"
#include <QDebug>

video_mode::video_mode(QObject *parent) :
QObject(parent)
{
	ready = false;
}

void video_mode::set(int _w, int _h)
{
	SDL_Init(SDL_INIT_VIDEO);
	SDL_ShowCursor(0);
	w = _w;
	h = _h;
//	system("export SDL_VIDEO_GF_REFRESH_RATE=60");
	surface = SDL_SetVideoMode(w, h, 24, SDL_FULLSCREEN);
	ready = true;
}

void video_mode::restore()
{
	ready = false;
	SDL_ShowCursor(1);
	SDL_Quit();
}

void video_mode::draw_image(QImage image)
{
	if(!ready)
	{
		qDebug() << "ERROR: video_mode::draw_image not ready";
	}

	SDL_Rect src, dst;
	SDL_Surface *rgb = SDL_CreateRGBSurfaceFrom((void*) image.bits(), image.width(), image.height(), 24, image.width()*3, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);

	src.x = 0;
	src.y = 0;
	src.w = image.width();
	src.h = image.height();

	dst.x = 0;
	dst.y = 0;
	dst.w = w;
	dst.h = h;

	int res = SDL_BlitSurface(rgb, &src, surface, &dst);
	qDebug() << "SDL_BlitSurface" << res;
	if(res != 0)
	{
		qDebug() << "ERROR: SDL" << res << QString((char*) SDL_GetError());
	}

//	image.save("test_qt.bmp");//!!!
//	QImage image_sdl = QImage((uchar*) rgb->pixels, rgb->w, rgb->h, QImage::Format_RGB888);//!!!
//	image_sdl.save("test_sdl.bmp");//!!!

	SDL_UpdateRect(surface, 0, 0, w, h);
	SDL_FreeSurface(rgb);
}

Никаких сообщений об ошибках операции SDL_BlitSurface не выводится - т.е. формально всё идеально работает. А по факту я как видел черный экран так и вижу...

★★★★★

Последнее исправление: I-Love-Microsoft (всего исправлений: 2)

Ответ на: комментарий от andreyu

Проверки кода ошибки для лохов, а реальные пацаны и без этого обходятся?

спасибо, это конечно ценное замечание, но у SDL_BlitSurface у меня есть проверка на ошибку и если предыдущие этапы были неверны - то и на блиттинге выдаст ошибку :)

добавил проверку ошибок - как я полагал - никаких ошибок и не было если blit всегда 0 выдает, т.е. успех

в общем - я заметил что если изменить загружаемую картинку на PNG то работает всегда стабильно и без ошибки, а было у меня в JPG, у меня в Qt какие-то серьезные траблы с jpeg, буду наверное через turbojpeg грузить картинку

а вообще странно, я все равно перегоняю в QImage::Format_RGB888 - разницы точно быть не должно, но с PNG стабильно - факт :)

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от andreyu

и еще... если можно, как установить частоту обновления картинки? мне надо чтобы было всегда 75 Гц, у меня преобразователь VGA->PAL, так вот на макс. разрешении он берет не более 75 Гц, а если больше то уже не кажет

я пока не нашел стандартного пути для задания частоты обновления...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от andreyu

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

я уже даже сделал так:

surface = SDL_SetVideoMode(w, h, 24, SDL_FULLSCREEN | SDL_DOUBLEBUF);
а затем
SDL_Flip(surface);
и возвращает успех всегда

но тем не менее - черный экран в 25% случаев вижу... с чем может быть связано? мне и коллеги говорили что когда они работают с SDL - тоже такое бывает у них, хотя они берут готовые примеры и прочие источники, не мой код а их личный

я уже пробовал и несколько раз blit делать и до и после SDL_Flip и все равно иногда черный экран и ноль ошибок - что это???

проблема не так проста как кажется

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Никогда не встречал подобных проблем с SDL. Если все проинициализировано правильно, то и работает все корректно.

Имиджи я грузил приблизительно так:

SDL_Surface* notOptimized = IMG_Load_RW(SDL_RWFromMem(rawData, dataSize), 1);
SDL_Surface* optimized = SDL_DisplayFormatAlpha(notOptimized);
SDL_FreeSurface(notOptimized);

Я очень давно отказался от SDL, поэтому могу ошибаться.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

А что используешь вместо SDL? Мне лишь надо ну хотя бы просто сменить разрешение экрана на 1024x768 и выставить 75 Гц. Я могу отказаться от SDL запросто, у меня ведь с гулькин нос кода под него написано.

Другие способы сделать 1024x768@75Гц есть? Программно, на C++.

I-Love-Microsoft ★★★★★
() автор топика

Если используешь Blit нужно в SDL_SetVideoMode() установить флаги SDL_HWSURFACE и SDL_DOUBLEBUF. А SDL_UpdateRect надо убрать.

int video_display_update(Screen_t *screen, Image_t *image) {
    SDL_Surface *tmp_img = SDL_CreateRGBSurfaceFrom(image->data, image->width, image->height, image->bpp, image->width * image->bpp / 8, 0, 0, 0, 0);
    SDL_BlitSurface(tmp_img, &screen->rect, screen->target, &screen->rect);
    SDL_Flip(screen->target);
    SDL_FreeSurface(tmp_img);
}

rimsleur
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.