mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Brand new Cocoa display module
This commit is contained in:
parent
d1c9bee195
commit
24cdca64e7
34
panda/src/cocoadisplay/Sources.pp
Normal file
34
panda/src/cocoadisplay/Sources.pp
Normal file
@ -0,0 +1,34 @@
|
||||
#define BUILD_DIRECTORY $[and $[IS_OSX],$[HAVE_GL]]
|
||||
|
||||
#define OTHER_LIBS p3interrogatedb:c p3dconfig:c p3dtoolconfig:m \
|
||||
p3dtoolutil:c p3dtoolbase:c p3dtool:m
|
||||
|
||||
#define OSX_SYS_FRAMEWORKS ApplicationServices AppKit
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET p3cocoadisplay
|
||||
#define LOCAL_LIBS \
|
||||
p3display p3putil p3glgsg
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.mm
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
config_cocoadisplay.h \
|
||||
cocoaGraphicsPipe.h cocoaGraphicsPipe.I \
|
||||
cocoaGraphicsWindow.h cocoaGraphicsWindow.I \
|
||||
cocoaGraphicsStateGuardian.h cocoaGraphicsStateGuardian.I \
|
||||
cocoaPandaView.h cocoaPandaWindowDelegate.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_cocoadisplay.mm \
|
||||
cocoaGraphicsPipe.mm \
|
||||
cocoaGraphicsStateGuardian.mm \
|
||||
cocoaGraphicsWindow.mm \
|
||||
cocoaPandaView.mm \
|
||||
cocoaPandaWindow.mm \
|
||||
cocoaPandaWindowDelegate.mm
|
||||
|
||||
#define SOURCES \
|
||||
$[INSTALL_HEADERS]
|
||||
|
||||
#end lib_target
|
230
panda/src/cocoadisplay/cocoaGraphicsBuffer.cxx
Normal file
230
panda/src/cocoadisplay/cocoaGraphicsBuffer.cxx
Normal file
@ -0,0 +1,230 @@
|
||||
// Filename: eglGraphicsBuffer.cxx
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eglGraphicsBuffer.h"
|
||||
#include "eglGraphicsStateGuardian.h"
|
||||
#include "config_egldisplay.h"
|
||||
#include "eglGraphicsPipe.h"
|
||||
|
||||
#include "graphicsPipe.h"
|
||||
#include "pStatTimer.h"
|
||||
|
||||
TypeHandle eglGraphicsBuffer::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsBuffer::
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) :
|
||||
GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||
{
|
||||
eglGraphicsPipe *egl_pipe;
|
||||
DCAST_INTO_V(egl_pipe, _pipe);
|
||||
_pbuffer = EGL_NO_SURFACE;
|
||||
|
||||
// Since the pbuffer never gets flipped, we get screenshots from the
|
||||
// same buffer we draw into.
|
||||
_screenshot_buffer_type = _draw_buffer_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsBuffer::
|
||||
~eglGraphicsBuffer() {
|
||||
nassertv(_pbuffer == EGL_NO_SURFACE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::begin_frame
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// before beginning rendering for a given frame. It
|
||||
// should do whatever setup is required, and return true
|
||||
// if the frame should be rendered, or false if it
|
||||
// should be skipped.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool eglGraphicsBuffer::
|
||||
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||
|
||||
begin_frame_spam(mode);
|
||||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
DCAST_INTO_R(eglgsg, _gsg, false);
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
|
||||
// Now that we have made the context current to a window, we can
|
||||
// reset the GSG state if this is the first time it has been used.
|
||||
// (We can't just call reset() when we construct the GSG, because
|
||||
// reset() requires having a current context.)
|
||||
eglgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
CDLockedReader cdata(_cycler);
|
||||
for (size_t i = 0; i != cdata->_textures.size(); ++i) {
|
||||
const RenderTexture &rt = cdata->_textures[i];
|
||||
RenderTextureMode rtm_mode = rt._rtm_mode;
|
||||
if (rtm_mode == RTM_bind_or_copy) {
|
||||
CDWriter cdataw(_cycler, cdata, false);
|
||||
nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
|
||||
cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
|
||||
}
|
||||
}
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::end_frame
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// after rendering is completed for a given frame. It
|
||||
// should do whatever finalization is required.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void eglGraphicsBuffer::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
end_frame_spam(mode);
|
||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||
|
||||
if (mode == FM_render) {
|
||||
copy_to_textures();
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::close_buffer
|
||||
// Access: Protected, Virtual
|
||||
// Description: Closes the buffer right now. Called from the window
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void eglGraphicsBuffer::
|
||||
close_buffer() {
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
DCAST_INTO_V(eglgsg, _gsg);
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
_gsg.clear();
|
||||
|
||||
if (_pbuffer != EGL_NO_SURFACE) {
|
||||
if (!eglDestroySurface(_egl_display, _pbuffer)) {
|
||||
egldisplay_cat.error() << "Failed to destroy surface: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
_pbuffer = EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: eglGraphicsBuffer::open_buffer
|
||||
// Access: Protected, Virtual
|
||||
// Description: Opens the buffer right now. Called from the window
|
||||
// thread. Returns true if the buffer is successfully
|
||||
// opened, or false if there was a problem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool eglGraphicsBuffer::
|
||||
open_buffer() {
|
||||
eglGraphicsPipe *egl_pipe;
|
||||
DCAST_INTO_R(egl_pipe, _pipe, false);
|
||||
|
||||
// GSG Creation/Initialization
|
||||
eglGraphicsStateGuardian *eglgsg;
|
||||
if (_gsg == 0) {
|
||||
// There is no old gsg. Create a new one.
|
||||
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
|
||||
_gsg = eglgsg;
|
||||
} else {
|
||||
// If the old gsg has the wrong pixel format, create a
|
||||
// new one that shares with the old gsg.
|
||||
DCAST_INTO_R(eglgsg, _gsg, false);
|
||||
if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||
eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
|
||||
eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
|
||||
_gsg = eglgsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (eglgsg->_fbconfig == None) {
|
||||
// If we didn't use an fbconfig to create the GSG, we can't create
|
||||
// a PBuffer.
|
||||
return false;
|
||||
}
|
||||
|
||||
int attrib_list[] = {
|
||||
EGL_WIDTH, _x_size,
|
||||
EGL_HEIGHT, _y_size,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
_pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
|
||||
|
||||
if (_pbuffer == EGL_NO_SURFACE) {
|
||||
egldisplay_cat.error()
|
||||
<< "Failed to create EGL pbuffer surface: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent(eglgsg->_egl_display, _pbuffer, _pbuffer, eglgsg->_context)) {
|
||||
egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
|
||||
<< get_egl_error_string(eglGetError()) << "\n";
|
||||
}
|
||||
eglgsg->reset_if_new();
|
||||
if (!eglgsg->is_valid()) {
|
||||
close_buffer();
|
||||
return false;
|
||||
}
|
||||
if (!eglgsg->get_fb_properties().verify_hardware_software
|
||||
(_fb_properties, eglgsg->get_gl_renderer())) {
|
||||
close_buffer();
|
||||
return false;
|
||||
}
|
||||
_fb_properties = eglgsg->get_fb_properties();
|
||||
|
||||
_is_valid = true;
|
||||
return true;
|
||||
}
|
69
panda/src/cocoadisplay/cocoaGraphicsBuffer.h
Normal file
69
panda/src/cocoadisplay/cocoaGraphicsBuffer.h
Normal file
@ -0,0 +1,69 @@
|
||||
// Filename: eglGraphicsBuffer.h
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGLGRAPHICSBUFFER_H
|
||||
#define EGLGRAPHICSBUFFER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eglGraphicsPipe.h"
|
||||
#include "graphicsBuffer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : eglGraphicsBuffer
|
||||
// Description : An offscreen buffer in the EGL environment. This
|
||||
// creates an EGL pbuffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class eglGraphicsBuffer : public GraphicsBuffer {
|
||||
public:
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host);
|
||||
virtual ~eglGraphicsBuffer();
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
protected:
|
||||
virtual void close_buffer();
|
||||
virtual bool open_buffer();
|
||||
|
||||
private:
|
||||
X11_Display *_display;
|
||||
EGLSurface _pbuffer;
|
||||
EGLDisplay _egl_display;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GraphicsBuffer::init_type();
|
||||
register_type(_type_handle, "eglGraphicsBuffer",
|
||||
GraphicsBuffer::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif
|
36
panda/src/cocoadisplay/cocoaGraphicsPipe.I
Normal file
36
panda/src/cocoadisplay/cocoaGraphicsPipe.I
Normal file
@ -0,0 +1,36 @@
|
||||
// Filename: cocoaGraphicsPipe.I
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::get_display
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the X display associated with
|
||||
// the pipe: the display on which to create the windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE X11_Display *CocoaGraphicsPipe::
|
||||
get_display() const {
|
||||
return _display;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::get_screen
|
||||
// Access: Public
|
||||
// Description: Returns the X screen number associated with the pipe.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int CocoaGraphicsPipe::
|
||||
get_screen() const {
|
||||
return _screen;
|
||||
}
|
||||
*/
|
91
panda/src/cocoadisplay/cocoaGraphicsPipe.h
Normal file
91
panda/src/cocoadisplay/cocoaGraphicsPipe.h
Normal file
@ -0,0 +1,91 @@
|
||||
// Filename: cocoaGraphicsPipe.h
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COCOAGRAPHICSPIPE_H
|
||||
#define COCOAGRAPHICSPIPE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "graphicsWindow.h"
|
||||
#include "graphicsPipe.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
|
||||
#import <AppKit/NSScreen.h>
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
class FrameBufferProperties;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CocoaGraphicsPipe
|
||||
// Description : This graphics pipe represents the interface for
|
||||
// creating OpenGL graphics windows on a Cocoa-based
|
||||
// (e.g. Mac OS X) client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CocoaGraphicsPipe : public GraphicsPipe {
|
||||
public:
|
||||
CocoaGraphicsPipe();
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display);
|
||||
CocoaGraphicsPipe(NSScreen *screen);
|
||||
virtual ~CocoaGraphicsPipe();
|
||||
|
||||
virtual string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
public:
|
||||
virtual PreferredWindowThread get_preferred_window_thread() const;
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsOutput) make_output(const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsEngine *engine,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify);
|
||||
|
||||
private:
|
||||
void load_display_information();
|
||||
|
||||
// _display and _screen refer to the same thing,
|
||||
// NSScreen being the tiny Cocoa wrapper around the Quartz
|
||||
// display ID. NSScreen isn't generally useful, but we need
|
||||
// it when creating the window.
|
||||
CGDirectDisplayID _display;
|
||||
NSScreen *_screen;
|
||||
|
||||
friend class CocoaGraphicsWindow;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GraphicsPipe::init_type();
|
||||
register_type(_type_handle, "CocoaGraphicsPipe",
|
||||
GraphicsPipe::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "cocoaGraphicsPipe.I"
|
||||
|
||||
#endif
|
362
panda/src/cocoadisplay/cocoaGraphicsPipe.mm
Normal file
362
panda/src/cocoadisplay/cocoaGraphicsPipe.mm
Normal file
@ -0,0 +1,362 @@
|
||||
// Filename: cocoaGraphicsPipe.mm
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
//#include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "frameBufferProperties.h"
|
||||
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <AppKit/NSApplication.h>
|
||||
|
||||
TypeHandle CocoaGraphicsPipe::_type_handle;
|
||||
|
||||
static void init_app() {
|
||||
if (NSApp == nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
[NSApp setActivationPolicy: nil];
|
||||
[NSApp finishLaunching];
|
||||
[NSApp activateIgnoringOtherApps: YES];
|
||||
|
||||
//[pool release];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::Constructor
|
||||
// Access: Public
|
||||
// Description: Uses the main screen (the one the user is most
|
||||
// likely to be working in at the moment).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe() {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
|
||||
init_app();
|
||||
|
||||
_screen = [NSScreen mainScreen];
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num pointerValue];
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for main screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::Constructor
|
||||
// Access: Public
|
||||
// Description: Takes a CoreGraphics display ID.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display) {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
_display = display;
|
||||
|
||||
init_app();
|
||||
|
||||
// Iterate over the screens to find the one with our display ID.
|
||||
NSEnumerator *e = [[NSScreen screens] objectEnumerator];
|
||||
while (NSScreen *screen = (NSScreen *) [e nextObject]) {
|
||||
NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
if (display == (CGDirectDisplayID) [num pointerValue]) {
|
||||
_screen = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::Constructor
|
||||
// Access: Public
|
||||
// Description: Takes an NSScreen pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe(NSScreen *screen) {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
|
||||
init_app();
|
||||
|
||||
if (screen == nil) {
|
||||
_screen = [NSScreen mainScreen];
|
||||
} else {
|
||||
_screen = screen;
|
||||
}
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num pointerValue];
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::load_display_information
|
||||
// Access: Private
|
||||
// Description: Fills in _display_information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CocoaGraphicsPipe::
|
||||
load_display_information() {
|
||||
//TODO: read display modes and display information.
|
||||
_display_information->_vendor_id = CGDisplayVendorNumber(_display);
|
||||
//_display_information->_device_id = CGDisplayUnitNumber(_display);
|
||||
//_display_information->_device_id = CGDisplaySerialNumber(_display);
|
||||
|
||||
// Display modes
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, NULL);
|
||||
size_t num_modes = CFArrayGetCount(modes);
|
||||
_display_information->_total_display_modes = num_modes;
|
||||
_display_information->_display_mode_array = new DisplayMode[num_modes];
|
||||
|
||||
for (size_t i = 0; i < num_modes; ++i) {
|
||||
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
|
||||
_display_information->_display_mode_array[i].width = CGDisplayModeGetWidth(mode);
|
||||
_display_information->_display_mode_array[i].height = CGDisplayModeGetHeight(mode);
|
||||
_display_information->_display_mode_array[i].refresh_rate = CGDisplayModeGetRefreshRate(mode);
|
||||
_display_information->_display_mode_array[i].fullscreen_only = false;
|
||||
|
||||
// Read number of bits per pixels from the pixel encoding
|
||||
CFStringRef encoding = CGDisplayModeCopyPixelEncoding(mode);
|
||||
if (CFStringCompare(encoding, CFSTR(kIO64BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
_display_information->_display_mode_array[i].bits_per_pixel = 64;
|
||||
|
||||
} else if (CFStringCompare(encoding, CFSTR(kIO32BitFloatPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
_display_information->_display_mode_array[i].bits_per_pixel = 32;
|
||||
|
||||
} else if (CFStringCompare(encoding, CFSTR(kIO16BitFloatPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
_display_information->_display_mode_array[i].bits_per_pixel = 16;
|
||||
|
||||
} else if (CFStringCompare(encoding, CFSTR(IOYUV422Pixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo ||
|
||||
CFStringCompare(encoding, CFSTR(IO8BitOverlayPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
_display_information->_display_mode_array[i].bits_per_pixel = 8;
|
||||
} else {
|
||||
// The other possible pixel formats in IOKit/IOGraphicsTypes.h
|
||||
// have strings like "PPPP" or "-RRRRRGGGGGBBBBB", so the number
|
||||
// of bits per pixel can be deduced from the string length. Nifty!
|
||||
_display_information->_display_mode_array[i].bits_per_pixel = CFStringGetLength(encoding);
|
||||
}
|
||||
CFRelease(encoding);
|
||||
}
|
||||
CFRelease(modes);
|
||||
|
||||
#else
|
||||
CFArrayRef modes = CGDisplayAvailableModes(_display);
|
||||
size_t num_modes = CFArrayGetCount(modes);
|
||||
_display_information->_total_display_modes = num_modes;
|
||||
_display_information->_display_mode_array = new DisplayMode[num_modes];
|
||||
|
||||
for (size_t i = 0; i < num_modes; ++i) {
|
||||
CFDictionaryRef mode = (CFDictionaryRef) CFArrayGetValueAtIndex(modes, i);
|
||||
|
||||
CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(mode, kCGDisplayWidth),
|
||||
kCFNumberIntType, &_display_information->_display_mode_array[i].width);
|
||||
|
||||
CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(mode, kCGDisplayHeight),
|
||||
kCFNumberIntType, &_display_information->_display_mode_array[i].height);
|
||||
|
||||
CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(mode, kCGDisplayBitsPerPixel),
|
||||
kCFNumberIntType, &_display_information->_display_mode_array[i].bits_per_pixel);
|
||||
|
||||
CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(mode, kCGDisplayRefreshRate),
|
||||
kCFNumberIntType, &_display_information->_display_mode_array[i].refresh_rate);
|
||||
|
||||
_display_information->_display_mode_array[i].fullscreen_only = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//XXX remove when done
|
||||
cerr << *_display_information << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsPipe::
|
||||
~CocoaGraphicsPipe() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::get_interface_name
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the name of the rendering interface
|
||||
// associated with this GraphicsPipe. This is used to
|
||||
// present to the user to allow him/her to choose
|
||||
// between several possible GraphicsPipes available on a
|
||||
// particular platform, so the name should be meaningful
|
||||
// and unique for a given platform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CocoaGraphicsPipe::
|
||||
get_interface_name() const {
|
||||
return "OpenGL";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::pipe_constructor
|
||||
// Access: Public, Static
|
||||
// Description: This function is passed to the GraphicsPipeSelection
|
||||
// object to allow the user to make a default
|
||||
// CocoaGraphicsPipe.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsPipe) CocoaGraphicsPipe::
|
||||
pipe_constructor() {
|
||||
return new CocoaGraphicsPipe;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::get_preferred_window_thread
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns an indication of the thread in which this
|
||||
// GraphicsPipe requires its window processing to be
|
||||
// performed: typically either the app thread (e.g. X)
|
||||
// or the draw thread (Windows).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsPipe::PreferredWindowThread
|
||||
CocoaGraphicsPipe::get_preferred_window_thread() const {
|
||||
// The NSView and NSWindow classes are not thread-safe,
|
||||
// they can only be called from the main thread!
|
||||
return PWT_app;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsPipe::make_output
|
||||
// Access: Protected, Virtual
|
||||
// Description: Creates a new window on the pipe, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsOutput) CocoaGraphicsPipe::
|
||||
make_output(const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsEngine *engine,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify) {
|
||||
|
||||
if (!_is_valid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CocoaGraphicsStateGuardian *cocoagsg = 0;
|
||||
if (gsg != 0) {
|
||||
DCAST_INTO_R(cocoagsg, gsg, NULL);
|
||||
}
|
||||
|
||||
// First thing to try: a CocoaGraphicsWindow
|
||||
|
||||
if (retry == 0) {
|
||||
if (((flags&BF_require_parasite)!=0)||
|
||||
((flags&BF_refuse_window)!=0)||
|
||||
((flags&BF_resizeable)!=0)||
|
||||
((flags&BF_size_track_host)!=0)||
|
||||
((flags&BF_rtt_cumulative)!=0)||
|
||||
((flags&BF_can_bind_color)!=0)||
|
||||
((flags&BF_can_bind_every)!=0)) {
|
||||
return NULL;
|
||||
}
|
||||
return new CocoaGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
/*
|
||||
// Second thing to try: a GLES(2)GraphicsBuffer
|
||||
if (retry == 1) {
|
||||
if ((host==0)||
|
||||
// (!gl_support_fbo)||
|
||||
((flags&BF_require_parasite)!=0)||
|
||||
((flags&BF_require_window)!=0)) {
|
||||
return NULL;
|
||||
}
|
||||
// Early failure - if we are sure that this buffer WONT
|
||||
// meet specs, we can bail out early.
|
||||
if ((flags & BF_fb_props_optional)==0) {
|
||||
if ((fb_prop.get_indexed_color() > 0)||
|
||||
(fb_prop.get_back_buffers() > 0)||
|
||||
(fb_prop.get_accum_bits() > 0)||
|
||||
(fb_prop.get_multisamples() > 0)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Early success - if we are sure that this buffer WILL
|
||||
// meet specs, we can precertify it.
|
||||
if ((cocoagsg != 0) &&
|
||||
(cocoagsg->is_valid()) &&
|
||||
(!cocoagsg->needs_reset()) &&
|
||||
(cocoagsg->_supports_framebuffer_object) &&
|
||||
(cocoagsg->_glDrawBuffers != 0)&&
|
||||
(fb_prop.is_basic())) {
|
||||
precertify = true;
|
||||
}
|
||||
|
||||
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
|
||||
// Third thing to try: a CocoaGraphicsBuffer
|
||||
if (retry == 2) {
|
||||
if (((flags&BF_require_parasite)!=0)||
|
||||
((flags&BF_require_window)!=0)||
|
||||
((flags&BF_resizeable)!=0)||
|
||||
((flags&BF_size_track_host)!=0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!support_rtt) {
|
||||
if (((flags&BF_rtt_cumulative)!=0)||
|
||||
((flags&BF_can_bind_every)!=0)) {
|
||||
// If we require Render-to-Texture, but can't be sure we
|
||||
// support it, bail.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return new CocoaGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
*/
|
||||
|
||||
// Nothing else left to try.
|
||||
return NULL;
|
||||
}
|
26
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.I
Normal file
26
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.I
Normal file
@ -0,0 +1,26 @@
|
||||
// Filename: cocoaGraphicsStateGuardian.I
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::get_fb_properties
|
||||
// Access: Private
|
||||
// Description: Gets the FrameBufferProperties for all windows and
|
||||
// buffers that use this GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const FrameBufferProperties &CocoaGraphicsStateGuardian::
|
||||
get_fb_properties() const {
|
||||
return _fbprops;
|
||||
}
|
||||
|
||||
|
70
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.h
Normal file
70
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Filename: cocoaGraphicsStateGuardian.h
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COCOAGRAPHICSSTATEGUARDIAN_H
|
||||
#define COCOAGRAPHICSSTATEGUARDIAN_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
#include "glgsg.h"
|
||||
|
||||
#import <AppKit/NSOpenGL.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CocoaGraphicsStateGuardian
|
||||
// Description : A tiny specialization on GLGraphicsStateGuardian
|
||||
// to add some Cocoa-specific information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CocoaGraphicsStateGuardian : public GLGraphicsStateGuardian {
|
||||
public:
|
||||
INLINE const FrameBufferProperties &get_fb_properties() const;
|
||||
void get_properties(FrameBufferProperties &properties,
|
||||
NSOpenGLPixelFormat *pixel_format, int virtual_screen);
|
||||
void choose_pixel_format(const FrameBufferProperties &properties,
|
||||
CGDirectDisplayID display,
|
||||
bool need_window, bool need_pbuffer);
|
||||
|
||||
CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
CocoaGraphicsStateGuardian *share_with);
|
||||
|
||||
virtual ~CocoaGraphicsStateGuardian();
|
||||
|
||||
NSOpenGLContext *_share_context;
|
||||
NSOpenGLContext *_context;
|
||||
FrameBufferProperties _fbprops;
|
||||
|
||||
protected:
|
||||
virtual void *do_get_extension_func(const char *prefix, const char *name);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GLGraphicsStateGuardian::init_type();
|
||||
register_type(_type_handle, "CocoaGraphicsStateGuardian",
|
||||
GLGraphicsStateGuardian::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "cocoaGraphicsStateGuardian.I"
|
||||
|
||||
#endif
|
251
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm
Normal file
251
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm
Normal file
@ -0,0 +1,251 @@
|
||||
// Filename: cocoaGraphicsStateGuardian.mm
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "lightReMutexHolder.h"
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#import <OpenGL/CGLRenderers.h>
|
||||
|
||||
TypeHandle CocoaGraphicsStateGuardian::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsStateGuardian::
|
||||
CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
CocoaGraphicsStateGuardian *share_with) :
|
||||
GLGraphicsStateGuardian(engine, pipe)
|
||||
{
|
||||
_share_context = nil;
|
||||
_context = nil;
|
||||
|
||||
if (share_with != (CocoaGraphicsStateGuardian *)NULL) {
|
||||
_prepared_objects = share_with->get_prepared_objects();
|
||||
_share_context = share_with->_context;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CocoaGraphicsStateGuardian::
|
||||
~CocoaGraphicsStateGuardian() {
|
||||
if (_context != nil) {
|
||||
[_context clearDrawable];
|
||||
[_context release];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::get_properties
|
||||
// Access: Private
|
||||
// Description: Gets the FrameBufferProperties to match the
|
||||
// indicated config.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CocoaGraphicsStateGuardian::
|
||||
get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_format, int screen) {
|
||||
|
||||
properties.clear();
|
||||
|
||||
// Now update our framebuffer_mode and bit depth appropriately.
|
||||
GLint double_buffer, stereo, aux_buffers, color_size, alpha_size,
|
||||
depth_size, stencil_size, accum_size, sample_buffers, samples,
|
||||
renderer_id, accelerated, window, pbuffer;
|
||||
|
||||
[pixel_format getValues: &double_buffer forAttribute: NSOpenGLPFADoubleBuffer forVirtualScreen: screen];
|
||||
[pixel_format getValues: &stereo forAttribute: NSOpenGLPFAStereo forVirtualScreen: screen];
|
||||
[pixel_format getValues: &aux_buffers forAttribute: NSOpenGLPFAAuxBuffers forVirtualScreen: screen];
|
||||
[pixel_format getValues: &color_size forAttribute: NSOpenGLPFAColorSize forVirtualScreen: screen];
|
||||
[pixel_format getValues: &alpha_size forAttribute: NSOpenGLPFAAlphaSize forVirtualScreen: screen];
|
||||
[pixel_format getValues: &depth_size forAttribute: NSOpenGLPFADepthSize forVirtualScreen: screen];
|
||||
[pixel_format getValues: &stencil_size forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: screen];
|
||||
[pixel_format getValues: &accum_size forAttribute: NSOpenGLPFAAccumSize forVirtualScreen: screen];
|
||||
[pixel_format getValues: &sample_buffers forAttribute: NSOpenGLPFASampleBuffers forVirtualScreen: screen];
|
||||
[pixel_format getValues: &samples forAttribute: NSOpenGLPFASamples forVirtualScreen: screen];
|
||||
[pixel_format getValues: &renderer_id forAttribute: NSOpenGLPFARendererID forVirtualScreen: screen];
|
||||
[pixel_format getValues: &accelerated forAttribute: NSOpenGLPFAAccelerated forVirtualScreen: screen];
|
||||
[pixel_format getValues: &window forAttribute: NSOpenGLPFAWindow forVirtualScreen: screen];
|
||||
[pixel_format getValues: &pbuffer forAttribute: NSOpenGLPFAPixelBuffer forVirtualScreen: screen];
|
||||
|
||||
properties.set_back_buffers(double_buffer);
|
||||
properties.set_stereo(stereo);
|
||||
properties.set_rgb_color(1);
|
||||
properties.set_color_bits(color_size);
|
||||
properties.set_stencil_bits(stencil_size);
|
||||
properties.set_depth_bits(depth_size);
|
||||
properties.set_alpha_bits(alpha_size);
|
||||
properties.set_accum_bits(accum_size);
|
||||
if (sample_buffers > 0) {
|
||||
properties.set_multisamples(samples);
|
||||
}
|
||||
//TODO: add aux buffers
|
||||
|
||||
if (renderer_id == kCGLRendererGenericID ||
|
||||
renderer_id == kCGLRendererGenericFloatID ||
|
||||
renderer_id == kCGLRendererAppleSWID) {
|
||||
properties.set_force_software(1);
|
||||
}
|
||||
if (accelerated) {
|
||||
properties.set_force_hardware(1);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::choose_pixel_format
|
||||
// Access: Private
|
||||
// Description: Selects a visual or fbconfig for all the windows
|
||||
// and buffers that use this gsg. Also creates the GL
|
||||
// context and obtains the visual.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CocoaGraphicsStateGuardian::
|
||||
choose_pixel_format(const FrameBufferProperties &properties,
|
||||
CGDirectDisplayID display,
|
||||
bool need_window, bool need_pbuffer) {
|
||||
|
||||
_context = nil;
|
||||
_fbprops.clear();
|
||||
|
||||
// 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
|
||||
// with the properties we have requested.
|
||||
pvector<NSOpenGLPixelFormatAttribute> attribs;
|
||||
attribs.reserve(13);
|
||||
|
||||
// Picked this up from the pyglet source - seems
|
||||
// to be necessary to support RAGE-II, which is not compliant.
|
||||
attribs.push_back(NSOpenGLPFAAllRenderers);
|
||||
|
||||
// Don't let it fall back to a different renderer.
|
||||
attribs.push_back(NSOpenGLPFANoRecovery);
|
||||
|
||||
// Selection policy.
|
||||
//attribs.push_back(NSOpenGLPFAMinimumPolicy);
|
||||
|
||||
if (!properties.is_single_buffered()) {
|
||||
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
||||
}
|
||||
|
||||
if (properties.is_stereo()) {
|
||||
attribs.push_back(NSOpenGLPFAStereo);
|
||||
}
|
||||
|
||||
int aux_buffers = properties.get_aux_rgba() + properties.get_aux_hrgba() + properties.get_aux_float();
|
||||
attribs.push_back(NSOpenGLPFAAuxBuffers);
|
||||
attribs.push_back(aux_buffers);
|
||||
attribs.push_back(NSOpenGLPFAColorSize);
|
||||
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(properties.get_depth_bits());
|
||||
attribs.push_back(NSOpenGLPFAStencilSize);
|
||||
attribs.push_back(properties.get_stencil_bits());
|
||||
|
||||
if (properties.get_multisamples() > 0) {
|
||||
attribs.push_back(NSOpenGLPFASampleBuffers);
|
||||
attribs.push_back(1);
|
||||
attribs.push_back(NSOpenGLPFASamples);
|
||||
attribs.push_back(properties.get_multisamples());
|
||||
attribs.push_back(NSOpenGLPFAMultisample);
|
||||
}
|
||||
|
||||
if (properties.get_force_software()) {
|
||||
attribs.push_back(NSOpenGLPFARendererID);
|
||||
attribs.push_back(kCGLRendererAppleSWID);
|
||||
}
|
||||
|
||||
if (properties.get_force_hardware()) {
|
||||
attribs.push_back(NSOpenGLPFAAccelerated);
|
||||
}
|
||||
|
||||
if (need_window) {
|
||||
//TODO: fullscreen != window on OSX
|
||||
attribs.push_back(NSOpenGLPFAWindow);
|
||||
//attribs.push_back(NSOpenGLPFAFullScreen);
|
||||
}
|
||||
|
||||
if (need_pbuffer) {
|
||||
attribs.push_back(NSOpenGLPFAPixelBuffer);
|
||||
}
|
||||
|
||||
// Required when going fullscreen, optional when windowed
|
||||
attribs.push_back(NSOpenGLPFAScreenMask);
|
||||
attribs.push_back(CGDisplayIDToOpenGLDisplayMask(display));
|
||||
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) nil);
|
||||
|
||||
// Create the format.
|
||||
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: &attribs[0]];
|
||||
if (format == nil) {
|
||||
cocoadisplay_cat.error() <<
|
||||
"Could not find a usable pixel format.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
//XXX not sure what to do with virtual_screen, let's just set it to 0.
|
||||
get_properties(_fbprops, format, 0);
|
||||
_context = [[NSOpenGLContext alloc] initWithFormat: format shareContext: _share_context];
|
||||
[format release];
|
||||
if (_context == nil) {
|
||||
cocoadisplay_cat.error() <<
|
||||
"Failed to create OpenGL context!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Set vsync setting on the context
|
||||
GLint swap = sync_video ? 1 : 0;
|
||||
[_context setValues:&swap forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Created context " << _context << ": " << _fbprops << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsStateGuardian::do_get_extension_func
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the pointer to the GL extension function with
|
||||
// the indicated name. It is the responsibility of the
|
||||
// caller to ensure that the required extension is
|
||||
// defined in the OpenGL runtime prior to calling this;
|
||||
// it is an error to call this for a function that is
|
||||
// not defined.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void *CocoaGraphicsStateGuardian::
|
||||
do_get_extension_func(const char *prefix, const char *name) {
|
||||
char* fullname = (char*) malloc(strlen(prefix) + strlen(name) + 2);
|
||||
strcpy(fullname + 1, prefix);
|
||||
strcpy(fullname + 1 + strlen(prefix), name);
|
||||
fullname[0] = '_';
|
||||
|
||||
// Believe it or not, but this is actually the
|
||||
// Apple-recommended way to do it. I know, right?
|
||||
|
||||
if (NSIsSymbolNameDefined(fullname)) {
|
||||
NSSymbol symbol = NSLookupAndBindSymbol(fullname);
|
||||
free(fullname);
|
||||
return (void *) NSAddressOfSymbol(symbol);
|
||||
}
|
||||
|
||||
cocoadisplay_cat.error() <<
|
||||
"do_get_extension_func failed for " << prefix << name << "!\n";
|
||||
|
||||
free(fullname);
|
||||
return NULL;
|
||||
}
|
34
panda/src/cocoadisplay/cocoaGraphicsWindow.I
Normal file
34
panda/src/cocoadisplay/cocoaGraphicsWindow.I
Normal file
@ -0,0 +1,34 @@
|
||||
// Filename: cocoaGraphicsWindow.I
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::get_nswindow
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the underlying NSWindow.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NSWindow *CocoaGraphicsWindow::
|
||||
get_nswindow() const {
|
||||
return _window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::get_nsview
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the underlying NSView.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NSView *CocoaGraphicsWindow::
|
||||
get_nsview() const {
|
||||
return _view;
|
||||
}
|
105
panda/src/cocoadisplay/cocoaGraphicsWindow.h
Normal file
105
panda/src/cocoadisplay/cocoaGraphicsWindow.h
Normal file
@ -0,0 +1,105 @@
|
||||
// Filename: cocoaGraphicsWindow.h
|
||||
// Created by: rdb (14May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COCOAGRAPHICSWINDOW_H
|
||||
#define COCOAGRAPHICSWINDOW_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
#include "graphicsWindow.h"
|
||||
|
||||
#import <AppKit/NSEvent.h>
|
||||
#import <AppKit/NSView.h>
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CocoaGraphicsWindow
|
||||
// Description : An interface to the Cocoa system for managing
|
||||
// OpenGL windows under Mac OS X.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CocoaGraphicsWindow : public GraphicsWindow {
|
||||
public:
|
||||
CocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host);
|
||||
virtual ~CocoaGraphicsWindow();
|
||||
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_flip();
|
||||
|
||||
virtual void process_events();
|
||||
virtual void set_properties_now(WindowProperties &properties);
|
||||
|
||||
void handle_move_event();
|
||||
void handle_resize_event();
|
||||
void handle_minimize_event(bool minimized);
|
||||
void handle_foreground_event(bool foreground);
|
||||
bool handle_close_request();
|
||||
void handle_close_event();
|
||||
void handle_key_event(NSEvent *event);
|
||||
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_wheel_event(double x, double y);
|
||||
|
||||
INLINE NSWindow *get_nswindow() const;
|
||||
INLINE NSView *get_nsview() const;
|
||||
|
||||
protected:
|
||||
virtual void close_window();
|
||||
virtual bool open_window();
|
||||
|
||||
virtual void mouse_mode_absolute();
|
||||
virtual void mouse_mode_relative();
|
||||
|
||||
private:
|
||||
void set_wm_properties(const WindowProperties &properties,
|
||||
bool already_mapped);
|
||||
|
||||
ButtonHandle map_function_key(unsigned short keycode);
|
||||
|
||||
private:
|
||||
NSWindow *_window;
|
||||
NSView *_view;
|
||||
NSUInteger _modifier_keys;
|
||||
CGDirectDisplayID _display;
|
||||
bool _mouse_hidden;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GraphicsWindow::init_type();
|
||||
register_type(_type_handle, "CocoaGraphicsWindow",
|
||||
GraphicsWindow::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "cocoaGraphicsWindow.I"
|
||||
|
||||
#endif
|
1239
panda/src/cocoadisplay/cocoaGraphicsWindow.mm
Normal file
1239
panda/src/cocoadisplay/cocoaGraphicsWindow.mm
Normal file
File diff suppressed because it is too large
Load Diff
53
panda/src/cocoadisplay/cocoaPandaView.h
Normal file
53
panda/src/cocoadisplay/cocoaPandaView.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Filename: cocoaPandaView.h
|
||||
// Created by: rdb (17May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import <AppKit/NSView.h>
|
||||
|
||||
class CocoaGraphicsWindow;
|
||||
|
||||
@interface CocoaPandaView : NSView {
|
||||
@private
|
||||
NSOpenGLContext *_context;
|
||||
CocoaGraphicsWindow *_graphicsWindow;
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window;
|
||||
- (BOOL) acceptsFirstResponder;
|
||||
- (BOOL) becomeFirstResponder;
|
||||
- (BOOL) resignFirstResponder;
|
||||
|
||||
- (void) setFrame: (NSRect) frame;
|
||||
|
||||
// Keyboard events
|
||||
- (void) keyDown: (NSEvent *) event;
|
||||
- (void) keyUp: (NSEvent *) event;
|
||||
- (void) flagsChanged: (NSEvent *) event;
|
||||
|
||||
// Mouse events
|
||||
- (void) mouseDown: (NSEvent *) event;
|
||||
- (void) mouseDragged: (NSEvent *) event;
|
||||
- (void) mouseUp: (NSEvent *) event;
|
||||
- (void) mouseMoved: (NSEvent *) event;
|
||||
- (void) rightMouseDown: (NSEvent *) event;
|
||||
- (void) rightMouseDragged: (NSEvent *) event;
|
||||
- (void) rightMouseUp: (NSEvent *) event;
|
||||
- (void) otherMouseDown: (NSEvent *) event;
|
||||
- (void) otherMouseDragged: (NSEvent *) event;
|
||||
- (void) otherMouseUp: (NSEvent *) event;
|
||||
|
||||
- (void) scrollWheel: (NSEvent *) event;
|
||||
|
||||
- (BOOL) isOpaque;
|
||||
|
||||
@end
|
129
panda/src/cocoadisplay/cocoaPandaView.mm
Normal file
129
panda/src/cocoadisplay/cocoaPandaView.mm
Normal file
@ -0,0 +1,129 @@
|
||||
// Filename: cocoaPandaView.mm
|
||||
// Created by: rdb (17May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "cocoaPandaView.h"
|
||||
#import "cocoaGraphicsWindow.h"
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
@implementation CocoaPandaView
|
||||
- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window {
|
||||
self = [super initWithFrame: frameRect];
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Created CocoaPandaView " << self << " for GraphicsWindow " << window << "\n";
|
||||
_graphicsWindow = window;
|
||||
|
||||
// Make sure that the view automatically resizes with the window
|
||||
//[self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) becomeFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) resignFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) setFrame: (NSRect) frame {
|
||||
[super setFrame: frame];
|
||||
[_context update];
|
||||
|
||||
_graphicsWindow->handle_resize_event();
|
||||
}
|
||||
|
||||
- (void) keyDown: (NSEvent *) event {
|
||||
_graphicsWindow->handle_key_event(event);
|
||||
}
|
||||
|
||||
- (void) keyUp: (NSEvent *) event {
|
||||
_graphicsWindow->handle_key_event(event);
|
||||
}
|
||||
|
||||
- (void) flagsChanged: (NSEvent *) event {
|
||||
_graphicsWindow->handle_key_event(event);
|
||||
}
|
||||
|
||||
- (void) mouseDown: (NSEvent *) event {
|
||||
_graphicsWindow->handle_mouse_button_event(0, true);
|
||||
}
|
||||
|
||||
- (void) mouseDragged: (NSEvent *) event {
|
||||
[self mouseMoved: event];
|
||||
}
|
||||
|
||||
- (void) mouseUp: (NSEvent *) event {
|
||||
_graphicsWindow->handle_mouse_button_event(0, false);
|
||||
}
|
||||
|
||||
- (void) mouseMoved: (NSEvent *) event {
|
||||
NSPoint loc = [self convertPoint: [event locationInWindow] fromView: nil];
|
||||
BOOL inside = [self mouse: loc inRect: [self bounds]];
|
||||
|
||||
if (_graphicsWindow->get_properties().get_mouse_mode() == WindowProperties::M_relative) {
|
||||
_graphicsWindow->handle_mouse_moved_event(inside, [event deltaX], [event deltaY], false);
|
||||
} else {
|
||||
_graphicsWindow->handle_mouse_moved_event(inside, loc.x, [self bounds].size.height - loc.y, true);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) rightMouseDown: (NSEvent *) event {
|
||||
_graphicsWindow->handle_mouse_button_event(2, true);
|
||||
}
|
||||
|
||||
- (void) rightMouseDragged: (NSEvent *) event {
|
||||
[self mouseMoved: event];
|
||||
}
|
||||
|
||||
- (void) rightMouseUp: (NSEvent *) event {
|
||||
_graphicsWindow->handle_mouse_button_event(2, false);
|
||||
}
|
||||
|
||||
- (void) otherMouseDown: (NSEvent *) event {
|
||||
// 2 and 3 are swapped, for consistency with X11 implementation
|
||||
if ([event buttonNumber] == 2) {
|
||||
_graphicsWindow->handle_mouse_button_event(1, true);
|
||||
} else {
|
||||
_graphicsWindow->handle_mouse_button_event([event buttonNumber], true);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) otherMouseDragged: (NSEvent *) event {
|
||||
[self mouseMoved: event];
|
||||
}
|
||||
|
||||
- (void) otherMouseUp: (NSEvent *) event {
|
||||
// 2 and 3 are swapped, for consistency with X11 implementation
|
||||
if ([event buttonNumber] == 2) {
|
||||
_graphicsWindow->handle_mouse_button_event(1, false);
|
||||
} else {
|
||||
_graphicsWindow->handle_mouse_button_event([event buttonNumber], false);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) scrollWheel: (NSEvent *) event {
|
||||
_graphicsWindow->handle_wheel_event([event deltaX], [event deltaY]);
|
||||
}
|
||||
|
||||
- (BOOL) isOpaque {
|
||||
return YES;
|
||||
}
|
||||
@end
|
27
panda/src/cocoadisplay/cocoaPandaWindow.h
Normal file
27
panda/src/cocoadisplay/cocoaPandaWindow.h
Normal file
@ -0,0 +1,27 @@
|
||||
// Filename: cocoaPandaWindow.h
|
||||
// Created by: rdb (25May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
class CocoaGraphicsWindow;
|
||||
|
||||
@interface CocoaPandaWindow : NSWindow {
|
||||
@private
|
||||
CocoaGraphicsWindow *_graphicsWindow;
|
||||
}
|
||||
|
||||
- (id) initWithContentRect:(NSRect)rect styleMask:(NSUInteger)styleMask screen:(NSScreen*)screen window:(CocoaGraphicsWindow*)window;
|
||||
- (BOOL)canBecomeKeyWindow;
|
||||
|
||||
@end
|
44
panda/src/cocoadisplay/cocoaPandaWindow.mm
Normal file
44
panda/src/cocoadisplay/cocoaPandaWindow.mm
Normal file
@ -0,0 +1,44 @@
|
||||
// Filename: cocoaPandaWindow.mm
|
||||
// Created by: rdb (25May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "cocoaPandaWindow.h"
|
||||
#import "cocoaPandaWindowDelegate.h"
|
||||
|
||||
@implementation CocoaPandaWindow
|
||||
- (id) initWithContentRect:(NSRect)rect styleMask:(NSUInteger)styleMask screen:(NSScreen*)screen window:(CocoaGraphicsWindow*)window {
|
||||
|
||||
if (self = [super initWithContentRect:rect
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES
|
||||
screen:screen]) {
|
||||
_graphicsWindow = window;
|
||||
|
||||
CocoaPandaWindowDelegate *delegate = [[CocoaPandaWindowDelegate alloc] initWithGraphicsWindow:window];
|
||||
[self setDelegate:delegate];
|
||||
[self setOpaque:YES];
|
||||
|
||||
// Necessary to be able to accept mouseMoved in the NSView
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) canBecomeKeyWindow {
|
||||
// Otherwise borderless windows won't be able to get keyboard events.
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
36
panda/src/cocoadisplay/cocoaPandaWindowDelegate.h
Normal file
36
panda/src/cocoadisplay/cocoaPandaWindowDelegate.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Filename: cocoaPandaWindowDelegate.h
|
||||
// Created by: rdb (24May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
class CocoaGraphicsWindow;
|
||||
|
||||
@interface CocoaPandaWindowDelegate : NSObject<NSWindowDelegate> {
|
||||
@private
|
||||
CocoaGraphicsWindow *_graphicsWindow;
|
||||
}
|
||||
|
||||
- (id) initWithGraphicsWindow:(CocoaGraphicsWindow*)window;
|
||||
- (void)windowDidMove:(NSNotification *)notification;
|
||||
- (void)windowDidResize:(NSNotification *)notification;
|
||||
- (void)windowDidMiniaturize:(NSNotification *)notification;
|
||||
- (void)windowDidDeminiaturize:(NSNotification *)notification;
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
||||
- (void)windowDidResignKey:(NSNotification *)notification;
|
||||
- (BOOL)windowShouldClose:(id)sender;
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
|
||||
//TODO: handle fullscreen on Lion.
|
||||
|
||||
@end
|
61
panda/src/cocoadisplay/cocoaPandaWindowDelegate.mm
Normal file
61
panda/src/cocoadisplay/cocoaPandaWindowDelegate.mm
Normal file
@ -0,0 +1,61 @@
|
||||
// Filename: cocoaPandaWindowDelegate.mm
|
||||
// Created by: rdb (24May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "cocoaPandaWindowDelegate.h"
|
||||
|
||||
@implementation CocoaPandaWindowDelegate
|
||||
- (id) initWithGraphicsWindow:(CocoaGraphicsWindow*)window {
|
||||
|
||||
if (self = [super init]) {
|
||||
_graphicsWindow = window;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) windowDidMove:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_move_event();
|
||||
}
|
||||
|
||||
- (void) windowDidResize:(NSNotification *)notification {
|
||||
// Forcing a move event is unfortunately necessary because
|
||||
// Cocoa does not call windowDidMove in case of window zooms.
|
||||
_graphicsWindow->handle_resize_event();
|
||||
}
|
||||
|
||||
- (void) windowDidMiniaturize:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_minimize_event(true);
|
||||
}
|
||||
|
||||
- (void) windowDidDeminiaturize:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_minimize_event(false);
|
||||
}
|
||||
|
||||
- (void) windowDidBecomeKey:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_foreground_event(true);
|
||||
}
|
||||
|
||||
- (void) windowDidResignKey:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_foreground_event(false);
|
||||
}
|
||||
|
||||
- (BOOL) windowShouldClose:(id)sender {
|
||||
return _graphicsWindow->handle_close_request();
|
||||
}
|
||||
|
||||
- (void) windowWillClose:(NSNotification *)notification {
|
||||
_graphicsWindow->handle_close_event();
|
||||
}
|
||||
|
||||
@end
|
25
panda/src/cocoadisplay/config_cocoadisplay.h
Normal file
25
panda/src/cocoadisplay/config_cocoadisplay.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Filename: config_cocoadisplay.h
|
||||
// Created by: rdb (17May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CONFIG_COCOADISPLAY_H
|
||||
#define CONFIG_COCOADISPLAY_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "notifyCategoryProxy.h"
|
||||
|
||||
NotifyCategoryDecl(cocoadisplay, EXPCL_PANDAGL, EXPTP_PANDAGL);
|
||||
|
||||
extern EXPCL_PANDAGL void init_libcocoadisplay();
|
||||
|
||||
#endif
|
56
panda/src/cocoadisplay/config_cocoadisplay.mm
Normal file
56
panda/src/cocoadisplay/config_cocoadisplay.mm
Normal file
@ -0,0 +1,56 @@
|
||||
// Filename: config_cocoadisplay.cxx
|
||||
// Created by: rdb (17May12)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "graphicsPipeSelection.h"
|
||||
#include "dconfig.h"
|
||||
#include "pandaSystem.h"
|
||||
|
||||
Configure(config_cocoadisplay);
|
||||
NotifyCategoryDef(cocoadisplay, "display");
|
||||
|
||||
ConfigureFn(config_cocoadisplay) {
|
||||
init_libcocoadisplay();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libcocoadisplay
|
||||
// Description: Initializes the library. This must be called at
|
||||
// least once before any of the functions or classes in
|
||||
// this library can be used. Normally it will be
|
||||
// called by the static initializers and need not be
|
||||
// called explicitly, but special cases exist.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
init_libcocoadisplay() {
|
||||
static bool initialized = false;
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
CocoaGraphicsPipe::init_type();
|
||||
CocoaGraphicsStateGuardian::init_type();
|
||||
CocoaGraphicsWindow::init_type();
|
||||
|
||||
GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
|
||||
selection->add_pipe_type(CocoaGraphicsPipe::get_class_type(),
|
||||
CocoaGraphicsPipe::pipe_constructor);
|
||||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
ps->set_system_tag("OpenGL", "window_system", "Cocoa");
|
||||
}
|
7
panda/src/cocoadisplay/p3cocoadisplay_composite1.mm
Normal file
7
panda/src/cocoadisplay/p3cocoadisplay_composite1.mm
Normal file
@ -0,0 +1,7 @@
|
||||
#include "config_cocoadisplay.mm"
|
||||
#include "cocoaGraphicsPipe.mm"
|
||||
#include "cocoaGraphicsStateGuardian.mm"
|
||||
#include "cocoaGraphicsWindow.mm"
|
||||
#include "cocoaPandaView.mm"
|
||||
#include "cocoaPandaWindow.mm"
|
||||
#include "cocoaPandaWindowDelegate.mm"
|
Loading…
x
Reference in New Issue
Block a user