BuildTerrain() in Threads

Everything related to 3D programming
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

BuildTerrain() in Threads

Post by Bananenfreak »

Heyho,

I want to outsource BuildTerrain() in Threads, because BuildTerrain() is too slow for use in my mainloop.
I wrote a Little code, but every time it stops with an IMA.
Why this IMA occures? Does anyone have an idea?

Before RenderWorld() is called, all Terrains must be built, so the program has to wait for the end of threads. I think there´s still a framedrop when new Terrains will be load runtime, but it won´t be as big as now.

Code: Select all

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>                             >>
;>>  Name: BuildTerrain()       >>
;>>         in Thread           >>
;>>                             >>
;>>  Author: Tom Zähringer      >>
;>>                             >>
;>>  Date: 22.02.2015           >>
;>>                             >>
;>>  OS: Windows                >>
;>>                             >>
;>>                             >>
;>>                             >>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EnableExplicit


Structure threadVer
  threadNr.i
  terrainNr.i
EndStructure


Define.f KeyX, KeyY, MouseX, MouseY
Define nx.f, nz.f, Boost.f = 1, Yaw.f, Pitch.f
Define.i Quit, boden, light
Global NewList Threads.threadVer()
#kam_0 = 0
#window = 0
#plane = 0
#planent = 0


Procedure BuildThreadTerrain(terrain.i)
  Debug terrain
  BuildTerrain(terrain)
EndProcedure


Procedure MakeTerrain()
  Protected.i x, y, terrain, size = 24
  
  
  For x = 0 To 3
    For y = 0 To 3
      terrain = CreateTerrain(#PB_Any, 513, size, 1, 3, "TerrainGroup" + x + "|" + y, "dat")
      TerrainLocate(terrain, x * size, 0, y * size)
      ; set all texture will be use when terrrain will be constructed 
      AddTerrainTexture(terrain,  0, 10, "dirt_grayrocky_diffusespecular.jpg",  "dirt_grayrocky_normalheight.jpg")
      AddTerrainTexture(terrain,  1,  3, "grass_green-01_diffusespecular.jpg", "grass_green-01_normalheight.jpg")
      AddTerrainTexture(terrain,  2, 20, "growth_weirdfungus-03_diffusespecular.jpg", "growth_weirdfungus-03_normalheight.jpg")
      DefineTerrainTile(terrain, 0, 0, "terrain513.png", 0, 0)
      Debug terrain
      
      AddElement(Threads())
      Threads()\terrainNr = terrain
      Threads()\threadNr = CreateThread(@BuildThreadTerrain(), Threads()\terrainNr)
      ;BuildThreadTerrain(terrain)
    Next y
  Next x
EndProcedure


Procedure ThreadSucher()
  While Not ListSize(Threads()) = 0
    FirstElement(Threads())
    If Not IsThread(Threads()\threadNr)
      TerrainPhysicBody(Threads()\terrainNr, 0.01, 0.3)       ;Erst nach dem BuildTerrain() aufrufen.
      DeleteElement(Threads())
    EndIf
  Wend
EndProcedure


If InitEngine3D(#PB_Engine3D_EnableCG)
  
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/nvidia", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  OpenWindow(#window, 0, 0, 1800, 1000, "BuildTerrain() in Thread", #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(#window), 10, 10, 2000, 2000, 0, 10, 10, #PB_Screen_SmartSynchronization)
  
  WorldShadows(#PB_Shadow_TextureAdditive, 200, RGB(255 * 0.2, 255 * 0.2, 255 * 0.2), 4096)
  
  AmbientColor(RGB(255 * 0.2, 255 * 0.2, 255 * 0.2))
  
  light = CreateLight(#PB_Any ,RGB(190, 190, 190), 4000, 1200, 1000,#PB_Light_Directional)
  SetLightColor(light, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4)) 
  LightDirection(light ,0.55, -0.3, -0.75)
  
  ;- Terrain definition
  SetupTerrains(LightID(Light), 3000, #PB_Terrain_NormalMapping)
  
  MakeTerrain()
  
  ;-Camera
  CreateCamera(#kam_0, 0, 0, 100, 100)
  MoveCamera(#kam_0, 0, 20, 0, #PB_Absolute)
  CameraLookAt(#kam_0, 20, 0, 20)
  CameraRange (#kam_0, 2, 5000)
  CameraFOV   (#kam_0, 90)
  CameraBackColor(#kam_0, RGB(0, 0, 0))
  
  Repeat
    Repeat
    Until WindowEvent() = 0
    
    If ExamineMouse()
      Yaw   = -MouseDeltaX() * 0.05
      Pitch = -MouseDeltaY() * 0.05
    EndIf
    
    If ExamineKeyboard()
      
      If KeyboardPushed(#PB_Key_Up)    
        MoveCamera(0,  0, 0, -1 * Boost)
      ElseIf KeyboardPushed(#PB_Key_Down)
        MoveCamera(0,  0, 0,  1 * Boost)
      EndIf 
      
      If KeyboardPushed(#PB_Key_Left)  
        MoveCamera(0, -1 * Boost, 0, 0) 
      ElseIf KeyboardPushed(#PB_Key_Right)
        MoveCamera(0,  1 * Boost, 0, 0)
      EndIf 
      
    EndIf
    
    RotateCamera(0, Pitch, Yaw, 0, #PB_Relative)
    
    ThreadSucher()
    
    RenderWorld()
    FlipBuffers()
  Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End
Last edited by Bananenfreak on Mon Feb 23, 2015 9:12 am, edited 1 time in total.
Image
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: BuildTerrain() in Threads

Post by Samuel »

I've heard you should keep all of OGRE within one thread and then only have non related portions (like sound, and ai systems) in separate threads.
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

Re: BuildTerrain() in Threads

Post by Bananenfreak »

Sure, but I thought it´s ok if all happens before RenderWorld() is called.
So, there´s a framedrop when loading new Terrains and I can´t do anything. That´s sad :cry:

Other question: I can outsource Sound in a thread? Good to know.
Image
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: BuildTerrain() in Threads

Post by Samuel »

Sinbad wrote: You should thread things that naturally fall into the background, ie to be spread over multiple frames. That's AI, buffering of streaming data, but probably not physics (because you need to keep it in sync with the frame rate if it's not going to look weird). None of these things are Ogre itself. Due to the fact that the graphics are the most noticeable thing, and that the GPU is asynchronous anyway, rendering processes are rarely farmed out to the background, so there's generally no need for thread safety. Projects which use threading thread non-graphical things.
Bananenfreak wrote: So, there´s a framedrop when loading new Terrains and I can´t do anything. That´s sad :cry:
Purebasic's terrain system has several issues. My issue with it has always been the lack of material script support.
I know Alexi had problems with it too so he created his own terrain system. One that you could use multithreading and have dynamic updates with, but I don't know if he ever finished it or plans on releasing it.

It might not be of any use to you, but you can take a look at my Terrain Generator.
If nothing else it might help give you ideas for creating your own terrain system.
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

Re: BuildTerrain() in Threads

Post by Bananenfreak »

Hmm, I think this is the only reliable way to get the things I want.
Thank you for your help, Samuel. I will be inspired by your TerrainGenerator :)
Image
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

Re: BuildTerrain() in Threads

Post by Bananenfreak »

Thank you both for your help
I think I´m going to work with the integrated Terrain. Framedrop or not, perhaps there will come an update and all my problems are gone (#TerrainPaging).
If there´s sometime enough sparetime for creating a Terrainsystem, I will do it, but now I have lot of work with my normal programs.

Eventually I use Samuels terraingenerator... :)
Image
Post Reply