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

Aktuelle Zeit: Fr Jul 18, 2025 07:58

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



Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: glDrawElements() zeichnet nichts
BeitragVerfasst: Do Jan 14, 2010 16:56 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Servus,

ich hab grad probleme ein lächerliches quad auf den bildschirm zu bringen.
Das rendern per indices funktioniert nicht und resultiert weder in einem fehler noch mit einem sichtbaren ergebnis.

Habe folgende Vertex Struktur die ich verwende:

Code:
  1.  
  2. type
  3.   TVector2f = record
  4.     X, Y : Single;
  5.   end;
  6.  
  7.   TVector3f = record
  8.     X, Y, Z : Single;
  9.   end;
  10.  
  11. type
  12.   TVertex = record
  13.     Pos  : TVector3f;               // 12
  14.     Nor  : TVector3f;               // 24
  15.     Tan  : TVector3f;               // 36
  16.     BNor : TVector3f;               // 48
  17.     Tex0 : TVector2f;               // 56
  18.     Pad  : array [0..1] of Single;  // 64 bytes
  19.   end;
  20.  


Ich versuch grad ein Quad zu erzeugen aus 2 Dreicken, dazu generiere ich mir 2 Dynamische Arrays in meinem Vertex Format oben, wobei ich nur Position und Texcoord verwende.

Code:
  1.  
  2. var
  3.   Vertices : array of Vertices;
  4.   Indices: array of Longword;
  5.  
  6. procedure CreateSimpleQuad;
  7. const
  8.   FDimX = 1;
  9.   FDimY = 1;
  10.   FDimZ = 1;
  11. const
  12.   Edges: array [0..11] of Single = (
  13.     -1, -1,  0, // Top left
  14.      1, -1,  0, // Top right
  15.     -1,  1,  0, // Bottom left
  16.      1,  1,  0  // Bottom right
  17.   );
  18.   Coords: array [0..7] of Single = (
  19.      0,  0,
  20.      1,  0,
  21.      0,  1,
  22.      1,  1
  23.   );
  24. begin
  25.   VerticeCount := 4;
  26.   SetLength(Vertices, VerticeCount);
  27.   Vertices[0] := Vertex(Vector3f(Edges[0]*FDimX,Edges[1]*FDimY,Edges[2]), Vector2f(Coords[0],Coords[1]));
  28.   Vertices[1] := Vertex(Vector3f(Edges[3]*FDimX,Edges[4]*FDimY,Edges[5]), Vector2f(Coords[2],Coords[3]));
  29.   Vertices[2] := Vertex(Vector3f(Edges[6]*FDimX,Edges[7]*FDimY,Edges[8]), Vector2f(Coords[4],Coords[5]));
  30.   Vertices[3] := Vertex(Vector3f(Edges[9]*FDimX,Edges[10]*FDimY,Edges[11]), Vector2f(Coords[6],Coords[7]));
  31.  
  32.   IndexCount := 6;
  33.   SetLength(Indices, IndexCount);
  34.   Indices[0] := 1;
  35.   Indices[1] := 0;
  36.   Indices[2] := 2;
  37.   Indices[3] := 2;
  38.   Indices[4] := 3;
  39.   Indices[5] := 1;
  40.  
  41.   ...
  42. end;
  43.  


Das füllt mir nur diese 2 arrays oben und dann ist das thema eigentlich durch.

Versuche ich nun das ganze mit glDrawElements() zu rendern, bekomm ich kein Ergebnis.
Es passiert auch kein Fehler, einfach es wird nix gerendert :-(

Code:
  1.  
  2.   glEnableClientState(GL_VERTEX_ARRAY);
  3.   glVertexPointer(3, GL_FLOAT, SizeOf(TVertex), @Vertices[0].Pos.X);
  4.   glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, @Indices[0]); // Ich render 6 indices, bzw. 2 Dreiecke
  5.   glDisableClientState(GL_VERTEX_ARRAY);
  6.  


Die Daten stimmen, weil folgende Funktion geht einwandfrei und liefert das quad.

Code:
  1.  
  2.   glBegin(GL_TRIANGLES);
  3.     For I := 0 to Length(Indices)-1 do
  4.     begin
  5.       //glTexcoord2fv(@Vertices[Indices[I]].Tex0);
  6.       glVertex3fv(@Vertices[Indices[I]].Pos);
  7.     end;
  8.   glEnd;
  9.  


