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

Aktuelle Zeit: Sa Jul 19, 2025 16:26

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



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Normalen im VBO
BeitragVerfasst: Sa Sep 29, 2007 01:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 22, 2007 16:30
Beiträge: 17
Tach allerseits.

Ich versuche eben eine Heightmap mit Normalen aufzurüsten.
Leider wird die Geometrie jedoch nicht mehr gezeichnet, wenn ich die Normalen aktiviere.

Die Vorgehensweise habe ich aus einem NeHe tutorial gelernt.
Dort wurde der zweite Buffer jedoch nicht mit Normalen, sondern mit Texturen gefüllt.
Texturen brauche ich aber keine - Beluchtungs-Effekte aber schon!

Ich habe mir also zwei Vertex-Arrays gebastelt welche die gleiche länge haben.

Nachdem diese gefüllt sind binde ich diese folgendermassen:

Code:
  1.     // delete old buffer
  2.     glDeleteBuffersARB( 1, &modelData.vboVertices );
  3.     glDeleteBuffersARB( 1, &modelData.vboNormals );
  4.  
  5.     // generate and add the vertex buffer
  6.     glGenBuffersARB( 1, &modelData.vboVertices );
  7.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboVertices );
  8.  
  9.     // generate and add the normal buffer
  10.     glGenBuffersARB( 1, &modelData.vboNormals );
  11.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboNormals );
  12.  
  13.     // load data
  14.     glBufferDataARB( GL_ARRAY_BUFFER_ARB, modelData.vertexCount * 3 * sizeof(float),
  15.                                    modelData.vertices, GL_STATIC_DRAW_ARB );
  16.     glBufferDataARB( GL_ARRAY_BUFFER_ARB, modelData.vertexCount * 3 * sizeof(float),
  17.                                    modelData.normals, GL_STATIC_DRAW_ARB );
  18.  


Im render code rufe ich dann so auf:

Code:
  1.  
  2.     // vertex buffer
  3.     glEnableClientState( GL_VERTEX_ARRAY );
  4.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboVertices );
  5.     glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
  6.  
  7.     // normal buffer
  8.     glEnableClientState( GL_NORMAL_ARRAY );
  9.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboNormals );
  10.     glNormalPointer( GL_FLOAT, 0, (char *) NULL );
  11.  
  12.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  13.     glDrawArrays( GL_TRIANGLES, 0, modelData.vertexCount );
  14.  
  15.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  16.     glColor3f(0,0,0);
  17.     glDrawArrays( GL_TRIANGLES, 0, modelData.vertexCount );
  18.     glColor3f(1,1,1);  
  19.  
  20.     glDisableClientState( GL_VERTEX_ARRAY );
  21.     glDisableClientState( GL_NORMAL_ARRAY );
  22.  


Zunächst soll eine Heightmap MIT NORMALEN gezeichnet werden und anschliessend noch ein Wireframe drüberglegt werden.
Solange ich die Normalen weder binde noch rendere funkzt alles tiptop.

Bitte helft mir die Normalen noch hinzubekommen dann bin ich wunschlos glücklich :lol:


Zuletzt geändert von Astazan am Sa Sep 29, 2007 13:22, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 02:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 22, 2007 16:30
Beiträge: 17
ach ja und wer genaueres über das tutorial möchte:
http://nehe.gamedev.net/
bzw. Lektion 45
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45
freue mich auf antworten :wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 09:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Habe das Thema mal verschoben.

Also spontan würde ich behaupten, dass du glEnableClientState erst nach dem entsprechenden gl*Pointer aufrufen solltest. Bzw eigentlich genügt es, wenn du alle States direkt vor dem Zeichnen aktivierst.

PS: Laut einem Dokument von NVidia sollte glVertexPointer der letzte gl*Pointer Befehl sein den du aufrufst, da dieser diverse Dinge initialisieret die bei anschließenden gl*Pointer noch mal initialisert werden müssten. Wenn ich das richtig in Erinnerung habe. Aber sollte wohl eher kaum einen markanten Unterschied mit sich bringen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 10:07 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Beim Füllen bindest zu die beiden Buffer hintereinander und rufst dann 2x glBufferData auf. glBufferData wirkt sich nur auf den aktuell gebundenen Buffer aus. Daher wäre richtiger:

