mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
WxPandaWindow
This commit is contained in:
parent
ce696a157e
commit
56f22e0692
@ -559,11 +559,18 @@ class ShowBase(DirectObject.DirectObject):
|
||||
def openWindow(self, props = None, pipe = None, gsg = None,
|
||||
type = None, name = None, size = None, aspectRatio = None,
|
||||
makeCamera = 1, keepCamera = 0,
|
||||
scene = None, stereo = None, rawmice = 0):
|
||||
scene = None, stereo = None, rawmice = 0,
|
||||
callbackWindowDict = None):
|
||||
"""
|
||||
Creates a window and adds it to the list of windows that are
|
||||
to be updated every frame.
|
||||
|
||||
If callbackWindowDict is not None, a CallbackGraphicWindow is
|
||||
created instead, which allows the caller to create the actual
|
||||
window with its own OpenGL context, and direct Panda's
|
||||
rendering into that window.
|
||||
"""
|
||||
|
||||
if pipe == None:
|
||||
pipe = self.pipe
|
||||
|
||||
@ -614,6 +621,9 @@ class ShowBase(DirectObject.DirectObject):
|
||||
elif type == 'offscreen':
|
||||
flags = flags | GraphicsPipe.BFRefuseWindow
|
||||
|
||||
if callbackWindowDict:
|
||||
flags = flags | GraphicsPipe.BFRequireCallbackWindow
|
||||
|
||||
if gsg:
|
||||
win = self.graphicsEngine.makeOutput(pipe, name, 0, fbprops,
|
||||
props, flags, gsg)
|
||||
@ -625,6 +635,23 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# Couldn't create a window!
|
||||
return None
|
||||
|
||||
if callbackWindowDict:
|
||||
# If we asked for (and received) a CallbackGraphicsWindow,
|
||||
# we now have to assign the callbacks, before we start
|
||||
# trying to do anything with the window.
|
||||
for callbackName in ['Events', 'Properties', 'Render']:
|
||||
func = callbackWindowDict.get(callbackName, None)
|
||||
if not func:
|
||||
continue
|
||||
|
||||
setCallbackName = 'set%sCallback' % (callbackName)
|
||||
setCallback = getattr(win, setCallbackName)
|
||||
setCallback(PythonCallbackObject(func))
|
||||
|
||||
# We also need to set up the mouse/keyboard objects.
|
||||
for inputName in callbackWindowDict.get('inputDevices', ['mouse']):
|
||||
win.createInputDevice(inputName)
|
||||
|
||||
if hasattr(win, "requestProperties"):
|
||||
win.requestProperties(props)
|
||||
|
||||
|
@ -2,16 +2,20 @@ import wx
|
||||
from direct.task.Task import Task
|
||||
|
||||
def wxLoop(self):
|
||||
# Do all the wxPython events waiting on this frame
|
||||
# First we need to ensure that the OS message queue is processed.
|
||||
base.wxApp.Yield()
|
||||
|
||||
# Now do all the wxPython events waiting on this frame.
|
||||
while base.wxApp.Pending():
|
||||
base.wxApp.Dispatch()
|
||||
|
||||
return Task.cont
|
||||
|
||||
def spawnWxLoop():
|
||||
if not getattr(base, 'wxApp', None):
|
||||
# Create a new base.wxApp, but only if it's not already
|
||||
# created.
|
||||
base.wxApp = wx.App(False)
|
||||
base.wxApp = wx.PySimpleApp(redirect = False)
|
||||
|
||||
# Spawn this task
|
||||
taskMgr.add(wxLoop, "wxLoop")
|
||||
|
206
direct/src/showbase/WxPandaWindow.py
Normal file
206
direct/src/showbase/WxPandaWindow.py
Normal file
@ -0,0 +1,206 @@
|
||||
""" This module implements a Panda3D window that can be embedded
|
||||
within a wx.Frame. The window itself is either an embedded window,
|
||||
which is a wx.Window with the Panda window attached to it, or it is a
|
||||
wxgl.GLCanvas, with Panda directed to draw into it, depending on the
|
||||
platform. In either case, you may simply embed this window into a
|
||||
wx.Frame of your choosing, using sizers or whatever you like. """
|
||||
|
||||
import wx
|
||||
import platform
|
||||
|
||||
try:
|
||||
import wx.glcanvas as wxgl
|
||||
except ImportError:
|
||||
wxgl = None
|
||||
|
||||
from panda3d.core import *
|
||||
|
||||
__all__ = ['WxPandaWindow']
|
||||
|
||||
if platform.system() != 'Darwin':
|
||||
class EmbeddedPandaWindow(wx.Window):
|
||||
""" This class implements a Panda3D window that is directly
|
||||
embedded within the frame. It is fully supported on Windows,
|
||||
partially supported on Linux, and not at all on OSX. """
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
wx.Window.__init__(self, *args, **kw)
|
||||
|
||||
wp = WindowProperties.getDefault()
|
||||
wp.setParentWindow(self.GetHandle())
|
||||
|
||||
if base.win:
|
||||
self.win = base.openWindow(props = wp)
|
||||
else:
|
||||
base.openDefaultWindow(props = wp)
|
||||
self.win = base.win
|
||||
|
||||
self.Bind(wx.EVT_SIZE, self.__resized)
|
||||
|
||||
def __resized(self, event):
|
||||
wp = WindowProperties()
|
||||
wp.setOrigin(0, 0)
|
||||
wp.setSize(*self.GetClientSizeTuple())
|
||||
self.win.requestProperties(wp)
|
||||
|
||||
if hasattr(wxgl, 'GLCanvas'):
|
||||
class OpenGLPandaWindow(wxgl.GLCanvas):
|
||||
""" This class implements a Panda3D "window" that actually draws
|
||||
within the wx GLCanvas object. It is supported whenever OpenGL is
|
||||
Panda's rendering engine, and GLCanvas is available in wx. """
|
||||
|
||||
Keymap = {
|
||||
wx.WXK_BACK : KeyboardButton.backspace(),
|
||||
wx.WXK_TAB : KeyboardButton.tab(),
|
||||
wx.WXK_RETURN : KeyboardButton.enter(),
|
||||
wx.WXK_ESCAPE : KeyboardButton.escape(),
|
||||
wx.WXK_DELETE : KeyboardButton._del(), # del is a Python keyword
|
||||
wx.WXK_SHIFT : KeyboardButton.shift(),
|
||||
wx.WXK_ALT : KeyboardButton.alt(),
|
||||
wx.WXK_CONTROL : KeyboardButton.control(),
|
||||
wx.WXK_MENU : KeyboardButton.meta(),
|
||||
wx.WXK_PAUSE : KeyboardButton.pause(),
|
||||
wx.WXK_END : KeyboardButton.end(),
|
||||
wx.WXK_HOME : KeyboardButton.home(),
|
||||
wx.WXK_LEFT : KeyboardButton.left(),
|
||||
wx.WXK_UP : KeyboardButton.up(),
|
||||
wx.WXK_RIGHT : KeyboardButton.right(),
|
||||
wx.WXK_DOWN : KeyboardButton.down(),
|
||||
wx.WXK_PRINT : KeyboardButton.printScreen(),
|
||||
wx.WXK_INSERT : KeyboardButton.insert(),
|
||||
wx.WXK_F1 : KeyboardButton.f1(),
|
||||
wx.WXK_F2 : KeyboardButton.f2(),
|
||||
wx.WXK_F3 : KeyboardButton.f3(),
|
||||
wx.WXK_F4 : KeyboardButton.f4(),
|
||||
wx.WXK_F5 : KeyboardButton.f5(),
|
||||
wx.WXK_F6 : KeyboardButton.f6(),
|
||||
wx.WXK_F7 : KeyboardButton.f7(),
|
||||
wx.WXK_F8 : KeyboardButton.f8(),
|
||||
wx.WXK_F9 : KeyboardButton.f9(),
|
||||
wx.WXK_F10 : KeyboardButton.f10(),
|
||||
wx.WXK_F11 : KeyboardButton.f11(),
|
||||
wx.WXK_F12 : KeyboardButton.f12(),
|
||||
wx.WXK_NUMLOCK : KeyboardButton.numLock(),
|
||||
wx.WXK_SCROLL : KeyboardButton.scrollLock(),
|
||||
wx.WXK_PAGEUP : KeyboardButton.pageUp(),
|
||||
wx.WXK_PAGEDOWN : KeyboardButton.pageDown(),
|
||||
wx.WXK_COMMAND : KeyboardButton.meta(),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
wxgl.GLCanvas.__init__(self, *args, **kw)
|
||||
|
||||
callbackWindowDict = {
|
||||
'Events' : self.__eventsCallback,
|
||||
'Properties' : self.__propertiesCallback,
|
||||
'Render' : self.__renderCallback,
|
||||
}
|
||||
|
||||
# Make sure we have an OpenGL GraphicsPipe.
|
||||
if not base.pipe:
|
||||
base.makeDefaultPipe()
|
||||
pipe = base.pipe
|
||||
if pipe.getInterfaceName() != 'OpenGL':
|
||||
base.makeAllPipes()
|
||||
for pipe in base.pipeList:
|
||||
if pipe.getInterfaceName() == 'OpenGL':
|
||||
break
|
||||
|
||||
if pipe.getInterfaceName() != 'OpenGL':
|
||||
raise StandardError, "Couldn't get an OpenGL pipe."
|
||||
|
||||
self.SetCurrent()
|
||||
if base.win:
|
||||
self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe)
|
||||
else:
|
||||
base.openDefaultWindow(callbackWindowDict = callbackWindowDict, pipe = pipe)
|
||||
self.win = base.win
|
||||
|
||||
self.inputDevice = self.win.getInputDevice(0)
|
||||
|
||||
self.Bind(wx.EVT_SIZE, self.__resized)
|
||||
self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one()))
|
||||
self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one()))
|
||||
self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two()))
|
||||
self.Bind(wx.EVT_MIDDLE_UP, lambda event: self.__buttonUp(MouseButton.two()))
|
||||
self.Bind(wx.EVT_RIGHT_DOWN, lambda event: self.__buttonDown(MouseButton.three()))
|
||||
self.Bind(wx.EVT_RIGHT_UP, lambda event: self.__buttonUp(MouseButton.three()))
|
||||
self.Bind(wx.EVT_MOTION, self.__mouseMotion)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.__mouseLeaveWindow)
|
||||
self.Bind(wx.EVT_KEY_DOWN, self.__keyDown)
|
||||
self.Bind(wx.EVT_KEY_UP, self.__keyUp)
|
||||
self.Bind(wx.EVT_CHAR, self.__keystroke)
|
||||
|
||||
def __buttonDown(self, button):
|
||||
self.inputDevice.buttonDown(button)
|
||||
|
||||
def __buttonUp(self, button):
|
||||
self.inputDevice.buttonUp(button)
|
||||
|
||||
def __mouseMotion(self, event):
|
||||
self.inputDevice.setPointerInWindow(*event.GetPosition())
|
||||
|
||||
def __mouseLeaveWindow(self, event):
|
||||
self.inputDevice.setPointerOutOfWindow()
|
||||
|
||||
def __keyDown(self, event):
|
||||
key = self.__getkey(event)
|
||||
if key:
|
||||
self.inputDevice.buttonDown(key)
|
||||
|
||||
def __keyUp(self, event):
|
||||
key = self.__getkey(event)
|
||||
if key:
|
||||
self.inputDevice.buttonUp(key)
|
||||
|
||||
def __getkey(self, event):
|
||||
code = event.GetKeyCode()
|
||||
key = self.Keymap.get(code, None)
|
||||
if key is not None:
|
||||
return key
|
||||
|
||||
if code >= 0x41 and code <= 0x5a:
|
||||
# wxWidgets returns uppercase letters, but Panda expects
|
||||
# lowercase letters.
|
||||
return KeyboardButton.asciiKey(code + 0x20)
|
||||
if code >= 0x20 and code <= 0x80:
|
||||
# Other ASCII keys are treated the same way in wx and Panda.
|
||||
return KeyboardButton.asciiKey(code)
|
||||
|
||||
return None
|
||||
|
||||
def __keystroke(self, event):
|
||||
if hasattr(event, 'GetUnicodeKey'):
|
||||
code = event.GetUnicodeKey()
|
||||
else:
|
||||
code = event.GetKeyCode()
|
||||
if code < 0x20 or code >= 0x80:
|
||||
return
|
||||
|
||||
self.inputDevice.keystroke(code)
|
||||
|
||||
def __eventsCallback(self, data):
|
||||
data.upcall()
|
||||
|
||||
def __propertiesCallback(self, data):
|
||||
data.upcall()
|
||||
|
||||
def __renderCallback(self, data):
|
||||
cbType = data.getCallbackType()
|
||||
if cbType == CallbackGraphicsWindow.RCTBeginFrame:
|
||||
self.SetCurrent()
|
||||
elif cbType == CallbackGraphicsWindow.RCTEndFlip:
|
||||
self.SwapBuffers()
|
||||
|
||||
data.upcall()
|
||||
|
||||
def __resized(self, event):
|
||||
wp = WindowProperties()
|
||||
wp.setSize(*self.GetClientSizeTuple())
|
||||
self.win.requestProperties(wp)
|
||||
|
||||
# Choose the best implementation of WxPandaWindow for the platform.
|
||||
if platform.system() == 'Darwin':
|
||||
WxPandaWindow = OpenGLPandaWindow
|
||||
else:
|
||||
WxPandaWindow = EmbeddedPandaWindow
|
@ -14,6 +14,7 @@
|
||||
standardMunger.I standardMunger.h \
|
||||
config_display.h \
|
||||
$[if $[HAVE_PYTHON], pythonGraphicsWindowProc.h] \
|
||||
callbackGraphicsWindow.I callbackGraphicsWindow.h \
|
||||
drawableRegion.I drawableRegion.h \
|
||||
displayRegion.I displayRegion.h \
|
||||
displayRegionCullCallbackData.I displayRegionCullCallbackData.h \
|
||||
@ -53,6 +54,7 @@
|
||||
standardMunger.cxx \
|
||||
config_display.cxx \
|
||||
$[if $[HAVE_PYTHON], pythonGraphicsWindowProc.cxx] \
|
||||
callbackGraphicsWindow.cxx \
|
||||
drawableRegion.cxx \
|
||||
displayRegion.cxx \
|
||||
displayRegionCullCallbackData.cxx \
|
||||
@ -85,6 +87,7 @@
|
||||
standardMunger.I standardMunger.h \
|
||||
config_display.h \
|
||||
$[if $[HAVE_PYTHON], pythonGraphicsWindowProc.h] \
|
||||
callbackGraphicsWindow.I callbackGraphicsWindow.h \
|
||||
drawableRegion.I drawableRegion.h \
|
||||
displayInformation.h \
|
||||
displayRegion.I displayRegion.h \
|
||||
|
260
panda/src/display/callbackGraphicsWindow.I
Normal file
260
panda/src/display/callbackGraphicsWindow.I
Normal file
@ -0,0 +1,260 @@
|
||||
// Filename: callbackGraphicsWindow.I
|
||||
// Created by: drose (06Jan11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: CallbackGraphicsWindow::set_events_callback
|
||||
// Access: Published
|
||||
// Description: Sets the CallbackObject that will be notified when
|
||||
// this window is polled for window events, including
|
||||
// mouse and keyboard events, as well as window resize
|
||||
// events and other system-generated events.
|
||||
//
|
||||
// This callback will receive a
|
||||
// CallbackGraphicsWindow::EventsCallbackData.
|
||||
//
|
||||
// This callback should process any system-generated
|
||||
// events, and call data->upcall() to process requested
|
||||
// property change requests made via
|
||||
// request_properties().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
set_events_callback(CallbackObject *object) {
|
||||
_events_callback = object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::clear_events_callback
|
||||
// Access: Published
|
||||
// Description: Removes the callback set by an earlier call to
|
||||
// set_events_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
clear_events_callback() {
|
||||
set_events_callback(NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::get_events_callback
|
||||
// Access: Published
|
||||
// Description: Returns the CallbackObject set by set_events_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackObject *CallbackGraphicsWindow::
|
||||
get_events_callback() const {
|
||||
return _events_callback;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::set_properties_callback
|
||||
// Access: Published
|
||||
// Description: Sets the CallbackObject that will be notified when
|
||||
// this window receives a property change request from
|
||||
// user code (e.g. via request_properties).
|
||||
//
|
||||
// This callback will receive a
|
||||
// CallbackGraphicsWindow::PropertiesCallbackData, which
|
||||
// provides a get_properties() method that returns a
|
||||
// modifiable reference to a WindowsProperties object.
|
||||
// This object will contain only those properties
|
||||
// requested by user code. The callback should handle
|
||||
// any of the requests it finds, including and
|
||||
// especially set_open(), and remove them from the
|
||||
// object when it has handled them. Any unhandled
|
||||
// properties should be left unchanged in the properties
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
set_properties_callback(CallbackObject *object) {
|
||||
_properties_callback = object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::clear_properties_callback
|
||||
// Access: Published
|
||||
// Description: Removes the callback set by an earlier call to
|
||||
// set_properties_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
clear_properties_callback() {
|
||||
set_properties_callback(NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::get_properties_callback
|
||||
// Access: Published
|
||||
// Description: Returns the CallbackObject set by set_properties_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackObject *CallbackGraphicsWindow::
|
||||
get_properties_callback() const {
|
||||
return _properties_callback;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::set_render_callback
|
||||
// Access: Published
|
||||
// Description: Sets the CallbackObject that will be notified when
|
||||
// this window is invoked (in the draw thread) to render
|
||||
// its contents, and/or flip the graphics buffers.
|
||||
//
|
||||
// This callback will actually serve several different
|
||||
// functions. It receivces a RenderCallbackData, and
|
||||
// you can query data->get_callback_type() to return the
|
||||
// actual function of each particular callback.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
set_render_callback(CallbackObject *object) {
|
||||
_render_callback = object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::clear_render_callback
|
||||
// Access: Published
|
||||
// Description: Removes the callback set by an earlier call to
|
||||
// set_render_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::
|
||||
clear_render_callback() {
|
||||
set_render_callback(NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::get_render_callback
|
||||
// Access: Published
|
||||
// Description: Returns the CallbackObject set by set_render_callback().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackObject *CallbackGraphicsWindow::
|
||||
get_render_callback() const {
|
||||
return _render_callback;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::WindowCallbackData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow::WindowCallbackData::
|
||||
WindowCallbackData(CallbackGraphicsWindow *window) : _window(window) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::WindowCallbackData::get_window
|
||||
// Access: Published
|
||||
// Description: Returns the window this callback was triggered from.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow *CallbackGraphicsWindow::WindowCallbackData::
|
||||
get_window() const {
|
||||
return _window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::EventsCallbackData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow::EventsCallbackData::
|
||||
EventsCallbackData(CallbackGraphicsWindow *window) :
|
||||
WindowCallbackData(window)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::PropertiesCallbackData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow::PropertiesCallbackData::
|
||||
PropertiesCallbackData(CallbackGraphicsWindow *window, WindowProperties &properties) :
|
||||
WindowCallbackData(window),
|
||||
_properties(properties)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::PropertiesCallbackData::get_properties
|
||||
// Access: Published
|
||||
// Description: Returns the WindowProperties object that this
|
||||
// callback should process. Any properties that are
|
||||
// handled should be removed from this object;
|
||||
// properties that are unhandled should be left alone.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowProperties &CallbackGraphicsWindow::PropertiesCallbackData::
|
||||
get_properties() const {
|
||||
return _properties;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow::RenderCallbackData::
|
||||
RenderCallbackData(CallbackGraphicsWindow *window, RenderCallbackType callback_type, FrameMode frame_mode) :
|
||||
WindowCallbackData(window),
|
||||
_callback_type(callback_type),
|
||||
_frame_mode(frame_mode),
|
||||
_render_flag(true)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::get_callback_type
|
||||
// Access: Published
|
||||
// Description: Since the render callback is shared for several
|
||||
// functions, this method is needed to indicate which
|
||||
// particular function is being invoked with this
|
||||
// callback.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CallbackGraphicsWindow::RenderCallbackType CallbackGraphicsWindow::RenderCallbackData::
|
||||
get_callback_type() const {
|
||||
return _callback_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::get_frame_mode
|
||||
// Access: Published
|
||||
// Description: If the callback type (returned by get_callback_type)
|
||||
// is RCT_begin_frame or RCT_end_frame, then this method
|
||||
// will return the particular frame mode indicating
|
||||
// what, precisely, we want to do this frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GraphicsOutput::FrameMode CallbackGraphicsWindow::RenderCallbackData::
|
||||
get_frame_mode() const {
|
||||
return _frame_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::set_render_flag
|
||||
// Access: Published
|
||||
// Description: If the callback type is RCT_begin_frame, this call is
|
||||
// available to specify the return value from the
|
||||
// begin_frame() call. If this is true (the default),
|
||||
// the frame is rendered normally; if it is false, the
|
||||
// frame is omitted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CallbackGraphicsWindow::RenderCallbackData::
|
||||
set_render_flag(bool render_flag) {
|
||||
_render_flag = render_flag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::get_render_flag
|
||||
// Access: Published
|
||||
// Description: Returns the current setting of the render flag. See
|
||||
// set_render_flag().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CallbackGraphicsWindow::RenderCallbackData::
|
||||
get_render_flag() const {
|
||||
return _render_flag;
|
||||
}
|
299
panda/src/display/callbackGraphicsWindow.cxx
Normal file
299
panda/src/display/callbackGraphicsWindow.cxx
Normal file
@ -0,0 +1,299 @@
|
||||
// Filename: callbackGraphicsWindow.cxx
|
||||
// Created by: drose (06Jan11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "callbackGraphicsWindow.h"
|
||||
|
||||
TypeHandle CallbackGraphicsWindow::_type_handle;
|
||||
TypeHandle CallbackGraphicsWindow::WindowCallbackData::_type_handle;
|
||||
TypeHandle CallbackGraphicsWindow::EventsCallbackData::_type_handle;
|
||||
TypeHandle CallbackGraphicsWindow::PropertiesCallbackData::_type_handle;
|
||||
TypeHandle CallbackGraphicsWindow::RenderCallbackData::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::Constructor
|
||||
// Access: Protected
|
||||
// Description: Use GraphicsEngine::make_output() to construct a
|
||||
// CallbackGraphicsWindow.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CallbackGraphicsWindow::
|
||||
CallbackGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg) :
|
||||
GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, NULL)
|
||||
{
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
MemoryUsage::update_type(this, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CallbackGraphicsWindow::
|
||||
~CallbackGraphicsWindow() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::get_input_device
|
||||
// Access: Published
|
||||
// Description: Returns a writable reference to the nth input device
|
||||
// (mouse). This is intended to be used for the window
|
||||
// implementation to record mouse and keyboard input
|
||||
// information for the Panda system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice &CallbackGraphicsWindow::
|
||||
get_input_device(int device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), _input_devices[0]);
|
||||
return _input_devices[device];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::create_input_device
|
||||
// Access: Published
|
||||
// Description: Adds a new input device (mouse) to the window with
|
||||
// the indicated name. Returns the index of the new
|
||||
// device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int CallbackGraphicsWindow::
|
||||
create_input_device(const string &name) {
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, name);
|
||||
return add_input_device(device);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::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 CallbackGraphicsWindow::
|
||||
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
bool result = false;
|
||||
if (_render_callback != NULL) {
|
||||
RenderCallbackData data(this, RCT_begin_frame, mode);
|
||||
_render_callback->do_callback(&data);
|
||||
result = data.get_render_flag();
|
||||
} else {
|
||||
result = GraphicsWindow::begin_frame(mode, current_thread);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_gsg->reset_if_new();
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::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 CallbackGraphicsWindow::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (_render_callback != NULL) {
|
||||
RenderCallbackData data(this, RCT_end_frame, mode);
|
||||
_render_callback->do_callback(&data);
|
||||
} else {
|
||||
GraphicsWindow::end_frame(mode, current_thread);
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::begin_flip
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// after end_frame() has been called on all windows, to
|
||||
// initiate the exchange of the front and back buffers.
|
||||
//
|
||||
// This should instruct the window to prepare for the
|
||||
// flip at the next video sync, but it should not wait.
|
||||
//
|
||||
// We have the two separate functions, begin_flip() and
|
||||
// end_flip(), to make it easier to flip all of the
|
||||
// windows at the same time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::
|
||||
begin_flip() {
|
||||
if (_render_callback != NULL) {
|
||||
RenderCallbackData data(this, RCT_begin_flip, FM_render);
|
||||
_render_callback->do_callback(&data);
|
||||
} else {
|
||||
GraphicsWindow::begin_flip();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::end_flip
|
||||
// Access: Public, Virtual
|
||||
// Description: This function will be called within the draw thread
|
||||
// after begin_flip() has been called on all windows, to
|
||||
// finish the exchange of the front and back buffers.
|
||||
//
|
||||
// This should cause the window to wait for the flip, if
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::
|
||||
end_flip() {
|
||||
if (_render_callback != NULL) {
|
||||
RenderCallbackData data(this, RCT_end_flip, FM_render);
|
||||
_render_callback->do_callback(&data);
|
||||
} else {
|
||||
GraphicsWindow::end_flip();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::process_events
|
||||
// Access: Public, Virtual
|
||||
// Description: Do whatever processing is necessary to ensure that
|
||||
// the window responds to user events. Also, honor any
|
||||
// requests recently made via request_properties().
|
||||
//
|
||||
// This function is called only within the window
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::
|
||||
process_events() {
|
||||
if (_events_callback != NULL) {
|
||||
EventsCallbackData data(this);
|
||||
_events_callback->do_callback(&data);
|
||||
} else {
|
||||
GraphicsWindow::process_events();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::set_properties_now
|
||||
// Access: Public, Virtual
|
||||
// Description: Applies the requested set of properties to the
|
||||
// window, if possible, for instance to request a change
|
||||
// in size or minimization status.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::
|
||||
set_properties_now(WindowProperties &properties) {
|
||||
if (_properties_callback != NULL) {
|
||||
PropertiesCallbackData data(this, properties);
|
||||
_properties_callback->do_callback(&data);
|
||||
} else {
|
||||
GraphicsWindow::set_properties_now(properties);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::open_window
|
||||
// Access: Protected, Virtual
|
||||
// Description: Opens the window right now. Called from the window
|
||||
// thread. Returns true if the window is successfully
|
||||
// opened, or false if there was a problem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CallbackGraphicsWindow::
|
||||
open_window() {
|
||||
// In this case, we assume the callback has handled the window
|
||||
// opening.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::do_reshape_request
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called from the window thread in response to a request
|
||||
// from within the code (via request_properties()) to
|
||||
// change the size and/or position of the window.
|
||||
// Returns true if the window is successfully changed,
|
||||
// or false if there was a problem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CallbackGraphicsWindow::
|
||||
do_reshape_request(int x_origin, int y_origin, bool has_origin,
|
||||
int x_size, int y_size) {
|
||||
// In this case, we assume the callback has handled the window
|
||||
// resizing.
|
||||
WindowProperties properties;
|
||||
if (has_origin) {
|
||||
properties.set_origin(x_origin, y_origin);
|
||||
}
|
||||
properties.set_size(x_size, y_size);
|
||||
system_changed_properties(properties);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::EventsCallbackData::upcall
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::EventsCallbackData::
|
||||
upcall() {
|
||||
_window->GraphicsWindow::process_events();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::PropertiesCallbackData::upcall
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::PropertiesCallbackData::
|
||||
upcall() {
|
||||
_window->GraphicsWindow::set_properties_now(_properties);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::RenderCallbackData::upcall
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CallbackGraphicsWindow::RenderCallbackData::
|
||||
upcall() {
|
||||
switch (_callback_type) {
|
||||
case RCT_begin_frame:
|
||||
_window->GraphicsWindow::begin_frame(_frame_mode, Thread::get_current_thread());
|
||||
break;
|
||||
|
||||
case RCT_end_frame:
|
||||
_window->GraphicsWindow::end_frame(_frame_mode, Thread::get_current_thread());
|
||||
break;
|
||||
|
||||
case RCT_begin_flip:
|
||||
_window->GraphicsWindow::begin_flip();
|
||||
break;
|
||||
|
||||
case RCT_end_flip:
|
||||
_window->GraphicsWindow::end_flip();
|
||||
break;
|
||||
}
|
||||
}
|
231
panda/src/display/callbackGraphicsWindow.h
Normal file
231
panda/src/display/callbackGraphicsWindow.h
Normal file
@ -0,0 +1,231 @@
|
||||
// Filename: callbackGraphicsWindow.h
|
||||
// Created by: drose (06Jan11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CALLBACKGRAPHICSWINDOW_H
|
||||
#define CALLBACKGRAPHICSWINDOW_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "graphicsWindow.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CallbackGraphicsWindow
|
||||
// Description : This special window object doesn't represent a window
|
||||
// in its own right, but instead hooks into some
|
||||
// third-party API for creating and rendering to windows
|
||||
// via callbacks. This can be used to allow Panda to
|
||||
// render into an already-created OpenGL context, for
|
||||
// instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DISPLAY CallbackGraphicsWindow : public GraphicsWindow {
|
||||
protected:
|
||||
CallbackGraphicsWindow(GraphicsEngine *engine,
|
||||
GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~CallbackGraphicsWindow();
|
||||
|
||||
class WindowCallbackData : public CallbackData {
|
||||
public:
|
||||
INLINE WindowCallbackData(CallbackGraphicsWindow *window);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE CallbackGraphicsWindow *get_window() const;
|
||||
|
||||
protected:
|
||||
PT(CallbackGraphicsWindow) _window;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CallbackData::init_type();
|
||||
register_type(_type_handle, "CallbackGraphicsWindow::WindowCallbackData",
|
||||
CallbackData::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;
|
||||
};
|
||||
|
||||
|
||||
class EventsCallbackData : public WindowCallbackData {
|
||||
public:
|
||||
INLINE EventsCallbackData(CallbackGraphicsWindow *window);
|
||||
|
||||
PUBLISHED:
|
||||
virtual void upcall();
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
WindowCallbackData::init_type();
|
||||
register_type(_type_handle, "CallbackGraphicsWindow::EventsCallbackData",
|
||||
WindowCallbackData::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;
|
||||
};
|
||||
|
||||
class PropertiesCallbackData : public WindowCallbackData {
|
||||
public:
|
||||
INLINE PropertiesCallbackData(CallbackGraphicsWindow *window, WindowProperties &properties);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE WindowProperties &get_properties() const;
|
||||
|
||||
virtual void upcall();
|
||||
|
||||
private:
|
||||
WindowProperties &_properties;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
WindowCallbackData::init_type();
|
||||
register_type(_type_handle, "CallbackGraphicsWindow::PropertiesCallbackData",
|
||||
WindowCallbackData::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;
|
||||
};
|
||||
|
||||
enum RenderCallbackType {
|
||||
RCT_begin_frame,
|
||||
RCT_end_frame,
|
||||
RCT_begin_flip,
|
||||
RCT_end_flip,
|
||||
};
|
||||
|
||||
class RenderCallbackData : public WindowCallbackData {
|
||||
public:
|
||||
INLINE RenderCallbackData(CallbackGraphicsWindow *window, RenderCallbackType callback_type, FrameMode frame_mode);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE CallbackGraphicsWindow::RenderCallbackType get_callback_type() const;
|
||||
INLINE GraphicsOutput::FrameMode get_frame_mode() const;
|
||||
|
||||
INLINE void set_render_flag(bool render_flag);
|
||||
INLINE bool get_render_flag() const;
|
||||
|
||||
virtual void upcall();
|
||||
|
||||
private:
|
||||
RenderCallbackType _callback_type;
|
||||
FrameMode _frame_mode;
|
||||
bool _render_flag;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
WindowCallbackData::init_type();
|
||||
register_type(_type_handle, "CallbackGraphicsWindow::RenderCallbackData",
|
||||
WindowCallbackData::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;
|
||||
};
|
||||
|
||||
INLINE void set_events_callback(CallbackObject *object);
|
||||
INLINE void clear_events_callback();
|
||||
INLINE CallbackObject *get_events_callback() const;
|
||||
|
||||
INLINE void set_properties_callback(CallbackObject *object);
|
||||
INLINE void clear_properties_callback();
|
||||
INLINE CallbackObject *get_properties_callback() const;
|
||||
|
||||
INLINE void set_render_callback(CallbackObject *object);
|
||||
INLINE void clear_render_callback();
|
||||
INLINE CallbackObject *get_render_callback() const;
|
||||
|
||||
GraphicsWindowInputDevice &get_input_device(int device);
|
||||
int create_input_device(const string &name);
|
||||
|
||||
public:
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
virtual void begin_flip();
|
||||
virtual void end_flip();
|
||||
|
||||
virtual void process_events();
|
||||
virtual void set_properties_now(WindowProperties &properties);
|
||||
|
||||
protected:
|
||||
virtual bool open_window();
|
||||
virtual bool do_reshape_request(int x_origin, int y_origin, bool has_origin,
|
||||
int x_size, int y_size);
|
||||
|
||||
private:
|
||||
PT(CallbackObject) _events_callback;
|
||||
PT(CallbackObject) _properties_callback;
|
||||
PT(CallbackObject) _render_callback;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GraphicsWindow::init_type();
|
||||
register_type(_type_handle, "CallbackGraphicsWindow",
|
||||
GraphicsWindow::get_class_type());
|
||||
WindowCallbackData::init_type();
|
||||
EventsCallbackData::init_type();
|
||||
PropertiesCallbackData::init_type();
|
||||
RenderCallbackData::init_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;
|
||||
|
||||
friend class GraphicsEngine;
|
||||
};
|
||||
|
||||
#include "callbackGraphicsWindow.I"
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_display.h"
|
||||
#include "callbackGraphicsWindow.h"
|
||||
#include "displayRegion.h"
|
||||
#include "displayRegionCullCallbackData.h"
|
||||
#include "displayRegionDrawCallbackData.h"
|
||||
@ -449,6 +450,7 @@ init_libdisplay() {
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
CallbackGraphicsWindow::init_type();
|
||||
DisplayRegion::init_type();
|
||||
DisplayRegionCullCallbackData::init_type();
|
||||
DisplayRegionDrawCallbackData::init_type();
|
||||
|
@ -336,12 +336,35 @@ make_output(GraphicsPipe *pipe,
|
||||
nassertr(threading_model.get_draw_name() ==
|
||||
gsg->get_threading_model().get_draw_name(), NULL);
|
||||
}
|
||||
|
||||
// Are we really asking for a callback window?
|
||||
if ((flags & GraphicsPipe::BF_require_callback_window)!=0) {
|
||||
PT(GraphicsStateGuardian) this_gsg = gsg;
|
||||
if (this_gsg == (GraphicsStateGuardian *)NULL) {
|
||||
// If we don't already have a GSG, we have to ask the pipe to
|
||||
// make a new one, unencumbered by window dressing.
|
||||
this_gsg = pipe->make_callback_gsg(this);
|
||||
}
|
||||
if (this_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
CallbackGraphicsWindow *window = new CallbackGraphicsWindow(this, pipe, name, fb_prop, win_prop, flags, this_gsg);
|
||||
window->_sort = sort;
|
||||
do_add_window(window, threading_model);
|
||||
do_add_gsg(window->get_gsg(), pipe, threading_model);
|
||||
display_cat.info() << "Created output of type CallbackGraphicsWindow\n";
|
||||
return window;
|
||||
}
|
||||
|
||||
// Couldn't make a callback window, because the pipe wouldn't make
|
||||
// an unencumbered GSG.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Determine if a parasite buffer meets the user's specs.
|
||||
|
||||
bool can_use_parasite = false;
|
||||
if ((host != 0)&&
|
||||
((flags&GraphicsPipe::BF_require_window)==0)&&
|
||||
((flags&GraphicsPipe::BF_require_callback_window)==0)&&
|
||||
((flags&GraphicsPipe::BF_refuse_parasite)==0)&&
|
||||
((flags&GraphicsPipe::BF_can_bind_color)==0)&&
|
||||
((flags&GraphicsPipe::BF_can_bind_every)==0)&&
|
||||
@ -1998,7 +2021,6 @@ void GraphicsEngine::
|
||||
do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe,
|
||||
const GraphicsThreadingModel &threading_model) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
nassertv(gsg->get_pipe() == pipe && gsg->get_engine() == this);
|
||||
gsg->_threading_model = threading_model;
|
||||
if (!_default_loader.is_null()) {
|
||||
|
@ -138,6 +138,20 @@ make_output(const string &name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsPipe::make_callback_gsg
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is called when make_output() is used to create a
|
||||
// CallbackGraphicsWindow. If the GraphicsPipe can
|
||||
// construct a GSG that's not associated with any
|
||||
// particular window object, do so now, assuming the
|
||||
// correct graphics context has been set up externally.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) GraphicsPipe::
|
||||
make_callback_gsg(GraphicsEngine *engine) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsPipe::get_display_information
|
||||
// Access: Published
|
||||
|
@ -78,6 +78,7 @@ PUBLISHED:
|
||||
BF_require_parasite = 0x0002,
|
||||
BF_refuse_window = 0x0004,
|
||||
BF_require_window = 0x0008,
|
||||
BF_require_callback_window = 0x0010,
|
||||
|
||||
// Miscellaneous control flags.
|
||||
BF_can_bind_color = 0x0040, // Need capability: bind the color bitplane to a tex.
|
||||
@ -124,6 +125,7 @@ protected:
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify);
|
||||
virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine);
|
||||
|
||||
LightMutex _lock;
|
||||
|
||||
|
@ -2398,8 +2398,7 @@ determine_target_texture() {
|
||||
|
||||
nassertv(target_texture != (TextureAttrib *)NULL &&
|
||||
target_tex_gen != (TexGenAttrib *)NULL);
|
||||
int max_texture_stages = get_max_texture_stages();
|
||||
_target_texture = target_texture->filter_to_max(max_texture_stages);
|
||||
_target_texture = target_texture;
|
||||
_target_tex_gen = target_tex_gen;
|
||||
|
||||
if (_has_texture_alpha_scale) {
|
||||
@ -2411,6 +2410,8 @@ determine_target_texture() {
|
||||
(stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
|
||||
}
|
||||
|
||||
int max_texture_stages = get_max_texture_stages();
|
||||
_target_texture = _target_texture->filter_to_max(max_texture_stages);
|
||||
nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
|
||||
}
|
||||
|
||||
|
@ -56,14 +56,3 @@ get_window_handle() const {
|
||||
return _window_handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::add_input_device
|
||||
// Access: Protected
|
||||
// Description: Adds a GraphicsWindowInputDevice to the vector.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindow::
|
||||
add_input_device(const GraphicsWindowInputDevice &device) {
|
||||
_input_devices.push_back(device);
|
||||
_input_devices.back().set_device_index(_input_devices.size()-1);
|
||||
}
|
||||
|
||||
|
@ -853,6 +853,21 @@ system_changed_size(int x_size, int y_size) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::add_input_device
|
||||
// Access: Protected
|
||||
// Description: Adds a GraphicsWindowInputDevice to the vector.
|
||||
// Returns the index of the new device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsWindow::
|
||||
add_input_device(const GraphicsWindowInputDevice &device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
int index = (int)_input_devices.size();
|
||||
_input_devices.push_back(device);
|
||||
_input_devices.back().set_device_index(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::mouse_mode_relative
|
||||
// Access: Protected, Virtual
|
||||
|
@ -141,7 +141,7 @@ protected:
|
||||
void system_changed_size(int x_size, int y_size);
|
||||
|
||||
protected:
|
||||
INLINE void add_input_device(const GraphicsWindowInputDevice &device);
|
||||
int add_input_device(const GraphicsWindowInputDevice &device);
|
||||
typedef vector_GraphicsWindowInputDevice InputDevices;
|
||||
InputDevices _input_devices;
|
||||
LightMutex _input_lock;
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
bool has_pointer_event() const;
|
||||
PT(PointerEventList) get_pointer_events();
|
||||
|
||||
public:
|
||||
PUBLISHED:
|
||||
// The following interface is for the various kinds of
|
||||
// GraphicsWindows to record the data incoming on the device.
|
||||
void button_down(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "config_display.cxx"
|
||||
#include "callbackGraphicsWindow.cxx"
|
||||
#include "displayInformation.cxx"
|
||||
#include "displayRegion.cxx"
|
||||
#include "displayRegionCullCallbackData.cxx"
|
||||
|
@ -383,7 +383,7 @@ make_output(const string &name,
|
||||
if (gsg != 0) {
|
||||
DCAST_INTO_R(osxgsg, gsg, NULL);
|
||||
}
|
||||
|
||||
|
||||
// First thing to try: an osxGraphicsWindow
|
||||
|
||||
if (retry == 0) {
|
||||
@ -464,3 +464,16 @@ make_output(const string &name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsPipe::make_callback_gsg
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is called when make_output() is used to create a
|
||||
// CallbackGraphicsWindow. If the GraphicsPipe can
|
||||
// construct a GSG that's not associated with any
|
||||
// particular window object, do so now, assuming the
|
||||
// correct graphics context has been set up externally.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) osxGraphicsPipe::
|
||||
make_callback_gsg(GraphicsEngine *engine) {
|
||||
return new osxGraphicsStateGuardian(engine, this, NULL);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ protected:
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify);
|
||||
virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -100,10 +100,12 @@ void osxGraphicsStateGuardian::reset()
|
||||
|
||||
GLGraphicsStateGuardian::reset();
|
||||
|
||||
// Apply the video-sync setting.
|
||||
GLint value = sync_video ? 1 : 0;
|
||||
aglSetInteger(_aglcontext, AGL_SWAP_INTERVAL, &value);
|
||||
}
|
||||
if (_aglcontext != (AGLContext)NULL) {
|
||||
// Apply the video-sync setting.
|
||||
GLint value = sync_video ? 1 : 0;
|
||||
aglSetInteger(_aglcontext, AGL_SWAP_INTERVAL, &value);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsStateGuardian::draw_resize_box
|
||||
|
Loading…
x
Reference in New Issue
Block a user