Window mit NSOpenGLView subclass verhält sich komisch...

  • Window mit NSOpenGLView subclass verhält sich komisch...

    Also ich bin mich jetzt doch wieder ein mal ein wenig mit Cocoa am beschäftigen. Hab hier ein Fenster mit einem NSOpenGLView drin. Allerdings verhält sich das nicht so wie ich will. Wenn ich meine Szene aktualisiert habe will ich neu zeichnen. Das funktioniert theoretisch auch super, drawRect: in meiner Subklasse wird aufgerufen. Allerdings wird das Bild nicht wirklich aktualisiert. Wenn ich das Fenster dann verschiebe, ist das aktuelle Bild dann ploetzlich sichtbar. Danach klappt alles wie es soll.

    Ich nehme mal an ich hab irgendwas beim Fenster nicht richtig eingestellt. Nur was?

    Danke.
    Gruss Dominik.
  • Bei mir funktioniert das auch.
    Wie du das machst ist aber sehr umständlich, auch die Anweisung

    Quellcode

    1. [super prepareOpenGL];

    macht keinen Sinn.

    Hier mal ein kleines Beispiel aus meinem Buch:

    Quellcode

    1. @implementation MyOpenGLView
    2. - (void) prepareOpenGL
    3. {
    4. glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    5. }
    6. - (void)reshape
    7. {
    8. NSRect rect = [self bounds];
    9. glViewport( 0, 0, (GLsizei)rect.size.width, (GLsizei)rect.size.height);
    10. glMatrixMode( GL_PROJECTION );
    11. glLoadIdentity();
    12. gluPerspective( 45.0, rect.size.width / rect.size.height, 1.0, 5.0 );
    13. glMatrixMode( GL_MODELVIEW );
    14. glLoadIdentity();
    15. }
    16. -(void) drawRect: (NSRect) bounds
    17. {
    18. glClear(GL_COLOR_BUFFER_BIT );
    19. glColor3f(1.0f, 0.85f, 0.35f);
    20. glBegin(GL_TRIANGLES);
    21. {
    22. glVertex3f( -0.2, -0.3, -2.0);
    23. glVertex3f( 0.2, -0.3, -2.0);
    24. glVertex3f( 0.0, 0.3, -2.0);
    25. }
    26. glEnd();
    27. glFlush();
    28. }
    29. @end
    Alles anzeigen


    Du siehst der Code ist viel übersichtlicher und weniger fehleranfällig.
    Allerdings wird auch hier nur das View erneuert, wenn du das Fenster in seiner Größe veränderst (ist ja klar), weshalb ein Timer wahrscheinlich besser ist (ok kommt drauf an ob du eine Echtzeitdarstellung brauchst)
  • So, ich würde nochmals gerne auf das "kompliziert" zurückkommen. Ich hab mein kleines Projekt jetzt mal fertiggestellt. So wird vielleicht auch eher klar was ich brauche. Ich will eigentlich nur einzelne Pixel anmalen können, wenn möglich halbwegs effizient.

    Hab mir zuerst was mit NSBitmapImageRep gedacht, da ich die API aber nicht wirklich verstehe hab ich das jetzt mit OpenGL und GL_POINTS gemacht ;)

    Die Frage ist nun wie man das vernünftig löst. Im Anhang ist noch meine, nicht ganz optimale, Variante (cmd-f -> fullscreen, scroll/pinch -> zoom, swipe -> naechstes Fraktal, click&drag -> verschieben).
    Gruss Dominik.
  • das muss ihn den die reshape-Methode

    Quellcode

    1. glMatrixMode(GL_MODELVIEW);
    2. glLoadIdentity();
    3. glClear(GL_COLOR_BUFFER_BIT);



    super prepare... brauchst du nicht aufrufen, die macht nämlich nix.

    Quellcode

    1. - (void)prepareOpenGL {
    2. [super prepareOpenGL];
    3. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    4. }




    Im Intermediate-Mode zu malen ist ziemlich ineffizient, mach das mit Vertex-Arrays oder VBO's.
    Der Rest vom Code hab ich nicht so genau angeschaut.

    Quellcode

    1. glBegin(GL_TRIANGLES);
    2. for (int i = 0; i < n; i++) {
    3. double *p = points[i];
    4. double *c = colors[i];
    5. double x = (p[0] - sceneBounds.origin.x)*rx;
    6. double y = (p[1] - sceneBounds.origin.y)*ry;
    7. glColor3dv(c);
    8. glVertex2d(x, y);
    9. }
    10. glEnd();
    11. glBegin(GL_POINTS);
    12. {
    13. for (int i = 0; i < w; i++) {
    14. for (int j = 0; j <h; j++) {
    15. CGFloat r,g,b,a;
    16. [colors[i*h+j] getRed:&r green:&g blue:&b alpha:&a];
    17. [colors[i*h+j] autorelease];
    18. glColor4d(r, g, b, a);
    19. glVertex2d(i*detail, j*detail);
    20. }
    21. }
    22. }
    23. glEnd();
    Alles anzeigen