00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <cassert>
00013 #include <algorithm>
00014 #include <set>
00015
00016 #include "TGLFormat.h"
00017 #include "TGLWSIncludes.h"
00018 #include "TGLWidget.h"
00019
00020 #include "TEnv.h"
00021 #include "TError.h"
00022 #include "TVirtualX.h"
00023
00024
00025
00026
00027
00028 ClassImp(TGLFormat);
00029
00030 std::vector<Int_t> TGLFormat::fgAvailableSamples;
00031
00032
00033 TGLFormat::TGLFormat() :
00034 fDoubleBuffered(kTRUE),
00035 fStereo(kFALSE),
00036 #ifdef WIN32
00037 fDepthSize(32),
00038 #else
00039 fDepthSize(16),
00040 #endif
00041 fAccumSize(0),
00042 fStencilSize(8),
00043 fSamples(GetDefaultSamples())
00044 {
00045
00046
00047
00048
00049
00050
00051
00052 }
00053
00054
00055 TGLFormat::TGLFormat(EFormatOptions opt) :
00056 fDoubleBuffered(opt & kDoubleBuffer),
00057 fStereo(kFALSE),
00058 #ifdef WIN32
00059 fDepthSize(opt & kDepth ? 32 : 0),
00060 #else
00061 fDepthSize(opt & kDepth ? 16 : 0),
00062 #endif
00063 fAccumSize(opt & kAccum ? 8 : 0),
00064 fStencilSize(opt & kStencil ? 8 : 0),
00065 fSamples(opt & kMultiSample ? GetDefaultSamples() : 0)
00066 {
00067
00068 }
00069
00070
00071 TGLFormat::~TGLFormat()
00072 {
00073
00074 }
00075
00076
00077 Bool_t TGLFormat::operator == (const TGLFormat &rhs)const
00078 {
00079
00080 return fDoubleBuffered == rhs.fDoubleBuffered && fDepthSize == rhs.fDepthSize &&
00081 fAccumSize == rhs.fAccumSize && fStencilSize == rhs.fStencilSize;
00082 }
00083
00084
00085 Bool_t TGLFormat::operator != (const TGLFormat &rhs)const
00086 {
00087
00088 return !(*this == rhs);
00089 }
00090
00091
00092 Int_t TGLFormat::GetDepthSize()const
00093 {
00094
00095 return fDepthSize;
00096 }
00097
00098
00099 void TGLFormat::SetDepthSize(Int_t depth)
00100 {
00101
00102 assert(depth);
00103 fDepthSize = depth;
00104 }
00105
00106
00107 Bool_t TGLFormat::HasDepth()const
00108 {
00109
00110 return GetDepthSize() != 0;
00111 }
00112
00113
00114 Int_t TGLFormat::GetStencilSize()const
00115 {
00116
00117 return fStencilSize;
00118 }
00119
00120
00121 void TGLFormat::SetStencilSize(Int_t stencil)
00122 {
00123
00124 assert(stencil);
00125 fStencilSize = stencil;
00126 }
00127
00128
00129 Bool_t TGLFormat::HasStencil()const
00130 {
00131
00132 return GetStencilSize() != 0;
00133 }
00134
00135
00136 Int_t TGLFormat::GetAccumSize()const
00137 {
00138
00139 return fAccumSize;
00140 }
00141
00142
00143 void TGLFormat::SetAccumSize(Int_t accum)
00144 {
00145
00146 assert(accum);
00147 fAccumSize = accum;
00148 }
00149
00150
00151 Bool_t TGLFormat::HasAccumBuffer()const
00152 {
00153
00154 return GetAccumSize() != 0;
00155 }
00156
00157
00158 Bool_t TGLFormat::IsDoubleBuffered()const
00159 {
00160
00161 return fDoubleBuffered;
00162 }
00163
00164
00165 void TGLFormat::SetDoubleBuffered(Bool_t db)
00166 {
00167
00168 fDoubleBuffered = db;
00169 }
00170
00171
00172 Bool_t TGLFormat::IsStereo()const
00173 {
00174
00175 return fStereo;
00176 }
00177
00178
00179 void TGLFormat::SetStereo(Bool_t db)
00180 {
00181
00182 fStereo = db;
00183 }
00184
00185
00186 Int_t TGLFormat::GetSamples()const
00187 {
00188
00189 return fSamples;
00190 }
00191
00192
00193 void TGLFormat::SetSamples(Int_t samples)
00194 {
00195
00196 fSamples = samples;
00197 }
00198
00199
00200 Bool_t TGLFormat::HasMultiSampling()const
00201 {
00202
00203 return fSamples != 0;
00204 }
00205
00206
00207 Int_t TGLFormat::GetDefaultSamples()
00208 {
00209
00210
00211 if (fgAvailableSamples.empty())
00212 InitAvailableSamples();
00213
00214 Int_t req = gEnv->GetValue("OpenGL.Framebuffer.Multisample", 0);
00215
00216 std::vector<Int_t>::iterator i = fgAvailableSamples.begin();
00217 while (i != fgAvailableSamples.end() - 1 && *i < req)
00218 ++i;
00219
00220 if (*i != req) {
00221 Info("TGLFormat::GetDefaultSamples", "Requested multi-sampling %d not available, using %d. Adjusting default.", req, *i);
00222 gEnv->SetValue("OpenGL.Framebuffer.Multisample", *i);
00223 }
00224
00225 return *i;
00226 }
00227
00228
00229 void TGLFormat::InitAvailableSamples()
00230 {
00231 std::set<Int_t> ns_set;
00232 ns_set.insert(0);
00233
00234 TGLWidget *widget = TGLWidget::CreateDummy();
00235 widget->MakeCurrent();
00236
00237 #ifdef WIN32
00238
00239
00240
00241 #else
00242 if (GLXEW_ARB_multisample)
00243 {
00244 Display *dpy = (Display*) gVirtualX->GetDisplay();
00245 XVisualInfo tmpl; tmpl.screen = gVirtualX->GetScreen();
00246 long mask = VisualScreenMask;
00247 int numVisuals, use_gl, ms_ns;
00248 XVisualInfo *vis = XGetVisualInfo(dpy, mask, &tmpl, &numVisuals);
00249 for (int i = 0; i < numVisuals; i++)
00250 {
00251 if (glXGetConfig(dpy, &vis[i], GLX_USE_GL, &use_gl) == 0)
00252 {
00253 glXGetConfig(dpy, &vis[i], GLX_SAMPLES_ARB, &ms_ns);
00254 ns_set.insert(ms_ns);
00255 }
00256 }
00257 XFree(vis);
00258 }
00259
00260 #endif
00261
00262 delete widget;
00263
00264 fgAvailableSamples.reserve(ns_set.size());
00265 for (std::set<Int_t>::iterator i = ns_set.begin(); i != ns_set.end(); ++i)
00266 {
00267 fgAvailableSamples.push_back(*i);
00268 }
00269 }