Ws ist n meinem VBO code falsch ?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Ws ist n meinem VBO code falsch ?

    Hallo,
    es ist das erste Mal, dass ich versuche im non-intermediate mode zu zeichnen.
    Als Objekt habe ich ein Icosahedron (red bible) gewählt, 20 Dreiecke.
    Ich bekomme keine Fehlermeldung, es erscheint aber nichts auf dem Schirm.

    Quellcode

    1. -(void)drawPointerForIndex:(unsigned)idx display:(unsigned)display
    2. {
    3. GLuint buffer = 0;
    4. switch (display)
    5. {
    6. case 0: // curvePointer
    7. buffer = vboBuffers[idx];
    8. break;
    9. case 1: // velocityPointer
    10. buffer = vboBuffers[idx + 1];
    11. break;
    12. case 2: // vectorPointer
    13. buffer = vboBuffers[idx + 2];
    14. break;
    15. }
    16. // icosahedron byte length = 20 * 3 * 6 * sizeof(float) = 1440
    17. glBindBuffer(GL_ARRAY_BUFFER, buffer); // buffer = 1
    18. glInterleavedArrays(GL_N3F_V3F, 0, [_pointerData bytes]);
    19. glBufferData(GL_ARRAY_BUFFER,[_pointerData length], [_pointerData bytes], GL_STATIC_DRAW);
    20. glPushMatrix();
    21. glColor3fv(pointerColor);
    22. // glTranslatef() kommt später dazu;
    23. glDrawArrays(GL_TRIANGLES, 0, _pointerVertexCount); // _pointerVertexCount = 60
    24. glPopMatrix();
    25. }
    Alles anzeigen


    Die Daten in _pointerData habe ich ausgelesen, die stimmen, z.B. erstes Dreieck:
    0.525731 0.000000 0.850651
    0.525731 0.000000 0.850651

    0.000000 0.850651 0.525731
    0.000000 0.850651 0.525731

    -0.525731 0.000000 0.850651
    -0.525731 0.000000 0.850651

    Beim Icosahedron sind Position und Normale identisch.

    Help me in my weakness (Dylan)

    Uwe
    How come I can't see me in my mirror ?
  • Ich verstehe den Code so gar nicht, das sieht ziemlich wirr aus. Für VBOs hast du zwei Teile: 1. Die Daten auf die GPU laden und 2. die Daten rendern. Um aus den VBOs den riesigen Vorteil zu ziehen passiert das Hochladen normalerweise nur einmal vorweg oder wenn sich Daten geändert haben, nicht notwendigerweise in jedem Renderdurchgang (Ziel des Ganzen ist es ja gerade, Anzahl und Menge der Transaktionen zwischen CPU und GPU zu minimieren).

    Um die Daten auf die GPU zu laden, musst du erst einen Buffer erzeugen (glGenVertexArrays), dann den Buffer aktivieren (glBindBuffer) und die Daten hochladen (glBufferData).

    Zum rendern hast du kein glInterleavedArrays mehr. Stattdessen aktivierst du den Buffer, in dem die zu verwendeten Daten liegen (glBindBuffer), aktivierst den Client State für alle gewünschten Eigenschaften (glEnableClientState - sagt quasi, dass dafür Daten verwendet werden sollen, die schon auf der GPU liegen), legst fest, wie die Daten im aktivierten Buffer organisiert sind (glNormalPointer, glVertexPointer usw) und malst dann (glDrawArrays).
    Multigrad - 360°-Produktfotografie für den Mac
  • Hier mal ein simples VBO Beispiel aus meinem Buch, das Beispiel ist zwar schon ein wenig älter funktioniert aber noch:

    Quellcode

    1. ​@implementation MyOpenGLView
    2. - (void) prepareOpenGL
    3. {
    4. glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    5. glEnable( GL_DEPTH_TEST );
    6. //glEnable(GL_CULL_FACE);
    7. float trigger = 1.0f / 30.0f;
    8. NSTimer *pTimer = [NSTimer timerWithTimeInterval:trigger target:self selector:@selector(idle:) userInfo:nil repeats:YES];
    9. [pTimer retain];
    10. [[NSRunLoop currentRunLoop]addTimer:pTimer forMode:NSDefaultRunLoopMode];
    11. _end = [NSDate timeIntervalSinceReferenceDate];
    12. _rotation = 0.0;
    13. // Vertex Puffer
    14. // Puffer erstellen
    15. glGenBuffers(1, &_vertexBuffer);
    16. // Puffer binden
    17. glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    18. // Puffer mit Daten fuellen
    19. glBufferData(GL_ARRAY_BUFFER, sizeof(_vertexData), _vertexData, GL_STATIC_DRAW);
    20. glBindBuffer(GL_ARRAY_BUFFER, 0);
    21. // Color Puffer
    22. // Puffer erstellen
    23. glGenBuffers(1, &_colorBuffer);
    24. // Puffer binden
    25. glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
    26. // Puffer mit Daten fuellen
    27. glBufferData(GL_ARRAY_BUFFER, sizeof(_colorData), _colorData, GL_STATIC_DRAW);
    28. glBindBuffer(GL_ARRAY_BUFFER, 0);
    29. }
    30. -(void)dealloc
    31. {
    32. // Puffer loeschen
    33. glDeleteBuffers(1, &_vertexBuffer);
    34. glDeleteBuffers(1, &_colorBuffer);
    35. [super dealloc];
    36. }
    37. - (void)idle:(NSTimer *)pTimer
    38. {
    39. if(![[NSApplication sharedApplication] isHidden])
    40. [self setNeedsDisplay:YES];
    41. }
    42. - (void)reshape
    43. {
    44. NSRect rect = [self bounds];
    45. glViewport( 0, 0, (GLsizei)rect.size.width, (GLsizei)rect.size.height);
    46. glMatrixMode( GL_PROJECTION );
    47. glLoadIdentity();
    48. gluPerspective( 45.0, rect.size.width / rect.size.height, 1.0, 50.0 );
    49. glMatrixMode( GL_MODELVIEW );
    50. }
    51. -(void) drawRect: (NSRect) bounds
    52. {
    53. //TimeDelta berechnen
    54. _start = [NSDate timeIntervalSinceReferenceDate];
    55. _deltaTime = _end-_start;
    56. _deltaTime =-_deltaTime;
    57. _end = _start;
    58. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    59. glLoadIdentity();
    60. gluLookAt(0.0, 0.0, 5.0,
    61. 0.0, 0.0, 0.0,
    62. 0.0, 1.0, 0.0);
    63. glRotatef(_rotation, 0.0, 1.0, 0.0);
    64. // VBO rendern
    65. glEnableClientState(GL_VERTEX_ARRAY);
    66. glEnableClientState(GL_COLOR_ARRAY);
    67. glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    68. glVertexPointer(3, GL_FLOAT, 0, 0);
    69. glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
    70. glColorPointer(3, GL_FLOAT, 0, 0);
    71. glDrawArrays(GL_TRIANGLES, 0, 3);
    72. glBindBuffer(GL_ARRAY_BUFFER, 0);
    73. glBindBuffer(GL_ARRAY_BUFFER, 0);
    74. glDisableClientState(GL_VERTEX_ARRAY);
    75. glDisableClientState(GL_COLOR_ARRAY);
    76. glFlush();
    77. _rotation+=20.0 * _deltaTime;
    78. if(_rotation > 360.0)
    79. _rotation = 0.0;
    80. }
    81. @end
    Alles anzeigen


    Hier das Model, dass ich in einer extra Datei definiert hab:

    Quellcode

    1. ​GLfloat _vertexData[] = { 0.f, 1.f, 0.f,
    2. -1.f, -1.f, 0.f,
    3. 1.f, -1.f, 0.f};
    4. GLfloat _colorData[] = { 0.f, 0.f, 1.f,
    5. 0.f, 1.f, 1.f,
    6. 1.f, 1.f, 1.f};
    Alles anzeigen


    Das ganze ist recht einfach gehalten, ich denke man sieht sehr gut daran, wie VBO's funktionieren.
  • Leider ist es mir nicht ganz gelungen, die Aufgabe zu lösen.
    Die Farbe stimmt nicht, es ist die, die ich für den Drahtwürfel gewählt habe, sollte aber rot sein.
    Ich habe die Reihenfolge von vertex, normal und color geändert, das Ergebnis war das gleiche.
    Auch specular reflection ändert sich, wenn ich die Grösse des Bildes ändere.
    Im Anhang befinden sich zwei Screenshots und die OpenGl files.
    Bin gespannt, welcher Fehler bei eurer Betrachtung da zu Tage tritt.

    Uwe
    Dateien
    • Wave#One.zip

      (32,95 kB, 232 mal heruntergeladen, zuletzt: )
    How come I can't see me in my mirror ?
  • Bist du sicher, dass das mit dem VBOs zu tun hat? Für mich sieht das Farbphänomen eher nach einem Fall für GL_COLOR_MATERIAL und das Specular-Ding nach GL_NORMALIZE aus (wenn du beim alten OpenGL bleiben willst). Ich habe den Code aber nur überflogen - ich finde ihn ziemlich schwierig verständlich und es ist anscheinend viel Zeug darin, das nicht zum eigentlichen Problem gehört. Kannst du den Kern in einem lauffähigen Projekt isolieren?
    Multigrad - 360°-Produktfotografie für den Mac

  • Kannst du den Kern in einem lauffähigen Projekt isolieren?

    Hallo mattik,
    ich kann deine Frage mit ja beantworten und hänge das Projekt an.
    Vorab muss ich dir sagen, dass die Farbe immer noch fehlt, ausserdem scheint das Licht nicht gleichmässig.
    Die material properties habe ich wieder eingefügt.

    Ich hoffe, du bringst das zu einem guten Schluss.
    Uwe
    Dateien
    • VBOTest1.zip

      (51,92 kB, 234 mal heruntergeladen, zuletzt: )
    How come I can't see me in my mirror ?
  • Doch, im Wesentlichen waren es GL_NORMALIZE und GL_COLOR_MATERIAL.

    Wenn man GL_COLOR_MATERIAL einschaltet und per glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE) angibt, dass die aktuelle Farbe auch auf die Diffuse- und Ambient-Materialeigenschaften abgebildet werden sollten, sollte die Kugel schon ziemlich rot werden. (Edit: Hattest du ja schon selbst gesehen).

    Die Sache mit den Normalen: Wenn du glScale() verwendest, bist du normalerweise schon im Eimer. Die Normalen werden mitskaliert und machen die ganze Beleuchtung kaputt. Ja, du willst GL_NORMALIZE haben - der repariert die so gut es geht (bei Scherungen kann der auch kaum noch etwas Sinnvolles machen, aber das kommt ja auch nicht so oft vor).

    Apropos Normalen: Die Beleuchtung funktioniert nur richtig, wenn in der GL_PROJECTION wirklich nur die Projektion steht - keine Verschiebung oder anderes, was einem viele Convenience-Methoden da reinkloppen. Zumindest nicht, wenn man das Beleuchtungsmodell auf "Local Viewer" stellt (was bei Specular Reflections sinnvoll ist, weil die sonst ziemlich falsch sein können).

    Was anderes: Depth Test bringt nur etwas, wenn man für den Kontext auch einen Depth Buffer anfordert :) (im Interface Builder).

    Die hässlich zerhäckselten Specular-Highlights sind beim alten OpenGL halt so, das ist Gouraud Shading. Im alten Modell hilft nur feiner zu unterteilen. Besser gleich auf eigene Shader wechseln, die dann Phong Shading machen können. Damit werden die Glanzlichter so rund wie sie sein sollen.

    Ich habe meine Veränderungen zum Diffen drangehängt. Nicht wundern, ich habe etwas Zeug rausgenommen, auf entzerrte Perspektivprojektion umgebaut und einen Pan-Tilt per Maus drangehängt, damit man die Beleuchtungssituation besser erkennen kann. Ich hoffe, dass das bei dir auch in etwa das Ergebnis bringt, das es soll.
    Dateien
    • VBOTest1 copy.zip

      (78,88 kB, 254 mal heruntergeladen, zuletzt: )
    Multigrad - 360°-Produktfotografie für den Mac
  • Darauf kann ich bauen !
    Bin gespannt, wie sich glFrustum auswirkt, ich möchte keine so grosse Tiefenwirkung erzielen.
    Welche(n) Parameter muss ich ändern ?

    Ich hab' die Rekursionstiefe auf 3 erhöht, das ist zufrieden stellend.

    Zur Zeit erstelle ich eine DreiecksMatrix (RotationsSolid), da gibt es ein Problem, an das mich deine Erwähnung der Scherung erinnert.
    Nächstes Thema

    Nochmals danke.
    Uwe
    How come I can't see me in my mirror ?
  • Dylans Ghost schrieb:

    Bin gespannt, wie sich glFrustum auswirkt, ich möchte keine so grosse Tiefenwirkung erzielen.
    Welche(n) Parameter muss ich ändern ?

    Wenn du keine Perspektivprojektion brauchst kannst du auch glOrtho nehmen oder die Projektionsmatrix gleich auf Identity lassen (ist dann eine Orthogonalprojektion in x=-1..1, y=-1..1, z=0..1). Dann kann auch GL_LIGHT_MODEL_LOCAL_VIEWER aus, da macht das keinen Unterschied.

    Um die Perspektivprojektion flacher zu bekommen, musst du quasi die Brennweite verlängern und die Kamera gleichzeitig weiter vom Objekt wegbewegen, um einen ähnlichen Ausschnitt zu behalten. Bei glFrustum resultiert der horizontale Bildwinkel aus dem Verhältnis zwischen (right-left) und near (der vertikale analog mit top und bottom). Ein Weg ist es left, right, top und bottom beizubehalten. Nur near vergrößern (far entsprechend, dass genug sichtbarer Raum bleibt, das wirkt sich aber nicht auf den Blickwinkel aus). Im gleichen Maß den z-Wert im ersten glTranslate in der Rendermethode vergrößern (das ist der Kameraabstand, er sollte also zwischen near und far liegen).
    Multigrad - 360°-Produktfotografie für den Mac
  • Lieber mattik, bevor wir das Thema abschliessen hab' ich noch eine Frage:
    Warum ist die Reflexion nicht seitlich versetzt, die Lichtquelle residiert doch bei 1,1,5 ?

    Ich hab den code aus VBOTest in mein Projekt eingearbeitet, jetzt kann ich so viele Boller malen bis der Speicher voll ist ;) .
    How come I can't see me in my mirror ?
  • Doch, die Reflektion ist seitlich versetzt, aber nur sehr leicht. (1,1,5) ist ja fast frontal. Die Spiegelung sitzt ja beim halben Weg zwischen Lichtvektor und Sichtvektor, daher ist sie weniger aus der Mitte raus als die hellste Stelle. Setz' die Lichtquelle mal stark seitlich, z.B. (1,1,0), dann sieht man das besser.
    Multigrad - 360°-Produktfotografie für den Mac