experimental libRocket support

This commit is contained in:
rdb 2012-01-07 19:02:41 +00:00
parent 2d78a0503b
commit 69fcb76b1a
17 changed files with 1422 additions and 0 deletions

View File

@ -232,6 +232,14 @@
#define EXPTP_PANDAX11 extern
#endif
#ifdef BUILDING_ROCKET
#define EXPCL_ROCKET __declspec(dllexport)
#define EXPTP_ROCKET
#else
#define EXPCL_ROCKET __declspec(dllimport)
#define EXPTP_ROCKET extern
#endif
#ifdef BUILDING_SHADER
#define EXPCL_SHADER __declspec(dllexport)
#define EXPTP_SHADER
@ -339,6 +347,9 @@
#define EXPCL_PANDAX11
#define EXPTP_PANDAX11
#define EXPCL_ROCKET
#define EXPTP_ROCKET
#define EXPCL_SHADER
#define EXPTP_SHADER

View File

@ -0,0 +1,38 @@
#define OTHER_LIBS p3interrogatedb:c p3dconfig:c p3dtoolconfig:m \
p3dtoolutil:c p3dtoolbase:c p3dtool:m p3prc:c
#define USE_PACKAGES rocket
#define BUILDING_DLL BUILDING_ROCKET
#begin lib_target
#define TARGET p3rocket
#define LOCAL_LIBS \
p3display p3pgraph p3gobj p3linmath p3putil p3dgraph
#define COMBINED_SOURCES rocket_composite1.cxx
#define SOURCES \
config_rocket.h \
rocketFileInterface.h \
rocketInputHandler.h \
rocketRegion.h $[if $[HAVE_ROCKET_PYTHON],rocketRegion_ext.I] \
rocketRenderInterface.h \
rocketSystemInterface.h
#define INCLUDED_SOURCES \
config_rocket.cxx \
rocketFileInterface.cxx \
rocketInputHandler.cxx \
rocketRegion.cxx \
rocketRenderInterface.cxx \
rocketSystemInterface.cxx
#define INSTALL_HEADERS \
config_rocket.h rocketRegion.h
#if $[HAVE_ROCKET_PYTHON]
#define IGATESCAN rocketInputHandler.h rocketInputHandler.cxx rocketRegion.h rocketRegion.cxx rocketRegion_ext.I
#endif
#end lib_target

View File

@ -0,0 +1,59 @@
// Filename: config_rocket.cxx
// Created by: rdb (04Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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_rocket.h"
#include "rocketFileInterface.h"
#include "rocketInputHandler.h"
#include "rocketRegion.h"
#include "rocketSystemInterface.h"
#include "pandaSystem.h"
#include "dconfig.h"
#include <Rocket/Core.h>
Configure(config_rocket);
NotifyCategoryDef(rocket, "");
ConfigureFn(config_rocket) {
init_librocket();
}
////////////////////////////////////////////////////////////////////
// Function: init_librocket
// 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_librocket() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
RocketInputHandler::init_type();
RocketRegion::init_type();
RocketFileInterface* fi = new RocketFileInterface;
Rocket::Core::SetFileInterface(fi);
RocketSystemInterface* si = new RocketSystemInterface;
Rocket::Core::SetSystemInterface(si);
Rocket::Core::Initialise();
}

View File

@ -0,0 +1,25 @@
// Filename: config_rocket.h
// Created by: rdb (04Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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_ROCKET_H
#define CONFIG_ROCKET_H
#include "pandabase.h"
#include "notifyCategoryProxy.h"
NotifyCategoryDecl(rocket, EXPCL_ROCKET, EXPTP_ROCKET);
extern EXPCL_ROCKET void init_librocket();
#endif

View File