glBindBuffer(,Vertex)
glBufferData(,Vertex)

glBindBuffer(,Normalen)
glBufferData(,Normalen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 10:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 22, 2007 16:30
Beiträge: 17
Habe eure Vorschläge bereits umgesetzt und....

... es tut :shock:

Jupeida und jupeidi!

Ihr seid spitzte! VIELEN DANK!

__________________________________________________________
(________)_\__|___|__/____/__\____|____\__|__|_\__\__/__/_
___|__|_____|__\_/__|____/____\___|__|\_\_|__|__\__\/__/__
___|__|_____|_______|___/__()__\__|__|_\_\|__|___>____<___
___|__|_____|__/_\__|__|________|_|__|__\____|__/__/\__\__
___|__|____/__|___|__\_|__(__)__|_|__|___\___|_/__/__\__\_


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 11:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Warum trennst du die Koordinaten und Normalen? Das kannst du in ein VBO schieben und entsprechend über den Offset adressieren.

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 13:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 22, 2007 16:30
Beiträge: 17
Wie mienst du das?

Habe mir mal die Variante von Nico mit glInterleavedArrays angesehen.
Den Ansatz finde ich bisher den schönsten.
Dort wusste ich dann aber nicht wie ich die Methode aktiviere.

Jaja, das wird wohl die Geschichte mit dem Header sein um den ich mich immer herumgemogelt habe.

Prinzipiell müsste es aber doch so ähnlich gehen wie die anderen ARB Funktionen:
Code:
  1.  
  2. // VBO Extension Definitions, From glext.h
  3. #define GL_ARRAY_BUFFER_ARB 0x8892
  4. #define GL_STATIC_DRAW_ARB 0x88E4
  5. typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC)    (GLenum target, GLuint buffer);
  6. typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
  7. typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC)    (GLsizei n, GLuint *buffers);
  8. typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC)    (GLenum target, int size,
  9.                                                      const GLvoid *data, GLenum usage);
  10.  
  11. // VBO Extension Function Pointers
  12. PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;      // VBO Name Generation Procedure
  13. PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;      // VBO Bind Procedure
  14. PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;      // VBO Data Loading Procedure
  15. PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;// VBO Deletion Procedure

-> auch aus dem NeHe Tutorial. :oops:

Wahrscheinlich meist du das aber anders:
etwa so?
Code:
  1.  
  2. // generate and add the normal buffer and load it
  3.     glGenBuffersARB( 2, &modelData.vboNormals );
  4.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboNormals );
  5.     glBufferDataARB( GL_ARRAY_BUFFER_ARB, modelData.vertexCount * 3 * sizeof(float),
  6.                                    modelData.normals, GL_STATIC_DRAW_ARB );
  7.     glBindBufferARB( GL_ARRAY_BUFFER_ARB, modelData.vboVertices );
  8.     glBufferDataARB( GL_ARRAY_BUFFER_ARB, modelData.vertexCount * 3 * sizeof(float),
  9.                                    modelData.vertices, GL_STATIC_DRAW_ARB );
  10.  

(poste das mal einfach ohne probiert zu haben :roll: )

ps: toller footer 8) sehe ich au so!
dieses forum ist trotzdem das beste für OpenGL :P


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Sep 29, 2007 18:33 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Nein ich meinte wirklich nur EIN VBO

Code:
  1. //einfache Vertex-Struktur
  2. struct Vertex
  3. {
  4.    float x,y,z;      //Position
  5.    float nx,ny,nz;  //Normalenvektor
  6. };
  7.  
  8.  
  9. ...
  10.  
  11.  
  12. //Buffer generieren und Daten reinschieben
  13. GLuint id;
  14. glGenBuffers(1,&id);
  15. glBindBuffer(GL_ARRAY_BUFFER,id);
  16.  
  17. //pData ist ein Zeiger auf ein Feld vom Typ Vertex
  18. //countVertices ist die Anzahl der Vertices im Feld auf das pData zeigt
  19. glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex) * countVertices,pData,GL_STATIC_DRAW_ARB);
  20.  
  21.  
  22. ...
  23.  
  24. //Buffer nutzen
  25. glBindBuffer(GL_ARRAY_BUFFER,id);
  26.  
  27. //3. Parameter  ist sizeof(Vertex), also die Byte-Größe, welche zwischen 2 Koordinatenangaben liegt
  28. //letzter Parameter: erste Positionsangabe ist an Stelle 0, also erste Zahl im Feld
  29. glVertexPointer(3,GL_FLOAT,sizeof(Vertex),0);                    
  30.  
  31. //erste Normalenvektorangabe an Stelle 3 (0,1,2 = x,y,z, Stelle 3 ist erste Normalen-Angabe, unser nx
  32. glNormalPointer(GL_FLOAT,sizeof(Vertex),3 * sizeof(float));
  33.  
  34. glEnableClientState(GL_VERTEX_ARRAY );
  35. glEnableClientState(GL_NORMAL_ARRAY );
  36.  


