obrazek raz jest a raz nie w zaleznosci od miejsca inicjalizacji obiektu

0

Mam dziwny problem - piszę program w Visual studio c++ 2010 - nie wiem czy przypadkiem przyczyna nie leży w jego odśmiecaczu, nie wiem.
Używam również biblioteki SDL do ładowania obrazków oraz WinAPI oraz OpenGL. Mam wiele klas, ale opisze najwazniejsze miejsca dwoch klas, ktore podejrzewam o problem.

Mam klase View do inicjalizacji i ladowania obrazkow - oto jej konstruktor:

 
View::View(void)
{
        //inicjalizacja zmiennych:
	x = 30;
	y = 10;	
	objectLength = 20;

	//zaladowanie obrazka przy uzyciu biblioteki SDL:
	TextureLoading t;
	texture[0] = t.LoadTexture("../images/obr.bmp");
}

W konstruktorze klasy OpenGL inicjalizuje klase View:

 
OpenGL::OpenGL(void)
{
	view = View();
}

Mam również procedurę okna WinAPI - wiadomo przechwytującą wszystkie komunikaty od uzytkownika oraz w ktorej sa wywolywane rozne metody klasy OpenGL:

 
LRESULT CALLBACK WindowProcedure::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
OpenGL openGL = OpenGL();
......
}

Jesli w tej procedurze daje tak jak teraz inicjalizacje klasy OpenGL to obrazki sie laduja i niby jest wszystko ok TYLKO ze zuzycie procesora siega 80% i program dziala bardzo wolno. Sadze, ze przyczyna moze byc to, ze wielokrotnie laduje obrazek, bo procedura okna jest wywolywana wielokrotnie, wiec pomyslalem sobie, ze zainicjalizuje klase OpenGL globalnie i bede tylko wywolywac jej metody w procedurze okna, ale niestety program kompiluje sie bez bledow, wszystko dziala tylko nie laduja sie obrazki i teraz czy ktos wie moze co moze byc tego przyczyna ? :P

0

Nie znam C++ i nie rozumie tego kodu, ale zawsze mi sie wydawało że jeśli korzystasz z SDL to obrazki wyświetlasz w SDL, a jeśli SDL inicjujesz jako okno OpenGL to ładujesz bitmape przez opcje OpenGL. A sugerując się opisem

//zaladowanie obrazka przy uzyciu biblioteki SDL:

A jakoś nie widze kodu w OpenGL do ładowania bitmap. W ogóle się dziwie że to działa ;)

W tutorialu NeHe w zasadzie chyba wszystko jest, a jak połaczyć SDL powinno być na stronie SDL. Tam jest kupa dokumentacji i tutoriale.

0

tzn. nie uzywam SDLa do tworzenia okna (choc oczywiscie mozna), wykorzystuje go tylko do ladowania bitmap, a wykorzystywany przeze mnie kod do tego celu to:

GLuint TextureLoading::LoadTexture(const char * filename)
{
	GLuint texture;
	GLint nOfColors;
	GLenum texture_format;
	SDL_Surface* surface; 
	
	if ( (surface = IMG_Load(filename)) ) 
	{  
		if ( (surface->w & (surface->w - 1)) != 0 ) 
		{
			MessageBox(hWnd, TEXT("image width is not a power of 2"), TEXT("error"), MB_OK | MB_ICONINFORMATION);
		} 
		if ( (surface->h & (surface->h - 1)) != 0 ) 
		{
			MessageBox(hWnd, TEXT("image height is not a power of 2"), TEXT("error"), MB_OK | MB_ICONINFORMATION);
		}
 
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)   
        {
            if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGBA;
            else texture_format = GL_BGRA;
        } 
		else if (nOfColors == 3)  
        {
            if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGB;
            else texture_format = GL_BGR;
        } 
		else 
		{
			MessageBox(hWnd, TEXT("the image is not truecolor.."), TEXT("error"), MB_OK | MB_ICONINFORMATION);
        }
 
		glGenTextures(1, &texture); 
		glBindTexture(GL_TEXTURE_2D, texture); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
		glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); 
	} 
	else 
	{
		MessageBox(hWnd, TEXT("SDL could not load image"), TEXT("error"), MB_OK | MB_ICONINFORMATION);
		SDL_Quit();
		return 1;
	}    

	SDL_FreeSurface(surface);
	return texture;
}
 
0

Strasznie to zakręcone ;)
Jeśli inicjujesz okno z OpenGL to, ja bym sie skupił na wyświetleniu zwykłego trójkąta w OpenGl. A potem martwił się bitmapą i SDL.

W linuxie okno z OpenGL odświeżasz jak masz sygnał. Choć nie pamiętam czy jest potrzeba to robić przy podwójnym buforowaniu.

Ale jeśli masz sygnał o odsłonięciu okna to po przerysowaniu powinieneś mieć trójkąt (obrazek), jeśli tylko OpenGL jest właściwie połaczone z oknem.

Wstaw jakieś linie debugujące. Sprawdź czy dbierasz (1) sygnał do przerysowania okna, czy funkcja (2) OpenGL w ogóle rysuje i czy wywoływana (3) jest funkcja wyświetlająca. Sprawdź czy działa jeśli wywołujesz to z automatu co 1 sek. Jeśli funkcje się wywołują a trójkąta dalej nie ma, to problem może być niewłaściwa konfiguracja OpenGl podczas odpalania.

Niestety więcej nie pomoge bo nie wiem jak w C++ i windowsie się to robi. Ale idea powinna być ta sama.

0
Arz napisał(a)

W linuxie okno z OpenGL odświeżasz jak masz sygnał. Choć nie pamiętam czy jest potrzeba to robić przy podwójnym buforowaniu.

Owszem, używając X11 rysujesz ponownie gdy otrzymasz odpowiedni sygnał. Przy podwójnym buforowaniu po kodzie OpenGL po prostu zmieniasz bufor. Poza tym nic się w programie nie zmienia. WinAPI wymaga (w przeciwieństwie do X11) odrębnej procedury do przetwarzania wiadomości od menedżera okien (w tym przypadku WndProc).

Co do tematu - na pierwszy rzut oka (i na tą ilość kodu) widzę, że wczytujesz swoją teksturę więcej niż 1 raz. Raczej bez potrzeby, bo funkcja WndProc jest wywoływana za każdym razem gdy dostajesz "wiadomość" od menedżera okien (a zdarza się to kiedy naciśniesz klawisz, poruszysz myszką, zminimalizujesz okno itd.).

Zauważyłem jeszcze jeden szkopuł w twojej funkcji do wczytywania tekstur:

// ... jeżeli tekstura nie była wczytana
SDL_Quit();
return 1;

Zwracasz identyfikator 1, pod którym może znajdować się wcześniej załadowana tekstura lub nic. Radziłbym zwracać 0, bo OpenGL pod identyfikatorem 0 trzyma pustą teksturę (blank), którą możesz używać jak poprawnie wczytaną teksturę (jest ona biała, więc od razu zauważysz problem).

Niestety nic więcej nie jestem w stanie ci powiedzieć z taką ilością kodu. Spróbuj poszukać problemu w innym miejscu (i wyrzuć to wczytywanie z WndProc).

1 użytkowników online, w tym zalogowanych: 0, gości: 1