00001 // Filename: graphicsChannel.cxx 00002 // Created by: mike (09Jan97) 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 #include "graphicsChannel.h" 00020 #include "graphicsWindow.h" 00021 #include "graphicsLayer.h" 00022 #include "config_display.h" 00023 #include "mutexHolder.h" 00024 00025 #include "pmap.h" 00026 00027 TypeHandle GraphicsChannel::_type_handle; 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: GraphicsChannel::Constructor 00031 // Access: Protected 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 GraphicsChannel:: 00035 GraphicsChannel() { 00036 _window = NULL; 00037 _is_active = true; 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: GraphicsChannel::Constructor 00042 // Access: Public 00043 // Description: This is public just so derived window types can 00044 // easily call it. Don't call it directly; instead, use 00045 // GraphicsWindow::get_channel() to get a channel. 00046 //////////////////////////////////////////////////////////////////// 00047 GraphicsChannel:: 00048 GraphicsChannel(GraphicsWindow *window) 00049 : _window(window) 00050 { 00051 _is_active = true; 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: GraphicsChannel::Copy Constructor 00056 // Access: Private 00057 // Description: 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE GraphicsChannel:: 00060 GraphicsChannel(const GraphicsChannel &) { 00061 nassertv(false); 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: GraphicsChannel::Copy Assignment Operator 00066 // Access: Private 00067 // Description: 00068 //////////////////////////////////////////////////////////////////// 00069 INLINE void GraphicsChannel:: 00070 operator = (const GraphicsChannel &) { 00071 nassertv(false); 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: GraphicsChannel::Destructor 00076 // Access: Published 00077 // Description: 00078 //////////////////////////////////////////////////////////////////// 00079 GraphicsChannel:: 00080 ~GraphicsChannel() { 00081 // We don't have to destruct our child display regions explicitly, 00082 // since they are all reference-counted and will go away when their 00083 // pointers do. However, we do need to zero out their pointers to 00084 // us. 00085 GraphicsLayers::iterator li; 00086 for (li = _layers.begin(); 00087 li != _layers.end(); 00088 ++li) { 00089 GraphicsLayer *layer = (*li); 00090 MutexHolder holder(layer->_lock); 00091 layer->_channel = NULL; 00092 } 00093 00094 // We don't need to remove ourself from the windows's list of 00095 // channels. We must have already been removed, or we wouldn't be 00096 // destructing! 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: GraphicsChannel::make_layer 00101 // Access: Published 00102 // Description: Creates a new GraphicsLayer, associated with the 00103 // window, at the indicated index position. If the 00104 // index position negative or past the end of the array, 00105 // the end of the array is assumed. The layers will be 00106 // rendered on top of each other, in increasing order by 00107 // index, from back to front. 00108 //////////////////////////////////////////////////////////////////// 00109 GraphicsLayer *GraphicsChannel:: 00110 make_layer(int index) { 00111 MutexHolder holder(_lock); 00112 PT(GraphicsLayer) layer = new GraphicsLayer(this); 00113 if (index < 0 || index >= (int)_layers.size()) { 00114 _layers.push_back(layer); 00115 } else { 00116 _layers.insert(_layers.begin() + index, layer); 00117 } 00118 return layer; 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: GraphicsChannel::get_num_layers 00123 // Access: Published 00124 // Description: Returns the number of layers currently associated 00125 // with the channel. 00126 //////////////////////////////////////////////////////////////////// 00127 int GraphicsChannel:: 00128 get_num_layers() const { 00129 MutexHolder holder(_lock); 00130 return _layers.size(); 00131 } 00132 00133 //////////////////////////////////////////////////////////////////// 00134 // Function: GraphicsChannel::get_layer 00135 // Access: Published 00136 // Description: Returns the nth layer associated with the channel. 00137 //////////////////////////////////////////////////////////////////// 00138 GraphicsLayer *GraphicsChannel:: 00139 get_layer(int index) const { 00140 MutexHolder holder(_lock); 00141 if (index >= 0 && index < (int)_layers.size()) { 00142 return _layers[index]; 00143 } 00144 return NULL; 00145 } 00146 00147 //////////////////////////////////////////////////////////////////// 00148 // Function: GraphicsChannel::move_layer 00149 // Access: Published 00150 // Description: Changes the ordering of the layers so that the 00151 // indicated layer will move to the indicated position. 00152 // If to_index is negative or past the end of the array, 00153 // the end of the array is assumed. 00154 //////////////////////////////////////////////////////////////////// 00155 void GraphicsChannel:: 00156 move_layer(int from_index, int to_index) { 00157 MutexHolder holder(_lock); 00158 nassertv(from_index >= 0 && from_index < (int)_layers.size()); 00159 PT(GraphicsLayer) layer = _layers[from_index]; 00160 00161 if (to_index < 0 || to_index >= (int)_layers.size()) { 00162 _layers.erase(_layers.begin() + from_index); 00163 _layers.push_back(layer); 00164 00165 } else if (to_index > from_index) { 00166 // Move the layer later in the list. 00167 _layers.insert(_layers.begin() + to_index, layer); 00168 _layers.erase(_layers.begin() + from_index); 00169 00170 } else if (to_index < from_index) { 00171 // Move the layer earlier in the list. 00172 _layers.erase(_layers.begin() + from_index); 00173 _layers.insert(_layers.begin() + to_index, layer); 00174 } 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function: GraphicsChannel::remove_layer 00179 // Access: Published 00180 // Description: Removes the nth layer. This changes the numbers of 00181 // all subsequent layers. 00182 //////////////////////////////////////////////////////////////////// 00183 void GraphicsChannel:: 00184 remove_layer(int index) { 00185 MutexHolder holder(_lock); 00186 nassertv(index >= 0 && index < (int)_layers.size()); 00187 _layers.erase(_layers.begin() + index); 00188 } 00189 00190 //////////////////////////////////////////////////////////////////// 00191 // Function: GraphicsChannel::get_window 00192 // Access: Published 00193 // Description: Returns the GraphicsWindow that this channel is 00194 // associated with. It is possible that the 00195 // GraphicsWindow might have been deleted while an 00196 // outstanding PT(GraphicsChannel) prevented all of its 00197 // children channels from also being deleted; in this 00198 // unlikely case, get_window() may return NULL. 00199 //////////////////////////////////////////////////////////////////// 00200 GraphicsWindow *GraphicsChannel:: 00201 get_window() const { 00202 MutexHolder holder(_lock); 00203 return _window; 00204 } 00205 00206 //////////////////////////////////////////////////////////////////// 00207 // Function: GraphicsChannel::get_pipe 00208 // Access: Published 00209 // Description: Returns the GraphicsPipe that this channel is 00210 // ultimately associated with, or NULL if no pipe is 00211 // associated. 00212 //////////////////////////////////////////////////////////////////// 00213 GraphicsPipe *GraphicsChannel:: 00214 get_pipe() const { 00215 MutexHolder holder(_lock); 00216 return (_window != (GraphicsWindow *)NULL) ? _window->get_pipe() : NULL; 00217 } 00218 00219 //////////////////////////////////////////////////////////////////// 00220 // Function: GraphicsChannel::set_active 00221 // Access: Published 00222 // Description: Sets the active flag on the channel. If the channel 00223 // is marked as inactive, nothing will be rendered. 00224 //////////////////////////////////////////////////////////////////// 00225 void GraphicsChannel:: 00226 set_active(bool active) { 00227 MutexHolder holder(_lock); 00228 if (active != _is_active) { 00229 _is_active = active; 00230 win_display_regions_changed(); 00231 } 00232 } 00233 00234 //////////////////////////////////////////////////////////////////// 00235 // Function: GraphicsChannel::window_resized 00236 // Access: Public, Virtual 00237 // Description: This is called whenever the parent window has been 00238 // resized; it should do whatever needs to be done to 00239 // adjust the channel to account for it. 00240 //////////////////////////////////////////////////////////////////// 00241 void GraphicsChannel:: 00242 window_resized(int x_size, int y_size) { 00243 // By default, a normal GraphicsChannel fills the whole window, and 00244 // so when the window resizes so does the channel, by the same 00245 // amount. 00246 MutexHolder holder(_lock); 00247 GraphicsLayers::iterator li; 00248 for (li = _layers.begin(); 00249 li != _layers.end(); 00250 ++li) { 00251 (*li)->channel_resized(x_size, y_size); 00252 } 00253 } 00254 00255 //////////////////////////////////////////////////////////////////// 00256 // Function: GraphicsChannel::win_display_regions_changed 00257 // Access: Private 00258 // Description: Intended to be called when the active state on a 00259 // nested channel or layer or display region changes, 00260 // forcing the window to recompute its list of active 00261 // display regions. It is assumed the lock is already 00262 // held. 00263 //////////////////////////////////////////////////////////////////// 00264 void GraphicsChannel:: 00265 win_display_regions_changed() { 00266 if (_window != (GraphicsWindow *)NULL) { 00267 _window->win_display_regions_changed(); 00268 } 00269 }