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