Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 06:35

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Apr 18, 2008 18:31 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Hallo Leute! Ich hab im Moment ein Problem, das ich nur sehr schlecht beschreiben kann, ich versuche es mal trotzdem. Ich gehe gerade den Code mit Einzelschrittabarbeitung durch, um einen Fehler zu finden. Der Code, der läuft, läuft in einem eigenen Thread (Multithreading) und kümmert sich darum, dass eine Displayliste kompiliert wird. Dann wird glVertexPointer() aufgerufen und auf einmal funktioniert die Einzelschrittabarbeitung nicht mehr. Der Zeilencursor geht nach dem Aufruf von glVertexPointer() ohne ersichtlichen Grund ans Ende der Prozedur.

Habt ihr vielleicht irgend eine Ahnung? Braucht ihr mehr Daten?
Ich benutzte übrigens Delphi 5 Prof.


Viele Grüße!

Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 18, 2008 18:43 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Ich hab mir gedacht, mit Code ist es vielleicht etwas verständlicher ;) Hier ein großer Teil meiner DisplayList-Klasse:
Code:
  1.  
  2. constructor TDisplayList.Create(Triangles : PVertexTriangles);
  3. begin
  4.   inherited Create;
  5.   ListReference := glGenLists(1);
  6.  
  7.   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  8.   glEnableClientState(GL_VERTEX_ARRAY);
  9.  
  10. end;
  11.  
  12.  
  13. procedure TDisplayList.AddGroup(MaterialID : Integer; Vertices : TVertices);
  14.   var i : Cardinal;
  15. begin
  16.   Inc(GroupCount);
  17.   SetLength(Groups, GroupCount);
  18.   Groups[GroupCount-1].Material := MaterialID;
  19.   Groups[GroupCount-1].ArrOffset := Length(Self.Vertices);
  20.   Groups[GroupCount-1].Size := Length(Vertices);
  21.   Inc(VertexCount, Length(Vertices));
  22.   SetLength(Self.Vertices, Groups[GroupCount-1].ArrOffset + Groups[GroupCount-1].Size);
  23.  
  24.   for i := 0 to Groups[GroupCount-1].Size-1 do
  25.   begin
  26.     Self.Vertices[i+Groups[GroupCount-1].ArrOffset] := Vertices[i];
  27.   end;
  28. end;
  29.  
  30. procedure TDisplayList.CompileGroups;
  31.   var i : Integer;
  32.       tmpTexCoords : Array of Single;
  33. begin
  34.   VertexCount := 0;
  35.  
  36.   SetLength(tmpTexCoords,Length(Vertices)*2);
  37.  
  38.   for i := 0 to Length(Vertices)-1 do
  39.   begin
  40.     tmpTexCoords[2*i] := Vertices[i].s * 10;
  41.     tmpTexCoords[2*i+1] := Vertices[i].t * 10;
  42.   end;
  43.   glVertexPointer(3,GL_FLOAT,Sizeof(TVertex),@Vertices[0].x);
  44.  
  45.   // Detailmap
  46.   glClientActiveTexture(GL_TEXTURE1);
  47.   glTexCoordPointer(2,GL_FLOAT,SizeOf(Single)*2,@tmpTexCoords[0]);
  48.  
  49.   // Haupttextur
  50.   glClientActiveTexture(GL_TEXTURE0);
  51.   glTexCoordPointer(2,GL_FLOAT,SizeOf(TVertex),@Vertices[0].s);
  52.  
  53.  
  54.   glNewList(ListReference,GL_COMPILE);
  55.   // Alle vorher geaddeten Groups rendern
  56.   for i := 0 to GroupCount-1 do
  57.   begin
  58.     VertexCount := VertexCount + Groups[i].Size;
  59.     MaterialManager.ApplyMaterial(Groups[i].Material); // Texturen binden
  60.       glDrawArrays(GL_Triangles,Groups[i].ArrOffset,Groups[i].Size);
  61.     MaterialManager.ClearMaterial(Groups[i].Material); // Texturen unbinden
  62.   end;
  63.   glEndList();
  64.  
  65.   GroupCount := 0;
  66.   SetLength(Groups,0);
  67.   SetLength(Vertices,0);
  68. end;
  69.  
  70. destructor TDisplayList.Destroy;
  71. begin
  72.   inherited Destroy;
  73. end;
  74.  
  75. procedure TDisplayList.ClearList;
  76. begin
  77.   GroupCount := 0;
  78.   SetLength(Groups,0);
  79.   SetLength(Vertices,0);
  80.   VertexCount := 0;
  81.   glDeleteLists(ListReference,1);
  82. end;
  83.  


