00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_GFX_GLXWRAPPER_CC_UTC20051112001015_DEFINED
00035 #define GROOVX_GFX_GLXWRAPPER_CC_UTC20051112001015_DEFINED
00036
00037 #ifdef GVX_GL_PLATFORM_GLX
00038
00039 #include "gfx/glxwrapper.h"
00040
00041 #include "gfx/glxopts.h"
00042
00043 #include "rutz/error.h"
00044 #include "rutz/shared_ptr.h"
00045
00046 #include "rutz/debug.h"
00047 GVX_DBG_REGISTER
00048 #include "rutz/trace.h"
00049
00050 namespace
00051 {
00052
00053 const GlxWrapper* currentGlxWrapper = 0;
00054
00055
00056 class AttribList
00057 {
00058 private:
00059 enum { MAXSIZE = 1000 };
00060
00061 void push(int v)
00062 {
00063 GVX_ASSERT(next < MAXSIZE);
00064 data[next++] = v;
00065 }
00066
00067 void cap()
00068 {
00069 data[next] = None;
00070 }
00071
00072 int data[MAXSIZE];
00073 int next;
00074
00075 public:
00077 AttribList(const GlxOpts& opts) : next(0)
00078 {
00079 push( GLX_USE_GL );
00080
00081 if (opts.rgbaFlag) this->rgba(opts.rgbaRed, opts.rgbaGreen, opts.rgbaBlue,
00082 opts.alphaFlag ? opts.alphaSize : -1);
00083
00084 else this->colorIndex( opts.colorIndexSize );
00085
00086 if (opts.depthFlag) this->depthBuffer( opts.depthSize );
00087
00088 if (opts.doubleFlag) this->doubleBuffer();
00089
00090 if (opts.stencilFlag) this->stencilBuffer( opts.stencilSize );
00091
00092 if (opts.accumFlag) this->accum(opts.accumRed, opts.accumGreen, opts.accumBlue,
00093 opts.alphaFlag ? opts.accumAlpha : -1);
00094
00095 if (opts.auxNumber > 0) this->auxBuffers( opts.auxNumber );
00096
00097 if (opts.level != 0) this->level( opts.level );
00098
00099 if (opts.transparent) this->transparent();
00100 }
00101
00103 int* get() { cap(); return data; }
00104
00106 void rgba(int rbits, int gbits, int bbits, int abits = -1)
00107 {
00108 push( GLX_RGBA );
00109 push( GLX_RED_SIZE );
00110 push( rbits ); dbg_eval(3, rbits);
00111 push( GLX_GREEN_SIZE );
00112 push( gbits ); dbg_eval(3, gbits);
00113 push( GLX_BLUE_SIZE );
00114 push( bbits ); dbg_eval_nl(3, bbits);
00115 if (abits > 0)
00116 {
00117 push( GLX_ALPHA_SIZE );
00118 push( abits ); dbg_eval_nl(3, abits);
00119 }
00120 }
00121
00123 void level(int lev)
00124 {
00125 push( GLX_LEVEL );
00126 push( lev );
00127 }
00128
00130 void colorIndex(int bits)
00131 {
00132 push( GLX_BUFFER_SIZE );
00133 push( bits );
00134 }
00135
00137 void depthBuffer(int bits)
00138 {
00139 push( GLX_DEPTH_SIZE );
00140 push( bits );
00141 }
00142
00144 void doubleBuffer()
00145 {
00146 push( GLX_DOUBLEBUFFER );
00147 }
00148
00150 void stencilBuffer(int bits)
00151 {
00152 push( GLX_STENCIL_SIZE );
00153 push( bits );
00154 }
00155
00157 void accum(int rbits, int gbits, int bbits, int abits = -1)
00158 {
00159 push( GLX_ACCUM_RED_SIZE );
00160 push( rbits );
00161 push( GLX_ACCUM_GREEN_SIZE );
00162 push( gbits );
00163 push( GLX_ACCUM_BLUE_SIZE );
00164 push( bbits );
00165 if (abits > 0)
00166 {
00167 push( GLX_ACCUM_ALPHA_SIZE );
00168 push( abits );
00169 }
00170 }
00171
00173 void auxBuffers(int n)
00174 {
00175 push( GLX_AUX_BUFFERS );
00176 push( n );
00177 }
00178
00180 void transparent()
00181 {
00182 #ifdef GLX_TRANSPARENT_TYPE_EXT
00183 push( GLX_TRANSPARENT_TYPE_EXT );
00184 push( GLX_TRANSPARENT_INDEX_EXT );
00185 #endif
00186 }
00187 };
00188 }
00189
00190 GlxWrapper::GlxWrapper(Display* dpy, GlxOpts& opts, GlxWrapper* share) :
00191 itsDisplay(dpy),
00192 itsVisInfo(0),
00193 itsContext(0),
00194 itsCurrentWin(0)
00195 {
00196 GVX_TRACE("GlxWrapper::GlxWrapper");
00197
00198 int dummy;
00199 if (!glXQueryExtension(dpy, &dummy, &dummy))
00200 {
00201 throw rutz::error("GlxWrapper: X server has no OpenGL GLX extension", SRC_POS);
00202 }
00203
00204 AttribList attribs(opts);
00205
00206 dbg_eval_nl(3, (void*)itsDisplay);
00207 dbg_eval_nl(3, DefaultScreen(itsDisplay));
00208
00209 int errorBase = 0;
00210 int eventBase = 0;
00211
00212 if (False == glXQueryExtension(itsDisplay, &errorBase, &eventBase))
00213 {
00214 throw rutz::error("no GLX extension on the X server", SRC_POS);
00215 }
00216
00217 itsVisInfo = glXChooseVisual(itsDisplay,
00218 DefaultScreen(itsDisplay),
00219 attribs.get());
00220
00221
00222
00223 if (itsVisInfo == 0)
00224 {
00225 attribs.doubleBuffer();
00226 itsVisInfo = glXChooseVisual(itsDisplay,
00227 DefaultScreen(itsDisplay),
00228 attribs.get());
00229 }
00230
00231
00232 if (itsVisInfo == 0)
00233 {
00234 throw rutz::error("couldn't find a matching visual", SRC_POS);
00235 }
00236
00237 dbg_eval_nl(3, (void*)itsVisInfo->visualid);
00238 dbg_eval_nl(3, itsVisInfo->depth);
00239 dbg_eval_nl(3, itsVisInfo->bits_per_rgb);
00240
00241 itsContext = glXCreateContext(itsDisplay,
00242 itsVisInfo,
00243 share ? share->itsContext : None,
00244 opts.indirect ? GL_FALSE : GL_TRUE);
00245
00246 dbg_eval_nl(3, itsContext);
00247
00248 if (itsContext == 0)
00249 {
00250 throw rutz::error("could not create GL rendering context", SRC_POS);
00251 }
00252 }
00253
00254 GlxWrapper::~GlxWrapper()
00255 {
00256 GVX_TRACE("GlxWrapper::~GlxWrapper");
00257
00258 glXDestroyContext(itsDisplay, itsContext);
00259 XFree(itsVisInfo);
00260 }
00261
00262 GlxWrapper* GlxWrapper::make(Display* dpy, GlxOpts& opts, GlxWrapper* share)
00263 {
00264 GVX_TRACE("GlxWrapper::make");
00265
00266
00267 GlxWrapper* glx = new GlxWrapper(dpy, opts, share);
00268
00269
00270 if ( !glx->isDirect() && opts.depthFlag )
00271 {
00272 delete glx;
00273 opts.depthFlag = false;
00274 return make(dpy, opts, share);
00275 }
00276
00277 opts.indirect = !glx->isDirect();
00278
00279 return glx;
00280 }
00281
00282 void GlxWrapper::makeCurrent()
00283 {
00284 GVX_TRACE("GlxWrapper::makeCurrent");
00285
00286 GVX_ASSERT(itsCurrentWin != 0);
00287
00288 if (currentGlxWrapper != this)
00289 {
00290 glXMakeCurrent(itsDisplay, itsCurrentWin, itsContext);
00291 currentGlxWrapper = this;
00292 }
00293 }
00294
00295 void GlxWrapper::onReshape(int , int )
00296 {
00297
00298 }
00299
00300 bool GlxWrapper::isDoubleBuffered() const
00301 {
00302 GVX_TRACE("GlxWrapper::isDoubleBuffered");
00303
00304 int dbl_flag;
00305
00306 if (glXGetConfig(itsDisplay, itsVisInfo, GLX_DOUBLEBUFFER, &dbl_flag) != 0)
00307 {
00308 throw rutz::error("glXGetConfig failed", SRC_POS);
00309 }
00310
00311 return bool(dbl_flag);
00312 }
00313
00314 unsigned int GlxWrapper::bitsPerPixel() const
00315 {
00316 GVX_TRACE("GlxWrapper::bitsPerPixel");
00317 return itsVisInfo->depth;
00318 }
00319
00320 void GlxWrapper::swapBuffers() const
00321 {
00322 glXSwapBuffers(itsDisplay, itsCurrentWin);
00323 }
00324
00325 #endif // GVX_GL_PLATFORM_GLX
00326
00327 static const char __attribute__((used)) vcid_groovx_gfx_glxwrapper_cc_utc20051112001015[] = "$Id: glxwrapper.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00328 #endif // !GROOVX_GFX_GLXWRAPPER_CC_UTC20051112001015DEFINED