mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
new Cocoa graphics pipe is now fully functional
This commit is contained in:
parent
dcdc6d9877
commit
1f0304c696
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#import <Foundation/NSAutoreleasePool.h>
|
#import <Foundation/NSAutoreleasePool.h>
|
||||||
#import <AppKit/NSApplication.h>
|
#import <AppKit/NSApplication.h>
|
||||||
|
#import <AppKit/NSRunningApplication.h>
|
||||||
|
|
||||||
#include <mach-o/arch.h>
|
#include <mach-o/arch.h>
|
||||||
|
|
||||||
@ -31,9 +32,15 @@ static void init_app() {
|
|||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
[NSApp setActivationPolicy:nil];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
[NSApp finishLaunching];
|
[NSApp finishLaunching];
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
|
||||||
|
// Put Cocoa into thread-safe mode
|
||||||
|
// by spawning a thread which immediately exits.
|
||||||
|
NSThread* thread = [[NSThread alloc] init];
|
||||||
|
[thread start];
|
||||||
|
[thread autorelease];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +271,7 @@ pipe_constructor() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
GraphicsPipe::PreferredWindowThread
|
GraphicsPipe::PreferredWindowThread
|
||||||
CocoaGraphicsPipe::get_preferred_window_thread() const {
|
CocoaGraphicsPipe::get_preferred_window_thread() const {
|
||||||
// The NSView and NSWindow classes are not thread-safe,
|
// The NSView and NSWindow classes are not completely thread-safe,
|
||||||
// they can only be called from the main thread!
|
// they can only be called from the main thread!
|
||||||
return PWT_app;
|
return PWT_app;
|
||||||
}
|
}
|
||||||
@ -309,8 +316,8 @@ make_output(const string &name,
|
|||||||
return new CocoaGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
return new CocoaGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
||||||
flags, gsg, host);
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// Second thing to try: a GLES(2)GraphicsBuffer
|
// Second thing to try: a GLGraphicsBuffer
|
||||||
if (retry == 1) {
|
if (retry == 1) {
|
||||||
if ((host==0)||
|
if ((host==0)||
|
||||||
// (!gl_support_fbo)||
|
// (!gl_support_fbo)||
|
||||||
@ -334,7 +341,7 @@ make_output(const string &name,
|
|||||||
(cocoagsg->is_valid()) &&
|
(cocoagsg->is_valid()) &&
|
||||||
(!cocoagsg->needs_reset()) &&
|
(!cocoagsg->needs_reset()) &&
|
||||||
(cocoagsg->_supports_framebuffer_object) &&
|
(cocoagsg->_supports_framebuffer_object) &&
|
||||||
(cocoagsg->_glDrawBuffers != 0)&&
|
(cocoagsg->_glDrawBuffers != 0) &&
|
||||||
(fb_prop.is_basic())) {
|
(fb_prop.is_basic())) {
|
||||||
precertify = true;
|
precertify = true;
|
||||||
}
|
}
|
||||||
@ -342,7 +349,7 @@ make_output(const string &name,
|
|||||||
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||||
flags, gsg, host);
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// Third thing to try: a CocoaGraphicsBuffer
|
// Third thing to try: a CocoaGraphicsBuffer
|
||||||
if (retry == 2) {
|
if (retry == 2) {
|
||||||
if (((flags&BF_require_parasite)!=0)||
|
if (((flags&BF_require_parasite)!=0)||
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
NSOpenGLPixelFormat *pixel_format, int virtual_screen);
|
NSOpenGLPixelFormat *pixel_format, int virtual_screen);
|
||||||
void choose_pixel_format(const FrameBufferProperties &properties,
|
void choose_pixel_format(const FrameBufferProperties &properties,
|
||||||
CGDirectDisplayID display,
|
CGDirectDisplayID display,
|
||||||
bool need_window, bool need_pbuffer);
|
bool need_pbuffer);
|
||||||
|
|
||||||
CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||||
CocoaGraphicsStateGuardian *share_with);
|
CocoaGraphicsStateGuardian *share_with);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "lightReMutexHolder.h"
|
#include "lightReMutexHolder.h"
|
||||||
|
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
#import <OpenGL/CGLRenderers.h>
|
#import <OpenGL/CGLRenderers.h>
|
||||||
|
|
||||||
TypeHandle CocoaGraphicsStateGuardian::_type_handle;
|
TypeHandle CocoaGraphicsStateGuardian::_type_handle;
|
||||||
@ -69,20 +70,20 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
|
|||||||
depth_size, stencil_size, accum_size, sample_buffers, samples,
|
depth_size, stencil_size, accum_size, sample_buffers, samples,
|
||||||
renderer_id, accelerated, window, pbuffer;
|
renderer_id, accelerated, window, pbuffer;
|
||||||
|
|
||||||
[pixel_format getValues: &double_buffer forAttribute: NSOpenGLPFADoubleBuffer forVirtualScreen: screen];
|
[pixel_format getValues:&double_buffer forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &stereo forAttribute: NSOpenGLPFAStereo forVirtualScreen: screen];
|
[pixel_format getValues:&stereo forAttribute:NSOpenGLPFAStereo forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &aux_buffers forAttribute: NSOpenGLPFAAuxBuffers forVirtualScreen: screen];
|
[pixel_format getValues:&aux_buffers forAttribute:NSOpenGLPFAAuxBuffers forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &color_size forAttribute: NSOpenGLPFAColorSize forVirtualScreen: screen];
|
[pixel_format getValues:&color_size forAttribute:NSOpenGLPFAColorSize forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &alpha_size forAttribute: NSOpenGLPFAAlphaSize forVirtualScreen: screen];
|
[pixel_format getValues:&alpha_size forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &depth_size forAttribute: NSOpenGLPFADepthSize forVirtualScreen: screen];
|
[pixel_format getValues:&depth_size forAttribute:NSOpenGLPFADepthSize forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &stencil_size forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: screen];
|
[pixel_format getValues:&stencil_size forAttribute:NSOpenGLPFAStencilSize forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &accum_size forAttribute: NSOpenGLPFAAccumSize forVirtualScreen: screen];
|
[pixel_format getValues:&accum_size forAttribute:NSOpenGLPFAAccumSize forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &sample_buffers forAttribute: NSOpenGLPFASampleBuffers forVirtualScreen: screen];
|
[pixel_format getValues:&sample_buffers forAttribute:NSOpenGLPFASampleBuffers forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &samples forAttribute: NSOpenGLPFASamples forVirtualScreen: screen];
|
[pixel_format getValues:&samples forAttribute:NSOpenGLPFASamples forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &renderer_id forAttribute: NSOpenGLPFARendererID forVirtualScreen: screen];
|
[pixel_format getValues:&renderer_id forAttribute:NSOpenGLPFARendererID forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &accelerated forAttribute: NSOpenGLPFAAccelerated forVirtualScreen: screen];
|
[pixel_format getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &window forAttribute: NSOpenGLPFAWindow forVirtualScreen: screen];
|
[pixel_format getValues:&window forAttribute:NSOpenGLPFAWindow forVirtualScreen:screen];
|
||||||
[pixel_format getValues: &pbuffer forAttribute: NSOpenGLPFAPixelBuffer forVirtualScreen: screen];
|
[pixel_format getValues:&pbuffer forAttribute:NSOpenGLPFAPixelBuffer forVirtualScreen:screen];
|
||||||
|
|
||||||
properties.set_back_buffers(double_buffer);
|
properties.set_back_buffers(double_buffer);
|
||||||
properties.set_stereo(stereo);
|
properties.set_stereo(stereo);
|
||||||
@ -97,11 +98,16 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
|
|||||||
}
|
}
|
||||||
//TODO: add aux buffers
|
//TODO: add aux buffers
|
||||||
|
|
||||||
|
// Extract the renderer ID bits and check if our
|
||||||
|
// renderer matches the known software renderers.
|
||||||
|
renderer_id &= kCGLRendererIDMatchingMask;
|
||||||
if (renderer_id == kCGLRendererGenericID ||
|
if (renderer_id == kCGLRendererGenericID ||
|
||||||
renderer_id == kCGLRendererGenericFloatID ||
|
renderer_id == kCGLRendererGenericFloatID ||
|
||||||
renderer_id == kCGLRendererAppleSWID) {
|
renderer_id == kCGLRendererAppleSWID) {
|
||||||
|
|
||||||
properties.set_force_software(1);
|
properties.set_force_software(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accelerated) {
|
if (accelerated) {
|
||||||
properties.set_force_hardware(1);
|
properties.set_force_hardware(1);
|
||||||
}
|
}
|
||||||
@ -117,16 +123,16 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
|
|||||||
void CocoaGraphicsStateGuardian::
|
void CocoaGraphicsStateGuardian::
|
||||||
choose_pixel_format(const FrameBufferProperties &properties,
|
choose_pixel_format(const FrameBufferProperties &properties,
|
||||||
CGDirectDisplayID display,
|
CGDirectDisplayID display,
|
||||||
bool need_window, bool need_pbuffer) {
|
bool need_pbuffer) {
|
||||||
|
|
||||||
_context = nil;
|
_context = nil;
|
||||||
_fbprops.clear();
|
_fbprops.clear();
|
||||||
|
|
||||||
// Neither Cocoa nor CGL seem to have a mechanism to query the available
|
// Neither Cocoa nor CGL seem to have a mechanism to query the available
|
||||||
// pixel formats, unfortunately, so the only thing we can do is ask for one
|
// pixel formats, unfortunately, so the only thing we can do is ask for
|
||||||
// with the properties we have requested.
|
// one with the properties we have requested.
|
||||||
pvector<NSOpenGLPixelFormatAttribute> attribs;
|
pvector<NSOpenGLPixelFormatAttribute> attribs;
|
||||||
attribs.reserve(13);
|
attribs.reserve(15);
|
||||||
|
|
||||||
// Picked this up from the pyglet source - seems
|
// Picked this up from the pyglet source - seems
|
||||||
// to be necessary to support RAGE-II, which is not compliant.
|
// to be necessary to support RAGE-II, which is not compliant.
|
||||||
@ -135,8 +141,9 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
// Don't let it fall back to a different renderer.
|
// Don't let it fall back to a different renderer.
|
||||||
attribs.push_back(NSOpenGLPFANoRecovery);
|
attribs.push_back(NSOpenGLPFANoRecovery);
|
||||||
|
|
||||||
// Selection policy.
|
// Consider pixel formats with properties equal
|
||||||
//attribs.push_back(NSOpenGLPFAMinimumPolicy);
|
// to or better than we requested.
|
||||||
|
attribs.push_back(NSOpenGLPFAMinimumPolicy);
|
||||||
|
|
||||||
if (!properties.is_single_buffered()) {
|
if (!properties.is_single_buffered()) {
|
||||||
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
||||||
@ -151,13 +158,22 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
attribs.push_back(aux_buffers);
|
attribs.push_back(aux_buffers);
|
||||||
attribs.push_back(NSOpenGLPFAColorSize);
|
attribs.push_back(NSOpenGLPFAColorSize);
|
||||||
attribs.push_back(properties.get_color_bits());
|
attribs.push_back(properties.get_color_bits());
|
||||||
attribs.push_back(NSOpenGLPFAAlphaSize);
|
|
||||||
attribs.push_back(properties.get_alpha_bits());
|
|
||||||
attribs.push_back(NSOpenGLPFADepthSize);
|
attribs.push_back(NSOpenGLPFADepthSize);
|
||||||
attribs.push_back(properties.get_depth_bits());
|
attribs.push_back(properties.get_depth_bits());
|
||||||
attribs.push_back(NSOpenGLPFAStencilSize);
|
attribs.push_back(NSOpenGLPFAStencilSize);
|
||||||
attribs.push_back(properties.get_stencil_bits());
|
attribs.push_back(properties.get_stencil_bits());
|
||||||
|
|
||||||
|
// Curious case - if we request anything less than 8 alpha bits,
|
||||||
|
// then on some ATI cards, it will grab a pixel format with just
|
||||||
|
// 2 alpha bits, which just shows a white window and nothing else.
|
||||||
|
// Might have something to do with the compositing window manager.
|
||||||
|
// Omitting it altogether seems to make it grab one with 8 bits, though.
|
||||||
|
// Dirty hack. Needs more research.
|
||||||
|
if (properties.get_alpha_bits() > 0) {
|
||||||
|
attribs.push_back(NSOpenGLPFAAlphaSize);
|
||||||
|
attribs.push_back(max(8, properties.get_alpha_bits()));
|
||||||
|
}
|
||||||
|
|
||||||
if (properties.get_multisamples() > 0) {
|
if (properties.get_multisamples() > 0) {
|
||||||
attribs.push_back(NSOpenGLPFASampleBuffers);
|
attribs.push_back(NSOpenGLPFASampleBuffers);
|
||||||
attribs.push_back(1);
|
attribs.push_back(1);
|
||||||
@ -167,19 +183,16 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (properties.get_force_software()) {
|
if (properties.get_force_software()) {
|
||||||
|
// Request the generic software renderer.
|
||||||
attribs.push_back(NSOpenGLPFARendererID);
|
attribs.push_back(NSOpenGLPFARendererID);
|
||||||
attribs.push_back(kCGLRendererAppleSWID);
|
attribs.push_back(kCGLRendererGenericFloatID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.get_force_hardware()) {
|
if (properties.get_force_hardware()) {
|
||||||
attribs.push_back(NSOpenGLPFAAccelerated);
|
attribs.push_back(NSOpenGLPFAAccelerated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_window) {
|
attribs.push_back(NSOpenGLPFAWindow);
|
||||||
//TODO: when to request fullscreen on Cocoa?
|
|
||||||
attribs.push_back(NSOpenGLPFAWindow);
|
|
||||||
//attribs.push_back(NSOpenGLPFAFullScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_pbuffer) {
|
if (need_pbuffer) {
|
||||||
attribs.push_back(NSOpenGLPFAPixelBuffer);
|
attribs.push_back(NSOpenGLPFAPixelBuffer);
|
||||||
@ -189,19 +202,25 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
attribs.push_back(NSOpenGLPFAScreenMask);
|
attribs.push_back(NSOpenGLPFAScreenMask);
|
||||||
attribs.push_back(CGDisplayIDToOpenGLDisplayMask(display));
|
attribs.push_back(CGDisplayIDToOpenGLDisplayMask(display));
|
||||||
|
|
||||||
|
// End of the array
|
||||||
attribs.push_back((NSOpenGLPixelFormatAttribute) nil);
|
attribs.push_back((NSOpenGLPixelFormatAttribute) nil);
|
||||||
|
|
||||||
// Create the format.
|
// Create the format.
|
||||||
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: &attribs[0]];
|
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||||
if (format == nil) {
|
if (format == nil) {
|
||||||
cocoadisplay_cat.error() <<
|
cocoadisplay_cat.error() <<
|
||||||
"Could not find a usable pixel format.\n";
|
"Could not find a usable pixel format.\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//XXX not sure what to do with virtual_screen, let's just set it to 0.
|
// For now, I'm just using the first virtual screen.
|
||||||
|
cocoadisplay_cat.debug() <<
|
||||||
|
"Pixel format has " << [format numberOfVirtualScreens] << " virtual screens.\n";
|
||||||
get_properties(_fbprops, format, 0);
|
get_properties(_fbprops, format, 0);
|
||||||
_context = [[NSOpenGLContext alloc] initWithFormat: format shareContext: _share_context];
|
|
||||||
|
//TODO: print out renderer
|
||||||
|
|
||||||
|
_context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:_share_context];
|
||||||
[format release];
|
[format release];
|
||||||
if (_context == nil) {
|
if (_context == nil) {
|
||||||
cocoadisplay_cat.error() <<
|
cocoadisplay_cat.error() <<
|
||||||
@ -230,6 +249,9 @@ query_gl_version() {
|
|||||||
// where the GL version has been output, and it's nice to see the
|
// where the GL version has been output, and it's nice to see the
|
||||||
// two of these together.
|
// two of these together.
|
||||||
if (glgsg_cat.is_debug()) {
|
if (glgsg_cat.is_debug()) {
|
||||||
|
//XXX this is supposed to work, but the NSOpenGLGetVersion
|
||||||
|
// symbol cannot be found when I do this
|
||||||
|
|
||||||
//GLint major, minor;
|
//GLint major, minor;
|
||||||
//NSOpenGLGetVersion(&major, &minor);
|
//NSOpenGLGetVersion(&major, &minor);
|
||||||
|
|
||||||
@ -264,7 +286,7 @@ do_get_extension_func(const char *prefix, const char *name) {
|
|||||||
return (void *) NSAddressOfSymbol(symbol);
|
return (void *) NSAddressOfSymbol(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
cocoadisplay_cat.error() <<
|
cocoadisplay_cat.warning() <<
|
||||||
"do_get_extension_func failed for " << prefix << name << "!\n";
|
"do_get_extension_func failed for " << prefix << name << "!\n";
|
||||||
|
|
||||||
free(fullname);
|
free(fullname);
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
void handle_close_event();
|
void handle_close_event();
|
||||||
void handle_key_event(NSEvent *event);
|
void handle_key_event(NSEvent *event);
|
||||||
void handle_mouse_button_event(int button, bool down);
|
void handle_mouse_button_event(int button, bool down);
|
||||||
void handle_mouse_moved_event(bool in_window, int x, int y, bool absolute);
|
void handle_mouse_moved_event(bool in_window, double x, double y, bool absolute);
|
||||||
void handle_wheel_event(double x, double y);
|
void handle_wheel_event(double x, double y);
|
||||||
|
|
||||||
INLINE NSWindow *get_nswindow() const;
|
INLINE NSWindow *get_nswindow() const;
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#import <AppKit/NSImage.h>
|
#import <AppKit/NSImage.h>
|
||||||
#import <AppKit/NSScreen.h>
|
#import <AppKit/NSScreen.h>
|
||||||
#import <OpenGL/OpenGL.h>
|
#import <OpenGL/OpenGL.h>
|
||||||
#import <Carbon/Carbon.h>
|
//#import <Carbon/Carbon.h>
|
||||||
|
|
||||||
TypeHandle CocoaGraphicsWindow::_type_handle;
|
TypeHandle CocoaGraphicsWindow::_type_handle;
|
||||||
|
|
||||||
@ -97,20 +97,35 @@ CocoaGraphicsWindow::
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool CocoaGraphicsWindow::
|
bool CocoaGraphicsWindow::
|
||||||
move_pointer(int device, int x, int y) {
|
move_pointer(int device, int x, int y) {
|
||||||
|
//Hack! Will go away when we have floating-point mouse pos.
|
||||||
|
MouseData md = get_pointer(device);
|
||||||
|
if (md.get_x() == x && md.get_y() == y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (device == 0) {
|
if (device == 0) {
|
||||||
CGPoint point;
|
CGPoint point;
|
||||||
if (_properties.get_fullscreen()) {
|
if (_properties.get_fullscreen()) {
|
||||||
point = CGPointMake(x, y);
|
point = CGPointMake(x, y + 1);
|
||||||
} else {
|
} else {
|
||||||
point = CGPointMake(x + _properties.get_x_origin(),
|
point = CGPointMake(x + _properties.get_x_origin(),
|
||||||
y + _properties.get_y_origin());
|
y + _properties.get_y_origin() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (CGDisplayMoveCursorToPoint(_display, point) == kCGErrorSuccess);
|
// I don't know what the difference between these two methods is.
|
||||||
|
//if (CGWarpMouseCursorPosition(point) == kCGErrorSuccess) {
|
||||||
|
if (CGDisplayMoveCursorToPoint(_display, point) == kCGErrorSuccess) {
|
||||||
|
// Generate a mouse event.
|
||||||
|
NSPoint pos = [_window mouseLocationOutsideOfEventStream];
|
||||||
|
NSPoint loc = [_view convertPoint:pos fromView:nil];
|
||||||
|
BOOL inside = [_view mouse:loc inRect:[_view bounds]];
|
||||||
|
handle_mouse_moved_event(inside, loc.x, loc.y, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// No support for raw mice at the moment.
|
// No support for raw mice at the moment.
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -145,13 +160,16 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
// Fullscreen.
|
// Fullscreen.
|
||||||
[cocoagsg->_context setFullScreen];
|
[cocoagsg->_context setFullScreen];
|
||||||
} else {
|
} else {
|
||||||
nassertr([_view lockFocusIfCanDraw], false);
|
|
||||||
// Although not recommended, it is technically possible to
|
// Although not recommended, it is technically possible to
|
||||||
// use the same context with multiple different-sized windows.
|
// use the same context with multiple different-sized windows.
|
||||||
// If that happens, the context needs to be updated accordingly.
|
// If that happens, the context needs to be updated accordingly.
|
||||||
if ([cocoagsg->_context view] != _view) {
|
if ([cocoagsg->_context view] != _view) {
|
||||||
|
//XXX I'm not 100% sure that changing the view requires it to update.
|
||||||
_context_needs_update = true;
|
_context_needs_update = true;
|
||||||
[cocoagsg->_context setView:_view];
|
[cocoagsg->_context setView:_view];
|
||||||
|
|
||||||
|
cocoadisplay_cat.spam()
|
||||||
|
<< "Switching context to view " << _view << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +179,11 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
_context_needs_update = false;
|
_context_needs_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lock the view for drawing.
|
||||||
|
if (!_properties.get_fullscreen()) {
|
||||||
|
nassertr([_view lockFocusIfCanDraw], false);
|
||||||
|
}
|
||||||
|
|
||||||
// Make the context current.
|
// Make the context current.
|
||||||
[cocoagsg->_context makeCurrentContext];
|
[cocoagsg->_context makeCurrentContext];
|
||||||
|
|
||||||
@ -191,6 +214,15 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
end_frame_spam(mode);
|
end_frame_spam(mode);
|
||||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
|
|
||||||
|
if (!_properties.get_fullscreen()) {
|
||||||
|
[_view unlockFocus];
|
||||||
|
}
|
||||||
|
// Release the context.
|
||||||
|
CocoaGraphicsStateGuardian *cocoagsg;
|
||||||
|
DCAST_INTO_V(cocoagsg, _gsg);
|
||||||
|
|
||||||
|
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||||
|
|
||||||
if (mode == FM_render) {
|
if (mode == FM_render) {
|
||||||
// end_render_texture();
|
// end_render_texture();
|
||||||
copy_to_textures();
|
copy_to_textures();
|
||||||
@ -221,12 +253,14 @@ end_flip() {
|
|||||||
CocoaGraphicsStateGuardian *cocoagsg;
|
CocoaGraphicsStateGuardian *cocoagsg;
|
||||||
DCAST_INTO_V(cocoagsg, _gsg);
|
DCAST_INTO_V(cocoagsg, _gsg);
|
||||||
|
|
||||||
[cocoagsg->_context flushBuffer];
|
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||||
if (!_properties.get_fullscreen()) {
|
|
||||||
[_view unlockFocus];
|
// Swap the front and back buffer.
|
||||||
}
|
[cocoagsg->_context flushBuffer];
|
||||||
|
|
||||||
|
// Flush the window
|
||||||
|
[[_view window] flushWindow];
|
||||||
|
|
||||||
// Release the context.
|
|
||||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||||
}
|
}
|
||||||
GraphicsWindow::end_flip();
|
GraphicsWindow::end_flip();
|
||||||
@ -247,15 +281,14 @@ process_events() {
|
|||||||
GraphicsWindow::process_events();
|
GraphicsWindow::process_events();
|
||||||
|
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
NSEvent *event = nil;
|
NSEvent *event = nil;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
event = [NSApp
|
event = [NSApp
|
||||||
nextEventMatchingMask: NSAnyEventMask
|
nextEventMatchingMask:NSAnyEventMask
|
||||||
untilDate: nil
|
untilDate:nil
|
||||||
inMode: NSDefaultRunLoopMode
|
inMode:NSDefaultRunLoopMode
|
||||||
dequeue: YES];
|
dequeue:YES];
|
||||||
|
|
||||||
if (event == nil) {
|
if (event == nil) {
|
||||||
break;
|
break;
|
||||||
@ -288,7 +321,7 @@ open_window() {
|
|||||||
if (_gsg == 0) {
|
if (_gsg == 0) {
|
||||||
// There is no old gsg. Create a new one.
|
// There is no old gsg. Create a new one.
|
||||||
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, NULL);
|
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||||
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, true, false);
|
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, false);
|
||||||
_gsg = cocoagsg;
|
_gsg = cocoagsg;
|
||||||
} else {
|
} else {
|
||||||
// If the old gsg has the wrong pixel format, create a
|
// If the old gsg has the wrong pixel format, create a
|
||||||
@ -296,7 +329,7 @@ open_window() {
|
|||||||
DCAST_INTO_R(cocoagsg, _gsg, false);
|
DCAST_INTO_R(cocoagsg, _gsg, false);
|
||||||
if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
|
if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, cocoagsg);
|
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, cocoagsg);
|
||||||
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, true, false);
|
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, false);
|
||||||
_gsg = cocoagsg;
|
_gsg = cocoagsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,7 +381,7 @@ open_window() {
|
|||||||
|
|
||||||
// Depending on whether the window handle comes from a Carbon or a Cocoa
|
// Depending on whether the window handle comes from a Carbon or a Cocoa
|
||||||
// application, it could be either a HIViewRef or an NSView or NSWindow.
|
// application, it could be either a HIViewRef or an NSView or NSWindow.
|
||||||
// Currently, we only support a Cocoa NSView, but we may in the future
|
// Currently, we only support a Cocoa NSView, but we could in the future
|
||||||
// add support for Carbon parents using HICocoaView.
|
// add support for Carbon parents using HICocoaView.
|
||||||
|
|
||||||
if (os_handle->is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
|
if (os_handle->is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
|
||||||
@ -373,6 +406,8 @@ open_window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Center the window if coordinates were set to -1 or -2
|
// Center the window if coordinates were set to -1 or -2
|
||||||
|
//TODO: perhaps in future, in the case of -1, it should use the origin
|
||||||
|
// used in a previous run of Panda
|
||||||
NSRect container;
|
NSRect container;
|
||||||
if (parent_nsview != NULL) {
|
if (parent_nsview != NULL) {
|
||||||
container = [parent_nsview bounds];
|
container = [parent_nsview bounds];
|
||||||
@ -498,14 +533,14 @@ open_window() {
|
|||||||
[_window setShowsResizeIndicator: !_properties.get_fixed_size()];
|
[_window setShowsResizeIndicator: !_properties.get_fixed_size()];
|
||||||
|
|
||||||
if (_properties.get_fullscreen()) {
|
if (_properties.get_fullscreen()) {
|
||||||
[_window makeKeyAndOrderFront: nil];
|
[_window makeKeyAndOrderFront:nil];
|
||||||
} else if (_properties.get_minimized()) {
|
} else if (_properties.get_minimized()) {
|
||||||
[_window makeKeyAndOrderFront: nil];
|
[_window makeKeyAndOrderFront:nil];
|
||||||
[_window miniaturize: nil];
|
[_window miniaturize:nil];
|
||||||
} else if (_properties.get_foreground()) {
|
} else if (_properties.get_foreground()) {
|
||||||
[_window makeKeyAndOrderFront: nil];
|
[_window makeKeyAndOrderFront:nil];
|
||||||
} else {
|
} else {
|
||||||
[_window orderBack: nil];
|
[_window orderBack:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_properties.get_fullscreen()) {
|
if (_properties.get_fullscreen()) {
|
||||||
@ -547,8 +582,9 @@ open_window() {
|
|||||||
|
|
||||||
// Make the context current.
|
// Make the context current.
|
||||||
_context_needs_update = false;
|
_context_needs_update = false;
|
||||||
[cocoagsg->_context update];
|
|
||||||
[cocoagsg->_context makeCurrentContext];
|
[cocoagsg->_context makeCurrentContext];
|
||||||
|
[cocoagsg->_context setView:_view];
|
||||||
|
[cocoagsg->_context update];
|
||||||
|
|
||||||
cocoagsg->reset_if_new();
|
cocoagsg->reset_if_new();
|
||||||
|
|
||||||
@ -821,8 +857,6 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
properties.clear_origin();
|
properties.clear_origin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: mouse mode
|
|
||||||
|
|
||||||
if (properties.has_title() && _window != nil) {
|
if (properties.has_title() && _window != nil) {
|
||||||
_properties.set_title(properties.get_title());
|
_properties.set_title(properties.get_title());
|
||||||
[_window setTitle:[NSString stringWithUTF8String:properties.get_title().c_str()]];
|
[_window setTitle:[NSString stringWithUTF8String:properties.get_title().c_str()]];
|
||||||
@ -1224,10 +1258,6 @@ handle_minimize_event(bool minimized) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowProperties properties;
|
|
||||||
properties.set_minimized(minimized);
|
|
||||||
system_changed_properties(properties);
|
|
||||||
|
|
||||||
if (cocoadisplay_cat.is_debug()) {
|
if (cocoadisplay_cat.is_debug()) {
|
||||||
if (minimized) {
|
if (minimized) {
|
||||||
cocoadisplay_cat.debug() << "Window was miniaturized\n";
|
cocoadisplay_cat.debug() << "Window was miniaturized\n";
|
||||||
@ -1235,6 +1265,10 @@ handle_minimize_event(bool minimized) {
|
|||||||
cocoadisplay_cat.debug() << "Window was deminiaturized\n";
|
cocoadisplay_cat.debug() << "Window was deminiaturized\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowProperties properties;
|
||||||
|
properties.set_minimized(minimized);
|
||||||
|
system_changed_properties(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1245,10 +1279,6 @@ handle_minimize_event(bool minimized) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CocoaGraphicsWindow::
|
void CocoaGraphicsWindow::
|
||||||
handle_foreground_event(bool foreground) {
|
handle_foreground_event(bool foreground) {
|
||||||
WindowProperties properties;
|
|
||||||
properties.set_foreground(foreground);
|
|
||||||
system_changed_properties(properties);
|
|
||||||
|
|
||||||
if (cocoadisplay_cat.is_debug()) {
|
if (cocoadisplay_cat.is_debug()) {
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
cocoadisplay_cat.debug() << "Window became key\n";
|
cocoadisplay_cat.debug() << "Window became key\n";
|
||||||
@ -1257,6 +1287,10 @@ handle_foreground_event(bool foreground) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowProperties properties;
|
||||||
|
properties.set_foreground(foreground);
|
||||||
|
system_changed_properties(properties);
|
||||||
|
|
||||||
if (foreground && _properties.get_mouse_mode() != WindowProperties::M_relative) {
|
if (foreground && _properties.get_mouse_mode() != WindowProperties::M_relative) {
|
||||||
// The mouse position may have changed during
|
// The mouse position may have changed during
|
||||||
// the time that we were not the key window.
|
// the time that we were not the key window.
|
||||||
@ -1500,7 +1534,7 @@ handle_mouse_button_event(int button, bool down) {
|
|||||||
// Should only be called by CocoaPandaView.
|
// Should only be called by CocoaPandaView.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CocoaGraphicsWindow::
|
void CocoaGraphicsWindow::
|
||||||
handle_mouse_moved_event(bool in_window, int x, int y, bool absolute) {
|
handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) {
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
if (cocoadisplay_cat.is_spam()) {
|
if (cocoadisplay_cat.is_spam()) {
|
||||||
if (in_window != _input_devices[0].get_pointer().get_in_window()) {
|
if (in_window != _input_devices[0].get_pointer().get_in_window()) {
|
||||||
@ -1553,11 +1587,11 @@ handle_wheel_event(double x, double y) {
|
|||||||
_input_devices[0].button_up(MouseButton::wheel_down());
|
_input_devices[0].button_up(MouseButton::wheel_down());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check if this is correct
|
//TODO: check if this is correct, I don't own a MacBook
|
||||||
if (x > 0.0) {
|
if (x > 0.0) {
|
||||||
_input_devices[0].button_down(MouseButton::wheel_right());
|
_input_devices[0].button_down(MouseButton::wheel_right());
|
||||||
_input_devices[0].button_up(MouseButton::wheel_right());
|
_input_devices[0].button_up(MouseButton::wheel_right());
|
||||||
} else if (y < 0.0) {
|
} else if (x < 0.0) {
|
||||||
_input_devices[0].button_down(MouseButton::wheel_left());
|
_input_devices[0].button_down(MouseButton::wheel_left());
|
||||||
_input_devices[0].button_up(MouseButton::wheel_left());
|
_input_devices[0].button_up(MouseButton::wheel_left());
|
||||||
}
|
}
|
||||||
@ -1659,6 +1693,7 @@ map_function_key(unsigned short keycode) {
|
|||||||
case NSUserFunctionKey:
|
case NSUserFunctionKey:
|
||||||
case NSSystemFunctionKey:
|
case NSSystemFunctionKey:
|
||||||
case NSPrintFunctionKey:
|
case NSPrintFunctionKey:
|
||||||
|
break;
|
||||||
case NSClearLineFunctionKey:
|
case NSClearLineFunctionKey:
|
||||||
return KeyboardButton::num_lock();
|
return KeyboardButton::num_lock();
|
||||||
case NSClearDisplayFunctionKey:
|
case NSClearDisplayFunctionKey:
|
||||||
@ -1673,6 +1708,7 @@ map_function_key(unsigned short keycode) {
|
|||||||
case NSUndoFunctionKey:
|
case NSUndoFunctionKey:
|
||||||
case NSRedoFunctionKey:
|
case NSRedoFunctionKey:
|
||||||
case NSFindFunctionKey:
|
case NSFindFunctionKey:
|
||||||
|
break;
|
||||||
case NSHelpFunctionKey:
|
case NSHelpFunctionKey:
|
||||||
return KeyboardButton::help();
|
return KeyboardButton::help();
|
||||||
case NSModeSwitchFunctionKey:
|
case NSModeSwitchFunctionKey:
|
||||||
|
@ -23,8 +23,13 @@ class CocoaGraphicsWindow;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window;
|
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window;
|
||||||
|
- (NSOpenGLContext*) openGLContext;
|
||||||
|
- (GraphicsWindow*) graphicsWindow;
|
||||||
|
|
||||||
|
- (void) drawRect:(NSRect)dirtyRect;
|
||||||
- (void) finalize;
|
- (void) finalize;
|
||||||
- (BOOL) isFlipped;
|
- (BOOL) isFlipped;
|
||||||
|
- (BOOL) needsDisplay;
|
||||||
- (BOOL) acceptsFirstResponder;
|
- (BOOL) acceptsFirstResponder;
|
||||||
- (BOOL) becomeFirstResponder;
|
- (BOOL) becomeFirstResponder;
|
||||||
- (BOOL) resignFirstResponder;
|
- (BOOL) resignFirstResponder;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window {
|
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window {
|
||||||
self = [super initWithFrame: frameRect];
|
self = [super initWithFrame: frameRect];
|
||||||
|
|
||||||
|
_context = context;
|
||||||
|
[self setCanDrawConcurrently:YES];
|
||||||
|
|
||||||
cocoadisplay_cat.debug()
|
cocoadisplay_cat.debug()
|
||||||
<< "Created CocoaPandaView " << self << " for GraphicsWindow " << window << "\n";
|
<< "Created CocoaPandaView " << self << " for GraphicsWindow " << window << "\n";
|
||||||
_graphicsWindow = window;
|
_graphicsWindow = window;
|
||||||
@ -28,6 +31,21 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSOpenGLContext*) openGLContext {
|
||||||
|
return _context;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GraphicsWindow*) graphicsWindow {
|
||||||
|
return _graphicsWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) drawRect:(NSRect)dirtyRect {
|
||||||
|
// Do nothing. We draw from another thread.
|
||||||
|
|
||||||
|
cocoadisplay_cat.spam()
|
||||||
|
<< "drawRect was called.\n";
|
||||||
|
}
|
||||||
|
|
||||||
- (void) finalize {
|
- (void) finalize {
|
||||||
_graphicsWindow->handle_close_event();
|
_graphicsWindow->handle_close_event();
|
||||||
[super finalize];
|
[super finalize];
|
||||||
@ -39,6 +57,11 @@
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) needsDisplay {
|
||||||
|
// Never, we don't use drawRect. We draw from elsewhere.
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) acceptsFirstResponder {
|
- (BOOL) acceptsFirstResponder {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@ -59,7 +82,6 @@
|
|||||||
|
|
||||||
- (void) setFrame: (NSRect) frame {
|
- (void) setFrame: (NSRect) frame {
|
||||||
[super setFrame: frame];
|
[super setFrame: frame];
|
||||||
//[_context update];
|
|
||||||
//_graphicsWindow->handle_resize_event();
|
//_graphicsWindow->handle_resize_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +133,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) otherMouseDown: (NSEvent *) event {
|
- (void) otherMouseDown: (NSEvent *) event {
|
||||||
// 2 and 3 are swapped, for consistency with X11 implementation
|
// 1 and 2 are swapped, for consistency with X11 implementation
|
||||||
if ([event buttonNumber] == 2) {
|
if ([event buttonNumber] == 2) {
|
||||||
_graphicsWindow->handle_mouse_button_event(1, true);
|
_graphicsWindow->handle_mouse_button_event(1, true);
|
||||||
} else {
|
} else {
|
||||||
@ -124,7 +146,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) otherMouseUp: (NSEvent *) event {
|
- (void) otherMouseUp: (NSEvent *) event {
|
||||||
// 2 and 3 are swapped, for consistency with X11 implementation
|
// 1 and 2 are swapped, for consistency with X11 implementation
|
||||||
if ([event buttonNumber] == 2) {
|
if ([event buttonNumber] == 2) {
|
||||||
_graphicsWindow->handle_mouse_button_event(1, false);
|
_graphicsWindow->handle_mouse_button_event(1, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
[self setDelegate:delegate];
|
[self setDelegate:delegate];
|
||||||
[self setOpaque:YES];
|
[self setOpaque:YES];
|
||||||
[self setReleasedWhenClosed:YES];
|
[self setReleasedWhenClosed:YES];
|
||||||
|
[self setAllowsConcurrentViewDrawing:YES];
|
||||||
|
|
||||||
// Necessary to be able to accept mouseMoved in the NSView
|
// Necessary to be able to accept mouseMoved in the NSView
|
||||||
[self setAcceptsMouseMovedEvents:YES];
|
[self setAcceptsMouseMovedEvents:YES];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user