Du siehst Position und Normalenvektor sind in einen Feld und durch den Offset bei den Pointer-Funktionen teilt man OpenGL mit, wie die Informationen im Feld aufgebaut sind. Durch den Offset weis das System nun, dass die Positionen nicht hintereinander im Feld liegen, sonder "irgendwas" dazwischen. Das geht mit allen Daten, welche über so eine Pointer-Funktione gesetzt werden können (Farbe, Texturkoordinaten, Attribute für glSlang)

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 01, 2007 14:41 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 22, 2007 16:30
Beiträge: 17
Kann man dadurch auch den Speicher minimieren?

Mein Problem ist bei zu hohen Auflösungen, dass der RAM voll wird :evil:

Ich versuche also folgendermassen den Speicher anzulegen, aber wenn vertexCout zu gross ist - krach
Code:
  1.  
  2.     modelData.vertices = new XYZ[ modelData.vertexCount ];
  3.     modelData.normals = new XYZ[ modelData.vertexCount ];
  4.     modelData.colors = new XYZ[ modelData.vertexCount ];


Wenn ichs recht sehe kann ich mit deiner Methode einfach die Anzahl Pointer reduzieren.
Bringts das schon?

Was ich auch nicht ganz verstehe, ist wo die Daten am Schluss (nach dem Binden) liegen?
Ein Memoryleak habe ich nicht, aber wenn die Datei geladen ist steht der RAM immer an höherer stelle als zuvor.
Eigentlich habe ich mir vorgestellt, dass die Daten nun wirklich nur noch auf der Grafikkarte liegen und mein RAM wieder frei ist.

Gruss


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Okt 01, 2007 17:12 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Zitat:
Kann man dadurch auch den Speicher minimieren?


Nein, es werden dadurch ja nicht weniger Daten, sie werden nur anders gelagert in deinem Programm. Bei der Ein-VBO-Variante brauchst du einen größeren zusammenhängenden Speicherblock, dafür sparst dir halt einmal den Buffer-Wechsel. Du kannst auch weiterhin mit deinen 2 VBOs arbeiten, wenn das so funzt.

Zitat:
Was ich auch nicht ganz verstehe, ist wo die Daten am Schluss (nach dem Binden) liegen?


Mit glBindData schaltest du erstmal nur einen Buffer aktiv, mehr nicht! Das Reservieren von Speicher passiert dann mit glBufferData. Sobald du dein VBO gefüllt hast, kannst/solltest du die externen Puffer wieder freigeben.

Code:
  1. modelData.vertices = new XYZ[ modelData.vertexCount ];

Nach dem Füllen also nicht das delete[] vergessen. Effektiv hast du nach dem Betanken des VBOs also nur noch die ID, mit welcher du arbeitest (wenn ich jetzt mal von nem statischen einmal betanktem VBO ausgehe)

Also sozusagen

1. Puffer im eigenen Programm anlegen und mit Daten füllen (new Vertex[ganz_viele])
2. VBO-ID generieren und binden
3. Mit glBufferData die Daten vom eigenen Programm in den VRAM kopieren lassen, so füllst du das VBO
4. eigene Puffer wieder freigeben (delete[] pPuffer), die Daten im VRAM verbleiben

_________________
__________
"C++ is the best language for garbage collection principally because it creates less garbage." Bjarne Stroustrup


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 24, 2007 23:18 
Offline
DGL Member

Registriert: Di Okt 23, 2007 10:20
Beiträge: 84
unwichtig


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


Wer ist online?

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