Author Topic: General questions about using Textures and FPS independent speed  (Read 4624 times)

0 Members and 1 Guest are viewing this topic.

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
As some know, i have coded on C64 and Amiga years ago! So i only know things like  x=x+1  or just x+1 to move an object for 1 pixel for example! This worked fine on any C64 and Amiga! On the PC site is a very bad way, because the programm runs on any computer in different speed and that is what we really dont want. Nowadays i tried to use more and more 3D textures (PB Sprite3D) because they are a lot faster and you can do some more things, arent possible with the slow PB Sprite2D... I know that a texture should be a quad like  256x256, 512x512 for example... but i think most modern gfx cards dont care if the texture is 256x128 or 256x256 !?

~ Textures:
However, for my actual entry i am using a 256x256 texture and resize this to 800x600 (fullscreen)... Title- and Credits- images has been saved as 800x400 texture... Is it possible that such a big texture (800x400) could slow down the speed of an older PC system? If so, does it makes sence and is there a diference in performance when save the Title- and Credits- images as 512x512 texture... and resize it at runtim to 800x400 ?

Does it make sence to save Textures in 8 bit (if possible) instead wasting memory and saving it as 32 bit? How does gfx cards works internally with a load 8 bit texture? Does it require internally the same memory size like an original 32 bit or could a 8 bit texture speed up things, because it has less data?

~ Timing:
I dont like to limit the FPS rate... because on a modern system i want like to have the full power and highest FPS rate thats possible. Older PC system would run to slow by limiting the FPS to a to high value. So possible the best timing and fps independent coding would be using timer(s) and delta time? I have a bit problem atm to use this technique and it would be nice if you could explain me, how to use this way for fading a picture in/out for example...  (maybe its more easy as i think and i think just to complicated ^^) Btw, what ways are you using for your projects, to run in same speed on all PCs without limiting the FPS?

Code: [Select]
        Select lTimer
       
            Case 0 To 3000
                ;
                ; // Fade in a texture
                ;
                DisplayTexture( hTexture, lPosX, lPosY, lTransparence )
                lTransparence = Int(fNewColor.f)
                fNewColor.f + 0.2
                If fNewColor.f > 255 : fNewColor.f = 255 : EndIf
             
            Default
                ;
                ; // Other code...
                ;
        EndSelect     

Case 0 to 3000 will be 3 seconds... in this time the image should hopefully compplete faded in... But how to say fade in... in let us say 1,5 seconds? How are you using such (easy) things... Btw possible this is more easy as following situation:

Code: [Select]
        aa = Cos(rotate.f)*127
        bb = Sin(rotate.f)*127
         
        rotate.f + 0.05     ; // Each loop +0.5 to animate out stuff like for Sin/Cos

Thanks in advance.
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Quote
Is it possible that such a big texture (800x400) could slow down the speed of an older PC system?
Non-Power-Of-Two-Textures are internally stored in a size of the next Power-Of-Two (in this case 1024x512) to speed up texel-adressing. The loss in performance is negligible.
There're still some cards which don't support it at all, so using powers of two is the saver solution.

Quote
when save the Title- and Credits- images as 512x512 texture... and resize it at runtim to 800x400 ?
Using 512x512-textures for fullscreen-images was okay when the default resolution was 640x480, with hd-screens it looks pretty crappy, though.
Speed-wise it doesn't make a difference.

Quote
Does it make sence to save Textures in 8 bit (if possible) instead wasting memory and saving it as 32 bit?
Support for paletized textures was dropped a few years ago. But you can use monochrome textures (which means only one colour-channel).

Quote
instead wasting memory and saving it as 32 bit?
That's what they invented Jpeg for.

