qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Stewart <peterfs74@gmail.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] cocoa.m using openGL
Date: Tue, 24 May 2005 01:29:18 +0200	[thread overview]
Message-ID: <16d65796e962fc2648b2bd8804a62afc@gmail.com> (raw)

Hi,

Sorry, kind of new at this...

Here is the diff -u version of cocoa.m, I guess you got the  
Makefile.target fix :-)


diff -u cocoa.m.orig cocoa.m > cocoa.m.diff

enjoy,
peter.


--- cocoa.m.orig        Sat May 21 17:19:45 2005
+++ cocoa.m     Mon May 23 19:24:00 2005
@@ -37,16 +37,23 @@

  #import <Cocoa/Cocoa.h>

+#include <OpenGL/CGLCurrent.h>
+#include <OpenGL/CGLContext.h>
+
  #include "vl.h"

-NSWindow *window = NULL;
-NSQuickDrawView *qd_view = NULL;
+static NSWindow *window = NULL;
+static NSOpenGLView *ogl_view = NULL;

+#define SCREEN_BPP 32

  int gArgc;
  char **gArgv;
  DisplayState current_ds;

+GLint screen_tex = 0;
+GLuint display_list_tex = 0;
+
  /* main defined in qemu/vl.c */
  int qemu_main(int argc, char **argv);

@@ -62,6 +69,7 @@
   ------------------------------------------------------
  */

+
  /*
   ------------------------------------------------------
      cocoa_update
@@ -70,22 +78,22 @@
  static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
  {
      //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+
+       // Make this context current
+       [[ogl_view openGLContext] makeCurrentContext];
+
+       // Bind, update and draw new image
+       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+       // glTexSubImage2D is faster when not using a texture range
+       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,  
(GLint)ds->width, (GLint)ds->height, 0, GL_BGRA,  
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+       // Use the compiled display list
+       glCallList(display_list_tex);
+
+       // Swap buffer to screen
+       [[ogl_view openGLContext] flushBuffer];

-    /* Use QDFlushPortBuffer() to flush content to display */
-    RgnHandle dirty = NewRgn ();
-    RgnHandle temp  = NewRgn ();
-
-    SetEmptyRgn (dirty);
-
-    /* Build the region of dirty rectangles */
-    MacSetRectRgn (temp, x, y,
-                        x + w, y + h);
-    MacUnionRgn (dirty, temp, dirty);
-
-    /* Flush the dirty region */
-    QDFlushPortBuffer ( [ qd_view  qdPort ], dirty );
-    DisposeRgn (dirty);
-    DisposeRgn (temp);
  }

  /*
@@ -95,74 +103,96 @@
  */
  static void cocoa_resize(DisplayState *ds, int w, int h)
  {
-    const int device_bpp = 32;
-    static void *screen_pixels;
-    static int  screen_pitch;
+
      NSRect contentRect;
+
+    // printf("resizing to %d %d\n", w, h);

-    //printf("resizing to %d %d\n", w, h);
-
-    contentRect = NSMakeRect (0, 0, w, h);
-    if(window)
-    {
-        [window close];
-        [window release];
-    }
-    window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
-                                   
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
-                                  backing:NSBackingStoreBuffered  
defer:NO];
-    if(!window)
-    {
-        fprintf(stderr, "(cocoa) can't create window\n");
-        exit(1);
-    }
-
-    if(qd_view)
-        [qd_view release];
-
-    qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
-    if(!qd_view)
-    {
-         fprintf(stderr, "(cocoa) can't create qd_view\n");
-        exit(1);
-    }
-
-    [ window setAcceptsMouseMovedEvents:YES ];
-    [ window setTitle:@"Qemu" ];
-    [ window setReleasedWhenClosed:NO ];
-
-    /* Set screen to black */
-    [ window setBackgroundColor: [NSColor blackColor] ];
-
-    /* set window position */
-    [ window center ];
-
-    [ qd_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
-    [ [ window contentView ] addSubview:qd_view ];
-    [ qd_view release ];
-    [ window makeKeyAndOrderFront:nil ];
-
-    /* Careful here, the window seems to have to be onscreen to do  
that */
-    LockPortBits ( [ qd_view qdPort ] );
-    screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort  
] ) );
-    screen_pitch  = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort  
] ) );
-    UnlockPortBits ( [ qd_view qdPort ] );
-    {
-            int vOffset = [ window frame ].size.height -
-                [ qd_view frame ].size.height - [ qd_view frame  
].origin.y;
-
-            int hOffset = [ qd_view frame ].origin.x;
-
-            screen_pixels += (vOffset * screen_pitch) + hOffset *  
(device_bpp/8);
-    }
-    ds->data = screen_pixels;
-    ds->linesize = screen_pitch;
-    ds->depth = device_bpp;
+    contentRect = NSMakeRect (0, 0, w, h);
+
+       [window setContentSize:contentRect.size];
+       [window update];
+
+       [[ogl_view openGLContext] makeCurrentContext];
+       [[ogl_view openGLContext] update];
+
+    glViewport(0, 0, (int) contentRect.size.width, (int)  
contentRect.size.height);
+
+       glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+
+       glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+       // This is used as a init'd flag as well...
+       if(screen_tex != 0) {
+               glDeleteTextures(1, &screen_tex);
+               glDeleteLists(display_list_tex, 1);
+       }
+
+       screen_tex = 1;
+
+       if(ds->data != NULL) free(ds->data);
+       ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
+       assert(ds->data != NULL);
+       ds->linesize = w * (SCREEN_BPP >> 3);
+    ds->depth = SCREEN_BPP;
      ds->width = w;
      ds->height = h;
