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

Aktuelle Zeit: Fr Jul 18, 2025 11:19

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: VBO Indizierter Zugriff auf Vertizes
BeitragVerfasst: Di Jun 16, 2009 10:42 
Offline
DGL Member

Registriert: Do Jun 04, 2009 07:28
Beiträge: 7
Hallo,
ich möchte Vertex Buffer Objects verwenden um Würfel zu zeichnen.
Um die Anzahl der Koordinaten für einen Würfel zu reduzieren greife ich indiziert auf die Koordinaten zu.
Anstatt in einem Vertex-Array also 24 Vertizes anzugeben, verwende ich nur 8 und greife dann über ein Index-Array darauf zu.

Nun habe ich auch noch ein Array für die Normalen und für die Farbwerte der Vertizes.
Das Problem ist folgendes:
Code:
  1.  
  2.         glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
  3.         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, vboIdIndices);
  4.  
  5.         glEnableClientState(GL_NORMAL_ARRAY);
  6.         glEnableClientState(GL_COLOR_ARRAY);
  7.         glEnableClientState(GL_VERTEX_ARRAY);
  8.  
  9.         glNormalPointer(GL_FLOAT, 0, (void*)sizeof(vertices));
  10.         glColorPointer(3, GL_FLOAT, 0, (void*)(sizeof(vertices)+sizeof(normals)));
  11.         glVertexPointer(3, GL_FLOAT, 0, 0);
  12.  
  13.         glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, NULL);
  14.  


Das Index-Array wird so nicht nur für die Indizierung der Vertices verwendet, sondern auch für die Normalen und Farbwerte.
Allerdings möchte ich ja die z.B. die Normalen den Vertices völlig anders zuweisen, als es das Index-Array vorgibt.

Hat jemand eine Idee, wie ich das Index-Array nur auf das Vertex-Array und nicht auf die Normalen und Farbwerte beziehen kann?

MfG Knaggy.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 11:28 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Hat jemand eine Idee, wie ich das Index-Array nur auf das Vertex-Array und nicht auf die Normalen und Farbwerte beziehen kann?

Also ich denke es macht keinen Unterschied ob du 8 oder 24 Vertices benutzt. Die Vertex-Postion die du maximal einsparen könntest ist 12 Byte groß. Du sparst 16 Vertices, kannst also insgesamt 192 Byte einsparen. Eine Grafikkarte hat eine Speicherbandbreite von irgendwie so etwa 50 GB pro Sekunde. Außerdem hast du dann alles in einem Buffer, was natürlich auch schneller ist als wenn die Grafikkarte erst alles aus verschiedenen Buffern zusammensuchen müsste. Lohnt also nicht wirklich.

Bei hochauflösenden Meshes mit einigen Millionen Vertices sieht die Sache natürlich ganz anderes aus. Dort könnte es möglicherweise Sinn machen an dieser Stelle zu optimieren. Hier könnte man vielleicht irgendwas im Vertexshader mit Texturen machen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 12:32 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
Und wie macht man das jetzt? Mich würde das auch mal interessieren, da ich in verschiedenen englisch-sprachigen papers die Beispiele nicht ganz verstanden habe. Ob etwas Sinn macht oder nicht sei erstmal dahin gestellt, immerhin können die wenigsten von uns abschätzen welchem Zweck das Code-Konstrukt anschließend dienen soll. Also wenn du das erklären könntest fände ich das echt klasse. Für meinen Teil versuche ich nähmlich md3 Modelle platzsparend zu zeichnen. dafür wollte ich gleiche Modelle in ein vbo zusammenstecken, die Texturkoordinaten aber aus einem anderen Buffer indizieren, weil es ja blödsinn wäre die für jedes Modell erneut zu speichern. Zu beachten ist, dass alle Modelle in einem anderen Animationsstatus sind, deshalb kann ich die Geometriedaten schlecht verkleiner/verkürzen. Die TexCoords bleiben aber immer gleich.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 12:57 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Soweit ich weiß ist es leider nicht möglich verschiedene Index-Arrays zu verwenden... hat mich auch schon oft gestört (denn sobald man dann TexturKoordinaten, Normalen, Tangenten etc hat bringt ein Index-Array kaum noch etwas..)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 13:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@Sellmann:
Normalerweise macht man sowas hier um einen VBO mit Indices zu rendern. Dabei sagt man mit GL_T2F_N3F_V3F was und in welcher Reihenfolge sich alles im VBO befindet.
Code:
  1. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
  2. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  3. glInterleavedArrays(GL_T2F_N3F_V3F, 0, 0);
  4.  
  5. glDrawElements(GL_TRIANGLES, m_faces*3, GL_UNSIGNED_INT, 0);


