qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] cocoa.m using openGL


From: Peter Stewart
Subject: Re: [Qemu-devel] cocoa.m using openGL
Date: Tue, 24 May 2005 01:29:18 +0200

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 via email to

[Prev in Thread] Current Thread [Next in Thread]