Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
Pinsirus
Založen: 13. 01. 2016 Příspěvky: 37 Bydliště: Slovensko
|
Zaslal: 15. září 2016, 23:40:00 Předmět: Problem s lagmi v OpenGL |
|
|
Zdravim, pardon že otravujem s trivialnostami ale mam taky menši problem a nerozumiem mu. Ak si v hre nastavim fps lock na 60, hra nebeži plynulo, resp laguje(je to vidiet hlavne na movemente). (a nechcem zapinat VSYNC- ale ked ho zapnem, beži to v pohode, akurat sa strašne zvyši vytaženie CPU)
Je to vidiet napr. na tomto videu:
Vidiet, že postava laguje
https://www.youtube.com/watch?v=2CVdLMFxuFE&feature=youtu.be
Deje sa to aj ked použijem iny kod(konkretne tutorialovy engine - nič neprepišem - rozdiel je ine IDE) - napriek tomu v tutorialoch to beži normalne Skušal som to aj na inom kompe a sprava sa to tak isto.
Video proof:(je vidiet že dane postavy sa pohybuju divne)
https://youtu.be/69h6ZuHhHmo
Neviete čo by mohlo sposobovat tieto lagy? Všimol som si, že čim nižši framecap mam tym su tie lagy väčšie. |
|
Návrat nahoru |
|
|
Ladis
Založen: 18. 09. 2007 Příspěvky: 1536 Bydliště: u Prahy
|
Zaslal: 16. září 2016, 11:46:14 Předmět: |
|
|
Se koukni na funkci, kterou čteš čas. Nevím, jak je to v SDL2, ale v SDL1 měla výchozí funkce (gettickcounts?) přenost 100 Hz, takže při VSync 60 fps to nesedělo a poskakovalo to (např. 2 snímky za sebou vrácen stejný čas - postavy se nepohnou - další snímek vrátí větší /naakumulovaný/ čas - postavy se pohnou o víc). |
|
Návrat nahoru |
|
|
Pinsirus
Založen: 13. 01. 2016 Příspěvky: 37 Bydliště: Slovensko
|
Zaslal: 16. září 2016, 14:14:18 Předmět: |
|
|
Ladis napsal: |
Se koukni na funkci, kterou čteš čas. Nevím, jak je to v SDL2, ale v SDL1 měla výchozí funkce (gettickcounts?) přenost 100 Hz, takže při VSync 60 fps to nesedělo a poskakovalo to (např. 2 snímky za sebou vrácen stejný čas - postavy se nepohnou - další snímek vrátí větší /naakumulovaný/ čas - postavy se pohnou o víc). |
vdaka za reakciu.
V SDL2 sa použiva tiež SDL_GetTicksCount() a jeho menšiu nepresnost som si všimol pri tom, že napriek FPS capom sa realne FPS lišilo(ale nie o velke hodnoty).
Chceš teda povedat že mam zmenit funkciu na meranie času? Povedzme QueryPerformanceCounter a na delay by som použil SDL_Delay()? (aj ked na win32 je SDL_Delay() definovane ako Sleep() a niesom si isty či SDL_GetTicks() nepouživa na win32 prave QueryPerformanceCounter a tak som si neni isty či to tak neni aj na win64) Alebo to mam locknut na nejake väčšie fps? (120-200)
Na physics som použil Fixed Timestep ale tam dostaval moj procesor pri 4k+ fps riadne zabrat.(pri vypnutom FPS locku)
Edit: Tak som to vyskušal aj s QueryPerformanceCounter metodou a robi to to iste.
Timer trieda
kód: |
void LTIMER::start(){
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&startTime);
}
void LTIMER::delay(){
QueryPerformanceCounter(&endTime);
elapsedMicroseconds.QuadPart = endTime.QuadPart - startTime.QuadPart;
//Converting to microseconds
elapsedMicroseconds.QuadPart /= frequency.QuadPart;
if ((1000.f / 60.0f)> elapsedMicroseconds.QuadPart){
SDL_Delay((1000.f/60.f)-elapsedMicroseconds.QuadPart);
}
} |
Gameloop:
kód: |
while (_gameState != GameState::EXIT) {
fpsTimer.start();
processInput();
_camera.update();
// Update all bullets
for (int i = 0; i < _bullets.size();i++) {
_bullets[i]->update();
}
drawGame();
fpsTimer.delay();
} |
|
|
Návrat nahoru |
|
|
frca
Založen: 28. 07. 2007 Příspěvky: 1558
|
Zaslal: 16. září 2016, 17:39:07 Předmět: |
|
|
Obávám se, že bez vsync to nevyřešíš. Tvůj problém se jmenuje tearing. Schválně zkus i měnit cyklicky barvu pozadí a uvidíš, že bude obraz jakoby "přetržený". _________________ www.FRANTICWARE.com |
|
Návrat nahoru |
|
|
mar
Založen: 16. 06. 2012 Příspěvky: 608
|
Zaslal: 16. září 2016, 18:36:41 Předmět: |
|
|
Jeden z problémů je, že GetTickCount stejně jako Sleep má granularitu ~16-20 msec.
Dá se to vyřešit tak, že na začátku programu zavoláš timeBeginPeriod(1) a na konci timeEndPeriod(1),
ale tím nastavíš systémové přerušení časovače na 1 kHz.
Nebo můžeš spinnovat 1 core dokud se nedostaneš na deltu, kterou potřebuješ. Jinak při 4kHz netrpí CPU, ale GPU.
Jak psal frca zapnout vsync je to, co asi chceš. Jinak ale palec nahoru za fps limiter.
kód: |
void LTIMER::start(){
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&startTime);
}
void LTIMER::delay(){
QueryPerformanceCounter(&endTime);
elapsedMicroseconds.QuadPart = endTime.QuadPart - startTime.QuadPart;
//Converting to microseconds
elapsedMicroseconds.QuadPart /= frequency.QuadPart;
if ((1000.f / 60.0f)> elapsedMicroseconds.QuadPart){
SDL_Delay((1000.f/60.f)-elapsedMicroseconds.QuadPart);
}
} |
Jak tohle může fungovat? Pokud vydělíš counter frekvencí, dostaneš to zaokrouhlené (dolů) na vteřiny. Navíc píšeš, že převádíš na mikrovteřiny, ale to porovnání počítá s milivteřinami.
Jinými slovy elapsedMicroseconds.QuadPart je pořád nula a v každém snímku děláš sleep na 16 msec. |
|
Návrat nahoru |
|
|
Pinsirus
Založen: 13. 01. 2016 Příspěvky: 37 Bydliště: Slovensko
|
Zaslal: 16. září 2016, 19:06:40 Předmět: |
|
|
mar napsal: |
Jeden z problémů je, že GetTickCount stejně jako Sleep má granularitu ~16-20 msec.
Dá se to vyřešit tak, že na začátku programu zavoláš timeBeginPeriod(1) a na konci timeEndPeriod(1),
ale tím nastavíš systémové přerušení časovače na 1 kHz.
Nebo můžeš spinnovat 1 core dokud se nedostaneš na deltu, kterou potřebuješ. Jinak při 4kHz netrpí CPU, ale GPU.
Jak psal frca zapnout vsync je to, co asi chceš. Jinak ale palec nahoru za fps limiter.
kód: |
void LTIMER::start(){
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&startTime);
}
void LTIMER::delay(){
QueryPerformanceCounter(&endTime);
elapsedMicroseconds.QuadPart = endTime.QuadPart - startTime.QuadPart;
//Converting to microseconds
elapsedMicroseconds.QuadPart /= frequency.QuadPart;
if ((1000.f / 60.0f)> elapsedMicroseconds.QuadPart){
SDL_Delay((1000.f/60.f)-elapsedMicroseconds.QuadPart);
}
} |
Jak tohle může fungovat? Pokud vydělíš counter frekvencí, dostaneš to zaokrouhlené (dolů) na vteřiny. Navíc píšeš, že převádíš na mikrovteřiny, ale to porovnání počítá s milivteřinami.
Jinými slovy elapsedMicroseconds.QuadPart je pořád nula a v každém snímku děláš sleep na 16 msec. |
Ten koment je tam preto že som to predym prevadzal na mikrosekundy, ale ked som to prevadzal, fps sa mi lockovalo na 0. Vdaka za postreh, popravde som uvidel že FPS sa pohybuje okolo 60 a myslel som že to funguje,pokusim sa z toho ešte vyhrabat a vyriešit to
frca: S VSYNCom mi to ide v pohode, avšak mi stupa cpu usage (30%+ - pričom momentalne renderujem ani nie 40 spritov). To bude mojim "spaghetti" kodom?
Edit: Zistil som, že zataž pri zapnutom VSYNC je s najväčšou pravdepodobnostou sposobena SDL_GL_SwapWindow() |
|
Návrat nahoru |
|
|
Ladis
Založen: 18. 09. 2007 Příspěvky: 1536 Bydliště: u Prahy
|
Zaslal: 17. září 2016, 00:02:39 Předmět: |
|
|
CPU-zátěž při VSync je způsobená ovladačem grafiky, s tím moc nenaděláš. |
|
Návrat nahoru |
|
|
Pinsirus
Založen: 13. 01. 2016 Příspěvky: 37 Bydliště: Slovensko
|
Zaslal: 17. září 2016, 17:58:21 Předmět: |
|
|
Tak, pravdepodobne som to už vyriešil (popravne som si musel dat pauzu a zapol som si FTL(kedže tam tiež použili SDL2/OpenGL a chcel som vidiet ako to tam poriešili s FPSkami) a videl som ich sposob kde necapuju fps)
Nechal som to nakoniec cele na fixed timestepe ktory je riadeny physics fps ktore som nastavil na 60, takže aj pri zapnutom VSYNC ide hra na rovnakej rychlosti a fps necham na volnej nohe (ale pravdepodobne tam nejaky lock necham aby zbytočne nezaberal procesor pri zbytočnych framoch) |
|
Návrat nahoru |
|
|
|