Panda3D

glxGraphicsPipe.cxx

00001 // Filename: glxGraphicsPipe.cxx
00002 // Created by:  mike (09Jan97)
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 "glxGraphicsPipe.h"
00016 #include "glxGraphicsWindow.h"
00017 #include "glxGraphicsBuffer.h"
00018 #include "glxGraphicsPixmap.h"
00019 #include "glxGraphicsStateGuardian.h"
00020 #include "posixGraphicsStateGuardian.h"
00021 #include "config_glxdisplay.h"
00022 #include "frameBufferProperties.h"
00023 
00024 TypeHandle glxGraphicsPipe::_type_handle;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: glxGraphicsPipe::Constructor
00028 //       Access: Public
00029 //  Description: 
00030 ////////////////////////////////////////////////////////////////////
00031 glxGraphicsPipe::
00032 glxGraphicsPipe(const string &display) : x11GraphicsPipe(display) {
00033   string display_spec (XDisplayString(_display));
00034   
00035   int errorBase, eventBase;
00036   if (!glXQueryExtension(_display, &errorBase, &eventBase)) {
00037     glxdisplay_cat.error()
00038       << "OpenGL GLX extension not supported on display \"" << display_spec
00039       << "\".\n";
00040     return;
00041   }
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: glxGraphicsPipe::get_interface_name
00046 //       Access: Published, Virtual
00047 //  Description: Returns the name of the rendering interface
00048 //               associated with this GraphicsPipe.  This is used to
00049 //               present to the user to allow him/her to choose
00050 //               between several possible GraphicsPipes available on a
00051 //               particular platform, so the name should be meaningful
00052 //               and unique for a given platform.
00053 ////////////////////////////////////////////////////////////////////
00054 string glxGraphicsPipe::
00055 get_interface_name() const {
00056   return "OpenGL";
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: glxGraphicsPipe::pipe_constructor
00061 //       Access: Public, Static
00062 //  Description: This function is passed to the GraphicsPipeSelection
00063 //               object to allow the user to make a default
00064 //               glxGraphicsPipe.
00065 ////////////////////////////////////////////////////////////////////
00066 PT(GraphicsPipe) glxGraphicsPipe::
00067 pipe_constructor() {
00068   return new glxGraphicsPipe;
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: glxGraphicsPipe::make_output
00073 //       Access: Protected, Virtual
00074 //  Description: Creates a new window on the pipe, if possible.
00075 ////////////////////////////////////////////////////////////////////
00076 PT(GraphicsOutput) glxGraphicsPipe::
00077 make_output(const string &name,
00078             const FrameBufferProperties &fb_prop,
00079             const WindowProperties &win_prop,
00080             int flags,
00081             GraphicsEngine *engine,
00082             GraphicsStateGuardian *gsg,
00083             GraphicsOutput *host,
00084             int retry,
00085             bool &precertify) {
00086   
00087   if (!_is_valid) {
00088     return NULL;
00089   }
00090 
00091   glxGraphicsStateGuardian *glxgsg = 0;
00092   if (gsg != 0) {
00093     DCAST_INTO_R(glxgsg, gsg, NULL);
00094   }
00095 
00096   bool support_rtt;
00097   support_rtt = false;
00098   /*
00099     Currently, no support for glxGraphicsBuffer render-to-texture.
00100   if (glxgsg) {
00101      support_rtt = 
00102       glxgsg -> get_supports_render_texture() && 
00103       support_render_texture;
00104   }  
00105   */
00106 
00107   // First thing to try: a glxGraphicsWindow
00108 
00109   if (retry == 0) {
00110     if (((flags&BF_require_parasite)!=0)||
00111         ((flags&BF_refuse_window)!=0)||
00112         ((flags&BF_resizeable)!=0)||
00113         ((flags&BF_size_track_host)!=0)||
00114         ((flags&BF_rtt_cumulative)!=0)||
00115         ((flags&BF_can_bind_color)!=0)||
00116         ((flags&BF_can_bind_every)!=0)) {
00117       return NULL;
00118     }
00119     return new glxGraphicsWindow(engine, this, name, fb_prop, win_prop,
00120                                  flags, gsg, host);
00121   }
00122   
00123   // Second thing to try: a GLGraphicsBuffer
00124 
00125   if (retry == 1) {
00126     if ((host==0)||
00127         (!gl_support_fbo)||
00128         ((flags&BF_require_parasite)!=0)||
00129         ((flags&BF_require_window)!=0)) {
00130       return NULL;
00131     }
00132     // Early failure - if we are sure that this buffer WONT
00133     // meet specs, we can bail out early.
00134     int _fbo_multisample = 0;
00135     if (!ConfigVariableBool("framebuffer-object-multisample", false, PRC_DESC("Enabled Multisample."))) {
00136         _fbo_multisample = 16;
00137     }
00138     if ((flags & BF_fb_props_optional)==0) {
00139       if ((fb_prop.get_indexed_color() > 0)||
00140           (fb_prop.get_back_buffers() > 0)||
00141           (fb_prop.get_accum_bits() > 0)||
00142           (fb_prop.get_multisamples() > _fbo_multisample)) {
00143         return NULL;
00144       }
00145     }
00146     // Early success - if we are sure that this buffer WILL
00147     // meet specs, we can precertify it.
00148     if ((glxgsg != 0) &&
00149         (glxgsg->is_valid()) &&
00150         (!glxgsg->needs_reset()) &&
00151         (glxgsg->_supports_framebuffer_object) &&
00152         (glxgsg->_glDrawBuffers != 0)&&
00153         (fb_prop.is_basic())) {
00154       precertify = true;
00155     }
00156     return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
00157                                 flags, gsg, host);
00158   }
00159 
00160   // Third thing to try: a glxGraphicsBuffer
00161   if (glxgsg == NULL || glxgsg->_supports_fbconfig) {
00162     if (retry == 2) {
00163       if (!glx_support_pbuffer) {
00164         return NULL;
00165       }
00166       
00167       if (((flags&BF_require_parasite)!=0)||
00168           ((flags&BF_require_window)!=0)||
00169           ((flags&BF_resizeable)!=0)||
00170           ((flags&BF_size_track_host)!=0)) {
00171         return NULL;
00172       }
00173       
00174       if (!support_rtt) {
00175         if (((flags&BF_rtt_cumulative)!=0)||
00176             ((flags&BF_can_bind_every)!=0)) {
00177           // If we require Render-to-Texture, but can't be sure we
00178           // support it, bail.
00179           return NULL;
00180         }
00181       }
00182       
00183       return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
00184                                    flags, gsg, host);
00185     }
00186   }
00187 
00188   // Third thing to try: a glxGraphicsPixmap.
00189   if (retry == 3) {
00190     if (!glx_support_pixmap) {
00191       return NULL;
00192     }
00193 
00194     if (((flags&BF_require_parasite)!=0)||
00195         ((flags&BF_require_window)!=0)||
00196         ((flags&BF_resizeable)!=0)||
00197         ((flags&BF_size_track_host)!=0)) {
00198       return NULL;
00199     }
00200 
00201     if (((flags&BF_rtt_cumulative)!=0)||
00202         ((flags&BF_can_bind_every)!=0)) {
00203       return NULL;
00204     }
00205 
00206     return new glxGraphicsPixmap(engine, this, name, fb_prop, win_prop,
00207                                  flags, gsg, host);
00208   }
00209   
00210   // Nothing else left to try.
00211   return NULL;
00212 }
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: glxGraphicsPipe::make_callback_gsg
00216 //       Access: Protected, Virtual
00217 //  Description: This is called when make_output() is used to create a
00218 //               CallbackGraphicsWindow.  If the GraphicsPipe can
00219 //               construct a GSG that's not associated with any
00220 //               particular window object, do so now, assuming the
00221 //               correct graphics context has been set up externally.
00222 ////////////////////////////////////////////////////////////////////
00223 PT(GraphicsStateGuardian) glxGraphicsPipe::
00224 make_callback_gsg(GraphicsEngine *engine) {
00225   // We create a PosixGraphicsStateGuardian instead of a
00226   // glxGraphicsStateGuardian, because the externally-created context
00227   // might not have anything to do with the glx interface.
00228   return new PosixGraphicsStateGuardian(engine, this);
00229 }
 All Classes Functions Variables Enumerations