CreateThread

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
darius676
Beiträge: 501
Registriert: 08.03.2010 22:12
Computerausstattung: Intel i5 16GB RAM nVidia 1050, Win11
Atari Jaguar, Surface Pro 5,Surface Laptop i5 7200, XBOX ONE X, XBOX Series X
Wohnort: AT
Kontaktdaten:

CreateThread

Beitrag von darius676 »

Guten Tag,
ich verstehe offensichtlich nicht wie und warum es zu dem Problem kommt:
ich versuche die Displayausgabe vom Rest des Programmes zu entkoppeln.

Warum? ich will das mal probieren. Aktuell arbeitet meine Engine unabhängig von der Displayrefreshrate, was ja so sein soll.
Aber, ich wollte probieren ob ich die Bildschirmausgabe als eigenen Thread verwenden kann.
Würde mich freuen, wenn einer dazu eine Idee hätte.

(PB Version 5.70LTS)

nun das Problem:
a) wenn ich einen Thread mit "repeat…...Code.....Code...forever" erstelle gibt es keine Bildschirmausgabe.
b) wenn ich einen Thread mit "...code...code ....code" erstelle (dieser wird in der mainschleife immer neu gestartet) funktioniert es, aber da wird ja jedesmal der thread neu gestartet.

Beispielcode:
ohne Repeat ...forever:
mainschleife:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Code: Alles auswählen

 Repeat
   
   If e_actuall_world.s<>e_next_world.s;check if we in a new room/area
     CHANGE_ROOM(e_next_world.s)
     E_SOUND_BASE()  ;......basic routine for soundplayback....   ;here we start/change the global world sound
   EndIf
   
   If e_screen_type.b=#ENGINE_WINDOWED_SCREEN
     v_message.l=WaitWindowEvent(1) ;mouse an window events, we do not use these, but we have to catch the value to prevent programcrash if mouse or other window input event happen
   EndIf
   
   E_KEYBOARD_BASE()

   ;-------------------------- do some  thread work.....---------------------------
   If e_engine_multi_core.b=#True
     If e_engine_display_status.i=#E_ENGINE_DISPLAY_READY
       E_START_THREAD_GLOBAL()  ;try some threads?
     EndIf
     
  EndIf  
;--------------------------------------------------------------------------------------


   E_SHOW_PLAY_FIELD()               ;here we handle all screen/window resolution and display output situations
   ForEver
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Thread erstellende Routine:

Code: Alles auswählen

;***************************************************************************************************************************

Procedure E_START_THREAD_GLOBAL()  ;------------------------- diese wird aus der Mainschleife aufgerufen
    If Not IsThread(e_thread_id_display_output.i)
    e_thread_id_display_output.i= CreateThread(@E_T_DRAW_FINAL_RENDER(),e_engine_display_status.i)
  EndIf
  If IsThread(e_thread_id_display_output.i)  
    WaitThread(e_thread_id_display_output.i);wird bei "repeat...forever" nicht verwendet.
  EndIf;
 EndProcedure

;****************************************************************************************************************************


;****************************************************************************************************************************
Procedure E_T_DRAW_FINAL_RENDER(my_display_port.i)  ;my_display_port.i wert wird von der Zeichenroutine übergeben.
 
  Define _frame_buffer_id.l=0
  

    If my_display_port.i=#E_ENGINE_DISPLAY_READY

    _frame_buffer_id=GrabSprite(#PB_Any,0,0, v_screen_w.f, v_screen_h.f)
    
    If  e_show_debug.b=#False
      ClearScreen(_REFRESH_COLOR) ;(black) delete origin screen       ;we use fullscreen only now
    Else
      ClearScreen(_RGB_DEBUG)  ;red
    EndIf
    
    If _frame_buffer_id<>0
      ZoomSprite(_frame_buffer_id,v_win_max_width.f, e_game_screen_height.f)
      DisplaySprite(_frame_buffer_id,0,e_screen_v_center.f)   
      
      If e_show_debug=#True 
       E_TEXT_OUTPUT_("",#ENGINE_TEXT_IS_TRANSPARENT) ;debugging output, standard text 
     EndIf
     
      FlipBuffers()
      FreeSprite(_frame_buffer_id)
      EndIf
    
    Else
      
      If _frame_buffer_id.l<>0
      FreeSprite(_frame_buffer_id.l)  
      EndIf

  EndIf
  
EndProcedure
;*****************************************************************************************************************************************

und hier mit "repeat ...forever" damit gibt es keine Bildschirmausgabe, my_display_port.i wird nicht verwendet.die debugausgabe wird nicht verwendet.

Code: Alles auswählen

;****************************************************************************************************************************
Procedure E_T_DRAW_FINAL_RENDER(my_display_port.i)  ;my_display_port.i wert wird von der Zeichenroutine übergeben.
 
  Define _frame_buffer_id.l=0
  
Repeat

    _frame_buffer_id=GrabSprite(#PB_Any,0,0, v_screen_w.f, v_screen_h.f)
    
    If  e_show_debug.b=#False
      ClearScreen(_REFRESH_COLOR) ;(black) delete origin screen       ;we use fullscreen only now
    Else
      ClearScreen(_RGB_DEBUG)  ;red
    EndIf
    
    If isSprite(_frame_buffer_id)

      ZoomSprite(_frame_buffer_id,v_win_max_width.f, e_game_screen_height.f)
      DisplaySprite(_frame_buffer_id,0,e_screen_v_center.f)   
      
     ; If e_show_debug=#True 
      ; E_TEXT_OUTPUT_("",#ENGINE_TEXT_IS_TRANSPARENT) ;debugging output, standard text 
     ;EndIf
     
      FlipBuffers()
      FreeSprite(_frame_buffer_id)
      EndIf

ForEver

EndProcedure
__________________________________________________
Code-Tags hinzugefügt
05.08.2019
RSBasic
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: CreateThread

Beitrag von STARGÅTE »

Also vorab erst mal:
In der Hilfe steht eindeutig:
Hinweis: Benutzen Sie innerhalb von Threads kein DirectX (MS Windows Einschränkung)! Wenn Sie auf Grafikdarstellung in Threads angewiesen sind, verwenden Sie stattdessen Images und 2DDrawing.
Somit würde ich vom Auslagern der ganzen Grafik-Sachen abraten.

Der erste Code (ohne Schleife) funktioniert vermutlich nur, weil der Thread und das Main-Programm nacheinander laufen (also also garkeine parallere Abarbeitung gibt, weil du ja auf den Thread wartest).
Der zweite Code geht deswegen nicht, weil wie in der Hilfe geschrieben, DirectX nicht in Threads arbeitet.

Wenn, dann sollte also die Grafikausgabe in der Main laufen, und den anderen Kram könntest du auslagern.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
darius676
Beiträge: 501
Registriert: 08.03.2010 22:12
Computerausstattung: Intel i5 16GB RAM nVidia 1050, Win11
Atari Jaguar, Surface Pro 5,Surface Laptop i5 7200, XBOX ONE X, XBOX Series X
Wohnort: AT
Kontaktdaten:

Re: CreateThread

Beitrag von darius676 »

danke für die schnelle Antwort.
diesen Punkt muss ich in der Hilfe übersehen haben, danke nochmals.

LG.


an RSBasic: Danke für die Nachbearbeitung :allright:
Antworten