Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

1

02.07.2009, 20:27

glDrawArrays,glDrawElements

Hi,
Ich habe grade einige Probleme beim umstellen meines Programms vom uralten glBegin/End rendern auf Vertexarrays (VBOs wären in meinem Fall erstmal nicht schneller denke ich). hier mal meinen Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
glEnableClientState(GL_VERTEX_ARRAY);

glVertexPointer(4, GL_DOUBLE, sizeof(Vertex), &(vertexArray[0].pos[0]));
glNormalPointer(GL_DOUBLE, sizeof(Vertex), &(vertexArray[0].normal[0]));
//glIndexPointer(GL_UNSIGNED_INT, 0, &(faceArray[0].i1));

glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertexArray[0].textureX);

//glDrawArrays(GL_TRIANGLES, 0, vertexArray.size());

glDrawElements( GL_TRIANGLES, faceArray.size()*3, GL_UNSIGNED_INT, &(faceArray[0].i1));

glDisableClientState(GL_VERTEX_ARRAY);

Ich verstehe nicht so ganz den unterschied zwischen drawArrays und drawElements, außer, dass man Elements, direkt die indizes übergibt...
Zum aufbau meines proramms: Face ist einfach ein struct mit 3 ints für die vertices, Vertex hat zwei Vec4 pos und normal und 2 floats textureX/Y, Vec4 wiederum ein double[4] array...
so wie es jetzt oben steht rendert er die objekte soweit vollständig, allerdings komplett einfarbig... d.h. weder normalen noch texturkoordinaten scheinen richtig zu sein. Wenn ich das ganze mit DrawArrays versuche, kommt ziemlicher blödsinn bei raus.

C-/C++-Quelltext

1
glDrawArrays(GL_TRIANGLES, 0, vertexArray.size());

render ein paar faces, allerdings nicht richtig verknüpft, d.h. es kommen auch faces bei raus, die es eigentlich garnicht gibt. (man beachte vertexArray.size(), obwohl ja eigentlich die anzahl der indizes angegeben werden soll)

C-/C++-Quelltext

1
glDrawArrays(GL_TRIANGLES, 0, faceArray.size()*3);

das hier mit der anzahl der indizes rendert kompletten schwachsinn, sogar zu vertices die es garnicht gibt...
Danke schonmal fürs lesen und hoffe ihr könnt mir helfen ^^

Moe

Frischling

Beiträge: 85

Wohnort: München

  • Private Nachricht senden

2

02.07.2009, 23:01

Brauchst Du wirklich double Werte? Auf float sollte die Grafikkarte schneller laufen...

Die Normalen und Texturen können gar nicht gehen. Du hast zwar die Arrays angelegt, aber Du hast es nicht angeschaltet. Du musst auf jeden Fall noch

C-/C++-Quelltext

