Panda3D
|
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 }