Will man die Sachen in einzelnen Buffern, geht das glaube ich so:
Code:
  1. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
  2. glBindBuffer(GL_ARRAY_BUFFER, m_vbo_vertices);
  3. glVertexPointer(3, GL_FLOAT, 0, 0);
  4. glBindBuffer(GL_ARRAY_BUFFER, m_vbo_normals);
  5. glNormalPointer(3, GL_FLOAT, 0, 0);
  6. glBindBuffer(GL_ARRAY_BUFFER, m_vbo_texcoords);
  7. glTexCoordPointer(2, GL_FLOAT, 0, 0);
  8.  
  9. glDrawElements(GL_TRIANGLES, m_faces*3, GL_UNSIGNED_INT, 0);


Dabei muss man aber beachten das alle Buffer gleich groß sind. Also Vertex mit der Nummer i im Buffer m_vbo_vertices, gehört immer zur Normale i im Buffer m_vbo_normals. Wenn man das völlig flexibel (wie Knaggy) will kann man statt VBOs Texturbuffer-Objects verwenden. Dann kann man die Zuordnung im Vertexshader selbst vornehmen. Würde ich aber als "fortgeschritten" bezeichnen und ich glaube auch nicht das man da soviel sparen kann, weil man ja noch irgendwie zusätzliche Indices pro Vertex etc. benötigt.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 13:31 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zusatz:
Mit Instancing könnte man das so lösen:
Man rendert eine einzelnes Dreieck per Instancing. Die Daten für dieses Dreieck sind egal, man nimmt also einfach nur 2D-Vertices ohne alles.
Mit einem TexturbufferObjekt vom Typ RGB32UI bauen wir uns einen eigenen Indexbuffer aus dem wir im Vertexshader an der Stelle 3*gl_InstanceID + gl_VertexID lesen. Im roten Farbkanal ist der Index für den Vertex, im grünen Kanal die Normale usw. Mit den erhaltenen Indices können wir dann aus weiteren Texturbufferobjekten (z.B. vom Typ RGB32F) lesen.
Solltest du dir aber gut überlegen ob sich das lohnt, weil Texturzugriffe die abhängig von anderen Texturzugriffen sind vergleichsweise langsam sind.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 16, 2009 14:06 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Bei einem Würfel ein paar vertices einzusparen bringt definitiv nichts. Vorallem nicht da sich alle vertices in den Normalen und Texturkoordinaten unterscheiden.

Der Indizierte zugriff bringt erst etwas wenn die Modelle größer und komplexer sind. Dann kann im besten fall ein Vertex ~6 mal wiederverwendet werden. aber auch nur wenn alle Attribute gleich sind.

_________________
Lumina plattform unabhängige GLSL IDE


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 20:55 
Offline
DGL Member

Registriert: Do Jun 04, 2009 07:28
Beiträge: 7
Hmm, nagut. Dann lasse ich das mit der Indizierung.
Es werden 20160 solcher Würfel gezeichnet, ich dachte, dass es sich dafür lohnen würde.
Gruß Knaggy


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 17, 2009 22:02 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Bei 20000 Würfeln kannst du sicher mehr rausholen, wenn du Aufrufe von glDraw*** einsparst. Sofern deine Szene statisch ist (bzw. die Relation der Würfel untereinander) könntest du alle Würfel in ein einziges großes VBO werfen.

Ansonsten bietet sich natürlich Instancing an. Der Aufruf sähe dann einfach so aus:
Code:
  1. glDrawElementsInstanced(GL_QUADS, 24, GL_UNSIGNED_BYTE, NULL, 20160);

In einem Texturbuffer-Objekt speicherst du die 20160 Matrizen der einzelnen Würfel. Im Vertexshader hast du mit gl_InstanceID die Nummer des aktuell gerenderten Würfels. Also einfach an Position gl_InstanceID in das Texturbuffer-Objekt mit den Matrizen gucken und diese als ModelViewMatrix verwenden.
Der einzige Nachteil von Instancing ist eigentlich, dass man relativ neue Grafikhardware benötigt und natürlich zwingend einen Vertexshader braucht.

_________________
Yeah! :mrgreen:


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


Wer ist online?

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