@ -0,0 +1,108 @@
// Filename: rocketFileInterface.cxx
// Created by: rdb (03Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketFileInterface.h"
#include "virtualFileSystem.h"
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Constructor
// Access: Public
// Description: Constructs a RocketFileInterface for the given
// VFS, or the default if NULL is given.
////////////////////////////////////////////////////////////////////
RocketFileInterface::
RocketFileInterface(VirtualFileSystem *vfs) : _vfs(vfs) {
if (_vfs == NULL) {
_vfs = VirtualFileSystem::get_global_ptr();
}
}
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Open
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
Rocket::Core::FileHandle RocketFileInterface::
Open(const Rocket::Core::String& path) {
// A FileHandle is actually just a void pointer
return (Rocket::Core::FileHandle)
_vfs->open_read_file(Filename::from_os_specific(path.CString()), true);
}
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Close
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void RocketFileInterface::
Close(Rocket::Core::FileHandle file) {
if ((istream*) file != (istream*) NULL) {
_vfs->close_read_file((istream*) file);
}
}
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Read
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
size_t RocketFileInterface::
Read(void* buffer, size_t size, Rocket::Core::FileHandle file) {
istream* const stream = (istream*) file;
if (stream == (istream*) NULL) {
return 0;
}
stream->read((char*) buffer, size);
return stream->gcount();
}
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Seek
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool RocketFileInterface::
Seek(Rocket::Core::FileHandle file, long offset, int origin) {
istream* stream = (istream*) file;
if (stream == (istream*) NULL) {
return false;
}
switch(origin) {
case SEEK_SET:
stream->seekg(offset, ios::beg);
break;
case SEEK_CUR:
stream->seekg(offset, ios::cur);
break;
case SEEK_END:
stream->seekg(offset, ios::end);
};
return !stream->fail();
}
////////////////////////////////////////////////////////////////////
// Function: RocketFileInterface::Tell
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
size_t RocketFileInterface::
Tell(Rocket::Core::FileHandle file) {
if ((istream*) file == (istream*) NULL) {
return -1;
}
return ((istream*) file)->tellg();
}

View File

@ -0,0 +1,40 @@
// Filename: rocketFileInterface.h
// Created by: rdb (03Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 ROCKET_FILE_INTERFACE_H
#define ROCKET_FILE_INTERFACE_H
#include "config_rocket.h"
#include <Rocket/Core/FileInterface.h>
class VirtualFileSystem;
class RocketFileInterface : public Rocket::Core::FileInterface {
public:
RocketFileInterface(VirtualFileSystem *vfs = NULL);
virtual ~RocketFileInterface() {};
Rocket::Core::FileHandle Open(const Rocket::Core::String& path);
void Close(Rocket::Core::FileHandle file);
size_t Read(void* buffer, size_t size, Rocket::Core::FileHandle file);
bool Seek(Rocket::Core::FileHandle file, long offset, int origin);
size_t Tell(Rocket::Core::FileHandle file);
protected:
VirtualFileSystem* _vfs;
};
#endif

View File

