Panda3D
|
00001 // Filename: callbackGraphicsWindow.cxx 00002 // Created by: drose (06Jan11) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "callbackGraphicsWindow.h" 00016 00017 TypeHandle CallbackGraphicsWindow::_type_handle; 00018 TypeHandle CallbackGraphicsWindow::WindowCallbackData::_type_handle; 00019 TypeHandle CallbackGraphicsWindow::EventsCallbackData::_type_handle; 00020 TypeHandle CallbackGraphicsWindow::PropertiesCallbackData::_type_handle; 00021 TypeHandle CallbackGraphicsWindow::RenderCallbackData::_type_handle; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: CallbackGraphicsWindow::Constructor 00025 // Access: Protected 00026 // Description: Use GraphicsEngine::make_output() to construct a 00027 // CallbackGraphicsWindow. 00028 //////////////////////////////////////////////////////////////////// 00029 CallbackGraphicsWindow:: 00030 CallbackGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 00031 const string &name, 00032 const FrameBufferProperties &fb_prop, 00033 const WindowProperties &win_prop, 00034 int flags, 00035 GraphicsStateGuardian *gsg) : 00036 GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, NULL) 00037 { 00038 #ifdef DO_MEMORY_USAGE 00039 MemoryUsage::update_type(this, this); 00040 #endif 00041 00042 // Let's ensure that these properties are set to *something* 00043 // initially. 00044 _properties.set_origin(0, 0); 00045 _properties.set_size(0, 0); 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: CallbackGraphicsWindow::Destructor 00050 // Access: Published, Virtual 00051 // Description: 00052 //////////////////////////////////////////////////////////////////// 00053 CallbackGraphicsWindow:: 00054 ~CallbackGraphicsWindow() { 00055 } 00056 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: CallbackGraphicsWindow::get_input_device 00060 // Access: Published 00061 // Description: Returns a writable reference to the nth input device 00062 // (mouse). This is intended to be used for the window 00063 // implementation to record mouse and keyboard input 00064 // information for the Panda system. 00065 //////////////////////////////////////////////////////////////////// 00066 GraphicsWindowInputDevice &CallbackGraphicsWindow:: 00067 get_input_device(int device) { 00068 LightMutexHolder holder(_input_lock); 00069 nassertr(device >= 0 && device < (int)_input_devices.size(), _input_devices[0]); 00070 return _input_devices[device]; 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: CallbackGraphicsWindow::create_input_device 00075 // Access: Published 00076 // Description: Adds a new input device (mouse) to the window with 00077 // the indicated name. Returns the index of the new 00078 // device. 00079 //////////////////////////////////////////////////////////////////// 00080 int CallbackGraphicsWindow:: 00081 create_input_device(const string &name) { 00082 GraphicsWindowInputDevice device = 00083 GraphicsWindowInputDevice::pointer_and_keyboard(this, name); 00084 return add_input_device(device); 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: CallbackGraphicsWindow::begin_frame 00089 // Access: Public, Virtual 00090 // Description: This function will be called within the draw thread 00091 // before beginning rendering for a given frame. It 00092 // should do whatever setup is required, and return true 00093 // if the frame should be rendered, or false if it 00094 // should be skipped. 00095 //////////////////////////////////////////////////////////////////// 00096 bool CallbackGraphicsWindow:: 00097 begin_frame(FrameMode mode, Thread *current_thread) { 00098 bool result = false; 00099 if (_render_callback != NULL) { 00100 RenderCallbackData data(this, RCT_begin_frame, mode); 00101 _render_callback->do_callback(&data); 00102 result = data.get_render_flag(); 00103 } else { 00104 result = GraphicsWindow::begin_frame(mode, current_thread); 00105 } 00106 00107 if (!result) { 00108 return false; 00109 } 00110 00111 _gsg->reset_if_new(); 00112 _gsg->set_current_properties(&get_fb_properties()); 00113 00114 return _gsg->begin_frame(current_thread); 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: CallbackGraphicsWindow::end_frame 00119 // Access: Public, Virtual 00120 // Description: This function will be called within the draw thread 00121 // after rendering is completed for a given frame. It 00122 // should do whatever finalization is required. 00123 //////////////////////////////////////////////////////////////////// 00124 void CallbackGraphicsWindow:: 00125 end_frame(FrameMode mode, Thread *current_thread) { 00126 if (_render_callback != NULL) { 00127 RenderCallbackData data(this, RCT_end_frame, mode); 00128 _render_callback->do_callback(&data); 00129 } else { 00130 GraphicsWindow::end_frame(mode, current_thread); 00131 } 00132 00133 _gsg->end_frame(current_thread); 00134 00135 if (mode == FM_render) { 00136 trigger_flip(); 00137 clear_cube_map_selection(); 00138 } 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: CallbackGraphicsWindow::begin_flip 00143 // Access: Public, Virtual 00144 // Description: This function will be called within the draw thread 00145 // after end_frame() has been called on all windows, to 00146 // initiate the exchange of the front and back buffers. 00147 // 00148 // This should instruct the window to prepare for the 00149 // flip at the next video sync, but it should not wait. 00150 // 00151 // We have the two separate functions, begin_flip() and 00152 // end_flip(), to make it easier to flip all of the 00153 // windows at the same time. 00154 //////////////////////////////////////////////////////////////////// 00155 void CallbackGraphicsWindow:: 00156 begin_flip() { 00157 if (_render_callback != NULL) { 00158 RenderCallbackData data(this, RCT_begin_flip, FM_render); 00159 _render_callback->do_callback(&data); 00160 } else { 00161 GraphicsWindow::begin_flip(); 00162 } 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: CallbackGraphicsWindow::end_flip 00167 // Access: Public, Virtual 00168 // Description: This function will be called within the draw thread 00169 // after begin_flip() has been called on all windows, to 00170 // finish the exchange of the front and back buffers. 00171 // 00172 // This should cause the window to wait for the flip, if 00173 // necessary. 00174 //////////////////////////////////////////////////////////////////// 00175 void CallbackGraphicsWindow:: 00176 end_flip() { 00177 if (_render_callback != NULL) { 00178 RenderCallbackData data(this, RCT_end_flip, FM_render); 00179 _render_callback->do_callback(&data); 00180 } else { 00181 GraphicsWindow::end_flip(); 00182 } 00183 } 00184 00185 //////////////////////////////////////////////////////////////////// 00186 // Function: CallbackGraphicsWindow::process_events 00187 // Access: Public, Virtual 00188 // Description: Do whatever processing is necessary to ensure that 00189 // the window responds to user events. Also, honor any 00190 // requests recently made via request_properties(). 00191 // 00192 // This function is called only within the window 00193 // thread. 00194 //////////////////////////////////////////////////////////////////// 00195 void CallbackGraphicsWindow:: 00196 process_events() { 00197 if (_events_callback != NULL) { 00198 EventsCallbackData data(this); 00199 _events_callback->do_callback(&data); 00200 } else { 00201 GraphicsWindow::process_events(); 00202 } 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: CallbackGraphicsWindow::set_properties_now 00207 // Access: Public, Virtual 00208 // Description: Applies the requested set of properties to the 00209 // window, if possible, for instance to request a change 00210 // in size or minimization status. 00211 //////////////////////////////////////////////////////////////////// 00212 void CallbackGraphicsWindow:: 00213 set_properties_now(WindowProperties &properties) { 00214 if (_properties_callback != NULL) { 00215 PropertiesCallbackData data(this, properties); 00216 _properties_callback->do_callback(&data); 00217 } else { 00218 GraphicsWindow::set_properties_now(properties); 00219 } 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: CallbackGraphicsWindow::open_window 00224 // Access: Protected, Virtual 00225 // Description: Opens the window right now. Called from the window 00226 // thread. Returns true if the window is successfully 00227 // opened, or false if there was a problem. 00228 //////////////////////////////////////////////////////////////////// 00229 bool CallbackGraphicsWindow:: 00230 open_window() { 00231 // In this case, we assume the callback has handled the window 00232 // opening. 00233 00234 // We also assume the callback has given us an accurate 00235 // FramebufferProperties, but we do go ahead and assume some certain 00236 // minimum properties. 00237 _fb_properties.set_rgb_color(1); 00238 00239 if (_fb_properties.get_color_bits() == 0) { 00240 _fb_properties.set_color_bits(16); 00241 } 00242 return true; 00243 } 00244 00245 //////////////////////////////////////////////////////////////////// 00246 // Function: CallbackGraphicsWindow::do_reshape_request 00247 // Access: Protected, Virtual 00248 // Description: Called from the window thread in response to a request 00249 // from within the code (via request_properties()) to 00250 // change the size and/or position of the window. 00251 // Returns true if the window is successfully changed, 00252 // or false if there was a problem. 00253 //////////////////////////////////////////////////////////////////// 00254 bool CallbackGraphicsWindow:: 00255 do_reshape_request(int x_origin, int y_origin, bool has_origin, 00256 int x_size, int y_size) { 00257 // In this case, we assume the callback has handled the window 00258 // resizing. 00259 WindowProperties properties; 00260 if (has_origin) { 00261 properties.set_origin(x_origin, y_origin); 00262 } 00263 properties.set_size(x_size, y_size); 00264 system_changed_properties(properties); 00265 00266 return true; 00267 } 00268 00269 //////////////////////////////////////////////////////////////////// 00270 // Function: CallbackGraphicsWindow::EventsCallbackData::upcall 00271 // Access: Published, Virtual 00272 // Description: 00273 //////////////////////////////////////////////////////////////////// 00274 void CallbackGraphicsWindow::EventsCallbackData:: 00275 upcall() { 00276 _window->GraphicsWindow::process_events(); 00277 } 00278 00279 //////////////////////////////////////////////////////////////////// 00280 // Function: CallbackGraphicsWindow::PropertiesCallbackData::upcall 00281 // Access: Published, Virtual 00282 // Description: 00283 //////////////////////////////////////////////////////////////////// 00284 void CallbackGraphicsWindow::PropertiesCallbackData:: 00285 upcall() { 00286 _window->GraphicsWindow::set_properties_now(_properties); 00287 } 00288 00289 //////////////////////////////////////////////////////////////////// 00290 // Function: CallbackGraphicsWindow::RenderCallbackData::upcall 00291 // Access: Published, Virtual 00292 // Description: 00293 //////////////////////////////////////////////////////////////////// 00294 void CallbackGraphicsWindow::RenderCallbackData:: 00295 upcall() { 00296 switch (_callback_type) { 00297 case RCT_begin_frame: 00298 { 00299 bool render_flag = _window->GraphicsWindow::begin_frame(_frame_mode, Thread::get_current_thread()); 00300 set_render_flag(render_flag); 00301 } 00302 break; 00303 00304 case RCT_end_frame: 00305 _window->GraphicsWindow::end_frame(_frame_mode, Thread::get_current_thread()); 00306 break; 00307 00308 case RCT_begin_flip: 00309 _window->GraphicsWindow::begin_flip(); 00310 break; 00311 00312 case RCT_end_flip: 00313 _window->GraphicsWindow::end_flip(); 00314 break; 00315 } 00316 }