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

Aktuelle Zeit: Fr Jul 18, 2025 12:26

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



Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: OpenGL + VBO
BeitragVerfasst: Do Jun 12, 2008 10:19 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Wenn ich den Code so auführe dann erhalte ich ein rot umramtes Dreieck bei dem die 3 Ecken in Blau dargestellt werden(siehe Anhang) :
Code:
  1. //FormCreate
  2. Vrt := TGLVertexBufferObject.Create; // Vrt und Ind sind bei mir von TStorage abgeleitete Klassen
  3. Ind := TGLVertexBufferObject.Create; // TStorage gibt den Ort an dem die Daten gespeichert werden und ermöglicht den Zugriff
  4. Ind.BufferType := GL_ELEMENT_ARRAY_BUFFER;
  5.  
  6. Vrt.Size := Vrt.Size + 3 * SizeOf(Single);
  7. Sgl :=   0; Vrt.Write(Sgl, SizeOf(Single));
  8. Sgl :=   0; Vrt.Write(Sgl, SizeOf(Single));
  9. Sgl := -10; Vrt.Write(Sgl, SizeOf(Single));
  10. Vrt.Size := Vrt.Size + 3 * SizeOf(Single);
  11. Sgl :=   1; Vrt.Write(Sgl, SizeOf(Single));
  12. Sgl :=   0; Vrt.Write(Sgl, SizeOf(Single));
  13. Sgl := -10; Vrt.Write(Sgl, SizeOf(Single));
  14. Vrt.Size := Vrt.Size + 3 * SizeOf(Single);
  15. Sgl :=   1; Vrt.Write(Sgl, SizeOf(Single));
  16. Sgl :=   1; Vrt.Write(Sgl, SizeOf(Single));
  17. Sgl := -10; Vrt.Write(Sgl, SizeOf(Single));
  18. {Vrt.Size := Vrt.Size + 3 * SizeOf(Single);
  19. Sgl :=   0; Vrt.Write(Sgl, SizeOf(Single));
  20. Sgl :=   1; Vrt.Write(Sgl, SizeOf(Single));
  21. Sgl := -10; Vrt.Write(Sgl, SizeOf(Single));}
  22.  
  23. IndList := TIntegerList.Create(Ind); // TIntegerList benutz den Speicher(TStorage) und eben Integerwerte zu speichern auszulesen usw. ...
  24. IndList.Add(0); IndList.Add(1); IndList.Add(2);
  25. IndList.Add(0); IndList.Add(2); IndList.Add(3);
  26.  
  27. // OnIdle
  28.  
  29. Context.Clear;
  30. Viewport.Update;
  31.  
  32. glEnableClientState(GL_VERTEX_ARRAY);
  33. Vrt.Bind;
  34. glVertexPointer(3, GL_FLOAT, 0, Vrt.PData);
  35. Ind.Bind;
  36.  
  37. glColor3f(0,1,0); glDrawRangeElements(GL_TRIANGLES , 0, 0, {6}3, GL_UNSIGNED_INT, Ind.PData);
  38. glColor3f(1,0,0); glDrawRangeElements(GL_LINE_STRIP, 0, 0, {6}3, GL_UNSIGNED_INT, Ind.PData);
  39. glColor3f(0,0,1); glDrawRangeElements(GL_POINTS    , 0, 0, {6}3, GL_UNSIGNED_INT, Ind.PData);
  40.  
  41. Vrt.Release;
  42. glDisableClientState(GL_VERTEX_ARRAY);
  43. Ind.Release;
  44.  
  45. SwapBuffers(DeviceContext);


wenn ich nun die auskommentierte Stellen wieder ausführen lasse erhalte ich nur einen blauen Punkt(siehe Anhang)

Danke im voraus an alle die sich die Mühe machen sich meine Problems anzunehmen...

MFG FrenK


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 12, 2008 10:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Nicht falsch verstehen aber wenn ich ehrlich bin halte ich das Eintragen der Daten für ziemlich unglücklich gelöst. Bzw ich vermute mal, dass du überhaupt das Dreieck siehst ist aktuell nur Glück.

Also bei TGLVertexBufferObject.SetSize machst du
Code:
  1.   FSize := AValue;
  2.   Generate;

In TGLVertexBufferObject.Generate machst du dann
Code:
  1.   Bind;
  2.   MYglBufferData(FBufferType, FSize, nil, FDrawType);


Das Binden ist ja vollkommen okay. Dass du eine neue Größe angibst ist auch okay. Aber dort kann es meines Wissens nach passieren, dass der Treiber den Speicher verschiebt. Damit wäre alles was du bereits in den Speicher geschrieben hast futsch! Vergleichbar mit einem FreeMem und anschließendem GetMem. Wenn du Glück hast bekommst du den gleichen Pointer. Wenn du pech hast bekommst du einen vollkommen neuen Speicherbereich.

