[Top][All Lists]
[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(¤t_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(¤t_ds, 640, 400);
-
+ cocoa_display_init(¤t_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);
}
- Re: [Qemu-devel] cocoa.m using openGL, (continued)
- Re: [Qemu-devel] cocoa.m using openGL, Pierre d'Herbemont, 2005/05/26
- Re: [Qemu-devel] cocoa.m using openGL, Peter Stewart, 2005/05/23
- Re: [Qemu-devel] cocoa.m using openGL, Peter Stewart, 2005/05/23
- Re: [Qemu-devel] cocoa.m using openGL,
Peter Stewart <=
- Re: [Qemu-devel] cocoa.m using openGL, Peter Stewart, 2005/05/23
- Re: [Qemu-devel] cocoa.m using openGL, Peter Stewart, 2005/05/23