Panda3D
|
00001 //////////////////////////////////////////////////////////////////// 00002 // 00003 // PANDA 3D SOFTWARE 00004 // Copyright (c) Carnegie Mellon University. All rights reserved. 00005 // 00006 // All use of this software is subject to the terms of the revised BSD 00007 // license. You should have received a copy of this license along 00008 // with this source code in a file named "LICENSE." 00009 // 00010 //////////////////////////////////////////////////////////////////// 00011 00012 #include "osxGraphicsBuffer.h" 00013 #include "osxGraphicsStateGuardian.h" 00014 #include "config_osxdisplay.h" 00015 #include "osxGraphicsPipe.h" 00016 00017 #include "graphicsPipe.h" 00018 #include "glgsg.h" 00019 #include "pStatTimer.h" 00020 00021 TypeHandle osxGraphicsBuffer::_type_handle; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: osxGraphicsBuffer::Constructor 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 osxGraphicsBuffer:: 00029 osxGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe, 00030 const string &name, 00031 const FrameBufferProperties &fb_prop, 00032 const WindowProperties &win_prop, 00033 int flags, 00034 GraphicsStateGuardian *gsg, 00035 GraphicsOutput *host) : 00036 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host) 00037 { 00038 osxGraphicsPipe *osx_pipe; 00039 DCAST_INTO_V(osx_pipe, _pipe); 00040 00041 _pbuffer = NULL; 00042 00043 // Since the pbuffer never gets flipped, we get screenshots from the 00044 // same buffer we draw into. 00045 _screenshot_buffer_type = _draw_buffer_type; 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: osxGraphicsBuffer::Destructor 00050 // Access: Public, Virtual 00051 // Description: 00052 //////////////////////////////////////////////////////////////////// 00053 osxGraphicsBuffer:: 00054 ~osxGraphicsBuffer() { 00055 nassertv(_pbuffer == NULL); 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: osxGraphicsBuffer::begin_frame 00060 // Access: Public, Virtual 00061 // Description: This function will be called within the draw thread 00062 // before beginning rendering for a given frame. It 00063 // should do whatever setup is required, and return true 00064 // if the frame should be rendered, or false if it 00065 // should be skipped. 00066 //////////////////////////////////////////////////////////////////// 00067 bool osxGraphicsBuffer:: 00068 begin_frame(FrameMode mode, Thread *current_thread) { 00069 PStatTimer timer(_make_current_pcollector); 00070 00071 begin_frame_spam(mode); 00072 if (_gsg == (GraphicsStateGuardian *)NULL) { 00073 return false; 00074 } 00075 nassertr(_pbuffer != NULL, false); 00076 00077 osxGraphicsStateGuardian *osxgsg; 00078 DCAST_INTO_R(osxgsg, _gsg, false); 00079 if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) { 00080 report_agl_error("aglSetPBuffer"); 00081 return false; 00082 } 00083 00084 if (!aglSetCurrentContext(osxgsg->get_context())) { 00085 report_agl_error("aglSetCurrentContext"); 00086 return false; 00087 } 00088 00089 osxgsg->reset_if_new(); 00090 00091 if (mode == FM_render) { 00092 for (int i=0; i<count_textures(); i++) { 00093 if (get_rtm_mode(i) == RTM_bind_or_copy) { 00094 _textures[i]._rtm_mode = RTM_copy_texture; 00095 } 00096 } 00097 clear_cube_map_selection(); 00098 } 00099 _gsg->set_current_properties(&get_fb_properties()); 00100 return _gsg->begin_frame(current_thread); 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: osxGraphicsBuffer::end_frame 00105 // Access: Public, Virtual 00106 // Description: This function will be called within the draw thread 00107 // after rendering is completed for a given frame. It 00108 // should do whatever finalization is required. 00109 //////////////////////////////////////////////////////////////////// 00110 void osxGraphicsBuffer:: 00111 end_frame(FrameMode mode, Thread *current_thread) { 00112 end_frame_spam(mode); 00113 nassertv(_gsg != (GraphicsStateGuardian *)NULL); 00114 00115 if (mode == FM_render) { 00116 copy_to_textures(); 00117 } 00118 00119 _gsg->end_frame(current_thread); 00120 00121 if (mode == FM_render) { 00122 trigger_flip(); 00123 if (_one_shot) { 00124 prepare_for_deletion(); 00125 } 00126 clear_cube_map_selection(); 00127 } 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: osxGraphicsBuffer::close_buffer 00132 // Access: Protected, Virtual 00133 // Description: Closes the buffer right now. Called from the window 00134 // thread. 00135 //////////////////////////////////////////////////////////////////// 00136 void osxGraphicsBuffer:: 00137 close_buffer() { 00138 if (_gsg != (GraphicsStateGuardian *)NULL) { 00139 // aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0); 00140 _gsg.clear(); 00141 _active = false; 00142 } 00143 if (_pbuffer != NULL) { 00144 aglDestroyPBuffer(_pbuffer); 00145 _pbuffer = NULL; 00146 } 00147 _is_valid = false; 00148 } 00149 00150 //////////////////////////////////////////////////////////////////// 00151 // Function: osxGraphicsBuffer::open_buffer 00152 // Access: Protected, Virtual 00153 // Description: Opens the buffer right now. Called from the window 00154 // thread. Returns true if the buffer is successfully 00155 // opened, or false if there was a problem. 00156 //////////////////////////////////////////////////////////////////// 00157 bool osxGraphicsBuffer:: 00158 open_buffer() { 00159 if (_gsg == 0) { 00160 _gsg = new osxGraphicsStateGuardian(_engine, _pipe, NULL); 00161 } 00162 00163 if (_pbuffer == NULL) { 00164 GLenum target = GL_TEXTURE_RECTANGLE_ARB; 00165 if (_x_size == Texture::up_to_power_2(_x_size) && 00166 _y_size == Texture::up_to_power_2(_x_size)) { 00167 // It's a power-of-two size, so we can use GL_TEXTURE_2D as the 00168 // target. Dunno, but maybe this will be more likely to work on 00169 // some hardware. 00170 target = GL_TEXTURE_2D; 00171 } 00172 if (!aglCreatePBuffer(_x_size, _y_size, target, GL_RGBA, 0, &_pbuffer)) { 00173 report_agl_error("aglCreatePBuffer"); 00174 close_buffer(); 00175 return false; 00176 } 00177 } 00178 00179 osxGraphicsStateGuardian *osxgsg; 00180 DCAST_INTO_R(osxgsg, _gsg, false); 00181 00182 OSStatus stat = osxgsg->build_gl(false, true, _fb_properties); 00183 if (stat != noErr) { 00184 return false; 00185 } 00186 00187 if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) { 00188 report_agl_error("aglSetPBuffer"); 00189 close_buffer(); 00190 return false; 00191 } 00192 00193 if (!aglSetCurrentContext(osxgsg->get_context())) { 00194 report_agl_error("aglSetCurrentContext"); 00195 return false; 00196 } 00197 00198 osxgsg->reset_if_new(); 00199 if (!osxgsg->is_valid()) { 00200 close_buffer(); 00201 return false; 00202 } 00203 00204 /* 00205 if (!osxgsg->get_fb_properties().verify_hardware_software 00206 (_fb_properties, osxgsg->get_gl_renderer())) { 00207 close_buffer(); 00208 return false; 00209 } 00210 _fb_properties = osxgsg->get_fb_properties(); 00211 */ 00212 00213 _is_valid = true; 00214 return true; 00215 } 00216