Seite 1 von 2

Programmabsturz / Crash bei OpenWindowedScreen in procedure

Verfasst: 24.11.2018 15:42
von Onetime
Hallo alle,
ich bin neu hier und auch bei Purebasic.
Weiß nicht ob der Beitrag hier gut passt oder lieber in die Grafikabteilung sollte:

Folgendes Problem:
Main Hauptprogrammm ruft ein Unterroutine auf die dann was in 3D anzeigt. Soweit so gut:
Wenn ich dann aber die Procedure ein zweites mal aufrufe stürzt es ab ohne das ein der Fehlermeldungen im Programm ausgeführt wurden.
Das passiert genau beim "OpenWindowedScreen" Kommando:
(Hoffe das ist ein Anfängerfehler, hab' aber im Moment keine Idee)


Gruß
Onetime

PS: Unter Windows 10 mit PureBasic 5.60 (Windows - x64)

Code: Alles auswählen

;========================================================================================================
; Issue with openwindowedscreen: When calling the procedure the second time -> program crashes with error
;
; Fehler bei openwindowedscreen : Wenn die Procedure das zweite Mal gerufen wird -> stürzt das Programm  ab
;
; Error: ; "The debugged executable quit unexpectedly"
;========================================================================================================


  #WinMain=0
  #Win3D=1
  Declare _3DSub()   ; 3d subroutine
  Define.i Quit

   
  If OpenWindow(0, 100, 200, 500, 500, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
    
    
    
    ; eventloop
    Repeat
      
      If MessageRequester("Press Yes to call 3D, NO to quit", " Call 3D?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes    
          _3DSub()
        Else
          Quit = 1
        EndIf
        
        
        
        Event = WaitWindowEvent()
        
        If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
          Quit = 1
        EndIf
        
      Until Quit = 1
      
    EndIf
    
    
; ******************************************************************************************************************    
Procedure _3DSub()
  Protected.i _SubQuit=0, _event
  Protected.i _Cube
  
  DisableWindow(#WinMain, #True)  ; disable main window
     Debug "InitEngine3D will be done now // kommt jetzt"
  If InitEngine3D(#PB_Engine3D_DebugLog) And InitSprite() And InitKeyboard()  
      Debug "OpenWindow will be done now // kommt jetzt"
    If  OpenWindow(#Win3D,50,50,500,500,"3D - Window ",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
        Debug "OpenWindowedScreen will be done now // kommt jetzt"
      If OpenWindowedScreen(WindowID(#Win3d),0,0,500,500 ,#False,0,0)  ; x/y bezieht sich auf das fenster  // x/y relates to window position
        Debug "OpenWindowedScreen has succeded / hatte Erfolg"    
      Else
        MessageRequester("Error", "Can't open windowed screen!", 0)
        _SubQuit=1
      EndIf 
    Else 
      MessageRequester("Error", "Can't open window!", 0)
      _SubQuit=1
    EndIf  ; openwindow
  Else
    _SubQuit=1
    MessageRequester("Error", "Init3dengine failure!", 0)    
  EndIf ; initengine
  
  
  If _SubQuit=0  ; All OK up to now -> perform 3d actions
    
    _Cube=CreateCube(#PB_Any, 2)
    _Entity1=CreateEntity(#PB_Any,MeshID(_Cube), #PB_Material_None, 0,0,0 )
    ;Create Camera
    CreateCamera(0,0,0,100,100)
    MoveCamera(0,0,0, 10,#PB_Absolute)
    CameraLookAt(0, 0, 0, 0)
    CameraBackColor(0, RGB(0,200,200))
    
    ; event loop -------------------------------------------------------------------------------------
    Repeat   ; main loop
      ExamineKeyboard()
      
      Repeat  ; clear events
        ; important: Clear all events between frames?
        _event= WindowEvent()
        Select _event
          Case #PB_Event_CloseWindow 
            _SubQuit = 1 
        EndSelect 
      Until _Event = 0
      
      Delay(50)
      RotateEntity(_Entity1, 0, 5, 5,#PB_Relative) ; just to do something 
      
      RenderWorld()
      FlipBuffers()
    Until _SubQuit=1 Or KeyboardPushed(#PB_Key_Escape) 
    ; event loop end ----------------------------------------------------------------------------------
    
  EndIf  ; 3d actions
  
  
  DisableWindow(#WinMain, #False)  ; main Window enable
  CloseScreen()
  CloseWindow(#Win3D)
  
EndProcedure ; _3DSub()


End   ; Program end


Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 24.11.2018 22:37
von DarkSoul
Dass keine Fehlermeldung kommt, stimmt nicht. :wink:

Schalte mal den Ogre-Debugger ein :)

Code: Alles auswählen

InitEngine3D(#PB_Engine3D_DebugOutput)
und in den Compileroptionen bei "Executable Format" auf "Console" umstellen.
Nun hast du immer ein Konsolenfenster nebenher laufen, wo Ogre seinen Debug-Output reinhaut.

Dazu gehört auch diese Exception, die diesen Absturz auslöst:
terminate called after throwing an instance of 'Ogre::InternalErrorException'
what(): OGRE EXCEPTION(7:InternalErrorException): Cannot create GL vertex buffer in GLHardwareVertexBuffer::GLHardwareVertexBuffer at OgreGLHardwareVertexBuffer.cpp (line 46)
Es kracht demnach innerhalb der Engine beim Versuch, die Speicherbereiche für deine Meshes zu reservieren (weshalb er auch im PB-Code dort abschmiert, wo diese erzeugt werden).

Schau mal in die Beschreibung von InitEngine3D:
Initializes the 3D environment for later use. You must put this function at the top of your source code if you want to use any of the 3D functions.
Also wenn ich diese Anweisung mit allen anderen InitBlabla()'s aus der Procedure herausnehme und ganz nach oben versetze, direkt unter den Kommentarblock, so dass diese als erstes und genau einmal aufgerufen werden, dann läuft dein Programm. :wink:
Allerdings habe ich Ubuntu. Sollte aber auch unter Windows funktionieren.

Man sollte bereits initialisierte Dinge nicht nochmal initialisieren. Das führt gerne zu unvorhersehbaren Problemen.

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 13:14
von Onetime
Danke DarkSoul für die Hinweise!

- Das Ogre log hatte ich ja mit "InitEngine3D(#PB_Engine3D_DebugLog)" ja schon eingeschaltet so daß das in die datei Ogre.log geschrieben wird. Wenn ich das mit dem Konsolen Window mache, stürzt die Konsole mit ab und ich kanns nicht mehr lesen (zumindest unter Win10).


- Wenn ich die Init Sachen an den Anfang des Haupprogrammes stelle, ist der Fehler noch da. Programm stürzt ab.

- Was beim 2. Durchlauf im Ogre.log dazugekommen ist sind folgende 2 Zeilen:


12:04:46: D3D9RenderSystem::_createRenderWindow "PureBasic Ogre", 500x500 windowed miscParams: FSAA=0 displayFrequency=0 externalWindowHandle=722974 vsync=true
12:04:46: D3D9 : Created D3D9 Rendering Window 'PureBasic Ogre' : 500x500, 32bpp

... danach stürzt es ab.

- evtl. kann Jemand der auch Win10 benutzt das ja mal ausprobieren.. Würde mich interessieren.

hier der geänderte Code, läuft das so bei dir?:

Code: Alles auswählen

;========================================================================================================
; Issue with openwindowedscreen: When calling the procedure the second time -> program crashes with error
;
; Fehler bei openwindowedscreen : Wenn die Procedure das zweite Mal gerufen wird -> stürzt das Programm  ab
;
; Error: ; "The debugged executable quit unexpectedly"
;========================================================================================================

  If Not InitEngine3D(#PB_Engine3D_DebugLog)
    MessageRequester("Error", "Init3dengine failure!", 0) 
    End
  EndIf ; initengine
  
  If Not  InitSprite()    
    MessageRequester("Error", "InitSprite failure!", 0) 
    End
    
  EndIf
  
  If Not  InitKeyboard()   
    
    MessageRequester("Error", "Initkeyboard failure!", 0) 
    End
  EndIf
  
   Add3DArchive(#PB_Compiler_Home + "examples\3d\Data\Textures", #PB_3DArchive_FileSystem)
   Add3DArchive(GetCurrentDirectory(), #PB_3DArchive_FileSystem)
     


  
  
  #WinMain=0
  #Win3D=1
  Declare _3DSub()   ; 3d subroutine
  Define.i Quit
  

  
  
   
  If OpenWindow(0, 300, 300, 500, 500, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
    
    
    
    ; eventloop
    Repeat
      
      If MessageRequester("Press Yes to call 3D, NO to quit", " Call 3D?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes    
          _3DSub()
        Else
          Quit = 1
        EndIf
        
        
        
        Event = WaitWindowEvent()
        
        If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
          Quit = 1
        EndIf
        
      Until Quit = 1
      
    EndIf
    
    
; ******************************************************************************************************************    
Procedure _3DSub()
  Protected.i _SubQuit=0, _event
  Protected.i _Cube
  
  DisableWindow(#WinMain, #True)  ; disable main window
     Debug "InitEngine3D will be done now // kommt jetzt"
     
       
      Debug "OpenWindow will be done now // kommt jetzt"
    If  OpenWindow(#Win3D,50,50,500,500,"3D - Window ",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
        Debug "OpenWindowedScreen will be done now // kommt jetzt"
      If OpenWindowedScreen(WindowID(#Win3d),0,0,500,500 ,#False,0,0)  ; x/y bezieht sich auf das fenster  // x/y relates to window position
        Debug "OpenWindowedScreen has succeded / hatte Erfolg"    
      Else
        MessageRequester("Error", "Can't open windowed screen!", 0)
        _SubQuit=1
      EndIf 
    Else 
      MessageRequester("Error", "Can't open window!", 0)
      _SubQuit=1
    EndIf  ; openwindow
    

  
  
  If _SubQuit=0  ; All OK up to now -> perform 3d actions
    
    
    _Cube=CreateCube(#PB_Any, 2)
    _Entity1=CreateEntity(#PB_Any,MeshID(_Cube), #PB_Material_None, 0,0,0 )
    ;Create Camera
    CreateCamera(0,0,0,100,100)
    MoveCamera(0,0,0, 10,#PB_Absolute)
    CameraLookAt(0, 0, 0, 0)
    CameraBackColor(0, RGB(0,200,200))
    
    ; event loop -------------------------------------------------------------------------------------
    Repeat   ; main loop
      ExamineKeyboard()
      
      Repeat  ; clear events
        ; important: Clear all events between frames?
        _event= WindowEvent()
        Select _event
          Case #PB_Event_CloseWindow 
            _SubQuit = 1 
        EndSelect 
      Until _Event = 0
      
      Delay(50)
      RotateEntity(_Entity1, 0, 5, 5,#PB_Relative) ; just to do something 
      
      RenderWorld()
      FlipBuffers()
    Until _SubQuit=1 Or KeyboardPushed(#PB_Key_Escape) 
    ; event loop end ----------------------------------------------------------------------------------
    
  EndIf  ; 3d actions
  
  
  DisableWindow(#WinMain, #False)  ; main Window enable
  CloseScreen()
  CloseWindow(#Win3D)
  
EndProcedure ; _3DSub()


End   ; Program end

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 13:42
von mk-soft
Kann an der installierten DX9 Version liegen oder an der Grafikkarte...

Bei mir läuft es unter Window 7 (VM) und Windows 10 (VM)

Nur die Event-Schleife läuft nicht richtig beim beenden... Muss noch kontrolliert werden

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 14:21
von DarkSoul
Ne.... Der Fehler ist nun gewandert.

Invalid Memory Access bei CloseScreen() und das schon im ersten Durchlauf. :shock:

Aber mein Fix von gestern funktioniert heute auch nict mehr. :freak:
12:04:46: D3D9RenderSystem::_createRenderWindow "PureBasic Ogre", 500x500 windowed miscParams: FSAA=0 displayFrequency=0 externalWindowHandle=722974 vsync=true
12:04:46: D3D9 : Created D3D9 Rendering Window 'PureBasic Ogre' : 500x500, 32bpp
Das ist nur Verbose-Debug-Output zu deiner Information. Nicht alles, was da aufgezeichnet wird, sind Fehler. Hiermit will er dir nur sagen, dass der (im Windows-Fall) hardwarebeschleunigte DirectX-View erfolgreich geöffnet wurde.

Vielleicht sollten wir uns erstmal einigen, wo (Zeilennummer) es jeweils abstürzt (Die betroffene Zeile wird auch dann rot angezeigt, wenn es innerhalb der Lib crasht) und welche PB-Version du verwendest. Das würde Missverständnisse vermeiden. :wink:

Ich habe bei der Ursprungsvariante den Absturz in der Zeile 97 (sowohl unter 5.62 als auch der aktuellen Beta):

Code: Alles auswählen

 _Cube=CreateCube(#PB_Any, 2)
Ich glaube fast, da ist in der Engine ein wenig der Wurm drin. <)

Habe deinen Code mal ein wenig heruntergebrochen auf das nötigste. Läuft das hier bei dir?

Ich vermute mal, die Engine will, dass du überall #PB_Any benutzt, weil wenn ich stattdessen irgendwo eine statische ID vergebe, stürzt es wieder an CreateCube() ab. /:->

Code: Alles auswählen

If Not InitEngine3D(#PB_Engine3D_DebugLog) Or Not InitSprite() 
  MessageRequester("Error", "init failure!", 0) : End
EndIf 

Repeat
  win3d = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 640, 480, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  If win3d = 0 
    MessageRequester("Error", "Bla", 0) : End  
  EndIf
  
  If OpenWindowedScreen(WindowID(win3d),0,0,640,480,#False,0,0) = 0
    MessageRequester("Error", "Blubb", 0) : End  
  EndIf
  
  cube=CreateCube(#PB_Any, 2)
  entity1=CreateEntity(#PB_Any,MeshID(cube), #PB_Material_None, 0,0,0 )
  cam=CreateCamera(#PB_Any,0,0,100,100)
  MoveCamera(cam,0,0, 10,#PB_Absolute)
  CameraLookAt(cam, 0, 0, 0)
  CameraBackColor(cam, RGB(0,200,200))
  
  Repeat 
    Delay(20)
    RotateEntity(entity1, 0, 5, 5,#PB_Relative)
    RenderWorld()
    FlipBuffers()      
  Until WindowEvent() = #PB_Event_CloseWindow    
  
  FreeCamera(cam)
  FreeEntity(entity1)
  FreeMesh(cube)
  
  CloseScreen()
  CloseWindow(win3d)
Until MessageRequester("","Once again?",#PB_MessageRequester_YesNo) = #PB_MessageRequester_No

End

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 14:58
von Onetime
Nö, stürzt ab beim 2. Durchgang. Der 1. Screen wird angezeigt wie geplant.

Ich hab mal folgende 2 Debugs eingefügt:

...
Debug " VOR openwindowedScreen"
If OpenWindowedScreen(WindowID(win3d),0,0,640,480,#False,0,0) = 0
MessageRequester("Error", "Blubb", 0) : End
EndIf

Debug " NACH openwindowedScreen"
...

Im 1. Durchgang kommen beide Meldungen.
Im 2, Durchgang geht's nur noch bis zur Meldung "VOR openwindowedScreen" --> also spackt das bei openwindowedscreen ab.
Keine Zeile ROT nach dem Absturz.


:evil:

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 15:00
von Onetime
PS: Unter Windows 10 mit PureBasic 5.60 (Windows - x64)


… hatte ich im 1. Beitrag schon geschrieben...

hier noch was ich in der Info gefunden habe:

IDE build on 03/02/2017 [10:30] by Fred
Branch: v5.60 Revision: 1808

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 15:24
von ccode_new
Scheint ein Bug mit der 3D-Engine in Verbindung mit "OpenWindowedScreen(...)" zu sein.

Wenn man die Eventschleife (und die Erstellung des Screens/Fensters) aber nicht blödsinnigerweise nochmal in eine Schleife packt geht es.

Code: Alles auswählen

;Achtung! Dieser Code gibt GOTO eine Chance ;)

If Not InitEngine3D(#PB_Engine3D_DebugLog) Or Not InitSprite()
  MessageRequester("Error", "init failure!", 0) : End
EndIf

  win3d = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 640, 480, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  If win3d = 0
    MessageRequester("Error", "Bla", 0) : End 
  EndIf
 
  If OpenWindowedScreen(WindowID(win3d),0,0,640,480,#False,0,0) = 0
    MessageRequester("Error", "Blubb", 0) : End 
  EndIf
  
Wiederholung:
  Delay(10)
  HideWindow(win3d, #False)
  
  cube=CreateCube(#PB_Any, 2)
  entity1=CreateEntity(#PB_Any,MeshID(cube), #PB_Material_None, 0,0,0 )
  cam=CreateCamera(#PB_Any,0,0,100,100)
  MoveCamera(cam,0,0, 10,#PB_Absolute)
  CameraLookAt(cam, 0, 0, 0)
  CameraBackColor(cam, RGB(0,200,200))
  
  Repeat
    Delay(20)
    RotateEntity(entity1, 0, 5, 5,#PB_Relative)
    RenderWorld()
    FlipBuffers()     
  Until WindowEvent() = #PB_Event_CloseWindow   
 
  FreeCamera(cam)
  FreeEntity(entity1)
  FreeMesh(cube)
  
  HideWindow(win3d, #True)

If MessageRequester("","Once again?",#PB_MessageRequester_YesNo) = #PB_MessageRequester_No
  End
Else
  Goto Wiederholung
EndIf

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 16:54
von Onetime
ok, das ist ja schon mal was... vielen Dank.

Vielleicht reicht's ja das openwindow 3d und den Openwindowedscreen in die Hauptroutine zu verlegen und zu "verstecken" und dann trotzdem den Rest in meiner Prozedur zu machen... mal sehen.
Damit muss ich natürlich meine Event Logik mit in die Hauptschleife verlegen und das 3D Fenster öffnen obwohl's vielleicht gar nicht aufgerufen wird.

Auf jeden Fall ein seltsames Verhalten.
Ich dachte ich könnte da schnell was 3D mäßiges in mein Programm integrieren... jetzt hänge ich schon wieder stundenlang an dem Zeug das eigentlich ja funktionieren müsste...

... aber wenn man's dann wenigstens überhaupt zum Laufen bekommt .. :)

Re: Programmabsturz / Crash bei OpenWindowedScreen in proced

Verfasst: 25.11.2018 17:15
von Onetime
Ok, so klappt's jetzt.

Ich hab mein originales Coding mal so abgeändert das die Init Sachen alle am Anfang der Hauproutine gemacht werden.
Dann wird das 3D Fenster und der Windowed Screen auch am Anfang der Hauproutine erzeugt und dann gleich "versteckt".
In meiner ursprünglichen Unterroutine wird dann statt open nur ein "Unhide" gemacht.. der Rest der Objekte scheint zu funktionieren.
Damit brauch ich kein GOTO und hab auch meine schöne zusätzliche Eventschleife ;-)


Vielen dank noch mal für die Anregungen!
Find ich super das man hier so schnell Rückmeldungen bekommt!

Ich schau jetzt mal ob ich das in meine Anwendung integrieren kann und ob's stabil läuft

Gruß
Onetime

Code: Alles auswählen

;========================================================================================================
; Issue with openwindowedscreen: When calling the procedure the second time -> program crashes with error
;
; Fehler bei openwindowedscreen : Wenn die Procedure das zweite Mal gerufen wird -> stürzt das Programm  ab
;
; Error: ; "The debugged executable quit unexpectedly"
;========================================================================================================
  #WinMain=0
  #Win3D=1

If Not InitEngine3D(#PB_Engine3D_DebugLog)
    MessageRequester("Error", "Init3dengine failure!", 0) 
    End
  EndIf ; initengine
  
  If Not  InitSprite()    
    MessageRequester("Error", "InitSprite failure!", 0) 
    End
    
  EndIf
  
  If Not  InitKeyboard()   
    
    MessageRequester("Error", "Initkeyboard failure!", 0) 
    End
  EndIf
  
   If  OpenWindow(#Win3D,50,50,500,500,"3D - Window ",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) = 0
    MessageRequester("Error", "Openwindow 3D  failure!", 0) 
    End
  EndIf
  
  If OpenWindowedScreen(WindowID(#Win3d),0,0,500,500 ,#False,0,0) = 0
    MessageRequester("Error", "OpenwindowedScreen 3D  failure!", 0) 
    End
  EndIf
  
  HideWindow(#Win3D, #True)
  
  
  


  Declare _3DSub()   ; 3d subroutine
  Define.i Quit

   
  If OpenWindow(0, 100, 200, 500, 500, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
    
    
    
    ; eventloop
    Repeat
      
      If MessageRequester("Press Yes to call 3D, NO to quit", " Call 3D?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes    
          _3DSub()
        Else
          Quit = 1
        EndIf
        
        
        
        Event = WaitWindowEvent()
        
        If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
          Quit = 1
        EndIf
        
      Until Quit = 1
      
    EndIf
  CloseScreen()
  CloseWindow(#Win3D)

    
    
; ******************************************************************************************************************    
Procedure _3DSub()
  Protected.i _SubQuit=0, _event
  Protected.i _Cube, _Entity1, _Cam
  
  DisableWindow(#WinMain, #True)  ; disable main window
  HideWindow(#Win3D, #False)  
  
  If _SubQuit=0  ; All OK up to now -> perform 3d actions
    
    _Cube=CreateCube(#PB_Any, 2)
    _Entity1=CreateEntity(#PB_Any,MeshID(_Cube), #PB_Material_None, 0,0,0 )
    ;Create Camera
    _cam=CreateCamera(#PB_Any,0,0,100,100)
    MoveCamera(_cam,0,0, 10,#PB_Absolute)
    CameraLookAt(_cam, 0, 0, 0)
    CameraBackColor(_cam, RGB(0,200,200))
    
    ; event loop -------------------------------------------------------------------------------------
    Repeat   ; main loop
      ExamineKeyboard()
      
      Repeat  ; clear events
        ; important: Clear all events between frames?
        _event= WindowEvent()
        Select _event
          Case #PB_Event_CloseWindow 
            _SubQuit = 1 
        EndSelect 
      Until _Event = 0
      
      Delay(50)
      RotateEntity(_Entity1, 0, 5, 5,#PB_Relative) ; just to do something 
      
      RenderWorld()
      FlipBuffers()
    Until _SubQuit=1 Or KeyboardPushed(#PB_Key_Escape) 
    ; event loop end ----------------------------------------------------------------------------------
    
  EndIf  ; 3d actions
  
  FreeCamera(_cam)
  FreeEntity(_Entity1)
  FreeMesh(_Cube)
  DisableWindow(#WinMain, #False)  ; main Window enable
  HideWindow(#Win3D, #True)
  
  
EndProcedure ; _3DSub()


End   ; Program end