Quote
would be nice if you could explain me, how to use this way for fading a picture in/out for example...
Something like this for example:
Code: [Select]
while (demoIsRunning)
{
  float time= getTimeSinceDemoWasStartedInSeconds;
  // fade in picture during the first 2 seconds:
  if (time>=0.0 && time<=2.0)
  {
    // intensity goes from 0..1 during 0..2sec
    float intensiy= (time)*0.5f;
    drawAlphaPicture(yourTexture, intensity);
  }
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
@hellfire:
thanks for all your answers and help!

Quote
Using 512x512-textures for fullscreen-images was okay when the default resolution was 640x480, with hd-screens it looks pretty crappy, though.
Speed-wise it doesn't make a difference.
I am using 800x600 as screen resolution... so 512x512 texture for fullscreen is okay too, or should i save then as 1024x1024 or just in original format 800x400 and 800*600 to have better image quality? (Sure i can save the textures as JPG format, without to much compression/quality lost)

Quote
Support for paletized textures was dropped a few years ago. But you can use monochrome textures (which means only one colour-channel).
Ah okay... Btw, what do you mean with monochrome textures? BMP 8 bit? Or do you mean just only a RED channel texture, only BLUE Channel and so on? I think this is not so important...

Quote
That's what they invented Jpeg for.
Yes i know... but i thought wasting memory inside the Gfx card (where are the textures always unpacked i think).

Thanks for your small example.. i will take a look and hope to get this work for everythink in my intro and for future projects.
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Even on the fastest PC, it's not worth rendering at more than 60fps, since any extra frames won't even get displayed.  If you have a vsync, you will get stuttering, if you disable vsync you will get tearing.

Agree with hellfire on all the texture things.  Any vaguely recent graphics card will do all the things you suggest without even batting an eyelid.

I usually implement my timing by keeping a track of how long the last frame took to render and passing that in as the time slice for the next frame.  You need to make sure the timer sits outside any vsync, and if you are feeling nice you should yield any unused time back to the OS by using Sleep().
So instead of writing
Code: [Select]
for x=0 to 3000 step 16
colour=f(x)
next
I write something like
Code: [Select]
counter=3000
...
counter -= last_frame_time_in_milliseconds
if counter < 0 then done
else
colour=f(counter)

Jim
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
@Jim:
Thanks for reply... atm i dont really understand your example... however atm i am trying to code a small example that should hopefully work when its finished... let us wait n see
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
The idea is, I want something to happen in 3seconds (3000ms).  If I just take away a fixed amount (say 10) every time I calculate then it would look like
3000,2990,2980,2970,2960 etc.
But if some frames take longer to draw than others (say 12) and some take shorter (say 8) because of faster or slower computers or because the complexity of the scene changes, then these fixed time steps are wrong.  So, if instead of using 10 for the amount to take away we should try to use how long we think it will take to draw the next frame.  A good guess for how long the next frame will take is how long did it take to draw the last frame.
So if our frames took 10ms, 12ms, 15ms, 8ms, 9ms our counter would look like
3000,2990,2978,2963,2954
the steps become uneven because the frame rate is uneven.  Which is exactly what we want

If you use the frame time in all your calcs (rotation, speed, acceleration, timers) etc, then you will always stay in time with the computer even if it only ends up doing 10fps.

Jim
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
Okay Jim... i will try to get this work... als to check how much speed is gone between actually and last frame...

btw i have found last night an article... sadly its only the orgiginal article because the interesting follow-up article: "RE: The Game Loop" still not exist anymore :(
When i am back at home later, i will try to get it work.. so i can hopefully use this technic for my actually project / contest..

- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
sooo... i found a very old test coded by me about fps independent fps in 04/2002 (http://forums.purebasic.com/english/viewtopic.php?p=12559#12559)
i dont know why nor whats wrong with the code... but it seems not to scroll smooth... i even changed floats to doubles without getting a smoother result...
damn, it cant be so hard to code smooth fps independent stuff... isnt it?

Code: [Select]
;-----------------------------------
;
; Run your prog in same speed on all
; PCs but FPS independent - Example
;
; Works 100% fine on all PCs Wink
;
;-----------------------------------
;
    #scrw = 640               ; screenwidth
    #scrh = 480               ; screendheight
    #scrd = 16                ; screendepth
;
;-------- Init all the needed system stuff --------
;
    If InitSprite() = 0 Or InitKeyboard() = 0
        MessageBox_ (0,"Can't open DirectX 7 or later", "WorkingExample", #MB_ICONINFORMATION|#MB_OK)
        End
    EndIf
;
;-------- Init Screen and load stuff --------
;
    If OpenScreen(#scrw,#scrh,#scrd,"ExampleSource") = 0                            
        MessageBox_ (0,"Could not open 640x480x16 screen", "WorkingExample", #MB_ICONINFORMATION|#MB_OK)
        End                                                                                    
    EndIf
    ;
    SetPriorityClass_(GetCurrentProcess_(), 13 )                 ; 13 = HIGH_PRIORITY_CLASS, better for games!
;  
;-------- Init Timer before innerloop --------
;
    oldmillisecs.d = timeGetTime_()                              ; TimeGetTime_ return better results as GetTickCount_
;
;-------- Test MainLoop --------
;
    Repeat    
        deltatime.d    = timeGetTime_() -oldmillisecs.d          ; Dont forget to use floats!
        oldmillisecs.d = timeGetTime_()  
        ;
        ClearScreen(0)                                       ; ClearScreen black
        ;      
        yscroll.d = yscroll.d+deltatime.d*(480/6000)             ; this is movement by time elapsed.        
        If yscroll.d >= 480 : yscroll.d=yscroll.d-480 : EndIf
        ;
        StartDrawing(ScreenOutput())
           FrontColor(RGB(255,255,255))
           Box(320,yscroll,16,16)  
        StopDrawing()
        ;    
        FlipBuffers()            
        ;              ;  
        ExamineKeyboard()            
   Until KeyboardPushed(#PB_Key_Escape)
  
End

;-------- How to understand the stuff --------
;
; "yscroll.f" is our variable we would normaly use to move our object like "yscroll+1" or whatever but we dont have
; to use a fix variable like +1 for an independent fps! We have to calculate this variable (moving steps) Wink
;
; We have to  calculate the steps using "yscroll.f = yscroll+deltatime.f*(480/2000)" for example... The only important
; things in this line are the vals 480 and 2000 for us... This means: We want to move an object on a way of 480 pixel
; (our screenhigh for example) and the object should move this way in only 2 seconds (also 2000 millisecs) ...
;
; If you want for example, that our object will need 4,5 seconds to move this 480 pixels - you have to write (480/4500)
; Thats all... I think this small example with documentation should be good enough and not to hard to understand for
; your next projects Wink
;
; Good luck... "Mr.Vain of Secretly!" aka Thorsten

Attached example as exe... Y moving in 6 seconds... here its not really smooth...
« Last Edit: July 25, 2009 by va!n »
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Try adding
timeBeginPeriod(1)
at the start of the program, before the first call to timeGetTime.  That should give you more accurate timing.

And setting the thread priority to high isn't that great an idea.  It'll probably work but it's very unfriendly :)

<edit>btw, the block is moving very smoothly for me, on my netbook

Jim
« Last Edit: July 25, 2009 by Jim »
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17409
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Moves pretty smooth here too on my desktop.
Shockwave ^ Codigos
Challenge Trophies Won: