Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

OpenGL + ThreadCall Problem

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Bibliotheken
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
schildron



Anmeldungsdatum: 25.08.2008
Beiträge: 86

BeitragVerfasst am: 18.09.2012, 19:43    Titel: OpenGL + ThreadCall Problem Antworten mit Zitat

Hallo FreeBASIC Profis!

Ich will bei meinem aktuellen Computerspiel sowohl OpenGL als auchThreadCall einsetzen.
Leider tritt folgendes Problem auf:
Ich kann in einem mit ThreadCall gestartenem Sub keine Vertexe zeichnen; egal ob ich mutexe einsetze oder nicht. Werden die Subs ohne Threadcall aufgerufen, werden beide Dreiecke einwandfrei angezeigt.

Hier der Code mit Mutexen:
Code:

'-------------------------
'DIMs
'-------------------------
Dim Shared As String Tastendruck

'-------------------------
'Includes
'-------------------------
#Include "fbgfx.bi"
#Include "GL/gl.bi"
#Include "GL/glu.bi"

'-------------------------
'Declarationen
'-------------------------
Declare Sub Objekt1(tlock1 As Any Ptr)
Declare Sub Objekt2(tlock1 As Any Ptr)

'-------------------------
'Textausgabe in Konsole
'-------------------------
Dim Shared DateiNr As Integer
DateiNr = FreeFile
Open Cons For Output As #DateiNr

'-------------------------
' das Fenster öffnen
'-------------------------
Screen 19, 16, , 2

'-------------------------
' Open-GL Init
'-------------------------
glViewport 0, 0, 800, 600                      ' den Current Viewport auf eine Ausgangsposition setzen
glMatrixMode GL_PROJECTION                     ' Den Matrix-Modus Projection wählen
glLoadIdentity                                 ' Diesen Modus auf Anfangswerte setzen
gluPerspective 45.0, 800.0/600.0, 0.1, 100.0   ' Grundeinstellungen des Anezeigefensters festlegen
glMatrixMode GL_MODELVIEW                      ' Auf den Matrix-Modus Modelview schalten
glLoadIdentity                                 ' und auch diesen auf Anfangswerte setzen
glClearColor 0.5, 0.5, 0.50, 0.0               ' Setze Farbe für löschen auf Mittelgrau
glClearDepth 1.0                               ' Depth-Buffer Löschen erlauben
glEnable GL_DEPTH_TEST                         ' den Tiefentest GL_DEPTH_TEST einschalten
glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT  'Tiefen- und Farbpufferbits löschen
'---------------------------
'HAUPTTEIL
'---------------------------
Dim tlock1 As Any Ptr = MutexCreate()

Do Until Tastendruck = Chr(27) :'die Schleife solange immer wiederholen, bis in der Variablen Tastendruck die Esc-Taste (chr(27) steht
   '---------------------------
   'ProgrammSchleife
   '---------------------------

   glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT


   Tastendruck = InKey   'Jeder Tastendruck wird sofort in die Variable Tastendruck gespeichert



   Dim Vertex1 As Any Ptr = ThreadCall Objekt1(tlock1)
   Dim Vertex2 As Any Ptr = ThreadCall Objekt2(tlock1)

   'Dim tlock1 As Any Ptr
   'Objekt1(tlock1)               '<<<<<<<<<<<<<<<<hier die neue Programmzeile rein
   'Objekt2(tlock1)

   ThreadWait Vertex1
   ThreadWait Vertex2


   Flip                  'liebes OpenGL, zeig alles, was in der Schleife für dich vornedran steht, auf Monitor an
   '---------------------------
   'Ende der Schleife
   '---------------------------
Loop

MutexDestroy tlock1

Close #DateiNr

End

'-------------------------
Sub Objekt1 (tlock1 As Any Ptr)
   'hier kommen die Programmzeilen zum Anzeigen
   'von dem Dreieck rein
   Print #DateiNr, "O1 aufgerufen!"
   MutexLock tlock1
   glBegin gl_TRIANGLES
   glColor3f 1.0,1.0,0.0       :' Zeichenfarbe auf gelb
   glVertex3f  0.5, 1.0, -6.0  :' der erste Punkt
   glVertex3f -0.5, 1.0, -6.0  :' der erste Punkt
   glVertex3f  0.0, 2.0, -6.0  :' der erste Punkt
   glEnd
   MutexUnlock tlock1
End Sub

Sub Objekt2 (tlock1 As Any Ptr)
   'hier kommen die Programmzeilen zum Anzeigen
   'von dem Dreieck rein
   MutexLock tlock1
   glBegin gl_TRIANGLES
   glColor3f 1.0,1.0,0.0       :' Zeichenfarbe auf gelb
   glVertex3f  0.5, -1.0, -6.0  :' der erste Punkt
   glVertex3f -0.5, -1.0, -6.0  :' der erste Punkt
   glVertex3f  0.0, 0.0, -6.0  :' der erste Punkt
   glEnd
   MutexUnLock tlock1
End Sub


