00001 // Filename: displayRegion.cxx 00002 // Created by: cary (10Feb99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 #include "graphicsLayer.h" 00021 #include "graphicsChannel.h" 00022 #include "graphicsWindow.h" 00023 #include "config_display.h" 00024 #include "displayRegion.h" 00025 #include "camera.h" 00026 #include "dcast.h" 00027 #include "mutexHolder.h" 00028 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: DisplayRegion::Constructor 00032 // Access: Public 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 DisplayRegion:: 00036 DisplayRegion(GraphicsLayer *layer) : 00037 _l(0.), _r(1.), _b(0.), _t(1.), 00038 _layer(layer), 00039 _camera_node((Camera *)NULL), 00040 _active(true) 00041 { 00042 compute_pixels(); 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: DisplayRegion::Constructor 00047 // Access: Public 00048 // Description: 00049 //////////////////////////////////////////////////////////////////// 00050 DisplayRegion:: 00051 DisplayRegion(GraphicsLayer *layer, const float l, 00052 const float r, const float b, const float t) : 00053 _l(l), _r(r), _b(b), _t(t), 00054 _layer(layer), 00055 _camera_node((Camera *)NULL), 00056 _active(true) 00057 { 00058 compute_pixels(); 00059 } 00060 00061 //////////////////////////////////////////////////////////////////// 00062 // Function: DisplayRegion::Constructor 00063 // Access: Public 00064 // Description: This constructor makes a DisplayRegion that is not 00065 // associated with any particular layer; this is 00066 // typically for rendering a temporary pass. 00067 //////////////////////////////////////////////////////////////////// 00068 DisplayRegion:: 00069 DisplayRegion(int xsize, int ysize) : 00070 _l(0.), _r(1.), _b(0.), _t(1.), 00071 _pl(0), _pr(xsize), _pb(0), _pt(ysize), 00072 _layer((GraphicsLayer *)NULL), 00073 _camera_node((Camera *)NULL), 00074 _active(true) 00075 { 00076 } 00077 00078 //////////////////////////////////////////////////////////////////// 00079 // Function: DisplayRegion::Copy Constructor 00080 // Access: Private 00081 // Description: 00082 //////////////////////////////////////////////////////////////////// 00083 DisplayRegion:: 00084 DisplayRegion(const DisplayRegion&) { 00085 nassertv(false); 00086 } 00087 00088 //////////////////////////////////////////////////////////////////// 00089 // Function: DisplayRegion::Copy Assignment Operator 00090 // Access: Private 00091 // Description: 00092 //////////////////////////////////////////////////////////////////// 00093 void DisplayRegion:: 00094 operator = (const DisplayRegion&) { 00095 nassertv(false); 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: DisplayRegion::Destructor 00100 // Access: Public 00101 // Description: 00102 //////////////////////////////////////////////////////////////////// 00103 DisplayRegion:: 00104 ~DisplayRegion() { 00105 set_camera(NodePath()); 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: DisplayRegion::get_dimensions 00110 // Access: Published 00111 // Description: Retrieves the coordinates of the DisplayRegion's 00112 // rectangle within its GraphicsLayer. These numbers 00113 // will be in the range [0..1]. 00114 //////////////////////////////////////////////////////////////////// 00115 void DisplayRegion:: 00116 get_dimensions(float &l, float &r, float &b, float &t) const { 00117 MutexHolder holder(_lock); 00118 l = _l; 00119 r = _r; 00120 b = _b; 00121 t = _t; 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: DisplayRegion::get_left 00126 // Access: Published 00127 // Description: Retrieves the x coordinate of the left edge of the 00128 // rectangle within its GraphicsLayer. This number 00129 // will be in the range [0..1]. 00130 //////////////////////////////////////////////////////////////////// 00131 float DisplayRegion:: 00132 get_left() const { 00133 MutexHolder holder(_lock); 00134 return _l; 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: DisplayRegion::get_right 00139 // Access: Published 00140 // Description: Retrieves the x coordinate of the right edge of the 00141 // rectangle within its GraphicsLayer. This number 00142 // will be in the range [0..1]. 00143 //////////////////////////////////////////////////////////////////// 00144 float DisplayRegion:: 00145 get_right() const { 00146 MutexHolder holder(_lock); 00147 return _r; 00148 } 00149 00150 //////////////////////////////////////////////////////////////////// 00151 // Function: DisplayRegion::get_bottom 00152 // Access: Published 00153 // Description: Retrieves the y coordinate of the bottom edge of 00154 // the rectangle within its GraphicsLayer. This 00155 // number will be in the range [0..1]. 00156 //////////////////////////////////////////////////////////////////// 00157 float DisplayRegion:: 00158 get_bottom() const { 00159 MutexHolder holder(_lock); 00160 return _b; 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function: DisplayRegion::get_top 00165 // Access: Published 00166 // Description: Retrieves the y coordinate of the top edge of the 00167 // rectangle within its GraphicsLayer. This number 00168 // will be in the range [0..1]. 00169 //////////////////////////////////////////////////////////////////// 00170 float DisplayRegion:: 00171 get_top() const { 00172 MutexHolder holder(_lock); 00173 return _t; 00174 } 00175 00176 //////////////////////////////////////////////////////////////////// 00177 // Function: DisplayRegion::set_dimensions 00178 // Access: Published 00179 // Description: Changes the portion of the framebuffer this 00180 // DisplayRegion corresponds to. The parameters range 00181 // from 0 to 1, where 0,0 is the lower left corner and 00182 // 1,1 is the upper right; (0, 1, 0, 1) represents the 00183 // whole screen. 00184 //////////////////////////////////////////////////////////////////// 00185 void DisplayRegion:: 00186 set_dimensions(float l, float r, float b, float t) { 00187 MutexHolder holder(_lock); 00188 _l = l; 00189 _r = r; 00190 _b = b; 00191 _t = t; 00192 00193 const GraphicsWindow *win = get_window(); 00194 if (win != (GraphicsWindow *)NULL) { 00195 WindowProperties properties = win->get_properties(); 00196 if (properties.has_size()) { 00197 do_compute_pixels(properties.get_x_size(), properties.get_y_size()); 00198 } 00199 } 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: DisplayRegion::get_layer 00204 // Access: Published 00205 // Description: Returns the layer associated with this particular 00206 // DisplayRegion, or NULL if no layer is associated 00207 // (or if the layer was deleted). 00208 //////////////////////////////////////////////////////////////////// 00209 GraphicsLayer *DisplayRegion:: 00210 get_layer() const { 00211 MutexHolder holder(_lock); 00212 return _layer; 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: DisplayRegion::get_channel 00217 // Access: Published 00218 // Description: Returns the GraphicsChannel that this DisplayRegion is 00219 // ultimately associated with, or NULL if no channel is 00220 // associated. 00221 //////////////////////////////////////////////////////////////////// 00222 GraphicsChannel *DisplayRegion:: 00223 get_channel() const { 00224 MutexHolder holder(_lock); 00225 return (_layer != (GraphicsLayer *)NULL) ? _layer->get_channel() : NULL; 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: DisplayRegion::get_window 00230 // Access: Published 00231 // Description: Returns the GraphicsWindow that this DisplayRegion is 00232 // ultimately associated with, or NULL if no window is 00233 // associated. 00234 //////////////////////////////////////////////////////////////////// 00235 GraphicsWindow *DisplayRegion:: 00236 get_window() const { 00237 MutexHolder holder(_lock); 00238 return (_layer != (GraphicsLayer *)NULL) ? _layer->get_window() : NULL; 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: DisplayRegion::get_pipe 00243 // Access: Published 00244 // Description: Returns the GraphicsPipe that this DisplayRegion is 00245 // ultimately associated with, or NULL if no pipe is 00246 // associated. 00247 //////////////////////////////////////////////////////////////////// 00248 GraphicsPipe *DisplayRegion:: 00249 get_pipe() const { 00250 MutexHolder holder(_lock); 00251 return (_layer != (GraphicsLayer *)NULL) ? _layer->get_pipe() : NULL; 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: DisplayRegion::set_camera 00256 // Access: Published 00257 // Description: Sets the camera that is associated with this 00258 // DisplayRegion. There is a one-to-many association 00259 // between cameras and DisplayRegions; one camera may be 00260 // shared by multiple DisplayRegions. 00261 // 00262 // The camera is actually set via a NodePath, which 00263 // clarifies which instance of the camera (if there 00264 // happen to be multiple instances) we should use. 00265 //////////////////////////////////////////////////////////////////// 00266 void DisplayRegion:: 00267 set_camera(const NodePath &camera) { 00268 MutexHolder holder(_lock); 00269 Camera *camera_node = (Camera *)NULL; 00270 if (!camera.is_empty()) { 00271 DCAST_INTO_V(camera_node, camera.node()); 00272 } 00273 00274 if (camera_node != _camera_node) { 00275 if (_camera_node != (Camera *)NULL) { 00276 // We need to tell the old camera we're not using him anymore. 00277 _camera_node->remove_display_region(this); 00278 } 00279 _camera_node = camera_node; 00280 if (_camera_node != (Camera *)NULL) { 00281 // Now tell the new camera we are using him. 00282 _camera_node->add_display_region(this); 00283 } 00284 } 00285 00286 _camera = camera; 00287 } 00288 00289 //////////////////////////////////////////////////////////////////// 00290 // Function: DisplayRegion::get_camera 00291 // Access: Published 00292 // Description: Returns the camera associated with this 00293 // DisplayRegion, or an empty NodePath if no camera is 00294 // associated. 00295 //////////////////////////////////////////////////////////////////// 00296 const NodePath &DisplayRegion:: 00297 get_camera() const { 00298 MutexHolder holder(_lock); 00299 return _camera; 00300 } 00301 00302 //////////////////////////////////////////////////////////////////// 00303 // Function: DisplayRegion::set_active 00304 // Access: Published 00305 // Description: Sets the active flag associated with the 00306 // DisplayRegion. If the DisplayRegion is marked 00307 // inactive, nothing is rendered. 00308 //////////////////////////////////////////////////////////////////// 00309 void DisplayRegion:: 00310 set_active(bool active) { 00311 MutexHolder holder(_lock); 00312 if (active != _active) { 00313 _active = active; 00314 win_display_regions_changed(); 00315 } 00316 } 00317 00318 //////////////////////////////////////////////////////////////////// 00319 // Function: DisplayRegion::compute_pixels 00320 // Access: Published 00321 // Description: Computes the pixel locations of the DisplayRegion 00322 // within its layer. The DisplayRegion will request the 00323 // size from the window. 00324 //////////////////////////////////////////////////////////////////// 00325 void DisplayRegion:: 00326 compute_pixels() { 00327 const GraphicsWindow *win = get_window(); 00328 if (win != (GraphicsWindow *)NULL) { 00329 MutexHolder holder(_lock); 00330 WindowProperties properties = win->get_properties(); 00331 if (!properties.has_size()) { 00332 // If the window doesn't know its size yet, maybe it will 00333 // eventually be given the size it's requesting. 00334 properties = win->get_requested_properties(); 00335 } 00336 00337 if (properties.has_size()) { 00338 do_compute_pixels(properties.get_x_size(), properties.get_y_size()); 00339 } else { 00340 do_compute_pixels(0, 0); 00341 } 00342 } 00343 } 00344 00345 //////////////////////////////////////////////////////////////////// 00346 // Function: DisplayRegion::compute_pixels 00347 // Access: Published 00348 // Description: Computes the pixel locations of the DisplayRegion 00349 // within its layer, given the size of the layer in 00350 // pixels. 00351 //////////////////////////////////////////////////////////////////// 00352 void DisplayRegion:: 00353 compute_pixels(int x_size, int y_size) { 00354 MutexHolder holder(_lock); 00355 do_compute_pixels(x_size, y_size); 00356 } 00357 00358 //////////////////////////////////////////////////////////////////// 00359 // Function: DisplayRegion::get_pixels 00360 // Access: Published 00361 // Description: Retrieves the coordinates of the DisplayRegion within 00362 // its layer, in pixels. 00363 //////////////////////////////////////////////////////////////////// 00364 void DisplayRegion:: 00365 get_pixels(int &pl, int &pr, int &pb, int &pt) const { 00366 MutexHolder holder(_lock); 00367 pl = _pl; 00368 pr = _pr; 00369 pb = _pb; 00370 pt = _pt; 00371 } 00372 00373 //////////////////////////////////////////////////////////////////// 00374 // Function: DisplayRegion::get_region_pixels 00375 // Access: Published 00376 // Description: Retrieves the coordinates of the DisplayRegion within 00377 // its layer, as the pixel location of its bottom-left 00378 // corner, along with a pixel width and height. 00379 //////////////////////////////////////////////////////////////////// 00380 void DisplayRegion:: 00381 get_region_pixels(int &xo, int &yo, int &w, int &h) const { 00382 MutexHolder holder(_lock); 00383 xo = _pl; 00384 yo = _pb; 00385 w = _pr - _pl; 00386 h = _pt - _pb; 00387 } 00388 00389 //////////////////////////////////////////////////////////////////// 00390 // Function: DisplayRegion::get_pixel_width 00391 // Access: Published 00392 // Description: Returns the width of the DisplayRegion in pixels. 00393 //////////////////////////////////////////////////////////////////// 00394 int DisplayRegion:: 00395 get_pixel_width() const { 00396 MutexHolder holder(_lock); 00397 return _pr - _pl; 00398 } 00399 00400 //////////////////////////////////////////////////////////////////// 00401 // Function: DisplayRegion::get_pixel_height 00402 // Access: Published 00403 // Description: Returns the height of the DisplayRegion in pixels. 00404 //////////////////////////////////////////////////////////////////// 00405 int DisplayRegion:: 00406 get_pixel_height() const { 00407 MutexHolder holder(_lock); 00408 return _pt - _pb; 00409 } 00410 00411 //////////////////////////////////////////////////////////////////// 00412 // Function: DisplayRegion::output 00413 // Access: Published 00414 // Description: 00415 //////////////////////////////////////////////////////////////////// 00416 void DisplayRegion:: 00417 output(ostream &out) const { 00418 MutexHolder holder(_lock); 00419 out << "DisplayRegion(" << _l << " " << _r << " " << _b << " " << _t 00420 << ")=pixels(" << _pl << " " << _pr << " " << _pb << " " << _pt 00421 << ")"; 00422 } 00423 00424 //////////////////////////////////////////////////////////////////// 00425 // Function: DisplayRegion::win_display_regions_changed 00426 // Access: Private 00427 // Description: Intended to be called when the active state on a 00428 // nested channel or layer or display region changes, 00429 // forcing the window to recompute its list of active 00430 // display regions. It is assumed the lock is already 00431 // held. 00432 //////////////////////////////////////////////////////////////////// 00433 void DisplayRegion:: 00434 win_display_regions_changed() { 00435 if (_layer != (GraphicsLayer *)NULL) { 00436 _layer->win_display_regions_changed(); 00437 } 00438 }