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 CDLockedReader cdata(_cycler); 00093 for (size_t i = 0; i != cdata->_textures.size(); ++i) { 00094 const RenderTexture &rt = cdata->_textures[i]; 00095 RenderTextureMode rtm_mode = rt._rtm_mode; 00096 if (rtm_mode == RTM_bind_or_copy) { 00097 CDWriter cdataw(_cycler, cdata, false); 00098 nassertr(cdata->_textures.size() == cdataw->_textures.size(), false); 00099 cdataw->_textures[i]._rtm_mode = RTM_copy_texture; 00100 } 00101 } 00102 clear_cube_map_selection(); 00103 } 00104 _gsg->set_current_properties(&get_fb_properties()); 00105 return _gsg->begin_frame(current_thread); 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: osxGraphicsBuffer::end_frame 00110 // Access: Public, Virtual 00111 // Description: This function will be called within the draw thread 00112 // after rendering is completed for a given frame. It 00113 // should do whatever finalization is required. 00114 //////////////////////////////////////////////////////////////////// 00115 void osxGraphicsBuffer:: 00116 end_frame(FrameMode mode, Thread *current_thread) { 00117 end_frame_spam(mode); 00118 nassertv(_gsg != (GraphicsStateGuardian *)NULL); 00119 00120 if (mode == FM_render) { 00121 copy_to_textures(); 00122 } 00123 00124 _gsg->end_frame(current_thread); 00125 00126 if (mode == FM_render) { 00127 trigger_flip(); 00128 clear_cube_map_selection(); 00129 } 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: osxGraphicsBuffer::close_buffer 00134 // Access: Protected, Virtual 00135 // Description: Closes the buffer right now. Called from the window 00136 // thread. 00137 //////////////////////////////////////////////////////////////////// 00138 void osxGraphicsBuffer:: 00139 close_buffer() { 00140 if (_gsg != (GraphicsStateGuardian *)NULL) { 00141 // aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0); 00142 _gsg.clear(); 00143 } 00144 if (_pbuffer != NULL) { 00145 aglDestroyPBuffer(_pbuffer); 00146 _pbuffer = NULL; 00147 } 00148 _is_valid = false; 00149 } 00150 00151 //////////////////////////////////////////////////////////////////// 00152 // Function: osxGraphicsBuffer::open_buffer 00153 // Access: Protected, Virtual 00154 // Description: Opens the buffer right now. Called from the window 00155 // thread. Returns true if the buffer is successfully 00156 // opened, or false if there was a problem. 00157 //////////////////////////////////////////////////////////////////// 00158 bool osxGraphicsBuffer:: 00159 open_buffer() { 00160 if (_gsg == 0) { 00161 _gsg = new osxGraphicsStateGuardian(_engine, _pipe, NULL); 00162 } 00163 00164 if (_pbuffer == NULL) { 00165 GLenum target = GL_TEXTURE_RECTANGLE_ARB; 00166 if (_x_size == Texture::up_to_power_2(_x_size) && 00167 _y_size == Texture::up_to_power_2(_x_size)) { 00168 // It's a power-of-two size, so we can use GL_TEXTURE_2D as the 00169 // target. Dunno, but maybe this will be more likely to work on 00170 // some hardware. 00171 target = GL_TEXTURE_2D; 00172 } 00173 if (!aglCreatePBuffer(_x_size, _y_size, target, GL_RGBA, 0, &_pbuffer)) { 00174 report_agl_error("aglCreatePBuffer"); 00175 close_buffer(); 00176 return false; 00177 } 00178 } 00179 00180 osxGraphicsStateGuardian *osxgsg; 00181 DCAST_INTO_R(osxgsg, _gsg, false); 00182 00183 OSStatus stat = osxgsg->build_gl(false, true, _fb_properties); 00184 if (stat != noErr) { 00185 return false; 00186 } 00187 00188 if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) { 00189 report_agl_error("aglSetPBuffer"); 00190 close_buffer(); 00191 return false; 00192 } 00193 00194 if (!aglSetCurrentContext(osxgsg->get_context())) { 00195 report_agl_error("aglSetCurrentContext"); 00196 return false; 00197 } 00198 00199 osxgsg->reset_if_new(); 00200 if (!osxgsg->is_valid()) { 00201 close_buffer(); 00202 return false; 00203 } 00204 00205 /* 00206 if (!osxgsg->get_fb_properties().verify_hardware_software 00207 (_fb_properties, osxgsg->get_gl_renderer())) { 00208 close_buffer(); 00209 return false; 00210 } 00211 _fb_properties = osxgsg->get_fb_properties(); 00212 */ 00213 00214 _is_valid = true; 00215 return true; 00216 } 00217