Optymalizacja zużycia procesora OpenGL

0

Dzień dobry

Nurtuje mnie pewna rzecz związana z zużyciem procesora.Pisze sobie gierkę w OpenGL/c++ gdy ją uruchamiam i odpalam menagera zadań na wydajności pokazuje mi ,że używa cały 1 rdzeń w moim przypadku 50% procesora.Na słabszych komputerach typu Athlon XP jest 100% zużycia procesora.Nie wiem co z tym zrobic.Wszystkie funkcje do renderingi uruchamiane są w głównej pętli while(Tak jak to pisze we wszystkich książkach).Tak szybko się ona wykonuje ,że nawet pomiędzy klamerkami jak nic nie ma to i tak morduje procesor na maxa.Jestem początkujący w pisaniu gier.Prosiłbym o wskazówki czego użyc aby to poprawic.

0

Procesora się nie morduje używając timerów, albo usypiaczy. Aktualnie pewnie twoja aplikacja osiąga kilkaset FPSów, które nie są nawet wyświetlane. Możesz użyć jakiś usypiaczy, np. Sleep(win)/usleep(linux), a najlepiej sprawdź w bibliotece której używasz czy nie ma niczego takiego.

0

Najlepiej ustalić jakaś wartość fps;
np. w taki sposób:

#define	MS_PER_FRAME (1000 / 25) //25 fps 

	while (loop)
	{
		int64 start = TimerGetMs();
		RENDER();
		while ((TimerGetMs() - start) < MS_PER_FRAME)
		{
			int32 yield = (int32) (MS_PER_FRAME - (TimerGetMs() - start));
			if (yield<0)
				break;
			sleep(yield);
		}
	}

TimerGetMs() zwraca obecny czas w mili sec.

0

A jeszcze lepiej po prostu ustawić synchronizację pionową (V-Sync) i wtedy żadna klatka nie "ucieknie", ani nie będzie też screen tearingu (nie wiem jak to na polski przetłumaczyć - cięcie ekranu?).

0

A tam, kombinujecie. Skoro autor pisze w OpenGL ma do tego (i wielu innych rzeczy) GLUT - mój pierwszy program w OpenGL, może się przydać jako przykład:

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void renderScene(void)
{
	glBegin(GL_TRIANGLES);
	
	float scale = 0.5f;
	
	glColor3f(1.0f, 0.0f, 0.0f);
	glVertex2f(-scale, -scale);
	
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex2f(scale, -scale);
	
	glColor3f(0.0f, 0.0f, 1.0f);
	glVertex2f(0.0f, scale);
	
	glEnd();
	
	glutSwapBuffers();
}

void render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	
	renderScene();
	
	glFlush();
}

void initDeviceContext(void)
{
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

int main(int argc, char *argv[])
{
	glutInit(&argc,argv);

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

	glutInitWindowSize(800, 600);
	glutInitWindowPosition(200, 200);
	glutCreateWindow("SimpleDraw");

	initDeviceContext();

	glutDisplayFunc(render);
	
	glutMainLoop();

	return 0;
}

Teraz jak na niego patrzę to nie jest idealny (po co mi głębia przy rysowaniu 2d trójkąta? :) ) ale zły też nie jest.

0

OpenGL mam osadzone już w WinApi.Prowadzący tak kazał:P

0

Pytanie nr 1: ustawiałeś Vsync w sterownikach?

0

Witam.Nie nie ustawiłem.A gdzie to trzeba ustawic?? Jakoś z poziomu OpenGL ??

0

Musisz wstawić w pętlę opóźnienia bo teraz procesor zapiernicza tylko na tej jednej pętli i nie widzi nic innego. Może zrób to na wątku, dodaj Sleep(10) i będzie dobrze.

0

Czesc,
to co teraz opisze sam kiedyś robiłem wiec jest sprawdzone i dziala.

Są generalnie 2 podejscia do renderowania:

  • CPU na 100% - dla grafiki dynamicznej (czyli glownie gry) - funkcje renderowania sceny wywyolujesz sobie w main loop
  • CPU oszczednie - dla grafiki statycznej (np. programy do modelowania 3d) - funkcje renderowania sceny wywolujesz sobie w WM_PAIN w message loop

To że procesor zapiernicza na 100% obrotów to jest najnormalniejsza sprawa w przypadku rysowania grafiki real time. Po prostu dla uzyskania maxymalnej plynnosci (duzo fps) procesor musi pocic sie i tyle.

Jesli nie zalezy Ci na fps'ach bo rysujesz grafike nieruchoma, mozesz renderowac scene tylko w przypadku odebrania komunikatu o odmalowaniu okna. Wtedy bedziesz mial najmniejsze mozliwe zuzycie procesora.

I Tyle! Pamietaj tylko, ze jesli zdecydujesz sie na opcje z oszczedzaniem CPU, w petli komunikatow (tam gdzie masz TranslateMessage) uzyj GetMessage, bo dajac PeekMessage nadal bedziesz mial 100% procka.
Pozdrawiam!

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