Die Prozedur AddGroup und auch CompileGroup werden vom zweiten Thread aufgerufen. Während der zweite Thread die Listen kompiliert, rendert der VCL-Thread andere Listen - sie dürften sich also eigentlich nicht in die Quere kommen. Die einzigen Bereiche, in denen sie sich überschneiden sind Bereiche, in denen beide nur lesen.


Viele Grüße,

Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 18, 2008 19:21 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ahm, die OpenGL-Kontexte sind Threadgebunden. Das heißt, du kannst vom zweiten Thread nicht ohne weiteres auf den OpenGL-Kontext deines Hauptthreads zugreifen. Geht nicht.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 19, 2008 13:49 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Oh mann... das wäre sehr ärgerlich ;) Ich möchte doch nur Displaylisten kompilieren. Kann ich die nicht irgendwie
"mitnehmen"? Oder muss ich wohl oder übel die Struktur fürs Multithreading ändern?


Viele Grüße,

Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 19, 2008 16:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Soweit ich weiss, musst du die Displaylisten im Hauptthread kompilieren. Eine Alternative wäre ein Workaround mit ShareLists, oder wie der Befehl heißt, aber das ist glaube ich keine so gute idee. Du brauchst dafür nen zweiten Kontext und dementsprechend auch einen in diesem Thread erzeugten DeviceContext (HDC). Und ich bin mir jetzt nicht sicher, ob sich dieser ShareLists-Befehl überhaupt auf Displaylisten auswirkt.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Apr 20, 2008 03:10 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Es ist möglich displaylisten genauso wie texturen zwischen versachiedenen kontexten zu sharen. Jedoch ist auch das nicht unproblematisch. (z.B. Plattformabhängigkeit)
Deutlich besser wäre es auf Vertex Buffer Objects zu setzten, hier kann man in einem zweiten Thread die daten vorbereiten und mit wenigen befehlen auf die Grafikkarte hochladen.

_________________
Lumina plattform unabhängige GLSL IDE


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 22, 2008 07:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich hätte eigentlich erwartet, dass man für VBO's in verschiedenen Renderkontexten auch wglShareLists braucht.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 22, 2008 08:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Doch Doch. Das braucht man auch. oc2k1 meinte ja nur das Vorbereiten der Daten. Also eigentlich nichts weiter als einen Buffer im RAM der innerhalb eines Threads gefüllt wird. Dieser kann dann im Renderloop recht einfach mit glBufferData oder glBufferSubData in einem Stück übergeben werden. Dann würde der Thread genau genommen gar kein OpenGL machen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 23, 2008 08:39 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
afaik geht es auch wenn man den buffer im hauptthread mapped, dann den pointer an den nebenthread übegibt und ihn dort füllt, und anschließend wieder im Huptthread unmapped. Ist nur hässlich zu programmieren.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 23, 2008 09:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Technisch gesehen sollte das auch funktionieren. Aber der Buffer ist dann für diesen Zeitraum gelockt. Und wenn man das VBO zwischenzeitlich zum Rendern benutzen will, dann wird man einen OpenGL Fehler bekommen. Da bleibt dann nichts Anderes übrig als selber so lange zu warten sonst gibts kaputte Frames. Der Vorteil von Threads wäre dann ziemlich gering. Bei der anderen Methode wäre es nicht so schlimm, wenn das Generieren auch mal nen Momemt länger dauern würde. Das VBO bleibt ja weiterhin vollkommen funktionstüchtig.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 16 Queries | GZIP : On ]