Panda3D
rocketRegion.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file rocketRegion.cxx
10  * @author rdb
11  * @date 2011-11-30
12  */
13 
14 #include "rocketRegion.h"
15 #include "graphicsOutput.h"
16 #include "orthographicLens.h"
17 #include "pStatTimer.h"
18 
19 #if defined(HAVE_ROCKET_DEBUGGER) && !defined(CPPPARSER)
20 #include <Rocket/Debugger.h>
21 #endif
22 
23 #ifdef HAVE_PYTHON
24 #include "py_panda.h"
25 #endif
26 
27 TypeHandle RocketRegion::_type_handle;
28 
29 /**
30  * Make sure that context_name is unique.
31  */
32 RocketRegion::
33 RocketRegion(GraphicsOutput *window, const LVecBase4 &dr_dimensions,
34  const std::string &context_name) :
35  DisplayRegion(window, dr_dimensions) {
36 
37  // A hack I don't like. libRocket's decorator system has a bug somewhere,
38  // and this seems to be a workaround.
39  if (Rocket::Core::GetRenderInterface() == nullptr) {
40  Rocket::Core::SetRenderInterface(&_interface);
41  }
42 
43  int pl, pr, pb, pt;
44  get_pixels(pl, pr, pb, pt);
45  Rocket::Core::Vector2i dimensions (pr - pl, pt - pb);
46 
47  rocket_cat.debug()
48  << "Setting initial context dimensions to ("
49  << dimensions.x << ", " << dimensions.y << ")\n";
50 
51  _context = Rocket::Core::CreateContext(context_name.c_str(),
52  dimensions, &_interface);
53  nassertv(_context != nullptr);
54 
55  _lens = new OrthographicLens;
56  _lens->set_film_size(dimensions.x, -dimensions.y);
57  _lens->set_film_offset(dimensions.x * 0.5, dimensions.y * 0.5);
58  _lens->set_near_far(-1, 1);
59 
60  PT(Camera) cam = new Camera(context_name, _lens);
61  set_camera(NodePath(cam));
62 }
63 
64 /**
65  *
66  */
67 RocketRegion::
68 ~RocketRegion() {
69  if (Rocket::Core::GetRenderInterface() == &_interface) {
70  Rocket::Core::SetRenderInterface(nullptr);
71  }
72 
73  if (_context != nullptr) {
74  if (_context->GetReferenceCount() > 1) {
75  _context->RemoveReference();
76  return;
77  }
78 
79  // We need to do this because libRocket may call into Python code to throw
80  // destruction events.
81 #ifdef HAVE_ROCKET_PYTHON
82  PyGILState_STATE gstate;
83  gstate = PyGILState_Ensure();
84 #endif
85 
86  _context->RemoveReference();
87 
88 #ifdef HAVE_ROCKET_PYTHON
89  PyGILState_Release(gstate);
90 #endif
91  }
92 }
93 
94 /**
95  * Performs a cull traversal for this region.
96  */
97 void RocketRegion::
98 do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
99  GraphicsStateGuardian *gsg, Thread *current_thread) {
100 
101  PStatTimer timer(get_cull_region_pcollector(), current_thread);
102 
103  // We (unfortunately) need to do this because libRocket may call into Python
104  // code to throw events.
105 #ifdef HAVE_ROCKET_PYTHON
106  PyGILState_STATE gstate;
107  gstate = PyGILState_Ensure();
108 #endif
109 
110  int pl, pr, pb, pt;
111  get_pixels(pl, pr, pb, pt);
112  Rocket::Core::Vector2i dimensions (pr - pl, pt - pb);
113 
114  if (_context->GetDimensions() != dimensions) {
115  rocket_cat.debug() << "Setting context dimensions to ("
116  << dimensions.x << ", " << dimensions.y << ")\n";
117 
118  _context->SetDimensions(dimensions);
119 
120  _lens->set_film_size(dimensions.x, -dimensions.y);
121  _lens->set_film_offset(dimensions.x * 0.5, dimensions.y * 0.5);
122  }
123 
124  if (_input_handler != nullptr) {
125  _input_handler->update_context(_context, pl, pb);
126  } else {
127  _context->Update();
128  }
129 
131  trav->set_cull_handler(cull_handler);
132  trav->set_scene(scene_setup, gsg, get_incomplete_render());
133  trav->set_view_frustum(nullptr);
134 
135  _interface.render(_context, trav);
136 
137 #ifdef HAVE_ROCKET_PYTHON
138  PyGILState_Release(gstate);
139 #endif
140 
141  trav->end_traverse();
142 }
143 
144 /**
145  * Initializes the libRocket debugger. This will return false if the debugger
146  * failed to initialize, or if support for the debugger has not been built in
147  * (for example in an optimize=4 build).
148  */
150 init_debugger() {
151 #ifdef HAVE_ROCKET_DEBUGGER
152  return Rocket::Debugger::Initialise(_context);
153 #else
154  return false;
155 #endif
156 }
157 
158 /**
159  * Sets whether the debugger should be visible.
160  */
161 void RocketRegion::
162 set_debugger_visible(bool visible) {
163 #ifdef HAVE_ROCKET_DEBUGGER
164  Rocket::Debugger::SetVisible(visible);
165 #endif
166 }
167 
168 /**
169  * Returns true if the debugger is visible.
170  */
171 bool RocketRegion::
172 is_debugger_visible() const {
173 #ifdef HAVE_ROCKET_DEBUGGER
174  return Rocket::Debugger::IsVisible();
175 #else
176  return false;
177 #endif
178 }
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
This defines the abstract interface for an object that receives Geoms identified by the CullTraverser...
Definition: cullHandler.h:28
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
void set_view_frustum(GeometricBoundingVolume *view_frustum)
Specifies the bounding volume that corresponds to the view frustum.
virtual void end_traverse()
Should be called when the traverser has finished traversing its scene, this gives it a chance to do a...
virtual void set_scene(SceneSetup *scene_setup, GraphicsStateGuardianBase *gsg, bool dr_incomplete_render)
Sets the SceneSetup object that indicates the initial camera position, etc.
void set_cull_handler(CullHandler *cull_handler)
Specifies the object that will receive the culled Geoms.
A rectangular subregion within a window for rendering into.
Definition: displayRegion.h:57
get_cull_traverser
Returns the CullTraverser that will be used to draw the contents of this DisplayRegion.
get_incomplete_render
Returns the incomplete_render flag.
PStatCollector & get_cull_region_pcollector()
Returns a PStatCollector for timing the cull operation for just this DisplayRegion.
void get_pixels(int &pl, int &pr, int &pb, int &pt) const
Retrieves the coordinates of the DisplayRegion within its window, in pixels.
This is a base class for the various different classes that represent the result of a frame of render...
Encapsulates all the communication with a particular instance of a given rendering backend.
set_film_size
Sets the horizontal size of the film without changing its shape.
Definition: lens.h:82
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
An orthographic lens.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:30
is_debugger_visible
Returns true if the debugger is visible.
Definition: rocketRegion.h:59
bool init_debugger()
Initializes the libRocket debugger.
set_debugger_visible
Sets whether the debugger should be visible.
Definition: rocketRegion.h:59
void render(Rocket::Core::Context *context, CullTraverser *trav)
Called by RocketNode in cull_callback.
This object holds the camera position, etc., and other general setup information for rendering a part...
Definition: sceneSetup.h:32
A thread; that is, a lightweight process.
Definition: thread.h:46
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.