Innerloop / fps problem with 2D and 3D sprites?

Everything else that doesn't fall into one of the other PB categories.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Info: Sorry for posting this very long mail with two sources! Please read carefully and check if you have any problems on your system too or not... However, please report the result and on which config you have tested both versions (CPU, GfxCard i.e. with driverinfo, DirectX, Ram) - Many thanks in advance for your help and to the persons testing and trying to find the problem too, before i will now post it here. :wink:


Hello @ all,
i wrote a very small newskool graphic demo example using 2D and 3D sprites. Seems there is somewhere a prob in my source (can´t find it) or a hidden bug in purebasic!? So i started with two versions of the source code. Both sources are exactly the same intro... The only differents are:

Code: Select all

TroubleWorkVersion: 2D and 3D (both) are in only one innerloop like following fast basic example and runs only in 25-26 fps on my machine!

    Repeat
      For
        2D
        3D
      Next
    Until

FineWorkingVersion: In this version i use for 2D and 3D an seperate innerloop instead to put both in only one innerloop, even if both loops are 100% the same, like following fast basic example which runs smooth at 52-53 fps on my machine! 

    Repeat
      For
        2D
      Next
      ;
      For
        3D
      Next
    Until



To test following two source you need following image, you can download at: http://mitglied.lycos.de/secretlygb/LightCircle.bmp



Source of TroubleWorkVersion (2D and 3D in one innerloop)

Code: Select all

; -----------------------------------------------------------------------------------------------------------------------
;
;   PureBasic Line() - Newskool Budbrain Effect - Example File v1.0   >>> Trouble working version  oldtime, we will create a new sprite + actual timer -------
    ;
    If oldsec  newsec
      ;
      ; -------- Get actual Hour --------
      ;
      If Info\wHour 



[u][b]Source of FineWorkingVersion (2D and 3D are using own innerloop.[/b][/u]

[code]

; -----------------------------------------------------------------------------------------------------------------------
;
;   PureBasic Line() - Newskool Budbrain Effect - Example File v1.0      >>> Fine working version  oldtime, we will create a new sprite + actual timer -------
    ;
    If oldsec  newsec
      ;
      ; -------- Get actual Hour --------
      ;
      If Info\wHour 

Maybe the problem is my fault somewhere in code... i really cant find it out... So many thanks for your support...


greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Hi @ all,
coudn´t sleep... so i have spent some mins again on the working version of topic effect and change this a bit... Just download the advanced/modified version at:

http://mitglied.lycos.de/secretlygb/_index.html

Code, Graphic/Dezign, Muzak
all done by MrVain!


greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.

Pff.. Start3D() initialize the 3D engine and you call it in every loop ! Of course it's slow. The same for StartDrawing() (BTW, it rememebers my some old comments about this topic).

Code: Select all

  For n = 0 To 360 Step 8 
          a = b + n
          ;            
          vaina.f = cax + r1 * MyGCos(a)
          vainb.f = cay + r1 * MyGSin(a)/2
          vainc.f = cbx - r2 * MyGCos(a)/1.5
          vaind.f = cby - r2 * MyGSin(a)
          ;
          Start3D()
              Sprite3DBlendingMode( 3,2)  
              ZoomSprite3D(4,40,40)
              DisplaySprite3D(4,vaina-20,vainb-20,10)
              DisplaySprite3D(4,vainc-20,vaind-20,10)
          Stop3D() 
          ;
          c+sc
        Next
must be changed to:

Code: Select all

Start3D()
  For ...

  ...
Stop3D()
Doesn't it sounds MUCH more logical when talking about optimized code ?! A golden rule: if you can remove any commands from a loop, do it. The same for StartDrawing().


Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by WolfgangS.
Originally posted by fred

Pff.. Start3D() initialize the 3D engine and you call it in every loop ! Of course it's slow. The same for StartDrawing() (BTW, it rememebers my some old comments about this topic).

Code: Select all

Start3D()
  For ...

  ...
Stop3D()
You´re right. But why ist THIS constellation working without problems ? It also Start3d()´s as often as the slow working intro ...

Repeat
For
2D
Next
;
For
3D
Next
Until

MFG
:)WolfgangS

