Page 1 of 1

BuildTerrain() in Threads

Posted: Sun Feb 22, 2015 10:03 am
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

Re: BuildTerrain() in Threads

Posted: Sun Feb 22, 2015 6:23 pm
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.

Re: BuildTerrain() in Threads

Posted: Mon Feb 23, 2015 9:22 am
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.

Re: BuildTerrain() in Threads

Posted: Mon Feb 23, 2015 6:20 pm
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.

Re: BuildTerrain() in Threads

Posted: Tue Feb 24, 2015 10:53 am
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 :)

Re: BuildTerrain() in Threads

Posted: Wed Feb 25, 2015 8:58 am
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... :)