-
-    current_ds = *ds;
+
+       // Setup some basic OpenGL stuff as from Apple
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+       glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+       glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+       glEnable(GL_TEXTURE_RECTANGLE_EXT);
+       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+       glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT,  w * h *  
(SCREEN_BPP >> 3), ds->data);
+
+       // Use CACHED for VRAM+reused tex  Use SHARED for AGP+used once  
tex
+       // Note the texture is always changing so use SHARED
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
+       glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,  
GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,  
GL_CLAMP_TO_EDGE);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0,  
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+       glFlush();
+
+       // Setup a display list to save all the operations below
+
+       display_list_tex = glGenLists(1);
+       glNewList(display_list_tex, GL_COMPILE);
+
+       glBegin(GL_QUADS);
+
+       glTexCoord2f(0.0f, 0.0f);
+       glVertex2f(-1.0f, 1.0f);
+
+       glTexCoord2f(0.0f, (GLfloat)h);
+       glVertex2f(-1.0f, -1.0f);
+
+       glTexCoord2f((GLfloat)w, (GLfloat)h);
+       glVertex2f(1.0f, -1.0f);
+
+       glTexCoord2f((GLfloat)w, 0.0f);
+       glVertex2f(1.0f, 1.0f);
+
+       glEnd();
+
+       glEndList();
+
+
+       // Swap buffer to screen
+       [[ogl_view openGLContext] flushBuffer];
+
+       memcpy(&current_ds, ds, sizeof(DisplayState));
  }

  /*
@@ -243,19 +273,16 @@
  static void cocoa_refresh(DisplayState *ds)
  {
      //printf("cocoa_refresh \n");
-    NSDate *distantPast;
      NSEvent *event;
-    NSAutoreleasePool *pool;
      int grab = 1;
-
-    pool = [ [ NSAutoreleasePool alloc ] init ];
-    distantPast = [ NSDate distantPast ];
-
+    NSDate *distantPast = [ NSDate distantPast ];;
+
      if (is_active_console(vga_console))
          vga_update_display();
+
      do {
-        event = [ NSApp nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast
-                        inMode: NSDefaultRunLoopMode dequeue:YES ];
+        event = [ window nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ];
+
          if (event != nil) {
              switch ([event type]) {
                  case NSKeyDown:
@@ -278,26 +305,74 @@
                          kbd_put_keycode(keycode | 0x80);
                      }
                      break;
+
+
                  case NSScrollWheel:
-
-                case NSLeftMouseDown:
-                case NSLeftMouseUp:
-
-                case NSOtherMouseDown:
-                case NSRightMouseDown:
-
-                case NSOtherMouseUp:
-                case NSRightMouseUp:
-
+                                       if(grab)
+                                       {
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(0, 0,  
dz, 0);
+                                       }
+                                       break;
+
+
                  case NSMouseMoved:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+
+                                               kbd_mouse_event(dx, dy,  
0, 0);
+                                       }
+                                       break;
+
+
+                case NSOtherMouseDown:
+                case NSOtherMouseUp:
                  case NSOtherMouseDragged:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_MBUTTON);
+                                       }
+                                       break;
+
+                               case NSRightMouseDown:
+                case NSRightMouseUp:
                  case NSRightMouseDragged:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_RBUTTON);
+                                       }
+                                       break;
+
+                case NSLeftMouseDown:
+                case NSLeftMouseUp:
                  case NSLeftMouseDragged:
-
-                default: [NSApp sendEvent:event];
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_LBUTTON);
+                                       }
+                                       break;
+
+                default:
+                                       [NSApp sendEvent:event];
              }
          }
      } while(event != nil);
+
  }

  /*
@@ -319,12 +394,72 @@

  void cocoa_display_init(DisplayState *ds, int full_screen)
  {
-    ds->dpy_update = cocoa_update;
-    ds->dpy_resize = cocoa_resize;
-    ds->dpy_refresh = cocoa_refresh;
+    //printf("resizing to %d %d\n", w, h);
+
+       const int w = 640;
+       const int h = 400;
+
+       if(window == nil)
+       {
+               // Init pixel format attribs
+               NSOpenGLPixelFormatAttribute attrs[] =
+               {
+                       NSOpenGLPFAAccelerated,
+                       NSOpenGLPFANoRecovery,
+                       NSOpenGLPFADoubleBuffer,
+                       0
+               };
+
+               NSRect contentRect = NSMakeRect (0, 0, w, h);
+
+               // Get pixel format from OpenGL
+               NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat  
alloc] initWithAttributes:attrs];
+               if (!pixFmt)
+               {
+                       fprintf(stderr, "No pixel format -- exiting");
+                       exit(1);
+               }
+
+               window = [ [ QemuWindow alloc ]  
initWithContentRect:contentRect
+                                                
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+                                                
backing:NSBackingStoreBuffered defer:NO];
+               if(!window)
+               {
+                       fprintf(stderr, "(cocoa) can't create  
window\n");
+                       exit(1);
+               }
+
+               ogl_view = [ [ NSOpenGLView alloc ]  
initWithFrame:contentRect pixelFormat:pixFmt ];
+
+               if(!ogl_view)
+               {
+                       fprintf(stderr, "(cocoa) can't create  
ogl_view\n");
+                       exit(1);
+               }
+
+               [ window setAcceptsMouseMovedEvents:YES ];
+               [ window setTitle:@"Qemu" ];
+               [ window setReleasedWhenClosed:NO ];
+
+               /* set window position */
+               [ window center ];
+               [ window makeKeyAndOrderFront:nil ];
+
+               [ ogl_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
+               [ window setContentView:ogl_view ];
+               [ ogl_view release ];
+       }
+
+       ds->dpy_update = cocoa_update;
+       ds->dpy_resize = cocoa_resize;
+       ds->dpy_refresh = cocoa_refresh;

      cocoa_resize(ds, 640, 400);