PS: Don´t hurt me
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Hello Fred,
in one point you are right that i call StartDrawing/StopDrawing and Start3D/Stop3D any loop and that this isnt optimized i know too. But, please tell me then how can i mix 2D and 3D sprites in ONE (!!) innerloop without calling every loop StartDrawing/StopDrawing and Start3D/Stop3D?????

Ok, i thought all the time that there is the SwitchScreenProblem (still in) and you haved me some ideas how to mangage it like "IfScreenIsActive()" and If StartDrawing()... What will be happen when i use Startdrawing/Stopdrawing outside a innerloop (i know this methode would be correct), and then switch screen... So i cant check If StartDrawing failed or not! Do you know what i mean?

Btw, this does not work to mix 2D and 3D in ONE innerloop:

Code: Select all

    Repeat
        StartDrawing()
        Start3D()
        ;
        For
           2D
           3D
        Next
        ; 
        Stop3D
        StopDrawing()
    Until

Btw, this seems to work with mixing 2D and 3D in ONE innerloop:

Code: Select all

    Repeat
        Start3D()         ; Start3D must called before StartDrawing, else it dont work!    
        StartDrawing()
        ;
        For
           2D
           3D
        Next
        ; 
        StopDrawing()
        Stop3D
    Until
With the last basic example it seems to work now... I ever thought that 2D stuff must be inside StartDrawing/StopDrawing and 3D stuff must be inside Start3D/Stop3D... It listen logical for me!

