From 6c97dd300c9061350cf6c1655fcde889577c56c3 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 25 Jun 2008 22:55:29 +0000 Subject: [PATCH] Added (Windows only): Use multisampling to achieve fullscreen antialiasing if available. Added (All platforms): Take advantage of the relaxed non-power-of-two rule in OpenGL if available, on textures which do not require mipmaps (can be disabled from the command line with -notexnonpow2). This dramatically reduces blurring on the smaller graphics caused by us having to previously rescale them. Revised GL_CalcLuminance so that it can be used with other resources and not just sprites. --- doomsday/engine/portable/include/de_dgl.h | 10 + doomsday/engine/portable/include/gl_tex.h | 11 +- doomsday/engine/portable/src/dgl_common.c | 236 ++++++++++++++++++++- doomsday/engine/portable/src/dgl_ext.c | 43 ++-- doomsday/engine/portable/src/dgl_texture.c | 3 +- doomsday/engine/portable/src/gl_tex.c | 160 +++++++++----- doomsday/engine/win32/src/sys_window.c | 21 +- 7 files changed, 401 insertions(+), 83 deletions(-) diff --git a/doomsday/engine/portable/include/de_dgl.h b/doomsday/engine/portable/include/de_dgl.h index 334cdf8a91..29f55e5e2a 100644 --- a/doomsday/engine/portable/include/de_dgl.h +++ b/doomsday/engine/portable/include/de_dgl.h @@ -85,6 +85,10 @@ typedef struct dgl_state_s { boolean useFog; float nearClip, farClip; float currentLineWidth; + int textureNonPow2; +#if WIN32 + int multisampleFormat; +#endif } dgl_state_t; typedef struct rgba_s { @@ -109,6 +113,7 @@ typedef struct dgl_state_ext_s { int lockArray; #if WIN32 int wglSwapIntervalEXT; + int wglMultisampleARB; #endif } dgl_state_ext_t; @@ -120,6 +125,7 @@ extern dgl_state_ext_t DGL_state_ext; #ifdef WIN32 extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; +extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; @@ -143,6 +149,10 @@ boolean DGL_Init(void); void DGL_Shutdown(void); void DGL_InitExtensions(void); +boolean DGL_QueryExtension(const char* name, const GLubyte* extensions); +#ifdef WIN32 +void DGL_InitWGLExtensions(void); +#endif void DGL_PrintExtensions(void); void DGL_Show(void); diff --git a/doomsday/engine/portable/include/gl_tex.h b/doomsday/engine/portable/include/gl_tex.h index 096890fa34..9a7ac5222e 100644 --- a/doomsday/engine/portable/include/gl_tex.h +++ b/doomsday/engine/portable/include/gl_tex.h @@ -32,7 +32,8 @@ #include "gl_texmanager.h" boolean GL_OptimalSize(int width, int height, int *optWidth, - int *optHeight, boolean noStretch); + int *optHeight, boolean noStretch, + boolean isMipMapped); void GL_ConvertBuffer(int width, int height, int informat, int outformat, byte *in, byte *out, byte *palette, boolean gamma); @@ -43,7 +44,8 @@ void GL_DownMipmap32(byte *in, int width, int height, int comps); void GL_ConvertToAlpha(image_t *image, boolean makeWhite); void GL_ConvertToLuminance(image_t *image); void GL_CalcLuminance(int pnum, byte *buffer, int width, - int height, int pixelsize); + int height, int pixelsize, float* brightX, + float* brightY, rgbcol_t* color); byte* GL_ApplyColorKeying(byte *buf, unsigned int pixelSize, unsigned int width, unsigned int height); int GL_ValidTexHeight2(int width, int height); @@ -56,8 +58,9 @@ void GL_PalIdxToRGB(int idx, float* rgba); void averageColorIdx(rgbcol_t col, byte *data, int w, int h, byte *palette, boolean hasAlpha); void averageColorRGB(rgbcol_t col, byte *data, int w, int h); -int LineAverageRGB(byte *imgdata, int width, int height, int line, - byte *rgb, byte *palette, boolean hasAlpha); +int lineAverageColorIdx(rgbcol_t col, byte* data, int w, int h, int line, + byte* palette, boolean hasAlpha); +int lineAverageColorRGB(rgbcol_t col, byte* data, int w, int h, int line); void ColorOutlines(byte *buffer, int width, int height); int DrawRealPatch(byte *buffer, int texwidth, int texheight, lumppatch_t *patch, int origx, int origy, diff --git a/doomsday/engine/portable/src/dgl_common.c b/doomsday/engine/portable/src/dgl_common.c index 344304af2d..11d3d78a1b 100644 --- a/doomsday/engine/portable/src/dgl_common.c +++ b/doomsday/engine/portable/src/dgl_common.c @@ -77,11 +77,14 @@ void activeTexture(const GLenum texture) static void checkExtensions(void) { + DGL_InitExtensions(); +#ifdef WIN32 + DGL_InitWGLExtensions(); +#endif + // Get the maximum texture size. glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &DGL_state.maxTexSize); - DGL_InitExtensions(); - glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*) &DGL_state.maxTexUnits); #ifndef USE_MULTITEXTURE DGL_state.maxTexUnits = 1; @@ -157,7 +160,206 @@ static void printDGLConfiguration(void) Con_Message(" Texture Compression: %s\n", yesNo[DGL_state_texture.useCompr? 1:0]); Con_Message(" Variable Texture Anisotropy: %s\n", yesNo[DGL_state.useAnisotropic? 1:0]); Con_Message(" Utilized Texture Units: %i\n", DGL_state.maxTexUnits); +#ifdef WIN32 + Con_Message(" Multisampling: %s", yesNo[DGL_state_ext.wglMultisampleARB? 1:0]); + if(DGL_state_ext.wglMultisampleARB) + Con_Message(" (%i)\n", DGL_state.multisampleFormat); +#endif +} + +#ifdef WIN32 +static void testMultisampling(HDC hDC) +{ + int pixelFormat; + int valid; + uint numFormats; + float fAttributes[] = {0,0}; + + /** + * These Attributes Are The Bits We Want To Test For In Our Sample + * Everything Is Pretty Standard, The Only One We Want To + * Really Focus On Is The SAMPLE BUFFERS ARB And WGL SAMPLES + * These Two Are Going To Do The Main Testing For Whether Or Not + * We Support Multisampling On This Hardware. + */ + int iAttributes[] = + { + WGL_DRAW_TO_WINDOW_ARB,GL_TRUE, + WGL_SUPPORT_OPENGL_ARB,GL_TRUE, + WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB,24, + WGL_ALPHA_BITS_ARB,8, + WGL_DEPTH_BITS_ARB,16, + WGL_STENCIL_BITS_ARB,0, + WGL_DOUBLE_BUFFER_ARB,GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB,GL_TRUE, + WGL_SAMPLES_ARB,4, + 0,0 + }; + + // First We Check To See If We Can Get A Pixel Format For 4 Samples + valid = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats); + + // If We Returned True, And Our Format Count Is Greater Than 1 + if(valid && numFormats >= 1) + { + DGL_state_ext.wglMultisampleARB = 1; + DGL_state.multisampleFormat = pixelFormat; + } + else + { + // Our Pixel Format With 4 Samples Failed, Test For 2 Samples + iAttributes[19] = 2; + valid = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats); + if(valid && numFormats >= 1) + { + DGL_state_ext.wglMultisampleARB = 1; + DGL_state.multisampleFormat = pixelFormat; + } + } +} + +static void createDummyWindow(application_t* app) +{ + HWND hWnd = NULL; + HGLRC hGLRC = NULL; + boolean ok = true; + int bpp = 32; + + // Create the window. + hWnd = CreateWindowEx(WS_EX_APPWINDOW, MAINWCLASS, "dummy", + (WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS), + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, + app->hInstance, NULL); + if(hWnd) + { // Initialize. + PIXELFORMATDESCRIPTOR pfd; + int pixForm = 0; + HDC hDC = NULL; + + // Setup the pixel format descriptor. + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.iLayerType = PFD_MAIN_PLANE; +#ifndef DRMESA + pfd.dwFlags = + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.cColorBits = 32; + pfd.cDepthBits = 16; +#else /* Double Buffer, no alpha */ + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_GENERIC_FORMAT | PFD_DOUBLEBUFFER | PFD_SWAP_COPY; + pfd.cColorBits = 24; + pfd.cRedBits = 8; + pfd.cGreenBits = 8; + pfd.cGreenShift = 8; + pfd.cBlueBits = 8; + pfd.cBlueShift = 16; + pfd.cDepthBits = 16; + pfd.cStencilBits = 8; +#endif + + if(ok) + { + // Acquire a device context handle. + hDC = GetDC(hWnd); + if(!hDC) + { + Sys_CriticalMessage("DD_CreateWindow: Failed acquiring device context handle."); + hDC = NULL; + ok = false; + } + } + + if(ok) + { // Request a matching (or similar) pixel format. + pixForm = ChoosePixelFormat(hDC, &pfd); + if(!pixForm) + { + Sys_CriticalMessage("DD_CreateWindow: Choosing of pixel format failed."); + pixForm = -1; + ok = false; + } + } + + if(ok) + { // Make sure that the driver is hardware-accelerated. + DescribePixelFormat(hDC, pixForm, sizeof(pfd), &pfd); + if((pfd.dwFlags & PFD_GENERIC_FORMAT) && !ArgCheck("-allowsoftware")) + { + Sys_CriticalMessage("DD_CreateWindow: GL driver not accelerated!\n" + "Use the -allowsoftware option to bypass this."); + ok = false; + } + } + + if(ok) + { // Set the pixel format for the device context. Can only be done once + // (unless we release the context and acquire another). + if(!SetPixelFormat(hDC, pixForm, &pfd)) + { + Sys_CriticalMessage("DD_CreateWindow: Warning, setting of pixel " + "format failed."); + } + } + + // Create the OpenGL rendering context. + if(ok) + { + if(!(hGLRC = wglCreateContext(hDC))) + { + Sys_CriticalMessage("createContext: Creation of rendering context " + "failed."); + ok = false; + } + // Make the context current. + else if(!wglMakeCurrent(hDC, hGLRC)) + { + Sys_CriticalMessage("createContext: Couldn't make the rendering " + "context current."); + ok = false; + } + } + + if(ok) + { +#define GETPROC(x) x = (void*)wglGetProcAddress(#x) + + PROC getExtString = wglGetProcAddress("wglGetExtensionsStringARB"); + const GLubyte* extensions = + ((const GLubyte*(__stdcall*)(HDC))getExtString)(hDC); + + if(DGL_QueryExtension("WGL_ARB_multisample", extensions)) + { + GETPROC(wglChoosePixelFormatARB); + if(wglChoosePixelFormatARB) + testMultisampling(hDC); + } + +#undef GETPROC + } + + // We've now finished with the device context. + if(hDC) + ReleaseDC(hWnd, hDC); + } + + // Delete the window's rendering context if one has been acquired. + if(hGLRC) + { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hGLRC); + } + + // Destroy the window and release the handle. + if(hWnd) + DestroyWindow(hWnd); } +#endif boolean DGL_PreInit(void) { @@ -171,6 +373,12 @@ boolean DGL_PreInit(void) memset(&DGL_state_ext, 0, sizeof(DGL_state_ext)); memset(&DGL_state_texture, 0, sizeof(DGL_state_texture)); +#ifdef WIN32 + // We want to be able to use multisampling if available so lets create a + // dummy window and see what pixel formats we have. + createDummyWindow(&app); +#endif + DGL_state_texture.dumpTextures = (ArgCheck("-dumptextures")? true : false); @@ -470,6 +678,10 @@ boolean DGL_GetIntegerv(int name, int *v) glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*) v); break; + case DGL_TEXTURE_NON_POWER_OF_TWO: + *v = DGL_state.textureNonPow2; + break; + case DGL_VSYNC: #if WIN32 *v = DGL_state_ext.wglSwapIntervalEXT? DGL_state.useVSync : -1; @@ -478,6 +690,14 @@ boolean DGL_GetIntegerv(int name, int *v) #endif break; + case DGL_MULTISAMPLE: +#if WIN32 + *v = DGL_state_ext.wglMultisampleARB? DGL_state.multisampleFormat : -1; +#else + *v = -1; +#endif + break; + case DGL_GRAY_MIPMAP: *v = (int) (DGL_state_texture.grayMipmapFactor * 255); break; @@ -785,6 +1005,12 @@ int DGL_Enable(int cap) #endif break; + case DGL_MULTISAMPLE: +#if WIN32 + glEnable(GL_MULTISAMPLE_ARB); +#endif + break; + default: return 0; } @@ -827,6 +1053,12 @@ void DGL_Disable(int cap) #endif break; + case DGL_MULTISAMPLE: +#if WIN32 + glDisable(GL_MULTISAMPLE_ARB); +#endif + break; + default: break; } diff --git a/doomsday/engine/portable/src/dgl_ext.c b/doomsday/engine/portable/src/dgl_ext.c index 6374b1eef0..eeccabc7b6 100644 --- a/doomsday/engine/portable/src/dgl_ext.c +++ b/doomsday/engine/portable/src/dgl_ext.c @@ -56,6 +56,7 @@ dgl_state_ext_t DGL_state_ext; #ifdef WIN32 PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; +PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTextureARB; PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; @@ -81,7 +82,7 @@ static PROC wglGetExtString; * and Tom McReynolds in the book "Advanced Graphics * Programming Using OpenGL" ISBN: 1-55860-659-9. */ -static boolean queryExtension(const char *name, const GLubyte *extensions) +boolean DGL_QueryExtension(const char* name, const GLubyte* extensions) { const GLubyte *start; GLubyte *c, *terminator; @@ -128,11 +129,11 @@ static int query(const char *ext, int *var) const GLubyte* extensions = ((const GLubyte*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC()); - result = (queryExtension(ext, extensions)? 1 : 0); + result = (DGL_QueryExtension(ext, extensions)? 1 : 0); } #endif if(!result) - result = (queryExtension(ext, glGetString(GL_EXTENSIONS))? 1 : 0); + result = (DGL_QueryExtension(ext, glGetString(GL_EXTENSIONS))? 1 : 0); if(var) *var = result; @@ -141,6 +142,27 @@ static int query(const char *ext, int *var) return result; } +#ifdef WIN32 +void DGL_InitWGLExtensions(void) +{ + wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB"); + + if(query("WGL_EXT_swap_control", &DGL_state_ext.wglSwapIntervalEXT)) + { + GETPROC(wglSwapIntervalEXT); + } + + if(query("WGL_ARB_multisample", NULL)) + { + GETPROC(wglChoosePixelFormatARB); + if(wglChoosePixelFormatARB) + { + DGL_state_ext.wglMultisampleARB = 1; + } + } +} +#endif + /** * Pre: A rendering context must be aquired and made current before this is * called. @@ -149,10 +171,6 @@ void DGL_InitExtensions(void) { GLint iVal; -#ifdef WIN32 - wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB"); -#endif - if(query("GL_EXT_compiled_vertex_array", &DGL_state_ext.lockArray)) { #ifdef WIN32 @@ -164,13 +182,8 @@ void DGL_InitExtensions(void) query("GL_EXT_paletted_texture", &DGL_state.palExtAvailable); query("GL_EXT_shared_texture_palette", &DGL_state.sharedPalExtAvailable); query("GL_EXT_texture_filter_anisotropic", &DGL_state_ext.aniso); - -#ifdef WIN32 - if(query("WGL_EXT_swap_control", &DGL_state_ext.wglSwapIntervalEXT)) - { - GETPROC(wglSwapIntervalEXT); - } -#endif + if(!ArgExists("-notexnonpow2")) + query("GL_ARB_texture_non_power_of_two", &DGL_state.textureNonPow2); // EXT_blend_subtract if(query("GL_EXT_blend_subtract", &DGL_state_ext.blendSub)) @@ -239,7 +252,7 @@ void printExtensions(const GLubyte* extensions) token = strtok(extbuf, " "); while(token) { - Con_Message(" "); // Indent. + Con_Message(" "); // Indent. if(verbose) { // Show full names. diff --git a/doomsday/engine/portable/src/dgl_texture.c b/doomsday/engine/portable/src/dgl_texture.c index fd6d7b6939..f372952a9c 100644 --- a/doomsday/engine/portable/src/dgl_texture.c +++ b/doomsday/engine/portable/src/dgl_texture.c @@ -345,7 +345,8 @@ boolean DGL_TexImage(gltexformat_t format, int width, int height, return false; // Check that the texture dimensions are valid. - if(width != M_CeilPow2(width) || height != M_CeilPow2(height)) + if(!DGL_state.textureNonPow2 && + (width != M_CeilPow2(width) || height != M_CeilPow2(height))) return false; if(width > DGL_state.maxTexSize || height > DGL_state.maxTexSize) diff --git a/doomsday/engine/portable/src/gl_tex.c b/doomsday/engine/portable/src/gl_tex.c index f10e829abf..858677e0be 100644 --- a/doomsday/engine/portable/src/gl_tex.c +++ b/doomsday/engine/portable/src/gl_tex.c @@ -37,11 +37,15 @@ #include "de_refresh.h" #include "de_graphics.h" #include "de_misc.h" +#include "de_dgl.h" // MACROS ------------------------------------------------------------------ #define RGB18(r, g, b) ((r)+((g)<<6)+((b)<<12)) +#define MINTEXWIDTH 8 +#define MINTEXHEIGHT 8 + // TYPES ------------------------------------------------------------------- // posts are runs of non masked source pixels @@ -422,26 +426,26 @@ void GL_DownMipmap32(byte *in, int width, int height, int comps) * Determine the optimal size for a texture. Usually the dimensions are * scaled upwards to the next power of two. * - * @param true If @c noStretch == true, and the stretching - * can be skipped. + * @param noStretch If @c true, the stretching can be skipped. + * @param isMipMapped If @c true, we will require mipmaps (this has + * an affect on the optimal size). */ boolean GL_OptimalSize(int width, int height, int *optWidth, int *optHeight, - boolean noStretch) + boolean noStretch, boolean isMipMapped) { - if(noStretch) + if(DGL_GetInteger(DGL_TEXTURE_NON_POWER_OF_TWO) && !isMipMapped) + { + *optWidth = width; + *optHeight = height; + } + else if(noStretch) { *optWidth = M_CeilPow2(width); *optHeight = M_CeilPow2(height); // MaxTexSize may prevent using noStretch. - if(*optWidth > glMaxTexSize) - { - *optWidth = glMaxTexSize; - noStretch = false; - } - if(*optHeight > glMaxTexSize) + if(*optWidth > glMaxTexSize || *optHeight > glMaxTexSize) { - *optHeight = glMaxTexSize; noStretch = false; } } @@ -479,14 +483,21 @@ boolean GL_OptimalSize(int width, int height, int *optWidth, int *optHeight, *optWidth = glMaxTexSize; if(*optHeight > glMaxTexSize) *optHeight = glMaxTexSize; + + // Some GL drivers seem to have problems with VERY small textures. + if(*optWidth < MINTEXWIDTH) + *optWidth = MINTEXWIDTH; + if(*optHeight < MINTEXHEIGHT) + *optHeight = MINTEXHEIGHT; + if(ratioLimit) { - if(*optWidth > *optHeight) // Wide texture. + if(*optWidth > *optHeight) // Wide texture. { if(*optHeight < *optWidth / ratioLimit) *optHeight = *optWidth / ratioLimit; } - else // Tall texture. + else // Tall texture. { if(*optWidth < *optHeight / ratioLimit) *optWidth = *optHeight / ratioLimit; @@ -732,30 +743,7 @@ int LineAverageRGB(byte *imgdata, int width, int height, int line, // We're going to make it! for(c = 0; c < 3; ++c) rgb[c] = (byte) (integerRGB[c] / count); - return 1; // Successful. -} - -/** - * The imgdata must have alpha info, too. - */ -void ImageAverageRGB(byte *imgdata, int width, int height, byte *rgb, - byte *palette) -{ - int i, c, integerRGB[3] = { 0, 0, 0 }, count = 0; - - for(i = 0; i < height; ++i) - { - if(LineAverageRGB(imgdata, width, height, i, rgb, palette, true)) - { - count++; - for(c = 0; c < 3; ++c) - integerRGB[c] += rgb[c]; - } - } - - if(count) // If there were pixels... - for(c = 0; c < 3; ++c) - rgb[c] = integerRGB[c] / count; + return 1; // Successful. } /** @@ -881,8 +869,9 @@ void averageColorIdx(rgbcol_t col, byte *data, int w, int h, byte *palette, b += rgb[2] / 255.f; } } + // All transparent? Sorry... if(!count) - return; // Line added by GMJ 22/07/01 + return; col[0] = r / count; col[1] = g / count; @@ -892,6 +881,67 @@ void averageColorIdx(rgbcol_t col, byte *data, int w, int h, byte *palette, amplify(col); } +int lineAverageColorIdx(rgbcol_t col, byte* data, int w, int h, int line, + byte* palette, boolean hasAlpha) +{ + int i; + uint count; + const int numpels = w * h; + byte* start = data + w * line; + byte* alphaStart = data + numpels + w * line, rgb[3]; + float r, g, b; + + // First clear them. + for(i = 0; i < 3; ++i) + col[i] = 0; + + r = g = b = count = 0; + for(i = 0; i < w; ++i) + { + if(!hasAlpha || alphaStart[i]) + { + count++; + // Ignore the gamma level. + memcpy(rgb, palette + 3 * start[i], 3); + r += rgb[0] / 255.f; + g += rgb[1] / 255.f; + b += rgb[2] / 255.f; + } + } + // All transparent? Sorry... + if(!count) + return 0; + + col[0] = r / count; + col[1] = g / count; + col[2] = b / count; + + return 1; // Successful. +} + +int lineAverageColorRGB(rgbcol_t col, byte* data, int w, int h, int line) +{ + int i; + float culmul[3]; + + for(i = 0; i < 3; ++i) + culmul[i] = 0; + + *data += 3 * w * line; + for(i = 0; i < w; ++i) + { + culmul[CR] += (*data++) / 255.f; + culmul[CG] += (*data++) / 255.f; + culmul[CB] += (*data++) / 255.f; + } + + col[CR] = culmul[CR] / w; + col[CG] = culmul[CG] / w; + col[CB] = culmul[CB] / w; + + return 1; // Successful. +} + void averageColorRGB(rgbcol_t col, byte *data, int w, int h) { uint i; @@ -981,7 +1031,8 @@ void GL_GetNonAlphaRegion(byte *buffer, int width, int height, int pixelsize, * Handles pixel sizes; 1 (==2), 3 and 4. */ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, - int pixelSize) + int pixelSize, float* brightX, float* brightY, + rgbcol_t* color) { byte *palette = (pixelSize == 1? GL_GetPalette() : NULL); spritetex_t *sprTex = spriteTextures[pnum]; @@ -989,7 +1040,6 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, byte rgb[3], *src, *alphaSrc = NULL; int limit = 0xc0, posLimit = 0xe0, colLimit = 0xc0; int avgCnt = 0, lowCnt = 0; - rgbcol_t *sprCol = &sprTex->color; float average[3], lowAvg[3]; int region[4]; @@ -1012,7 +1062,7 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, src += pixelSize * width * region[2]; alphaSrc += width * region[2]; } - sprTex->flareX = sprTex->flareY = 0; + (*brightX) = (*brightY) = 0; for(k = region[2], y = 0; k < region[3] + 1; ++k, ++y) { @@ -1051,8 +1101,8 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, { // This pixel will participate in calculating the average // center point. - sprTex->flareX += x; - sprTex->flareY += y; + (*brightX) += x; + (*brightY) += y; posCnt++; } @@ -1084,17 +1134,17 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, if(!posCnt) { - sprTex->flareX = region[0] + ((region[1] - region[0]) / 2.0f); - sprTex->flareY = region[2] + ((region[3] - region[2]) / 2.0f); + (*brightX) = region[0] + ((region[1] - region[0]) / 2.0f); + (*brightY) = region[2] + ((region[3] - region[2]) / 2.0f); } else { // Get the average. - sprTex->flareX /= posCnt; - sprTex->flareY /= posCnt; + (*brightX) /= posCnt; + (*brightY) /= posCnt; // Add the origin offset. - sprTex->flareX += region[0]; - sprTex->flareY += region[2]; + (*brightX) += region[0]; + (*brightY) += region[2]; } // The color. @@ -1104,20 +1154,20 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, { // Doesn't the thing have any pixels??? Use white light. for(c = 0; c < 3; ++c) - (*sprCol)[c] = 1; + (*color)[c] = 1; } else { // Low-intensity color average. for(c = 0; c < 3; ++c) - (*sprCol)[c] = lowAvg[c] / lowCnt; + (*color)[c] = lowAvg[c] / lowCnt; } } else { // High-intensity color average. for(c = 0; c < 3; ++c) - (*sprCol)[c] = average[c] / avgCnt; + (*color)[c] = average[c] / avgCnt; } #ifdef _DEBUG @@ -1129,15 +1179,15 @@ void GL_CalcLuminance(int pnum, byte *buffer, int width, int height, W_CacheLumpNum(sprTex->lump, PU_GETNAME), width, height, pixelSize, region[0], region[1], region[2], region[3], - sprTex->flareX, sprTex->flareY, + (*brightX), (*brightY), (posCnt? "(average)" : "(center)"), - (*sprCol)[0], (*sprCol)[1], (*sprCol)[2], + (*color)[0], (*color)[1], (*color)[2], (avgCnt? "(hi-intensity avg)" : lowCnt? "(low-intensity avg)" : "(white light)")); #endif // Amplify color. - amplify(*sprCol); + amplify(*color); // How about the size of the light source? sprTex->lumSize = (2 * cnt + avgCnt) / 3.0f / 70.0f; if(sprTex->lumSize > 1) diff --git a/doomsday/engine/win32/src/sys_window.c b/doomsday/engine/win32/src/sys_window.c index bde58aed51..866317de43 100644 --- a/doomsday/engine/win32/src/sys_window.c +++ b/doomsday/engine/win32/src/sys_window.c @@ -645,13 +645,22 @@ static ddwindow_t *createGLWindow(application_t *app, uint parentIDX, } if(ok) - { // Request a matching (or similar) pixel format. - pixForm = ChoosePixelFormat(hDC, &pfd); - if(!pixForm) + { + // Choose a suitable pixel format. + // If multisampling is available, make use of it. + if(DGL_state_ext.wglMultisampleARB) { - Sys_CriticalMessage("DD_CreateWindow: Choosing of pixel format failed."); - pixForm = -1; - ok = false; + pixForm = DGL_state.multisampleFormat; + } + else + { // Request a matching (or similar) pixel format. + pixForm = ChoosePixelFormat(hDC, &pfd); + if(!pixForm) + { + Sys_CriticalMessage("DD_CreateWindow: Choosing of pixel format failed."); + pixForm = -1; + ok = false; + } } }