-
+
+       [ window display ];
+       [ window makeMainWindow ];
+       [ window makeKeyWindow ];
+
      atexit(cocoa_cleanup);
  }

@@ -341,30 +476,13 @@
      Some trick from SDL to use miniwindow
   ------------------------------------------------------
  */
-static void QZ_SetPortAlphaOpaque ()
-{
-    /* Assume 32 bit if( bpp == 32 )*/
-    if ( 1 ) {
-
-        uint32_t    *pixels = (uint32_t*) current_ds.data;
-        uint32_t    rowPixels = current_ds.linesize / 4;
-        uint32_t    i, j;
-
-        for (i = 0; i < current_ds.height; i++)
-            for (j = 0; j < current_ds.width; j++) {
-
-                pixels[ (i * rowPixels) + j ] |= 0xFF000000;
-            }
-    }
-}
+

  @implementation QemuWindow
  - (void)miniaturize:(id)sender
  {

-    /* make the alpha channel opaque so anim won't have holes in it */
-    QZ_SetPortAlphaOpaque ();
-
+    /* make the alpha channel opaque so anim won't have holes in it */
      [ super miniaturize:sender ];

  }
@@ -377,12 +495,10 @@
          UI elements, and restore the SDL surface. This way, no expose  
event
          is required, and the deminiaturize works perfectly.
      */
-
-    /* make sure pixels are fully opaque */
-    QZ_SetPortAlphaOpaque ();
+

      /* save current visible SDL surface */
-    [ self cacheImageInRect:[ qd_view frame ] ];
+    [ self cacheImageInRect:[ ogl_view frame ] ];

      /* let the window manager redraw controls, border, etc */
      [ super display ];
@@ -424,8 +540,8 @@
      {
          NSOpenPanel *op = [[NSOpenPanel alloc] init];

-        cocoa_resize(&current_ds, 640, 400);
-
+               cocoa_display_init(&current_ds, 0);
+
          [op setPrompt:@"Boot image"];

          [op setMessage:@"Select the disk image you want to  
boot.\n\nHit the \"Cancel\" button to quit"];
@@ -449,9 +565,16 @@
      exit(0);
  }

+
+
+
+
+
  - (void)openPanelDidEnd:(NSOpenPanel *)sheet  
returnCode:(int)returnCode contextInfo:(void *)contextInfo
  {
-    if(returnCode == NSCancelButton)
+       [sheet close];
+
+       if(returnCode == NSCancelButton)
      {
          exit(0);
      }

             reply	other threads:[~2005-05-23 23:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-23 23:29 Peter Stewart [this message]
  -- strict thread matches above, loose matches on Subject: below --
2005-05-23 23:58 [Qemu-devel] cocoa.m using openGL Peter Stewart
2005-05-23 23:31 Peter Stewart
2005-05-24  0:20 ` Mike Kronenberg
2005-05-23 17:31 Peter Stewart
2005-05-23 19:17 ` Mike Kronenberg
2005-05-23 21:54   ` Hetz Ben Hamo
2005-05-23  7:47 Peter Stewart
2005-05-23  8:38 ` Mike Kronenberg
2005-05-22 13:00 Peter Stewart
2005-05-22 13:45 ` Hetz Ben Hamo
2005-05-23  7:20 ` Mike Kronenberg
2005-05-24 15:11 ` Mike Kronenberg
2005-05-26 15:09   ` Pierre d'Herbemont
2005-05-27 14:57   ` Pierre d'Herbemont
2005-05-28 18:39     ` Mike Kronenberg
2005-05-29 14:47       ` Pierre d'Herbemont
2005-05-26 14:52 ` Pierre d'Herbemont

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=16d65796e962fc2648b2bd8804a62afc@gmail.com \
    --to=peterfs74@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).