Hardware Skinning (GPU Animation)

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: I need help with Hardware Skinning

Post by applePi »

thanks Samuel for the great demo, and also for the maslobojik. here is the fps = 20 using 100 X 2 characters
Image
and it is not bad, since my graphics card are Geforce 520 GT which have memory 2GB DDR3. on windows xp. cpu: i5-2500 3.3 GHZ. usable ram 3.23 GB. it is possible better on windows 7 or windows 8 .
Edit: i don't see the fps is different if we use a normal material for the model such as the the floor material #FloorMat. so could be my graphics card does not support hardware skinning !!
here is your code for the hlsl v2 version to show the above soldiers circles :

Code: Select all


Define.f KeyX, KeyY, MouseX, MouseY

Enumeration
  #Info
  #Window
  #Font
  #FloorTex
  #FloorMat
  #JaiquaMat
  #JaiquaMesh
  #Jaiqua
  #PlaneMesh
  #Plane
  #Camera
  #Light1
  #Light2
EndEnumeration

If InitEngine3D(#PB_Engine3D_DebugLog)
  
  Add3DArchive("\", #PB_3DArchive_FileSystem)

  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
    If LoadFont(#Font, "Courier New", 10,#PB_Font_Bold)
      SetGadgetFont(#PB_Default, FontID(#Font))
    EndIf
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
Total=100

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "Hardware Skinning")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
  
    
    CPU$ = CPUName()
    
    CreateSprite(#Info, 350, 120)
    StartDrawing(SpriteOutput(#Info))
      Box(0,0,350,120,RGB(0,0,0))
    StopDrawing()
    
    CreateTexture(#FloorTex,32,32)
    StartDrawing(TextureOutput(#FloorTex))
      Box(0,0,16,16,RGB(55,55,55))
      Box(16,0,16,16,RGB(0,50,75))
      Box(0,16,16,16,RGB(0,50,75))
      Box(16,16,16,16,RGB(55,55,55))
    StopDrawing()
    
    CreateMaterial(#FloorMat, TextureID(#FloorTex))
    CreatePlane(#PlaneMesh, 150, 150, 1, 1, 30, 30)
    CreateEntity(#Plane,MeshID(#PlaneMesh),MaterialID(#FloorMat),0.1,-0.2,0.2)

    GetScriptMaterial(#JaiquaMat,"jaiqua")

    LoadMesh(#JaiquaMesh,"jaiqua.mesh")
    
    For EN=1 To Total
      X.f=X+#PI*2/Total
      Z.f=Z+#PI*2/Total
      XX.f=Cos(X)*60
      ZZ.f=Sin(Z)*60
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
    X=0
    Z=0
    For EN=1 To Total
      X=X+#PI*2/Total
      Z=Z+#PI*2/Total
      XX.f=Cos(X)*30
      ZZ.f=Sin(Z)*30
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
            
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
   
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 5, 20, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)

    CreateLight(#Light1, RGB(0, 0, 0), -20, 40, 20)
    SetLightColor(#Light1, #PB_Light_DiffuseColor, RGB(255,255,255))
    CreateLight(#Light2, RGB(0, 0, 0), 20, 40, 20)
    SetLightColor(#Light2, #PB_Light_DiffuseColor, RGB(0,0,255))
    
    AmbientColor(RGB(80, 80, 80))

  EndIf
EndIf

    Repeat
      
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
      
          
      If ExamineKeyboard()
      
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -1
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = 1
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -1
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = 1
        Else
          KeyY = 0
        EndIf
            
      EndIf
  
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      
      ShowFPS=1
      If ShowFPS=1
        CurrentFPS = Engine3DFrameRate(#PB_Engine3D_Current)
        AverageFPS = Engine3DFrameRate(#PB_Engine3D_Average)
        MaximumFPS = Engine3DFrameRate(#PB_Engine3D_Maximum)
        MinimumFPS = Engine3DFrameRate(#PB_Engine3D_Minimum)
        CountTris=CountRenderedTriangles()
        StartDrawing(SpriteOutput(#Info))
          Box(0,0,350,120,RGB(40,40,40))
          DrawingFont(FontID(#Font)) 
          DrawText(2,2,CPU$,RGB(255,0,0),RGB(40,40,40))
          DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(40,40,40))
        StopDrawing()
        DisplayTransparentSprite(#Info,20,20)
        If FirstFrame=0
          Engine3DFrameRate(#PB_Engine3D_Reset)
          FirstFrame=1
        EndIf
      EndIf
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: I need help with Hardware Skinning

Post by Samuel »

I haven't fixed the problem maslobojik pointed out, yet.
Hopefully, I'll be able to update the download with the fix soon.

These two lines need to be moved after the open screen.

Code: Select all

  Add3DArchive("\", #PB_3DArchive_FileSystem)
  Parse3DScripts()

In your example I get 60 FPS with hardware skinning. Without it I'm in the 20s.

Code: Select all

Define.f KeyX, KeyY, MouseX, MouseY

Enumeration
  #Info
  #Window
  #Font
  #FloorTex
  #FloorMat
  #JaiquaMat
  #JaiquaMesh
  #Jaiqua
  #PlaneMesh
  #Plane
  #Camera
  #Light1
  #Light2
EndEnumeration

If InitEngine3D(#PB_Engine3D_DebugLog)
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
If LoadFont(#Font, "Courier New", 10,#PB_Font_Bold)
  SetGadgetFont(#PB_Default, FontID(#Font))
EndIf
 
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
Total=100

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "Hardware Skinning")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    
    Add3DArchive("\", #PB_3DArchive_FileSystem)
    Parse3DScripts()
   
    CPU$ = CPUName()
   
    CreateSprite(#Info, 350, 120)
    StartDrawing(SpriteOutput(#Info))
      Box(0,0,350,120,RGB(0,0,0))
    StopDrawing()
   
    CreateTexture(#FloorTex,32,32)
    StartDrawing(TextureOutput(#FloorTex))
      Box(0,0,16,16,RGB(55,55,55))
      Box(16,0,16,16,RGB(0,50,75))
      Box(0,16,16,16,RGB(0,50,75))
      Box(16,16,16,16,RGB(55,55,55))
    StopDrawing()
   
    CreateMaterial(#FloorMat, TextureID(#FloorTex))
    CreatePlane(#PlaneMesh, 150, 150, 1, 1, 30, 30)
    CreateEntity(#Plane,MeshID(#PlaneMesh),MaterialID(#FloorMat),0.1,-0.2,0.2)

    GetScriptMaterial(#JaiquaMat,"jaiqua")

    LoadMesh(#JaiquaMesh,"jaiqua.mesh")
   
    For EN=1 To Total
      X.f=X+#PI*2/Total
      Z.f=Z+#PI*2/Total
      XX.f=Cos(X)*60
      ZZ.f=Sin(Z)*60
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
    X=0
    Z=0
    For EN=1 To Total
      X=X+#PI*2/Total
      Z=Z+#PI*2/Total
      XX.f=Cos(X)*30
      ZZ.f=Sin(Z)*30
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
           
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
   
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 5, 20, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)

    CreateLight(#Light1, RGB(0, 0, 0), -20, 40, 20)
    SetLightColor(#Light1, #PB_Light_DiffuseColor, RGB(255,255,255))
    CreateLight(#Light2, RGB(0, 0, 0), 20, 40, 20)
    SetLightColor(#Light2, #PB_Light_DiffuseColor, RGB(0,0,255))
   
    AmbientColor(RGB(80, 80, 80))

  EndIf
EndIf

    Repeat
     
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20
        MouseY = -MouseDeltaY()/20
      EndIf
     
         
      If ExamineKeyboard()
     
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -1
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = 1
        Else
          KeyX = 0
        EndIf
       
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -1
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = 1
        Else
          KeyY = 0
        EndIf
           
      EndIf
 
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
     
      RenderWorld()
     
      ShowFPS=1
      If ShowFPS=1
        CurrentFPS = Engine3DFrameRate(#PB_Engine3D_Current)
        AverageFPS = Engine3DFrameRate(#PB_Engine3D_Average)
        MaximumFPS = Engine3DFrameRate(#PB_Engine3D_Maximum)
        MinimumFPS = Engine3DFrameRate(#PB_Engine3D_Minimum)
        CountTris=CountRenderedTriangles()
        StartDrawing(SpriteOutput(#Info))
          Box(0,0,350,120,RGB(40,40,40))
          DrawingFont(FontID(#Font))
          DrawText(2,2,CPU$,RGB(255,0,0),RGB(40,40,40))
          DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(40,40,40))
          DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(40,40,40))
        StopDrawing()
        DisplayTransparentSprite(#Info,20,20)
        If FirstFrame=0
          Engine3DFrameRate(#PB_Engine3D_Reset)
          FirstFrame=1
        EndIf
      EndIf
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
   
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
 
End
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: I need help with Hardware Skinning

Post by applePi »

i can't believe it, now the fps = 57 and much more better
the fps = 28 if i increased the number to 500 X 2, that is madness.
thanks
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

Re: I need help with Hardware Skinning

Post by Bananenfreak »

Could this also work with custom shadowcaster and -receiver (And is this something similar to AMD Mantle)?
Image
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: I need help with Hardware Skinning

Post by Samuel »

As far as I know it should work with shadow casters and receivers.
Bananenfreak wrote:(And is this something similar to AMD Mantle)?
Kinda, since we're using DirectX.
From what I've read and seen Mantle is just another Graphics API. Same as OpenGL and DirectX, but Mantle is still young and it's future is uncertain.
Whereas OpenGL and DirectX are both mature APIs that have no where to go, but up.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Hardware Skinning (GPU Animation)

Post by Samuel »

I finally updated the download link in the original post.

One thing I've noticed and I don't think this is the shaders fault. Is that it runs a lot faster with Purebasic x86 compared to the x64 version.
Might be related to how the compilers send information or something.

Purebasic 5.2 x86
With 200 animated entities I get 60 Frames Per Second.

Purebasic 5.2 x64
The same amount as above, but I only get 40 Frames Per Second.

I'm running Windows 7 Professional 64-bit.

@ApplePi
I took a portion of your example. I think the entities look a lot nicer in a circle.
I hope you don't mind.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Hardware Skinning (GPU Animation)

Post by Thunder93 »

Same experiences, regarding fps.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Hardware Skinning (GPU Animation)

Post by applePi »

thanks Samuel for using the circle, it is a pleasure you have posted such a shader. i thought first that such feats can be only possible in super computers and now we can use it in purebasic. tft have posted last year the display of 300000 cubes and his fps was 360 FPS
3600648 Tris rendered while my fps was only 15, i wonder how much his results since he have the card titan-graphics-card considered by some a super computer http://www.nvidia.co.uk/titan-graphics-card
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Hardware Skinning (GPU Animation)

Post by applePi »

i have tried Samuel example (download link in page 1) in PB5.31 and now it needs some editing
1- Engine3DFrameRate replaced by Engine3DStatus with suitable constants
2- CountTris=CountRenderedTriangles() replaced with CountTris=Engine3DStatus(#PB_Engine3D_NbRenderedTriangles)
3- Add3DArchive("\", #PB_3DArchive_FileSystem) replaced with
Add3DArchive(".", #PB_3DArchive_FileSystem) to search the current folder
the example after editing looks like: (you need all the package in the download link)

Code: Select all


Global.f KeyX, KeyY, MouseX, MouseY
Global Help,FirstFrame,Total,CPU$

Enumeration
  #Help
  #Window
  #Font
  #FloorTex
  #FloorMat
  #JaiquaMat
  #JaiquaMesh
  #Jaiqua
  #PlaneMesh
  #Plane
  #Camera
  #Light
EndEnumeration

Declare DisplayHelp()
Declare CheckKeyboard()

If InitEngine3D(#PB_Engine3D_DebugLog)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

Total = 100; The true total number of entities is twice this number
CPU$ = CPUName()

LoadFont(#Font, "Courier New", 10,#PB_Font_Bold)
  
If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "Hardware Skinning")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)

    Add3DArchive(".", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    CreateSprite(#Help, 350, 160)
    
    CreateTexture(#FloorTex,32,32)
    StartDrawing(TextureOutput(#FloorTex))
      Box(0,0,16,16,RGB(55,55,55))
      Box(16,0,16,16,RGB(0,50,75))
      Box(0,16,16,16,RGB(0,50,75))
      Box(16,16,16,16,RGB(55,55,55))
    StopDrawing()
    CreateMaterial(#FloorMat, TextureID(#FloorTex))
    
    CreatePlane(#PlaneMesh, 150, 150, 1, 1, 30, 30)
    CreateEntity(#Plane,MeshID(#PlaneMesh),MaterialID(#FloorMat),0.1,-0.2,0.2)
    EntityRenderMode(#Plane,0)
    
    
    GetScriptMaterial(#JaiquaMat,"jaiqua")
    
    ;# Uncomment this next line to see how slow it is without hardware acceleration.
    ;CreateMaterial(#JaiquaMat, TextureID(#FloorTex))

    LoadMesh(#JaiquaMesh,"jaiqua.mesh")
    
    For EN=1 To Total
      X.f=X+#PI*2/Total
      Z.f=Z+#PI*2/Total
      XX.f=Cos(X)*60
      ZZ.f=Sin(Z)*60
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
    X=0
    Z=0
    For EN=1 To Total
      X=X+#PI*2/Total
      Z=Z+#PI*2/Total
      XX.f=Cos(X)*30
      ZZ.f=Sin(Z)*30
      Jaiqua=CreateEntity(#PB_Any, MeshID(#JaiquaMesh), MaterialID(#JaiquaMat),XX,0,ZZ)
      ScaleEntity(Jaiqua,0.2,0.2,0.2)
      RotateEntity(Jaiqua,0,180,0)
      StartEntityAnimation(Jaiqua, "Sneak")
    Next
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 30, 120, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)

    CreateLight(#Light, RGB(0, 0, 0), -20, 40, 20)
    SetLightColor(#Light, #PB_Light_DiffuseColor, RGB(255,255,255))

    AmbientColor(RGB(80, 80, 80))
    
    Repeat
      
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
      
          
      If ExamineKeyboard()
        CheckKeyboard()
      EndIf
  
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      
      If Help = 0
        DisplayHelp()
      EndIf
      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End


Procedure DisplayHelp()
  
  CurrentFPS = Engine3DStatus(#PB_Engine3D_Current)
  AverageFPS = Engine3DStatus(#PB_Engine3D_Average)
  MaximumFPS = Engine3DStatus(#PB_Engine3D_Maximum)
  MinimumFPS = Engine3DStatus(#PB_Engine3D_Minimum)
  ;CountTris=CountRenderedTriangles()
  CountTris=Engine3DStatus(#PB_Engine3D_NbRenderedTriangles)
  StartDrawing(SpriteOutput(#Help))
    Box(0,0,280,160,RGB(40,40,40))
    DrawingFont(FontID(#Font)) 
    DrawText(2,2,CPU$,RGB(255,0,0),RGB(40,40,40))
    DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(40,40,40))
    DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(40,40,40))
    DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(40,40,40))
    DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(40,40,40))
    DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(40,40,40))
    DrawText(2,122,Str(Total*2)+" Animated Entities",RGB(255,155,0),RGB(40,40,40))
    DrawText(2,142,"Press H to Toggle Help.",RGB(255,55,255),RGB(40,40,40))
  StopDrawing()
  DisplayTransparentSprite(#Help,20,20)
  If FirstFrame=0
    Engine3DStatus(#PB_Engine3D_Reset)
    FirstFrame=1
  EndIf
  
EndProcedure

Procedure CheckKeyboard()
  
  If KeyboardPushed(#PB_Key_Left)
    KeyX = -0.2
  ElseIf KeyboardPushed(#PB_Key_Right)
    KeyX = 0.2
  Else
    KeyX = 0
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    KeyY = -0.2
  ElseIf KeyboardPushed(#PB_Key_Down)
    KeyY = 0.2
  Else
    KeyY = 0
  EndIf
  
  
  If KeyboardReleased(#PB_Key_H)
    If Help=0
      Help=1
    Else
      Help=0
    EndIf
  EndIf
        
EndProcedure
Post Reply