@ -0,0 +1,241 @@
// Filename: rocketInputHandler.cxx
// Created by: rdb (20Dec11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketInputHandler.h"
#include "buttonEventList.h"
#include "dataGraphTraverser.h"
#include "linmath_events.h"
#include "rocketRenderInterface.h"
#include "keyboardButton.h"
#include "mouseButton.h"
#include <Rocket/Core/Input.h>
using namespace Rocket::Core::Input;
TypeHandle RocketInputHandler::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: RocketInputHandler::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
RocketInputHandler::
RocketInputHandler(const string &name) :
DataNode(name),
_modifiers(0),
_wheel_delta(0)
{
_pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
_button_events_input = define_input("button_events", ButtonEventList::get_class_type());
}
////////////////////////////////////////////////////////////////////
// Function: RocketInputHandler::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
RocketInputHandler::
~RocketInputHandler() {
}
////////////////////////////////////////////////////////////////////
// Function: RocketInputHandler::do_transmit_data
// Access: Protected, Virtual
// Description: The virtual implementation of transmit_data(). This
// function receives an array of input parameters and
// should generate an array of output parameters. The
// input parameters may be accessed with the index
// numbers returned by the define_input() calls that
// were made earlier (presumably in the constructor);
// likewise, the output parameters should be set with
// the index numbers returned by the define_output()
// calls.
////////////////////////////////////////////////////////////////////
void RocketInputHandler::
do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
DataNodeTransmit &output) {
Thread *current_thread = trav->get_current_thread();
MutexHolder holder(_lock);
if (input.has_data(_pixel_xy_input)) {
// The mouse is within the window. Get the current mouse position.
const EventStoreVec2 *pixel_xy;
DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
LVecBase2 p = pixel_xy->get_value();
// Determine if mouse moved from last position
if (p != _mouse_xy) {
_mouse_xy_changed = true;
_mouse_xy = p;
}
}
ButtonEventList new_button_events;
// Look for new button events.
if (input.has_data(_button_events_input)) {
const ButtonEventList *this_button_events;
DCAST_INTO_V(this_button_events, input.get_data(_button_events_input).get_ptr());
int num_events = this_button_events->get_num_events();
for (int i = 0; i < num_events; i++) {
const ButtonEvent &be = this_button_events->get_event(i);
switch (be._type) {
case ButtonEvent::T_down:
if (be._button == KeyboardButton::control()) {
_modifiers |= KM_CTRL;
} else if (be._button == KeyboardButton::shift()) {
_modifiers |= KM_SHIFT;
} else if (be._button == KeyboardButton::alt()) {
_modifiers |= KM_ALT;
} else if (be._button == KeyboardButton::meta()) {
_modifiers |= KM_META;
} else if (be._button == MouseButton::wheel_up()) {
_wheel_delta -= 1;
} else if (be._button == MouseButton::wheel_down()) {
_wheel_delta += 1;
}
break;
case ButtonEvent::T_repeat:
break;
case ButtonEvent::T_up:
if (be._button == KeyboardButton::control()) {
_modifiers &= ~KM_CTRL;
} else if (be._button == KeyboardButton::shift()) {
_modifiers &= ~KM_SHIFT;
} else if (be._button == KeyboardButton::alt()) {
_modifiers &= ~KM_ALT;
} else if (be._button == KeyboardButton::meta()) {
_modifiers &= ~KM_META;
}
break;
case ButtonEvent::T_keystroke:
_text_input.push_back(be._keycode);
break;
case ButtonEvent::T_resume_down:
break;
case ButtonEvent::T_move:
break;
}
bool down = (be._type == ButtonEvent::T_down);
if (down || be._type == ButtonEvent::T_up) {
if (be._button == MouseButton::one()) {
_mouse_buttons[1] = down;
} else if (be._button == MouseButton::two()) {
_mouse_buttons[2] = down;
} else if (be._button == MouseButton::three()) {
_mouse_buttons[3] = down;
} else if (be._button == MouseButton::four()) {
_mouse_buttons[4] = down;
} else if (be._button == MouseButton::five()) {
_mouse_buttons[5] = down;
// In the order they are specified in Rocket/Core/Input.h
} else if (be._button == KeyboardButton::space()) {
_keys[KI_SPACE] = down;
} else if (be._button == KeyboardButton::backspace()) {
_keys[KI_BACK] = down;
} else if (be._button == KeyboardButton::tab()) {
_keys[KI_TAB] = down;
} else if (be._button == KeyboardButton::enter()) {
_keys[KI_RETURN] = down;
} else if (be._button == KeyboardButton::escape()) {
_keys[KI_ESCAPE] = down;
} else if (be._button == KeyboardButton::end()) {
_keys[KI_END] = down;
} else if (be._button == KeyboardButton::home()) {
_keys[KI_HOME] = down;
} else if (be._button == KeyboardButton::left()) {
_keys[KI_LEFT] = down;
} else if (be._button == KeyboardButton::up()) {
_keys[KI_UP] = down;
} else if (be._button == KeyboardButton::right()) {
_keys[KI_RIGHT] = down;
} else if (be._button == KeyboardButton::down()) {
_keys[KI_DOWN] = down;
} else if (be._button == KeyboardButton::insert()) {
_keys[KI_INSERT] = down;
} else if (be._button == KeyboardButton::del()) {
_keys[KI_DELETE] = down;
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: RocketInputHandler::update_context
// Access: Public
// Description: Updates the libRocket context with the changes
// that we have gathered in do_transmit_data.
// Also calls Update() on the context.
////////////////////////////////////////////////////////////////////
void RocketInputHandler::
update_context(Rocket::Core::Context *context, int xoffs, int yoffs) {
MutexHolder holder(_lock);
if (_mouse_xy_changed) {
_mouse_xy_changed = false;
context->ProcessMouseMove(_mouse_xy.get_x() - xoffs,
_mouse_xy.get_y() - yoffs, _modifiers);
}
if (_mouse_buttons.size() > 0) {
ButtonActivityMap::const_iterator it;
for (it = _mouse_buttons.begin(); it != _mouse_buttons.end(); ++it) {
if (it->second) {
context->ProcessMouseButtonDown(it->first, _modifiers);
} else {
context->ProcessMouseButtonUp(it->first, _modifiers);
}
}
_mouse_buttons.clear();
}
if (_wheel_delta != 0) {
context->ProcessMouseWheel(_wheel_delta, _modifiers);
_wheel_delta = 0;
}
if (_keys.size() > 0) {
ButtonActivityMap::const_iterator it;
for (it = _keys.begin(); it != _keys.end(); ++it) {
if (it->second) {
context->ProcessKeyDown((KeyIdentifier) it->first, _modifiers);
} else {
context->ProcessKeyUp((KeyIdentifier) it->first, _modifiers);
}
}
_mouse_buttons.clear();
}
if (_text_input.size() > 0) {
pvector<short>::const_iterator it;
for (it = _text_input.begin(); it != _text_input.end(); ++it) {
context->ProcessTextInput(*it);
}
_text_input.clear();
}
context->Update();
}

View File

@ -0,0 +1,80 @@
// Filename: rocketInputHandler.h
// Created by: rdb (20Dec11)
//
////////////////////////////////////////////////////////////////////
//
// 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 ROCKETINPUTHANDLER_H
#define ROCKETINPUTHANDLER_H
#include "config_rocket.h"
#include "dataNode.h"
namespace Rocket {
namespace Core {
class Context;
}
};
////////////////////////////////////////////////////////////////////
// Class : RocketInputHandler
// Description : DataNode that listens for keyboard and mouse
// events and passes them to libRocket.
////////////////////////////////////////////////////////////////////
class EXPCL_ROCKET RocketInputHandler : public DataNode {
PUBLISHED:
RocketInputHandler(const string &name = string());
virtual ~RocketInputHandler();
public:
void update_context(Rocket::Core::Context *context, int xoffs, int yoffs);
protected:
// Inherited from DataNode
virtual void do_transmit_data(DataGraphTraverser *trav,
const DataNodeTransmit &input,
DataNodeTransmit &output);
private:
Mutex _lock;
// inputs
int _pixel_xy_input;
int _button_events_input;
LVecBase2 _mouse_xy;
bool _mouse_xy_changed;
int _modifiers;
int _wheel_delta;
typedef pmap<int, bool> ButtonActivityMap;
ButtonActivityMap _mouse_buttons;
ButtonActivityMap _keys;
pvector<short> _text_input;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
DataNode::init_type();
register_type(_type_handle, "RocketInputHandler",
DataNode::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

View File

@ -0,0 +1,84 @@
// Filename: rocketRegion.I
// Created by: rdb (01Dec11)
//
////////////////////////////////////////////////////////////////////
//
// 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: RocketRegion::make
// Access: Published, Static
// Description: Creates a libRocket context with the given name
// (must be unique) for the given window. Returns
// a new DisplayRegion where the libRocket context
// will render to.
// This variant of make() creates a region that
// fills the entire window.
////////////////////////////////////////////////////////////////////
INLINE RocketRegion *RocketRegion::
make(const string &context_name, GraphicsOutput *window) {
return make(context_name, window, LVecBase4(0.0f, 1.0f, 0.0f, 1.0f));
}
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::make
// Access: Published, Static
// Description: Creates a libRocket context with the given name
// (must be unique) for the given window. Returns
// a new DisplayRegion where the libRocket context
// will render to.
////////////////////////////////////////////////////////////////////
INLINE RocketRegion *RocketRegion::
make(const string &context_name, GraphicsOutput *window,
const LVecBase4 &dimensions) {
return new RocketRegion(window, dimensions, context_name);
}
#ifndef CPPPARSER
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::get_context
// Access: Published
// Description: Returns a pointer to the Rocket context associated
// with this region. Will only be valid as long as
// this region still exists, so be sure to toss it
// when you toss the region itself.
////////////////////////////////////////////////////////////////////
Rocket::Core::Context* RocketRegion::
get_context() const {
return _context;
}
#endif
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::set_input_handler
// Access: Published
// Description: Sets the RocketInputHandler object from which to
// gather the keyboard and mouse inputs to pass to
// the libRocket context before rendering.
// You may use one input handler to provide inputs to
// any number of RocketRegion objects.
////////////////////////////////////////////////////////////////////
INLINE void RocketRegion::
set_input_handler(RocketInputHandler *handler) {
_input_handler = handler;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::get_input_handler
// Access: Published
// Description: Returns the RocketInputHandler object previously
// passed to set_input_handler.
////////////////////////////////////////////////////////////////////
INLINE RocketInputHandler *RocketRegion::
get_input_handler() const {
return _input_handler;
}

View File

@ -0,0 +1,156 @@
// Filename: rocketRegion.cxx
// Created by: rdb (30Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketRegion.h"
#include "graphicsOutput.h"
#include "orthographicLens.h"
#include "pStatTimer.h"
TypeHandle RocketRegion::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::Constructor
// Access: Protected
// Description: Make sure that context_name is unique.
////////////////////////////////////////////////////////////////////
RocketRegion::
RocketRegion(GraphicsOutput *window, const LVecBase4 &dimensions,
const string &context_name) :
DisplayRegion(window, dimensions),
_dimensions(0, 0) {
cerr << "rocket " << this << "\n";
if (window != (GraphicsOutput *)NULL && window->has_size()) {
_dimensions.x = (dimensions[1] - dimensions[0]) * window->get_fb_x_size();
_dimensions.y = (dimensions[3] - dimensions[2]) * window->get_fb_y_size();
}
rocket_cat.debug()
<< "Setting initial context dimensions to ("
<< _dimensions.x << ", " << _dimensions.y << ")\n";
_context = Rocket::Core::CreateContext(context_name.c_str(),
_dimensions, &_interface);
nassertv(_context != NULL);
_lens = new OrthographicLens;
_lens->set_film_size(_dimensions.x, -_dimensions.y);
_lens->set_film_offset(_dimensions.x * 0.5, _dimensions.y * 0.5);
_lens->set_near_far(-1, 1);
set_camera(new Camera(context_name, _lens));
}
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
RocketRegion::
~RocketRegion() {
if (_context != NULL) {
if (_context->GetReferenceCount() > 1) {
_context->RemoveReference();
return;
}
// We need to do this because libRocket may call into Python
// code to throw events.
#ifdef HAVE_ROCKET_PYTHON
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
#endif
_context->RemoveReference();
#ifdef HAVE_ROCKET_PYTHON
PyGILState_Release(gstate);
#endif
}
}
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::pixel_size_changed
// Access: Private, Virtual
// Description: Called when the size in pixels of this region
// has changed.
////////////////////////////////////////////////////////////////////
void RocketRegion::
pixel_size_changed(int x_size, int y_size) {
if (x_size == _dimensions.x && y_size == _dimensions.y) {
return;
}
// We need to do this because libRocket may call into Python
// code to throw events.
#ifdef HAVE_ROCKET_PYTHON
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
#endif
rocket_cat.debug() << "Setting context dimensions to ("
<< x_size << ", " << y_size << ")\n";
_dimensions.x = x_size;
_dimensions.y = y_size;
_context->SetDimensions(_dimensions);
#ifdef HAVE_ROCKET_PYTHON
PyGILState_Release(gstate);
#endif
_lens->set_film_size(_dimensions.x, -_dimensions.y);
_lens->set_film_offset(_dimensions.x * 0.5, _dimensions.y * 0.5);
}
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::do_cull
// Access: Protected, Virtual
// Description: Performs a cull traversal for this region.
////////////////////////////////////////////////////////////////////
void RocketRegion::
do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
GraphicsStateGuardian *gsg, Thread *current_thread) {
PStatTimer timer(get_cull_region_pcollector(), current_thread);
CullTraverser *trav = get_cull_traverser();
trav->set_cull_handler(cull_handler);
trav->set_scene(scene_setup, gsg, get_incomplete_render());
trav->set_view_frustum(NULL);
// We need to do this because libRocket may call into Python
// code to throw events.
#ifdef HAVE_ROCKET_PYTHON
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
#endif
if (_input_handler != NULL) {
int pl, pr, pb, pt;
get_pixels(pl, pr, pb, pt);
_input_handler->update_context(_context, pl, pb);
} else {
_context->Update();
}
#ifdef HAVE_ROCKET_PYTHON
PyGILState_Release(gstate);
#endif
_interface.render(_context, trav);
trav->end_traverse();
}

View File

@ -0,0 +1,85 @@
// Filename: rocketRegion.h
// Created by: rdb (30Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 ROCKETREGION_H
#define ROCKETREGION_H
#include "config_rocket.h"
#include "displayRegion.h"
#include "rocketRenderInterface.h"
#include "rocketInputHandler.h"
class OrthographicLens;
////////////////////////////////////////////////////////////////////
// Class : RocketRegion
// Description : Represents a region in a window or buffer where
// the libRocket UI will be rendered to.
////////////////////////////////////////////////////////////////////
class EXPCL_ROCKET RocketRegion : public DisplayRegion {
protected:
RocketRegion(GraphicsOutput *window, const LVecBase4 &dimensions,
const string &context_name);
virtual void pixel_size_changed(int x_size, int y_size);
virtual void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
GraphicsStateGuardian *gsg, Thread *current_thread);
public:
virtual ~RocketRegion();
PUBLISHED:
INLINE static RocketRegion* make(const string &context_name,
GraphicsOutput *window);
INLINE static RocketRegion* make(const string &context_name,
GraphicsOutput *window,
const LVecBase4 &dimensions);
#ifndef CPPPARSER
INLINE Rocket::Core::Context* get_context() const;
#endif
#ifdef HAVE_ROCKET_PYTHON
EXTENSION(PyObject *get_context() const);
#endif
INLINE void set_input_handler(RocketInputHandler *handler);
INLINE RocketInputHandler *get_input_handler() const;
private:
RocketRenderInterface _interface;
Rocket::Core::Context* _context;
Rocket::Core::Vector2i _dimensions;
OrthographicLens* _lens;
PT(RocketInputHandler) _input_handler;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
DisplayRegion::init_type();
register_type(_type_handle, "RocketRegion",
DisplayRegion::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 "rocketRegion.I"
#endif /* ROCKETREGION_H */

View File

@ -0,0 +1,37 @@
// Filename: rocketRegion_ext.I
// Created by: rdb (06Dec11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketRegion.h"
#ifndef CPPPARSER
#undef this
#include <Rocket/Core/Python/Utilities.h>
#endif
////////////////////////////////////////////////////////////////////
// Function: RocketRegion::get_context
// Access: Published
// Description: Returns a pointer to the Rocket context associated
// with this region. Will only be valid as long as this
// region still exists, so be sure to toss it when you
// toss the region itself.
// It's best to call this method just once and store
// the context in a Python variable, to avoid overhead.
////////////////////////////////////////////////////////////////////
PyObject* EXT_CONST_METHOD(RocketRegion,
get_context) {
Rocket::Core::Context* context = _ext_this->get_context();
python::object py_context = Rocket::Core::Python::Utilities::MakeObject(context);
return py_context.ptr();
}

View File

@ -0,0 +1,302 @@
// Filename: rocketRenderInterface.cxx
// Created by: rdb (04Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketRenderInterface.h"
#include "cullableObject.h"
#include "cullHandler.h"
#include "geomVertexData.h"
#include "geomVertexArrayData.h"
#include "internalName.h"
#include "geomVertexWriter.h"
#include "geomTriangles.h"
#include "texture.h"
#include "textureAttrib.h"
#include "texturePool.h"
#include "colorBlendAttrib.h"
#include "cullBinAttrib.h"
#include "depthTestAttrib.h"
#include "depthWriteAttrib.h"
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::render
// Access: Public
// Description: Called by RocketNode in cull_callback. Invokes
// context->Render() and culls the result.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
render(Rocket::Core::Context* context, CullTraverser *trav) {
nassertv(context != NULL);
MutexHolder holder(_lock);
const Rocket::Core::Vector2i &dimensions = context->GetDimensions();
//CPT(TransformState) scale = TransformState::make_scale(
// LVector3::right() * (1.0 / dimensions.x) +
// LVector3::down() * (1.0 / dimensions.y));
_trav = trav;
_net_transform = trav->get_world_transform();
_net_state = RenderState::make(
CullBinAttrib::make("unsorted", 0),
DepthTestAttrib::make(RenderAttrib::M_none),
DepthWriteAttrib::make(DepthWriteAttrib::M_off),
ColorBlendAttrib::make(ColorBlendAttrib::M_add,
ColorBlendAttrib::O_incoming_alpha,
ColorBlendAttrib::O_one_minus_incoming_alpha
)
);
context->Render();
_trav = NULL;
_net_transform = NULL;
_net_state = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::make_geom
// Access: Protected
// Description: Called internally to make a Geom from Rocket data.
////////////////////////////////////////////////////////////////////
PT(Geom) RocketRenderInterface::
make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, GeomEnums::UsageHint uh) {
PT(GeomVertexData) vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4t2(), uh);
vdata->unclean_set_num_rows(num_vertices);
{
GeomVertexWriter vwriter(vdata, InternalName::get_vertex());
GeomVertexWriter cwriter(vdata, InternalName::get_color());
GeomVertexWriter twriter(vdata, InternalName::get_texcoord());
// Write the vertex information.
for (int i = 0; i < num_vertices; ++i) {
const Rocket::Core::Vertex &vertex = vertices[i];
vwriter.add_data3f(LVector3f::right() * vertex.position.x + LVector3f::up() * vertex.position.y);
cwriter.add_data4i(vertex.colour.red, vertex.colour.green,
vertex.colour.blue, vertex.colour.alpha);
twriter.add_data2f(vertex.tex_coord.x, 1.0f - vertex.tex_coord.y);
}
}
// Create a primitive and write the indices.
PT(GeomTriangles) triangles = new GeomTriangles(uh);
{
PT(GeomVertexArrayData) idata = triangles->modify_vertices();
idata->unclean_set_num_rows(num_indices);
GeomVertexWriter iwriter(idata, 0);
for (int i = 0; i < num_indices; ++i) {
iwriter.add_data1i(indices[i]);
}
}
PT(Geom) geom = new Geom(vdata);
geom->add_primitive(triangles);
return geom;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::render_geom
// Access: Protected
// Description: Only call this during render(). Culls a geom.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
render_geom(const Geom* geom, const RenderState* state, const Rocket::Core::Vector2f& translation) {
LVector3 offset = LVector3::right() * translation.x + LVector3::up() * translation.y;
rocket_cat.spam()
<< "Rendering geom " << geom << " with state "
<< *state << " and translation " << offset << "\n";
CPT(TransformState) net_transform, modelview_transform;
net_transform = _net_transform->compose(TransformState::make_pos(offset));
modelview_transform = _trav->get_world_transform()->compose(net_transform);
CullableObject *object =
new CullableObject(geom, _net_state->compose(state),
net_transform, modelview_transform,
_trav->get_gsg());
_trav->get_cull_handler()->record_object(object, _trav);
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::RenderGeometry
// Access: Protected
// Description: Called by Rocket when it wants to render geometry
// that the application does not wish to optimize.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) {
PT(Geom) geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_stream);
CPT(RenderState) state;
if ((Texture*) texture != (Texture*) NULL) {
state = RenderState::make(TextureAttrib::make((Texture*) texture));
} else {
state = RenderState::make_empty();
}
render_geom(geom, state, translation);
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::CompileGeometry
// Access: Protected
// Description: Called by Rocket when it wants to compile geometry
// it believes will be static for the forseeable future.
////////////////////////////////////////////////////////////////////
Rocket::Core::CompiledGeometryHandle RocketRenderInterface::
CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture) {
CompiledGeometry *c = new CompiledGeometry;
c->_geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_static);
if ((Texture*) texture != (Texture*) NULL) {
PT(TextureStage) stage = new TextureStage("");
stage->set_mode(TextureStage::M_replace);
CPT(TextureAttrib) attr = DCAST(TextureAttrib, TextureAttrib::make());
attr = DCAST(TextureAttrib, attr->add_on_stage(stage, (Texture*) texture));
c->_state = RenderState::make(attr);
rocket_cat.debug()
<< "Compiled geom " << c->_geom << " with texture '"
<< ((Texture*) texture)->get_name() << "'\n";
} else {
c->_state = RenderState::make_empty();
rocket_cat.debug()
<< "Compiled geom " << c->_geom << " without texture\n";
}
return (Rocket::Core::CompiledGeometryHandle) c;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::RenderCompiledGeometry
// Access: Protected
// Description: Called by Rocket when it wants to render
// application-compiled geometry.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation) {
CompiledGeometry *c = (CompiledGeometry*) geometry;
render_geom(c->_geom, c->_state, translation);
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::ReleaseCompiledGeometry
// Access: Protected
// Description: Called by Rocket when it wants to release
// application-compiled geometry.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry) {
delete (CompiledGeometry*) geometry;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::LoadTexture
// Access: Protected
// Description: Called by Rocket when a texture is required by the
// library.
////////////////////////////////////////////////////////////////////
bool RocketRenderInterface::
LoadTexture(Rocket::Core::TextureHandle& texture_handle,
Rocket::Core::Vector2i& texture_dimensions,
const Rocket::Core::String& source) {
PT(Texture) tex = TexturePool::load_texture(Filename::from_os_specific(source.CString()));
if (tex == NULL) {
texture_handle = 0;
texture_dimensions.x = 0;
texture_dimensions.y = 0;
return false;
}
texture_dimensions.x = tex->get_x_size();
texture_dimensions.y = tex->get_y_size();
tex->ref();
texture_handle = (Rocket::Core::TextureHandle) tex.p();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::GenerateTexture
// Access: Protected
// Description: Called by Rocket when a texture is required to be
// built from an internally-generated sequence of pixels.
////////////////////////////////////////////////////////////////////
bool RocketRenderInterface::
GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
const Rocket::Core::byte* source,
const Rocket::Core::Vector2i& source_dimensions) {
PT(Texture) tex = new Texture;
tex->setup_2d_texture(source_dimensions.x, source_dimensions.y,
Texture::T_unsigned_byte, Texture::F_rgba);
PTA_uchar image = tex->modify_ram_image();
// Convert RGBA to BGRA
for (size_t i = 0; i < image.size(); i += 4) {
image[i] = source[i + 2];
image[i + 1] = source[i + 1];
image[i + 2] = source[i];
image[i + 3] = source[i + 3];
}
tex->set_wrap_u(Texture::WM_clamp);
tex->set_wrap_v(Texture::WM_clamp);
tex->ref();
texture_handle = (Rocket::Core::TextureHandle) tex.p();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::ReleaseTexture
// Access: Protected
// Description: Called by Rocket when a loaded texture is no longer
// required.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
ReleaseTexture(Rocket::Core::TextureHandle texture_handle) {
Texture* tex = (Texture*) texture_handle;
if (tex != (Texture*) NULL) {
tex->unref();
}
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::EnableScissorRegion
// Access: Protected
// Description: Called by Rocket when it wants to enable or disable
// scissoring to clip content.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
EnableScissorRegion(bool enable) {
}
////////////////////////////////////////////////////////////////////
// Function: RocketRenderInterface::SetScissorRegion
// Access: Protected
// Description: Called by Rocket when it wants to change the
// scissor region.
////////////////////////////////////////////////////////////////////
void RocketRenderInterface::
SetScissorRegion(int x, int y, int width, int height) {
}

View File

@ -0,0 +1,65 @@
// Filename: rocketRenderInterface.h
// Created by: rdb (04Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 ROCKET_RENDER_INTERFACE_H
#define ROCKET_RENDER_INTERFACE_H
#include "config_rocket.h"
#include "cullTraverser.h"
#include "cullTraverserData.h"
#include "geom.h"
#include "renderState.h"
#include "transformState.h"
#include <Rocket/Core/RenderInterface.h>
class RocketRenderInterface : public Rocket::Core::RenderInterface {
public:
void render(Rocket::Core::Context* context, CullTraverser *trav);
protected:
struct CompiledGeometry {
CPT(Geom) _geom;
CPT(RenderState) _state;
};
PT(Geom) make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, GeomEnums::UsageHint uh);
void render_geom(const Geom* geom, const RenderState* state, const Rocket::Core::Vector2f& translation);
void RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation);
Rocket::Core::CompiledGeometryHandle CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture);
void RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation);
void ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry);
bool LoadTexture(Rocket::Core::TextureHandle& texture_handle,
Rocket::Core::Vector2i& texture_dimensions,
const Rocket::Core::String& source);
bool GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
const Rocket::Core::byte* source,
const Rocket::Core::Vector2i& source_dimensions);
void ReleaseTexture(Rocket::Core::TextureHandle texture_handle);
void EnableScissorRegion(bool enable);
void SetScissorRegion(int x, int y, int width, int height);
private:
Mutex _lock;
// These are temporarily filled in by render().
CullTraverser *_trav;
CPT(TransformState) _net_transform;
CPT(RenderState) _net_state;
};
#endif

View File

@ -0,0 +1,56 @@
// Filename: rocketSystemInterface.h
// Created by: rdb (03Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 "rocketSystemInterface.h"
#include "clockObject.h"
////////////////////////////////////////////////////////////////////
// Function: RocketSystemInterface::GetElapsedTime
// Access: Public
// Description: Get the number of seconds elapsed since the start
// of the application.
////////////////////////////////////////////////////////////////////
float RocketSystemInterface::
GetElapsedTime() {
ClockObject *clock = ClockObject::get_global_clock();
//XXX not sure exactly how Rocket uses uses it, maybe get_frame_time is better?
return clock->get_real_time();
}
////////////////////////////////////////////////////////////////////
// Function: RocketSystemInterface::LogMessage
// Access: Public
// Description: Log the specified message. Returns true to
// continue execution, false to break into the
// debugger.
////////////////////////////////////////////////////////////////////
bool RocketSystemInterface::
LogMessage(Rocket::Core::Log::Type type, const Rocket::Core::String& message) {
switch(type) {
case Rocket::Core::Log::LT_ALWAYS:
case Rocket::Core::Log::LT_ERROR:
case Rocket::Core::Log::LT_ASSERT:
rocket_cat.error() << message.CString() << "\n";
return true;
case Rocket::Core::Log::LT_WARNING:
rocket_cat.warning() << message.CString() << "\n";
return true;
case Rocket::Core::Log::LT_INFO:
rocket_cat.info() << message.CString() << "\n";
return true;
case Rocket::Core::Log::LT_DEBUG:
rocket_cat.debug() << message.CString() << "\n";
}
return true;
}

View File

@ -0,0 +1,29 @@
// Filename: rocketSystemInterface.h
// Created by: rdb (03Nov11)
//
////////////////////////////////////////////////////////////////////
//
// 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 ROCKET_SYSTEM_INTERFACE_H
#define ROCKET_SYSTEM_INTERFACE_H
#include "config_rocket.h"
#include <Rocket/Core/SystemInterface.h>
#include <Rocket/Core/Log.h>
class RocketSystemInterface : public Rocket::Core::SystemInterface {
public:
float GetElapsedTime();
bool LogMessage(Rocket::Core::Log::Type type, const Rocket::Core::String& message);
};
#endif

View File

@ -0,0 +1,6 @@
#include "config_rocket.cxx"
#include "rocketFileInterface.cxx"
#include "rocketInputHandler.cxx"
#include "rocketRegion.cxx"
#include "rocketRenderInterface.cxx"
#include "rocketSystemInterface.cxx"