Fred, now we found a way to mix 2D and 3D in one innerloop without slowing down the fps! Can you show me now a working example how to manage (fix) the SwitchScreenProblem? When i try this, the graphics will be trash or the prog will crash ;( (i think it cant be that i have to reload ALL graphics when switching back to my program!?)

However Fred... can you tell us please as WolfganS would know too... Why does the problem happens only in the version where i used 2D and 3D sprite in one innerloop with calling everytime StartDrawing/StopDrawing and Start3D/Stop3D and not in version two, where i used for 2D stuff an own innerloop with calling everytime Startdrawing/Stopdrawing and in the 3D innerloop calling everytime Start3D/Stop3D??? I think this is a bit corious...

Anyway thanks for all your info/help...

PS: Have someone tried to download and test the topic link with a compiled modified exe?


greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.
me wrote:
"With the last basic example it seems to work now... I ever thought that 2D stuff must be inside StartDrawing/StopDrawing and 3D stuff must be inside Start3D/Stop3D... It listen logical for me!"
Hi again,
i checked again the docs and they are saying that i thought right all the time, to use StartDrawing/StopDrawing for 2D stuff and Start3D/Stop3D for 3D everytime, when i mix both together in one loop - as i used in my posting source (2D and 3D in one loop) - also looks like:

Code: Select all

    Repeat
        ;
        ; -------- Loop Start --------
        ;
        For
          ;
          ; -------- 2D Stuff --------        
          ;
          StartDrawing()     
            2D      
          StopDrawing()
          ;
          ; -------- 3D Stuff --------        
          ; 
          Start3D()
            3D
          Stop3D()
          ;
        Next
        ;
        ; -------- Loop end --------
        ;
    Until

Start3D() - Description
Start the 3D engine and setup it to display the 3D Sprites. This command must be called before using DisplaySprite3D() and Stop3D() must be called when all the rendering are done. If the 'Result' is 0, the initialize has failed and 3D sprites commands can't be used.

StopD() - Description
Stop the 3D engine. It's tipically called after rendering the last 3D sprite. Start3D() must be called before using this command.



greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.

It's tipically called after rendering the last 3D sprite and Stop3D() must be called when all the rendering are done. Yes, when all the rendering are done. You call in your For/Next loop so please don't talk about performance, when I see such ugly code. You can NOT mix 3D and 2D commands, the prefered way is:

- All 2D for background etc...
- All 3D
- All 2D over the 3D stuffs.

Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Pffff... yes fred, i already know this...

I know to begin with 2D background, 3D and then 2D stuff over 3D... take a look to my WeatherEngine i send you and you will see that i understand that concept in which order i have to draw stuff... no problem! (take a look to the 4th message here)

However i think it would be better to add one more sentence to the docs so other people dont do the mistake like me as i have understand it from the docs!!!!

But Fred, you are telling that the "first source" is slow due fact that i use everyloop the start/stop commands... How could it be, that the "second source" where i use two innerloops and the calling Start/Stop same often as in the first source... that this version works smooth?????

So dont blame only me that its my fault... seems there is any problem and you dont want give us an answer? I dont want any fight here... but when reading yours answers here dont saying us why this happen.. only that i cant code (ugly not optimized code) i get frustrated... (So better add some more lines to the docs that its for everybody clear and we dont would have this disucssion!) I want just ONLY an answer, why are both versions runs in different fps!!!! (even when calling in both versions Start/Stop same often)
Thanks!


greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

If you have 2 separate loops, each loop is smaller. Right?
If you have all in 1 loop, the loop is bigger. Right?

Maybe the big loop is too big for your processor chache size.

In the small loop all this stuff is used:
the loop code itself, MyGCos(), MyGSin(), StartDrawing()
ScreenOutput(), LineXY(), RGB(), Circle(), StopDrawing()
In the big loop all this is used:
the loop code itself, MyGCos(), MyGSin(), StartDrawing()
ScreenOutput(), LineXY(), RGB(), Circle(), StopDrawing()
Start3D(), Sprite3DBlendingMode(), ZoomSprite3D()
DisplaySprite3D(), Stop3D()
Maybe this doesnt look much to you, but the complete code
of all this commands and the code of the loop itself must
completely be in chache.
Remember that this commands can be very big internally,
you dont know how big they are (especially 3D sprite stuff).
Also this commands call DirectX functions, which then should
also be in chache while running the loop.

Loops must always be as small as possible, so
maybe a chache problem if loop is too big...

And of course it could be a problem with mixing 2D
and 3D in the same loop.
I read that in DirectX everything must be in a 'good'
order for full performance and DX doesnt like to mix
up such things like 2D and 3D too much.

cya,
...Danilo
(registered PureBasic user)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Hi Danilo,
the cache problem listen possible! I will check how mutch catch my CPU has and then we can compare with other persons having/dont having same problems...


Fred wrote:
It's tipically called after rendering the last 3D sprite and Stop3D() must be called when all the rendering are done. Yes, when all the rendering are done. You call in your For/Next loop so please don't talk about performance, when I see such ugly code. You can NOT mix 3D and 2D commands, the prefered way is:

- All 2D for background etc...
- All 3D
- All 2D over the 3D stuffs.
Hi Fred,
what you wrote, to Stop3D if all rendering is done isnt really ok too :wink: because i have tried following test and its works even if you dont use Start/Stop3D between Flipbuffers() !! So it seems the user only need this commands 1time to intit the drawing and when closing the program to Stop this drawing... You can see in following working example what i mean:

Code: Select all

    Start3D()
    Repeat
      StartDrawing()
        For
          2D
        Next
        ;
        For
          3D
        Next
      StopDrawing()
      FlipBuffers()
    Until
    Stop3D()
;
; -------- I dont know if this is correct to call Start3D/Stop3D only 1 time in your program --------
;
    Start3D()
    Repeat
      StartDrawing()
        For
          2D
          3D
        Next
      StopDrawing()
      FlipBuffers()
    Until
    Stop3D()
greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Btw i know that the code snip of the last message i posted wouldn´t be correct as i thought before and as Danilo said again too... I know now that i dont should put 2D and 3D sprites in just one innerloop. (i think this way isnt nice for big projects but who cares)! So it would be better to use two innerloops, one for 2D and one for the 3D stuff, right? Also the code should look like following before you blame me again that i cant code and haven´t to talk with you about optimizing and performence things...

Code: Select all

;
; -------- Here the version to use for 2D and 3D an own innerloop (i.e without caching problems) --------
;
    Repeat
      ;
      ; -------- Here the 2D stuff -------
      ;
      StartDrawing()
        For
          2D
        Next
      StopDrawing()
      ;
      ; -------- Here the 3D stuff -------
      ;
      Start3D()
        For
          3D
        Next
      Stop3D()
      ;
      ; -------- Finish, so SwapBuffers --------
      ;
      FlipBuffers()
    Until
Btw i dont really like this coding style to use two innerloops, one for 2D and one for 3D stuff, even if both loops are exactly the same code... Who cares?


greetz
MrVainSCL! aka Thorsten

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by chr1sb.

Will Sprite3DBlendingMode( 3,2) work for any 3d card? it's a nice effect, but when I've tried to use Sprite3DBlendingMode sometimes it works on for example GeForce3 but looks wrong on VooDoo3.

chr1sb
Post Reply