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