Ich peils irgendwie grad nicht, warum geht die Draw Elements methode nicht.
Es sind doch 6 Indices, also 6 Punkte = 2 Dreiecke.

Wo liegt denn der fehler ? Es muss ja an den indices liegen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Do Jan 14, 2010 19:37 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
A few questions:
-what opengl context do you use? 2.x or 3.x
-how do you load the vertex buffer after setting your arrays and before rendering?
-do you bind the indices buffer, you also need to do that again before rendering
-i dont trust your indices however you say the work using old skool opengl
-also i do not trust your vertexpointer, can you try nil/0 as you want to start at the first element.
-personaly is use arrays of glfloat instead of a record structure.
Hope this is of some help...

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 00:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich kann mich auch irren, aber - ich finde bei Dir kein einziges glBindBuffer ...

Also so etwas:

Code:
  1. glBindBuffer(GL_ARRAY_BUFFER, AShape3D);
  2. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, AIndex);

lgTraude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 12:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@Traude: Er nutzt VertexArrays, das ist ok so. Mir ist ein Rätsel warum das nicht funktioniert...

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 13:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
An sich ist der Code in Ordnung. Hast du es mal mit einem packed record für dein TVertex probiert?

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 16:09 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Sascha Willems hat geschrieben:
An sich ist der Code in Ordnung. Hast du es mal mit einem packed record für dein TVertex probiert?


Jop hab ich und kein unterschied, das rekord hat auch weiterhin 64 bytes.
Weil ich ja 8 Bytes padding anhänge (Pad)
Siehe opengl.org wiki http://www.opengl.org/wiki/Vertex_Buffer_Objects

noeska hat geschrieben:
A few questions:
-what opengl context do you use? 2.x or 3.x
-how do you load the vertex buffer after setting your arrays and before rendering?
-do you bind the indices buffer, you also need to do that again before rendering
-i dont trust your indices however you say the work using old skool opengl
-also i do not trust your vertexpointer, can you try nil/0 as you want to start at the first element.
-personaly is use arrays of glfloat instead of a record structure.
Hope this is of some help...


I use normal old opengl 2.x.
There are no vertex buffer or binding in my case, because i use old style vertex array without buffer.


Mein problem ist aktuell das das gleiche Konstrukt auch mit VBO nicht geht.
Wenn ich also meine Daten in ein VBO und IBO hochlade und mit nil Pointer rendere,
dann hab ich das gleiche ergebnis.

Sprich wenn die Vertex Array geschichte nicht geht, dann geht auch die VBO sache nicht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 16:38 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Evtl. setz ich mich voll in die Nessel (kann mich grad kaum konzentrieren), aber es kann an den Datentypen liegen. Du gibts an GL_UNSIGNED_INT, und wenn ich recht entsinne ist unsigned int doch 16 bit, während du für die Indices aber Longword = 32 Bit benutzt. Oder hab ich da was verpeilt?

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 16:47 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Sascha Willems hat geschrieben:
Evtl. setz ich mich voll in die Nessel (kann mich grad kaum konzentrieren), aber es kann an den Datentypen liegen. Du gibts an GL_UNSIGNED_INT, und wenn ich recht entsinne ist unsigned int doch 16 bit, während du für die Indices aber Longword = 32 Bit benutzt. Oder hab ich da was verpeilt?


Unsigned Int = 32bit.. :)
Unsigned Short = 16bit

*nesseln rüberreich* :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 17:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
@Aya : I stand corrected...

Aber echt komisch. Ich hab grad mal meinen alten Scenemanager (Bumpmapping, PP-Lighting usw.) geöffnet und da nutz ich glDrawElements für die Schattenvolumen. Das sieht fast genauso aus wie bei dir, klappt aber problemlos. Einziger Unterschied dass ich nicht den Pointer auf die X-Koordinate vom Vertex setze. Das dürfte aber ja eigentlich nix ausmachen, aber probier mal nur @Vertices[0] ohne Pos.X.

P.S. : So siehts bei mir aus :
Code:
  1. glVertexPointer(4, GL_FLOAT, SizeOf(TglVertex4f), @FVA[0]);
  2. glDrawElements(GL_TRIANGLES, Length(FIA), GL_UNSIGNED_INT, @FIA[0]);

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 17:18 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Auf die gefahr hin das ich mich mit in die Nesseln setz... :)

