00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wglGraphicsPipe.h"
00016 #include "config_wgldisplay.h"
00017 #include "config_windisplay.h"
00018 #include "wglGraphicsWindow.h"
00019 #include "wglGraphicsBuffer.h"
00020
00021 typedef enum {Software, MCD, ICD} OGLDriverType;
00022
00023 TypeHandle wglGraphicsPipe::_type_handle;
00024 bool wglGraphicsPipe::_current_valid;
00025 HDC wglGraphicsPipe::_current_hdc;
00026 HGLRC wglGraphicsPipe::_current_hglrc;
00027
00028
00029
00030
00031
00032
00033 wglGraphicsPipe::
00034 wglGraphicsPipe() {
00035 _current_valid = false;
00036 }
00037
00038
00039
00040
00041
00042
00043 wglGraphicsPipe::
00044 ~wglGraphicsPipe() {
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 void wglGraphicsPipe::
00054 wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) {
00055 if ((_current_valid) &&
00056 (_current_hdc == hdc) &&
00057 (_current_hglrc == hglrc)) {
00058 return;
00059 }
00060 _current_valid = true;
00061 _current_hdc = hdc;
00062 _current_hglrc = hglrc;
00063 BOOL res;
00064 if (collector) {
00065 PStatTimer timer(*collector);
00066 res = wglMakeCurrent(hdc, hglrc);
00067 } else {
00068 res = wglMakeCurrent(hdc, hglrc);
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 string wglGraphicsPipe::
00083 get_interface_name() const {
00084 return "OpenGL";
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 PT(GraphicsPipe) wglGraphicsPipe::
00095 pipe_constructor() {
00096 return new wglGraphicsPipe;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105 PT(GraphicsOutput) wglGraphicsPipe::
00106 make_output(const string &name,
00107 const FrameBufferProperties &fb_prop,
00108 const WindowProperties &win_prop,
00109 int flags,
00110 GraphicsEngine *engine,
00111 GraphicsStateGuardian *gsg,
00112 GraphicsOutput *host,
00113 int retry,
00114 bool &precertify) {
00115
00116 if (!_is_valid) {
00117 return NULL;
00118 }
00119
00120 wglGraphicsStateGuardian *wglgsg = 0;
00121 if (gsg != 0) {
00122 DCAST_INTO_R(wglgsg, gsg, NULL);
00123 }
00124
00125 bool support_rtt;
00126 support_rtt = false;
00127 if (wglgsg) {
00128 support_rtt =
00129 wglgsg -> get_supports_wgl_render_texture() &&
00130 support_render_texture;
00131 }
00132
00133
00134
00135 if (retry == 0) {
00136 if (((flags&BF_require_parasite)!=0)||
00137 ((flags&BF_refuse_window)!=0)||
00138 ((flags&BF_resizeable)!=0)||
00139 ((flags&BF_size_track_host)!=0)||
00140 ((flags&BF_rtt_cumulative)!=0)||
00141 ((flags&BF_can_bind_color)!=0)||
00142 ((flags&BF_can_bind_every)!=0)) {
00143 return NULL;
00144 }
00145 if ((flags & BF_fb_props_optional)==0) {
00146 if ((fb_prop.get_aux_rgba() > 0)||
00147 (fb_prop.get_aux_hrgba() > 0)||
00148 (fb_prop.get_aux_float() > 0)) {
00149 return NULL;
00150 }
00151 }
00152 return new wglGraphicsWindow(engine, this, name, fb_prop, win_prop,
00153 flags, gsg, host);
00154 }
00155
00156
00157
00158 if (retry == 1) {
00159 if ((!gl_support_fbo)||
00160 (host==0)||
00161 ((flags&BF_require_parasite)!=0)||
00162 ((flags&BF_require_window)!=0)) {
00163 return NULL;
00164 }
00165
00166
00167 int _fbo_multisample = 0;
00168 if (!ConfigVariableBool("framebuffer-object-multisample", false, PRC_DESC("Enabled Multisample."))) {
00169 _fbo_multisample = 16;
00170 }
00171 if ((flags & BF_fb_props_optional)==0) {
00172 if ((fb_prop.get_indexed_color() > 0)||
00173 (fb_prop.get_back_buffers() > 0)||
00174 (fb_prop.get_accum_bits() > 0)||
00175 (fb_prop.get_multisamples() > _fbo_multisample)) {
00176 return NULL;
00177 }
00178 }
00179 if ((wglgsg != 0) &&
00180 (wglgsg->is_valid()) &&
00181 (!wglgsg->needs_reset()) &&
00182 !wglgsg->_supports_framebuffer_object) {
00183 return NULL;
00184 }
00185
00186
00187
00188 if ((wglgsg != 0) &&
00189 (wglgsg->is_valid()) &&
00190 (!wglgsg->needs_reset()) &&
00191 (wglgsg->_supports_framebuffer_object) &&
00192 (wglgsg->_glDrawBuffers != 0)&&
00193 (fb_prop.is_basic())) {
00194 precertify = true;
00195 }
00196 return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
00197 flags, gsg, host);
00198 }
00199
00200
00201
00202 if (retry == 2) {
00203 if (((flags&BF_require_parasite)!=0)||
00204 ((flags&BF_require_window)!=0)) {
00205 return NULL;
00206 }
00207 if ((wglgsg != 0) &&
00208 (wglgsg->is_valid()) &&
00209 (!wglgsg->needs_reset()) &&
00210 !wglgsg->_supports_pbuffer) {
00211 return NULL;
00212 }
00213
00214 if (!support_rtt) {
00215 if (((flags&BF_rtt_cumulative)!=0)||
00216 ((flags&BF_can_bind_every)!=0)) {
00217
00218
00219 return NULL;
00220 }
00221 }
00222
00223
00224
00225 if ((flags & BF_fb_props_optional) == 0) {
00226 if ((fb_prop.get_aux_rgba() > 0)||
00227 (fb_prop.get_aux_rgba() > 0)||
00228 (fb_prop.get_aux_float() > 0)) {
00229 return NULL;
00230 }
00231 }
00232
00233
00234 if ((wglgsg != 0) &&
00235 (wglgsg->is_valid()) &&
00236 (!wglgsg->needs_reset()) &&
00237 (wglgsg->pfnum_supports_pbuffer()) &&
00238 (wglgsg->get_fb_properties().subsumes(fb_prop))&&
00239 (wglgsg->get_fb_properties().is_single_buffered())) {
00240 precertify = true;
00241 }
00242 return new wglGraphicsBuffer(engine, this, name, fb_prop, win_prop,
00243 flags, gsg, host);
00244 }
00245
00246
00247 return NULL;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 PT(GraphicsStateGuardian) wglGraphicsPipe::
00260 make_callback_gsg(GraphicsEngine *engine) {
00261 return new wglGraphicsStateGuardian(engine, this, NULL);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271 string wglGraphicsPipe::
00272 format_pfd_flags(DWORD pfd_flags) {
00273 struct FlagDef {
00274 DWORD flag;
00275 const char *name;
00276 };
00277 static FlagDef flag_def[] = {
00278 { PFD_DRAW_TO_WINDOW, "PFD_DRAW_TO_WINDOW" },
00279 { PFD_DRAW_TO_BITMAP, "PFD_DRAW_TO_BITMAP" },
00280 { PFD_SUPPORT_GDI, "PFD_SUPPORT_GDI" },
00281 { PFD_SUPPORT_OPENGL, "PFD_SUPPORT_OPENGL" },
00282 { PFD_GENERIC_ACCELERATED, "PFD_GENERIC_ACCELERATED" },
00283 { PFD_GENERIC_FORMAT, "PFD_GENERIC_FORMAT" },
00284 { PFD_NEED_PALETTE, "PFD_NEED_PALETTE" },
00285 { PFD_NEED_SYSTEM_PALETTE, "PFD_NEED_SYSTEM_PALETTE" },
00286 { PFD_DOUBLEBUFFER, "PFD_DOUBLEBUFFER" },
00287 { PFD_STEREO, "PFD_STEREO" },
00288 { PFD_SWAP_LAYER_BUFFERS, "PFD_SWAP_LAYER_BUFFERS" },
00289 { PFD_SWAP_COPY, "PFD_SWAP_COPY" },
00290 { PFD_SWAP_EXCHANGE, "PFD_SWAP_EXCHANGE" },
00291 };
00292 static const int num_flag_defs = sizeof(flag_def) / sizeof(FlagDef);
00293
00294 ostringstream out;
00295
00296 const char *sep = "";
00297 bool got_any = false;
00298 for (int i = 0; i < num_flag_defs; i++) {
00299 if (pfd_flags & flag_def[i].flag) {
00300 out << sep << flag_def[i].name;
00301 pfd_flags &= ~flag_def[i].flag;
00302 sep = "|";
00303 got_any = true;
00304 }
00305 }
00306
00307 if (pfd_flags != 0 || !got_any) {
00308 out << sep << hex << "0x" << pfd_flags << dec;
00309 }
00310
00311 return out.str();
00312 }