Auch ist es äußerst unpraktisch, wenn du den Buffer im Mode GL_WRITE_ONLY mappst. Denn beim Unmappen wird der gemappte Speicherbereich komplett in das VBO geschrieben. Also müsstest du normal beim Setzen eines einzelnen Singles den kompletten Speicher wieder in den gemappten schreiben oder aber du nimmst ReadWrite als Modus. ABER dann muss das komplette VBO 2 Mal übertragen werden. Und das nur um ein einzigen Single zu setzen.


Meine Idee wäre folgende. Du erstellst eine Klasse bei der du Single oder Records hinzufügen kannst. Die Größe solltest du dann auch intern behandeln. Und wenn du fertig bist, dann sagst du "Erstellen" und die Klasse erzeugt ein VBO und lädt mit glBufferData dann auf einen Schlag den kompletten Speicherbereich hoch. Damit würdest du den Speicher nur ein einziges Mal zur Grafikkarte übetragen müssen. Falls du später mal mehr als 4 Vertices hättest (1 Mio) wären das aktuell wirklich gigantische Datenmengen die da hin und hergeschaufelt werden müssten. Was im Endeffekt dann alles nur richtig ausbremsen würde.

PS: Um die volle Hardwarebeschleunigung nutzen zu können MUSS der IndexBuffer aber auch auf die Karte hochgeladen werden und dort auch aktiviert und benutzt werden. Aktuell übergibst du ihn ja noch als Pointer an die Methode. Das dürfte das alles auch wieder ausbremsen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 12, 2008 12:47 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Der Index Buffer wird nicht als pointer übergeben da PData bei den VBOs nil ist solange sie nicht gemappt sind PData ist nur dort angegeben um auch mit einem normalen TMemorystorage zeichnen zu können... (hab ich benutz um zu testen ob ich in meiner TList Klasse oder in der VBO Kalsse der Fehler ist)

Das Problem dabei ist das das ganze dynamisch bleiben soll...

das komische daran ist ich erhalte jedesmal wenn ich das programm ausführe nur das Dreieck(natürlich auskommentiert)

kann ich irgendwie nur einen Teil des Buffers mappen ?? denn ich weis ja von welchem offset auf wie viele Bytes zugegriffen wird


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 12, 2008 13:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also ich würde sagen, dass es zufall ist, dass du immer nur das Dreieck siehst. Da kommst es vermutlich darauf an wie die internen Strukturen im Treiber sind.

Gemappt werden kann immer nur der gesammte Buffer. Du kannst aber mittels glBufferSubData auch einen Teilbereich des Buffer aktualisieren. Aber auch da würde ich dir nicht empfehlen jeden einzelnen Single darüber zu transportieren. Es ist zwar harmloser als den gesammten Buffer zu übertragen. Aber für "lächerliche" 4 Byte einen solchen Funktionsaufruf zu machen halte ich für übertrieben.

Außerdem besteht weiterhin noch das Problem, dass beim "Erweitern" des Buffers dieser gelöscht/verschoben werden kann. Und du somit alle bisherigen Daten des Buffers verliehst. Dann musst dafür sorgen, dass alles was du schon mal geschrieben hast noch ein weiteres mal geschrieben wird. Entweder musst du dir dann den Inhalt des Buffers vor der Größenänderung von der Grafikkarte holen oder du musst es dir lokal merken. Wenn es abzusehen ist, dass so etwas häufig passiert (bei jedem vergrößern (Vertex hinzufügen) möglich) kannst du dir und der Grafikkarte den Aufwand ersparen und die Daten gleich dauerhaft lokal halten. Zu mindest bis das Erstellen vollendet ist.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 11:05 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
In der alten Pascal Version von Karmarama hab ich auch ein VBO Klasse verwendet.
https://svn.linuxprofessionals.org/filedetails.php?repname=karmarama&path=%2Fprerelease%2Fcode%2FKar_GL.pas
In meiner C++ version hab ich alles in ein Template verpackt.
Vieleicht kannst du damit was anfangen.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 12:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Wie schon gesagt das Ganze soll dynamisch bleiben heist also es soll auch die Möglichkeit geben die Daten permanent zu ändern... lässt sich sowas mit einem VBO vereinbaren?? Oder müsste ich wenn ich das genze so regeln :

Daten Lokal übergeben
Wenn nicht dynamisch -> Daten an VBO übergeben
Wenn dynamisch
1)Daten lokal ändern(also ohne VBO)
2)Daten lokal ändern und bei jedem drawcall überprüfen ob sich die Daten geändert haben und dementschprechen an VBO übergeben
3)???


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 12:29 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Wenn ich das Wiki Tutorial richtig verstanden habe, kannst du dir jedes Vertex mit [edit] glMapBufferARB [/edit] in den Hauptspeicher mappen und den Pointer gezielt bewegen um nur bestimmte Vertices zu verändern.