Ist dein stride richtig?... müßte das nicht sizeof(TVertex) - 12 sein?

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 17:28 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Nein, sein Stride ist korrekt. Der gibt nich an wie viel Platz zwischen den Vertices ist, sondern wo das nächste beginnt. Da ist also SizeOf(Struktur) richtig,

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 17:31 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Zitat:
Specifies the byte offset between consecutive vertices. If stride is 0, the vertices are understood to be tightly packed in the array. The initial value is 0.


Wenn das stimmt wie du es sagst, würde ein stride von 0 aber keinen sinn machen... und rein theoretisch versteh ich den text in der doku so, dass stride den abstand zwischen aufeinanderfolgenden vertices angibt.

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 19:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
Stride is the third not fourth parameter. Stride has to be the size of the records used. So opengl knows where the next vertex coords can be found
The fourth parameter is the position of the first element unless you want to skip some it can be set to 0 or nil. You can skip texture and normal coords with that.
Personaly i would use ptr(0) or in case of my normals:
Code:
  1. glNormalPointer( GL_FLOAT, sizeof(TVertex), ptr(2*sizeof(GLFLOAT)+0) );
to skip 2 vertex coord floats.
but then i use an array of floats. (is an record structure always equal internaly to an array of glfloat?)
But in your case there is no need to skip anything to 0 or ptr(0) should be fine. But now that i think of it refering to the .x should also give a ptr to the first element in the array meaning 0 or ptr(0). Or is there something like a record header that needs to be skipped?

http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Fr Jan 15, 2010 20:26 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Ok ich habs hinbekommen.

Es lag wohl definitiv am Index Array.
Longword passt einfach nicht, das ganze auf Word geändert geht.

Code:
  1.  
  2.     glEnableClientState(GL_VERTEX_ARRAY);
  3.     glEnableClientState(GL_COLOR_ARRAY);
  4.  
  5.     glVertexPointer(3, GL_FLOAT, SizeOf(TVertex), @Vertexes[0].V);
  6.     glColorPointer(4, GL_FLOAT, SizeOf(TVertex), @Vertexes[0].C);
  7.  
  8.     glDrawElements(GL_TRIANGLES, NumIndices, GL_UNSIGNED_SHORT, @Indices[0]);
  9.  
  10.     glDisableClientState(GL_COLOR_ARRAY);
  11.     glDisableClientState(GL_VERTEX_ARRAY);
  12.  


Das lief, und sogar mit farben ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glDrawElements() zeichnet nichts
BeitragVerfasst: Sa Jan 16, 2010 13:09 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
K ich hab noch ne weitere frage:

Ich hab nun auch VBO ans laufen gebracht und aber feststellen müssen,
sobald meine VBO daten hochgeladen wurden, dann kann ich keine normalen Vertex Array´s mehr nutzen für die Daten welches die basis für VBO waren.

So lade ich meine Daten in den VRAM:

Code:
  1.  
  2.     glBindBuffer(GL_ARRAY_BUFFER, FID[0]);
  3.     glBufferData(GL_ARRAY_BUFFER, AMesh.VerticeSize, nil, GL_DYNAMIC_DRAW);
  4.     glBufferSubData(GL_ARRAY_BUFFER, 0, AMesh.VerticeSize, @AMesh.Vertices[0]);
  5.  
  6.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, FID[1]);
  7.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, AMesh.IndexSize, nil, GL_DYNAMIC_DRAW);
  8.     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, AMesh.IndexSize, @AMesh.Indices[0]);
  9.  
  10.     glBindBuffer(GL_ARRAY_BUFFER, 0);
  11.  


Das lädt meine Vertex Daten und meine Index Daten in den VRAM mit einer VBO und einer IBO id.
Das passiert direkt nachdem initialisieren von OpenGL, da wo ich auch meine Texturen lade und so.

Wenn ich aber nun, per vertex array meine Mesh Daten Ohne VBO rendern will... AMesh.Vertices und AMesh.Indices.
welche in einer Klasse gespeichert sind, wieso knallt es dann mit einer Zugriffsverletzung in Lazarus?

Würde gerne verstehen wieso es da knallt, sobald ich versuche mit AMesh.Vertices über Vertex Array zu rendern.

Weil das VBO dürfte nachdem upload ja eigentlich gar kein zugriff mehr haben auf meine Rohdaten,
weil ja alles im VRAM ist. (Raff ich grad nicht)

Da muss ja noch irgendein bezug da sein.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 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.010s | 15 Queries | GZIP : On ]