00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "wglGraphicsPipe.h"
00020 #include "config_wgldisplay.h"
00021 #include "config_windisplay.h"
00022
00023 typedef enum {Software, MCD, ICD} OGLDriverType;
00024 static const char * const OGLDrvStrings[] = { "Software", "MCD", "ICD" };
00025
00026 TypeHandle wglGraphicsPipe::_type_handle;
00027
00028
00029
00030
00031
00032
00033 wglGraphicsPipe::
00034 wglGraphicsPipe() {
00035 }
00036
00037
00038
00039
00040
00041
00042 wglGraphicsPipe::
00043 ~wglGraphicsPipe() {
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 string wglGraphicsPipe::
00057 get_interface_name() const {
00058 return "OpenGL";
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068 PT(GraphicsPipe) wglGraphicsPipe::
00069 pipe_constructor() {
00070 return new wglGraphicsPipe;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080 PT(GraphicsStateGuardian) wglGraphicsPipe::
00081 make_gsg(const FrameBufferProperties &properties) {
00082 if (!_is_valid) {
00083 return NULL;
00084 }
00085
00086 FrameBufferProperties new_properties = properties;
00087
00088
00089
00090
00091 HDC hdc = GetDC(NULL);
00092 int pfnum = choose_pfnum(new_properties, hdc);
00093
00094 if (gl_force_pixfmt != 0) {
00095 wgldisplay_cat.info()
00096 << "overriding pixfmt choice algorithm (" << pfnum
00097 << ") with gl-force-pixfmt(" << gl_force_pixfmt << ")\n";
00098 pfnum = gl_force_pixfmt;
00099 }
00100
00101 if (wgldisplay_cat.is_debug()) {
00102 wgldisplay_cat.debug()
00103 << "config() - picking pixfmt #" << pfnum <<endl;
00104 }
00105
00106
00107 ReleaseDC(NULL, hdc);
00108
00109
00110 PT(wglGraphicsStateGuardian) gsg =
00111 new wglGraphicsStateGuardian(new_properties, pfnum);
00112
00113 return gsg.p();
00114 }
00115
00116
00117
00118
00119
00120
00121 PT(GraphicsWindow) wglGraphicsPipe::
00122 make_window(GraphicsStateGuardian *gsg) {
00123 return new wglGraphicsWindow(this, gsg);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 int wglGraphicsPipe::
00137 choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
00138 int pfnum;
00139 bool bUsingSoftware = false;
00140
00141 if (force_software_renderer) {
00142 pfnum = find_pixfmtnum(properties, hdc, false);
00143
00144 if (pfnum == 0) {
00145 wgldisplay_cat.error()
00146 << "Couldn't find compatible software-renderer OpenGL pixfmt, check your window properties!\n";
00147 return 0;
00148 }
00149 bUsingSoftware = true;
00150
00151 } else {
00152 pfnum = find_pixfmtnum(properties, hdc, true);
00153 if (pfnum == 0) {
00154 if (allow_software_renderer) {
00155 pfnum = find_pixfmtnum(properties, hdc, false);
00156 if (pfnum == 0) {
00157 wgldisplay_cat.error()
00158 << "Couldn't find HW or Software OpenGL pixfmt appropriate for this desktop!!\n";
00159 }
00160 } else {
00161 wgldisplay_cat.error()
00162 << "Couldn't find HW-accelerated OpenGL pixfmt appropriate for this desktop!!\n";
00163 }
00164
00165 if (pfnum == 0) {
00166 wgldisplay_cat.error()
00167 << "make sure OpenGL driver is installed, and try reducing the screen size, reducing the\n"
00168 << "desktop screen pixeldepth to 16bpp,and check your panda window properties\n";
00169 return 0;
00170 }
00171 bUsingSoftware = true;
00172 }
00173 }
00174
00175 if (bUsingSoftware) {
00176 wgldisplay_cat.info()
00177 << "Couldn't find compatible OGL HW pixelformat, using software rendering.\n";
00178 }
00179
00180 return pfnum;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 int wglGraphicsPipe::
00192 find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
00193 bool bLookforHW) const {
00194 int frame_buffer_mode = properties.get_frame_buffer_mode();
00195 bool want_depth_bits = properties.has_depth_bits();
00196 bool want_color_bits = properties.has_color_bits();
00197 OGLDriverType drvtype;
00198
00199 PIXELFORMATDESCRIPTOR pfd;
00200 ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
00201 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00202 pfd.nVersion = 1;
00203
00204
00205
00206 int MaxPixFmtNum =
00207 DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00208 int cur_bpp = GetDeviceCaps(hdc,BITSPIXEL);
00209 int pfnum;
00210
00211 for(pfnum = 1; pfnum <= MaxPixFmtNum; pfnum++) {
00212 DescribePixelFormat(hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00213
00214
00215 if ((pfd.dwFlags & PFD_GENERIC_FORMAT) != 0) {
00216 drvtype = Software;
00217 } else if (pfd.dwFlags & PFD_GENERIC_ACCELERATED) {
00218 drvtype = MCD;
00219 } else {
00220 drvtype = ICD;
00221 }
00222
00223
00224 if (bLookforHW) {
00225 if (drvtype == Software) {
00226 continue;
00227 }
00228 } else {
00229 if (drvtype != Software) {
00230 continue;
00231 }
00232 }
00233
00234 if ((pfd.iPixelType == PFD_TYPE_COLORINDEX) &&
00235 (frame_buffer_mode & FrameBufferProperties::FM_index) == 0) {
00236 continue;
00237 }
00238
00239 DWORD dwReqFlags = (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW);
00240
00241 if (wgldisplay_cat.is_debug()) {
00242 wgldisplay_cat->debug()
00243 << "----------------" << endl;
00244
00245 if ((frame_buffer_mode & FrameBufferProperties::FM_alpha) != 0) {
00246 wgldisplay_cat->debug()
00247 << "want alpha, pfd says '"
00248 << (int)(pfd.cAlphaBits) << "'" << endl;
00249 }
00250 if ((frame_buffer_mode & FrameBufferProperties::FM_depth) != 0) {
00251 wgldisplay_cat->debug()
00252 << "want depth, pfd says '"
00253 << (int)(pfd.cDepthBits) << "'" << endl;
00254 }
00255 if ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0) {
00256 wgldisplay_cat->debug()
00257 << "want stencil, pfd says '"
00258 << (int)(pfd.cStencilBits) << "'" << endl;
00259 }
00260 wgldisplay_cat->debug()
00261 << "final flag check " << (int)(pfd.dwFlags & dwReqFlags) << " =? "
00262 << (int)dwReqFlags << endl;
00263 wgldisplay_cat->debug()
00264 << "pfd bits = " << (int)(pfd.cColorBits) << endl;
00265 wgldisplay_cat->debug()
00266 << "cur_bpp = " << cur_bpp << endl;
00267 }
00268
00269 if ((frame_buffer_mode & FrameBufferProperties::FM_double_buffer) != 0) {
00270 dwReqFlags|= PFD_DOUBLEBUFFER;
00271 }
00272 if ((frame_buffer_mode & FrameBufferProperties::FM_alpha) != 0 &&
00273 (pfd.cAlphaBits==0)) {
00274 continue;
00275 }
00276 if ((frame_buffer_mode & FrameBufferProperties::FM_depth) != 0 &&
00277 (pfd.cDepthBits==0)) {
00278 continue;
00279 }
00280 if ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0 &&
00281 (pfd.cStencilBits==0)) {
00282 continue;
00283 }
00284
00285 if ((pfd.dwFlags & dwReqFlags) != dwReqFlags) {
00286 continue;
00287 }
00288
00289
00290
00291
00292 if ((pfd.cColorBits!=cur_bpp) &&
00293 (!((cur_bpp==16) && (pfd.cColorBits==15))) &&
00294 (!((cur_bpp==32) && (pfd.cColorBits==24)))) {
00295 continue;
00296 }
00297
00298
00299
00300
00301
00302 break;
00303 }
00304
00305 if (pfnum > MaxPixFmtNum) {
00306 pfnum = 0;
00307 }
00308
00309 return pfnum;
00310 }