1
2
glEnableClientState(GL_NORMAL_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

ausführen, um diese beiden Typen zu aktivieren. Im Detail kenne ich mich nicht mit Vertexarrays aus, ich habe immer direkt VBOs verwendet, weil die genauso einfach zu implementieren sind.
Der Hauptunterschied zwischen DrawArray und DrawElements ist, dass du bei DrawArray zusammenhängende Vertices malst, bei DrawElements übergibst du eine Liste, die die Indizes der verschiedenen Elemente enthält. Also im ersten Fall kannst du nur etwas wie "male Element 1 2 3 4 5 6 7" machen, im Zweiten geht aber auch "1 6 5 2 1 1 5".

Zu deinen Renderproblemen: Hast du die Dreiecke richtig definiert?

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

3

03.07.2009, 07:44

Naja, ich weiß nicht ob ich wirklich doubles brauche... sind eben genauer, aber würde man bei "normalen" sachen da überhaupt einen unterschied merken?
Und ich hab wirklich das enablen vergessen -.-' *kopf gegen die wand hau*
Das mit den normalen stimmt jetzt, die texturkoordinaten irgendwie noch nicht, liegt wohl daran, dass der compiler die beiden einzelnen floats nicht hintereinander gelegt hat ^^ naja muss ich da auch ein array draus machen. Danke soweit schonmal für die Hilfe :D

Edit: der einzige Vorteil bei VBOs liegt doch darin, dass man die ganzen daten nicht jedesmal neu an die Grafikkarte übergeben muss, oder? aber ich rendere eh nur wenn sich was ändert und dann müsste ich bei den VBOs ja auch neu übertragen... oder versteh ich das falsch?

4

03.07.2009, 08:52

Zitat von »"n0_0ne"«


Edit: der einzige Vorteil bei VBOs liegt doch darin, dass man die ganzen daten nicht jedesmal neu an die Grafikkarte übergeben muss, oder? aber ich rendere eh nur wenn sich was ändert und dann müsste ich bei den VBOs ja auch neu übertragen... oder versteh ich das falsch?

Joah, so ungefähr. Wenn du einen dynamischen VertexBuffer mit fester Größe hast, dann kann die Grafikkarte vielleicht beim hochladen das schneller managen da sie ja nicht erst einen freien Platz suchen muss. Aber das eigentliche aufwändige, nämlich das übertragen der VertexDaten an die Grafikkarten bleibt natürlich.
Lieber dumm fragen, als dumm bleiben!

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

5

04.07.2009, 10:28

hatte nen blöden denkfehler und ich denke VBOs würden in meinem fall doch einen extremen performance gewinn bringen...
Also implementiere ich sie jetzt doch, habe aber ein problem: ich habe die meisten daten: positionsvektor, normale, texture coords alle in einer Vertex-klasse. d.h. die einzelnen positionscoords liegen nicht direkt hintereinander im speicher. bei vertex arrays kann ich ja angeben, dass er z.B. immer um sizeof(Vertex) zwischen den einzelnen daten springen soll... wenn ich das richtig sehe geht das bei den VBOs nicht. versteh ich was falsch, oder muss ich jetzt wirklich neue arrays für die daten anlegen?

Edit: hier http://www.opengl.org/wiki/GL_ARB_vertex_buffer_object hab ich gefunden wie es geht... zwar nicht wirklich verstanden, wie das ganze jetzt funktioniert, aber egal ^^

Nur zur info, falls das problem mal jemand anderes hat:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));

n0_0ne

1x Contest-Sieger

  • »n0_0ne« ist der Autor dieses Themas
  • Private Nachricht senden

6

04.07.2009, 17:35

Und ein weiteres Problem... auf http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45 hat nehe eindeutig
glGenBuffersARB( 1, &m_nVBOVertices );
verwendet, wobei m_nVBOVertices eine membervariable ist... wenn ich das gleiche versuche bringt er mir jedesmal einen Segmentation fault (rufe genau das gleiche 1 mal im konstruktor auf, und mache sonst testweise erstmal nichts mehr damit) ... wenn ich die variable beim rendern neu deklariere und zuweisen lasse, funktioniert es. woran kann das liegen?

Moe

Frischling

Beiträge: 85

Wohnort: München

  • Private Nachricht senden

7

07.07.2009, 23:06

Hast du zu dem Zeitpunkt schon alles initialisiert (z.B. Glew, wenn du es verwendest) und bist im richtigem Kontext?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

08.07.2009, 09:18

Zitat von »"n0_0ne"«

hatte nen blöden denkfehler und ich denke VBOs würden in meinem fall doch einen extremen performance gewinn bringen...
Also implementiere ich sie jetzt doch, habe aber ein problem: ich habe die meisten daten: positionsvektor, normale, texture coords alle in einer Vertex-klasse. d.h. die einzelnen positionscoords liegen nicht direkt hintereinander im speicher. bei vertex arrays kann ich ja angeben, dass er z.B. immer um sizeof(Vertex) zwischen den einzelnen daten springen soll... wenn ich das richtig sehe geht das bei den VBOs nicht. versteh ich was falsch, oder muss ich jetzt wirklich neue arrays für die daten anlegen?


Vertex Arrays und Vertexbuffer Objects sind von der Handhabung austauschbar.

Werbeanzeige