openGL: flydende firkant med fejl

Tags:    c++

Jeg har hentet et meget enkelt program i openGL, der bare åbner et vindue, og har herefter tilføjet kode til at tegne en firkant (ingen textures, blending, eller andet fancy). Derudover har jeg tilført kode der ændrer på en global variabel via piletasterne, som så indgår i glTranslatef, inden firkanten tegnes. Problemmet er at hvis jeg skifter positionen for hurtigt, f.eks. ved at holde en piletast nede, ser det ikke spor godt ud. Firkanten flytter sig ikke flydende, det er derimod som om den ikke når at blive tegnet helt før den igen flyttes. Jeg bruger dobbeltbuffering.
Da der kun er tale om en enkel firkant virker det mærkeligt at det ikke skulle være muligt at lave en flydende animation.



10 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 4 karma
Sorter efter stemmer Sorter efter dato
Så har jeg kigget lidt på din kode ;)

Problemet ligger i, at du flytter den med meget store "skridt" ad gangen, så selvfølgelig bevæger den sig ikke "flydende" (hvilket jo er et vidt begreb), den hopper jo fra et sted til et andet.

Du skal simpelthen flytte den i mindre skridt, og hertil skal du have ordentlige synkronisering mellem dit message-loop og din render funktion. Du kan fx gøre dette i stedet:

global variabel:
Fold kodeboks ind/udKode 


render:
Fold kodeboks ind/udKode 


message-loop:
Fold kodeboks ind/udKode 


PS. når du så på et tidspunkt finder ud af, at din kode afhænger af fps'en og ikke af tiden, hvilket skaber store forskelle i hoppene på både din egen og sandelig også alle andres computere, så vil jeg anbefale dig at kigge på "time based movement", altså tidsbaseret bevægelse ;)

1101110100010110000101000001

Killers don't end up in jail - they end up on a high-score!

[Redigeret d. 22/02-06 23:45:14 af Nicolai Lyster Fersner]



Hvordan "flytter" du den?
Jeg kan godt gætte, men jeg vil meget hellere have lidt kode at kigge på. Der er jo uendeligt mange måder, man kan flytte en firkant på, også selvom man benytter glTranslatef.
Det kan jo også være, du ikke synkroniserer din render funktion godt nok med dit Win32 message-loop, så der opstår små artifakter ved flytningen.

1101110100010110000101000001

Killers don't end up in jail - they end up on a high-score!

[Redigeret d. 22/02-06 08:32:55 af Nicolai Lyster Fersner]



globale variabler:
Fold kodeboks ind/udKode 

Kode til at få input ( findes i
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) :
Fold kodeboks ind/udKode 


Og kode til at tegne:
Fold kodeboks ind/udKode 




Ups, Den stiger/falder med 0.5 og ikke 0.1 ved tryk på piletasterne.

Problemet fremkommer i den side den bevæger sig til. Altså i siderne hvis den bevæges til højre/venstre.
Kan det være noget med at firkanten ikke kan nå at blive fyldt?
Det virker lidt underligt men jeg kan ikke komme på andet.
Jeg ville blive glad for lidt hjælp.



Det virker fint nok. Men det var ikke den form for hak jeg snakkede om. Hvis jeg bruger din kode, men sætter en højere ændring af x_pos, vil bliver det tegnet som

|||||||||
|||||||||
|||||||||
|||||||||

og ikke

|||||||||
|||||||||
|||||||||
|||||||||

Hvis du ved det, vil jeg meget gerne vide hvad det skyldes.



(kan godt se, hvad der er galt med de to tilsyneladende ens figurer, for da jeg prøvede at give svar på din kommentar, viste browseren "fejlen", så jeg ved godt, hvad du mener, selvom man ikke lige kan se det)

Hmm, det lyder meget mærkeligt... du benytter jo double buffering, så den slags burde ikke kunne opstå, når nu alle vertices bliver flyttet lige meget hver gang (det eneste, der skulle kunne opstå, er de hak, jeg nævnte før).
Er du nu også 100% sikker på, du benytter double buffering?

Den eneste anden grund, jeg lige umiddelbart kan tænke mig til, er, at dit gfx har for meget arbejde at lave, så den ikke får opdateret din figur helt. Prøv at indsætte glFinish(); før din SwapBuffers();
Dette kald venter til dit gfx er færdigt, således at din cpu og gpu atter bliver synkroniseret.
Prøv i øvrigt at tage et kig på din fps med fx Fraps - den skulle gerne være lige så høj som din skærms lodretteopdateringshastighed eller højere, for du beder den jo nærmest ikke om at lave noget.

1101110100010110000101000001

Killers don't end up in jail - they end up on a high-score!

[Redigeret d. 23/02-06 01:04:28 af Nicolai Lyster Fersner]



Ja, det mener jeg helt bestemt, men du kan jo selv prøve at se:

Fold kodeboks ind/udKode 


[Redigeret d. 23/02-06 13:38:30 af Kristian]



Tja, jeg tror simpelthen, det er fordi du afvikler det for hurtigt.
På min com kører i det i hvert fald mindst med et par tusind fps.

Jeg kan sagtens se problemet, men på den anden side afvikler man jo heller ikke normalt spil så hurtigt eller på den måde, så det plejer jo ikke at være et problem.

Du kan evt. prøve med 2-8xAA (anti-aliasing), for det ser jo ud som den slags "fejl".
Dette kræver dog en lidt længere forklaring, så det bliver vist nemmest, hvis du selv finder ud af, hvordan den slags skal gøres.
Har dog fundet koden til dig:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=46

Jeg kan godt implementere den for dig, så vi kan se, om det virker, men jeg har ikke lige tid i dag.



Jeg har fundet ud af det. Det viste sig at jeg skulle sætte indstillingerne så der blev ventet på lodret synkronisering. Herefter virkede det fint.



Ok ;)

Det må vist være det, man kalder "tearing" i fagsprog - har bare aldrig lige oplevet et eksempel før nu, så var ikke helt sikker, hvad det lige var, der skete.

1101110100010110000101000001

Killers don't end up in jail - they end up on a high-score!



t