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