Panda3D

osxGraphicsBuffer.cxx

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 
 All Classes Functions Variables Enumerations