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