Würde ohnehin keinen Sinn machen, dass soetwas nicht geht, wenn VBO die Zukunft sein soll...

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Zuletzt geändert von damadmax am Fr Jun 13, 2008 14:57, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 14:09 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
damadmax: du meinst glMapBuffer anstelle von glBufferData, oder? Denn glBufferData dient zum festlegen der VBO Größe. Ähnlich wie glTexImage2D das für Texturen ist.

Aber um das von Oben noch mal deutlicher zu sagen. Du kannst ein VBO in den Speicher mappen. Aber nur komplett. Du kannst nicht sagen ich möchte nur die ersten 3 Vertices mappen. Beim Mappen wird meines Wissens nach eine Kopie des VBOs im RAM abgelegt. Der GRAM wird nicht einfach nur in den Addressbereich eingeblendet. So zu mindest meine Meinung und meine Auffassung davon.

Beim Mappen gibt es 3verschiedene Methoden.
GL_READ_ONLY: Kopiert den Speicher vom GRAM in den RAM. Aber beim Unmappen nicht wieder zurück auf die Grafikkarte.
GL_WRITE_ONLY: Kopiert den Speicher vom GRAM nicht in den RAM. Aber beim Unmappen wird dieser komplett zurückgeschrieben.
GL_READ_WRITE: Kopiert den Speicher vom GRAM in den RAM und beim unmappen auch wieder zurück.

Wenn du nur eine einzelne kleine Stelle (4Bytes) ändern willst und dein VBO 32MB groß ist. Mit READ_WRITE wäre das möglich. ABER für 4 Bytes müssen mal eben 64MB übertragen werden. Das steht in keinen Verhältniss mehr! Mit READ würden deine Änderungen ignoriert werden und mit WRITE würde alles andere gelöscht bzw unbrauchbar gemacht werden bzw nur mit viel Glück bleiben ein paar sinnvolle Daten erhalten.

Dynamisch ist möglich. Dafür sind VBOs ja auch gemacht. Nur du solltest nicht (können könntest du schon) für jeden Wert den Buffer mappen und wieder unmappen. Wenn du weißt, dass 1000 Werte geschrieben werden, dann solltest du den Buffer nur ein einziges mal mappen und am Ende wieder unmappen.

Wenn dein VBO entsprechend groß ist und der Speicher den du veränderst an einem Stück vorliegt, dann kannst du das auch lokal zwischenspeichern und dann das gecachte mit glBufferSubData in den Speicher des VBOs kopieren. Denn dann wird nur das kleine Stück übertragen und sofern du es richtig positioniert hast auch genau in das VBO gepackt.

Wenn du nicht weißt wie viele Vertices du im Endeffekt bekommst, dann solltest dafür sorgen, dass du es weißt (cachen oder sonst was) oder aber du dimensionierst das VBO von hause aus etwas größer. Aber du solltest das VBO nicht immer um ein Vertex "vergrößern". Wobei "vergrößern" ja eh nicht geht. Der wird zerstört und neu erstellt.

PS: Falls dir das bei deiner Frage nicht wirklich geholfen hat, dann sei doch bitte so lieb und schilder und mal dein genaues Einsatzgebiet. Also was du genau vor hast.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 14:56 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Oops! Das hat man davon wenn mans eilig hat...dann verrutscht man schonmal in der Zeile :D
Ich korrigier das mal da oben, nicht dass das für Verwirrung sorgt.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 19:56 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Eigentlich sollte im system kein Grund geben, wieso man ein VBO updaten soll.
Das ändern kostet ja auch Zeit und es gibt ne menge Techniken um updates zu vermeiden.
LOD kann man einfach durch mehere Index VBO's lösen, verschiebungen von Vertice(animationen) kann man über vertexshader realisieren und bei zerstörbarer geometrie verändert sich die verticecount und man braucht ein komplett neues vbo.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 13, 2008 20:57 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Doch ich denke solch einen Grund gibt es. Spätestens, wenn OpenGL 3.0 da ist. Dann fungieren VBOs eher als eine Art Durchlauferhitzer. Bei meinen Fonts werde ich bei jedem Frame die VBOs updaten müssen. Wenn ich die denn irgendwann mal einbaue.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jun 14, 2008 12:54 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Hat mal jemand ein Beispiel wie man Animationen über den Vertexshader macht? Ohne unzählige Uniforms/Attribs zu benutzen?

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jun 14, 2008 16:45 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Du müsstest das schon präzisieren, denn es gibt einige möglichkeiten.
Bones,Keyframes und procedurale animationen fallen mir da so ein.
Keyframes kann man z.B. über 3D Texturen machen(wird wohl keiner machen), Bones hat oc2k1 z.B. in seinem Lumina Projekt drin und glaube auch ein Tut auf seiner projektseite.
Procedural sind dann so sachen wie, je höher y koordinate des so stärker wird eine funktion auf den vektor multipliziert.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
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.009s | 15 Queries | GZIP : On ]