Ich hoffe es ist nur ein kleiner Fehler, ich arbeite erst seit kurzer Zeit mit Threads und wahrscheinlich übersehe ich irgendetwas.

Ich hoffe hier kann mir jemand helfen in Threads Dreiecke zu zeichnen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 18.09.2012, 19:48    Titel: Antworten mit Zitat

10 Sekunden googeln:
http://www.opengl.org/wiki/OpenGL_and_multithreading
-> Du benötigst höchstwahrscheinlich http://wiki.delphigl.com/index.php/wglMakeCurrent um dem Thread überhaupt zu sagen, wo er denn hinzeichnen soll.

BTW: Threadwechsel sind teuer und langsam. Das Zeichnen von Objekten auf mehrere Threads auszulagern (vor allem mit Mutexen, die noch mal langsamer sind!) ist keine gute Idee. Separiere lieber Programmlogik und Zeichenaufrufe in zwei verschiedene Threads.
Das Zeichnen eines Objektes dauert wesentlich als der Verwaltungsoverhead aller Threadfunktionen hier, d.h. dein Programm wird mit Threads langsamer, nicht schneller. Erst ab einer gewissen Funktionsgröße macht es überhaupt Sinn, diese in einen eigenen Thread zu packen. Ein dutzend OpenGL-Aufrufe liegen sicherlich unter dieser Größe.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 19.09.2012, 11:32    Titel: Antworten mit Zitat

Drawcalls werden immer aus einem und v.a. dem gleichen Thread gemacht. Immer. API-unabhängig.

/e: Also um das vielleicht etwas besser auszudrücken: Drawcalls werden immer aus dem gleichen Thread gemacht, allerdings kann es durchaus Sinn ergeben einen anderen Thread oder mehrere Threads* zum Upload von Texturen und Meshes zu nutzen. Allerdings wird man dann meistens eher context-sharing o.ä. nutzen, weil man eher nicht möchte, dass der Treiber seine command list(s) sperrt, nur weil man gerade im Hintergrund Texturen nachlädt zwinkern

* nur wenn man schon vorher konzeptionelle Fehler gemacht hat. Warum? Wenn das Laden von Texturen/Meshes, also den Daten, die in rauen Mengen vorliegen, CPU-bound ist, hat man bereits einiges falsch gemacht. Und wenn sie, wie sie sein sollten, IO-bound sind, dann bringen mehrere Threads auch nichts mehr.
Ein tolles Negativbeispiel ist Oblivion (Skyrim?) bei dem das Laden von Leveldaten fast vollständig CPU-bound ist, aber nicht parallelisiert wurde. Tja grinsen

/e2: (Nur weil ich gerade langeweile habe) Wenn du jetzt deinen eigenen Rendering-Thread hast, in dem du alle Drawcalls abhandelst, und einen seperaten Upload-Thread und noch weitere Threads für Ton und game logic, stellt sich natürlich die Frage, wie du das synchronisiert kriegst ohne allzu häufig langsame multi-threading primitiven wie locks zu verwenden.
Nach meinem Kenntnisstand ist das übliche Verfahren, die Threads so wenig wie möglich zu koppeln (ist ja eh logisch) und möglichst einbahnige producer->consumer-beziehungen herzustellen. wenn man dann noch für die kommunikation zwischen den threads asynchrone mittel nimmt und für das bereitstellen von daten datenstrukturen, die atomar aktualisiert werden können, hast du das problem praktisch schon gelöst.
wenn du nämlich alles schon bei der konzeption sauber in nur definiert interagierende teile filettiert hast, lösen sich die meisten probleme hier von selbst. ein nachteil der losen synchronisation ist natürlich, dass es bei verzögerungen in einem thread zu inkonsistenten ausgaben kommen kann, also z.b. hängenden ton und flüssiges bild oder ein kurz stehendes bild, weil ein texturenmanager scheiße gebaut hat und eine textur nicht früh genug precached hat und erst auf die HDD warten muss, während der ton einfach weiterläuft. aber sowas sind keine beinbrüche.

as i said: saubere trennung, definierte schnittstellen und "unverletzliche" datenstrukturen


simple "unverletzliche" datenstruktur? nun, wie wäre es mit einem producer-consumer-"pipe"/array?
zwei felder in der nativen wortbreite:
offset
length
daten
daten
daten

der producer schreibt jetzt im laufe des produzierens seine daten dahinter, die daten sollten dabei ne fixe länge haben, also meistens pointer. das juckt den consumer nicht. keine synchro hier erforderlich
jetzt is der producer fertig und will dem consumer die daten zur verfügung stellen
er schreibt also atomar den neuen length wert, den der consumer sieht und weiterarbeitne kann, mit den neuen daten.
wenn der consumer mit einem element fertig ist schriebt er einfach an offset die position des fertigen elements, geht atomar, weil native wortbreite (je nach arch, aber spätestens mit amd64 geht das).
jetzt hast du nur noch das kleine problem, dass die liste wandert. durch den heap. nicht gut.
dafür gibts verschiedene lösungsansätze, kommst sicher selber drauf.... is ja kein sonderlich komplexes problem...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Bibliotheken Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz