diff --git a/doomsday/plugins/opengl/portable/include/dropengl.h b/doomsday/plugins/opengl/portable/include/dropengl.h index 54bfd4e805..041c8e0ba9 100644 --- a/doomsday/plugins/opengl/portable/include/dropengl.h +++ b/doomsday/plugins/opengl/portable/include/dropengl.h @@ -143,7 +143,7 @@ extern rgba_t palette[256]; extern int usePalTex, dumpTextures, useCompr; extern float grayMipmapFactor; -int Power2(int num); +int DG_Power2(int num); int enablePalTexExt(int enable); DGLuint DG_NewTexture(void); int DG_TexImage(int format, int width, int height, int mipmap, @@ -179,6 +179,6 @@ extern int extGenMip; extern int extBlendSub; extern int extS3TC; -void initExtensions(void); +void DG_InitExtensions(void); #endif diff --git a/doomsday/plugins/opengl/portable/src/ext.c b/doomsday/plugins/opengl/portable/src/ext.c index fa97b7280b..666550e3ac 100644 --- a/doomsday/plugins/opengl/portable/src/ext.c +++ b/doomsday/plugins/opengl/portable/src/ext.c @@ -78,56 +78,64 @@ PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; /** * @return Non-zero iff the extension string is found. This - * function is based on Mark J. Kilgard's tutorials - * about OpenGL extensions. + * function is based on the method used by David Blythe + * and Tom McReynolds in the book "Advanced Graphics + * Programming Using OpenGL" ISBN: 1-55860-659-9. */ -int queryExtension(const char *name) +static int queryExtension(const char *name) { - const GLubyte *extensions = glGetString(GL_EXTENSIONS); + const GLubyte *extensions = NULL; const GLubyte *start; - GLubyte *where, *terminator; - - if(!extensions) - return false; + GLubyte *c, *terminator; // Extension names should not have spaces. - where = (GLubyte *) strchr(name, ' '); - if(where || *name == '\0') + c = (GLubyte *) strchr(name, ' '); + if(c || *name == '\0') return false; + extensions = glGetString(GL_EXTENSIONS); + // It takes a bit of care to be fool-proof about parsing the // OpenGL extensions string. Don't be fooled by sub-strings, etc. start = extensions; - for(;;) { - where = (GLubyte *) strstr((const char *) start, name); - if(!where) + c = (GLubyte *) strstr((const char *) start, name); + if(!c) break; - terminator = where + strlen(name); - if(where == start || *(where - 1) == ' ') + terminator = c + strlen(name); + if(c == start || *(c - 1) == ' ') if(*terminator == ' ' || *terminator == '\0') { return true; } start = terminator; } + return false; } -int query(const char *ext, int *var) +static int query(const char *ext, int *var) { - if((*var = queryExtension(ext)) != DGL_FALSE) + int result = DGL_FALSE; + + if(ext) { Con_Message("Checking OpenGL extension: %s\n", ext); - return true; + result = (queryExtension(ext)? DGL_TRUE : DGL_FALSE); + if(var) + *var = result; } - return false; + return result; } -void initExtensions(void) +/** + * Pre: A rendering context must be aquired and made current before this is + * called. + */ +void DG_InitExtensions(void) { int i; diff --git a/doomsday/plugins/opengl/portable/src/texture.c b/doomsday/plugins/opengl/portable/src/texture.c index 1581bc1289..0dad4b6208 100644 --- a/doomsday/plugins/opengl/portable/src/texture.c +++ b/doomsday/plugins/opengl/portable/src/texture.c @@ -60,46 +60,47 @@ PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; // CODE -------------------------------------------------------------------- -//=========================================================================== -// chooseFormat -// Return the internal texture format. -// The compression method is chosen here. -//=========================================================================== +/** + * Choose an internal texture format based on the number of color components. + * + * @param comps Number of color components. + * @return The internal texture format. + */ GLenum ChooseFormat(int comps) { - boolean compress = (useCompr && allowCompression); + boolean compress = (useCompr && allowCompression); - switch (comps) + switch(comps) { - case 1: // Luminance + case 1: // Luminance return compress ? GL_COMPRESSED_LUMINANCE : GL_LUMINANCE; - case 3: // RGB + case 3: // RGB return !compress ? 3 : extS3TC ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB; - case 4: // RGBA - return !compress ? 4 : extS3TC ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT // >1-bit alpha + case 4: // RGBA + return !compress ? 4 : extS3TC ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT // >1-bit alpha : GL_COMPRESSED_RGBA; + + default: + Con_Error("drOpenGL.ChooseFormat: Unsupported comps: %i.", comps); } // The fallback. return comps; } -//=========================================================================== -// loadPalette -//=========================================================================== void loadPalette(int sharedPalette) { - byte paldata[256 * 3]; - int i; + int i; + byte paldata[256 * 3]; if(usePalTex == DGL_FALSE) return; // Prepare the color table (RGBA -> RGB). - for(i = 0; i < 256; i++) + for(i = 0; i < 256; ++i) memcpy(paldata + i * 3, palette[i].color, 3); glColorTableEXT(sharedPalette ? GL_SHARED_TEXTURE_PALETTE_EXT : @@ -107,9 +108,6 @@ void loadPalette(int sharedPalette) paldata); } -//=========================================================================== -// enablePalTexExt -//=========================================================================== int enablePalTexExt(int enable) { if(!palExtAvailable && !sharedPalExtAvailable) @@ -118,7 +116,8 @@ int enablePalTexExt(int enable) ("drOpenGL.enablePalTexExt: No paletted texture support.\n"); return DGL_FALSE; } - if((enable && usePalTex) || (!enable && !usePalTex)) + + if((enable && usePalTex) || (!enable && !usePalTex)) return DGL_TRUE; if(!enable && usePalTex) @@ -151,28 +150,26 @@ int enablePalTexExt(int enable) loadPalette(true); } else - { + { // Palette will be loaded separately for each texture. Con_Message("drOpenGL.enablePalTexExt: Using tex palette.\n"); - // Palette will be loaded separately for each texture. } return DGL_TRUE; } -//=========================================================================== -// Power2 -//=========================================================================== -int Power2(int num) +int DG_Power2(int num) { - int cumul; + int cumul; - for(cumul = 1; num > cumul; cumul <<= 1); - return cumul; + for(cumul = 1; num > cumul; cumul *= 2); + + return cumul; } -//=========================================================================== -// DG_NewTexture -// Create a new texture. -//=========================================================================== +/** + * Create a new GL texture. + * + * @return Name of the new texture. + */ DGLuint DG_NewTexture(void) { DGLuint texName; @@ -183,9 +180,6 @@ DGLuint DG_NewTexture(void) return texName; } -//=========================================================================== -// setTexAniso -//=========================================================================== void setTexAniso(void) { // Should anisotropic filtering be used? @@ -197,94 +191,82 @@ void setTexAniso(void) } } -//=========================================================================== -// downMip8 -// Works within the given data, reducing the size of the picture to half -// its original. Width and height must be powers of two. -//=========================================================================== +/** + * Works within the given data, reducing the size of the picture to half + * its original. + * + * @param width Width of the final texture, must be power of two. + * @param height Height of the final texture, must be power of two. + */ void downMip8(byte *in, byte *fadedOut, int width, int height, float fade) { - byte *out = in; - int x, y, outW = width >> 1, outH = height >> 1; - float invFade; + byte *out = in; + int x, y, outW = width / 2, outH = height / 2; + float invFade; if(fade > 1) fade = 1; invFade = 1 - fade; if(width == 1 && height == 1) - { - // Nothing can be done. + { // Nothing can be done. return; } - if(!outW || !outH) // Limited, 1x2|2x1 -> 1x1 reduction? - { - int outDim = width > 1 ? outW : outH; + if(!outW || !outH) + { // Limited, 1x2|2x1 -> 1x1 reduction? + int outDim = (width > 1 ? outW : outH); for(x = 0; x < outDim; x++, in += 2) { - *out = (in[0] + in[1]) >> 1; + *out = (in[0] + in[1]) / 2; *fadedOut++ = (byte) (*out * invFade + 0x80 * fade); out++; } } - else // Unconstrained, 2x2 -> 1x1 reduction? - { + else + { // Unconstrained, 2x2 -> 1x1 reduction? for(y = 0; y < outH; y++, in += width) for(x = 0; x < outW; x++, in += 2) { - *out = (in[0] + in[1] + in[width] + in[width + 1]) >> 2; + *out = (in[0] + in[1] + in[width] + in[width + 1]) / 4; *fadedOut++ = (byte) (*out * invFade + 0x80 * fade); out++; } } } -//=========================================================================== -// grayMipmap -//=========================================================================== int grayMipmap(int format, int width, int height, void *data) { - byte *image, *in, *out, *faded; - int i, numLevels, w, h, size = width * height, res; - float invFactor = 1 - grayMipmapFactor; + byte *image, *in, *out, *faded; + int i, numLevels, w, h, size = width * height, res; + uint comps = (format == DGL_LUMINANCE? 1 : 3); + float invFactor = 1 - grayMipmapFactor; // Buffer used for the faded texture. faded = malloc(size / 4); image = malloc(size); // Initial fading. - if(format == DGL_LUMINANCE) + if(format == DGL_LUMINANCE || format == DGL_RGB) { - for(i = 0, in = data, out = image; i < size; i++) + for(i = 0, in = data, out = image; i < size; ++i, in += comps) { - // Result is clamped to [0,255]. - res = (int) (*in++ * grayMipmapFactor + 0x80 * invFactor); - if(res < 0) - res = 0; - if(res > 255) - res = 255; - *out++ = res; - } - } - else if(format == DGL_RGB) - { - for(i = 0, in = data, out = image; i < size; i++, in += 3) - { - // Result is clamped to [0,255]. res = (int) (*in * grayMipmapFactor + 0x80 * invFactor); + + // Clamp to [0, 255]. if(res < 0) res = 0; if(res > 255) res = 255; - *out++ = res; + + *out++ = res; } } // How many levels will there be? for(numLevels = 0, w = width, h = height; w > 1 || h > 1; - w >>= 1, h >>= 1, numLevels++); + w /= 2, h /= 2, numLevels++); // We do not want automatical mipmaps. if(extGenMip) @@ -295,15 +277,15 @@ int grayMipmap(int format, int width, int height, void *data) GL_LUMINANCE, GL_UNSIGNED_BYTE, image); // Generate all mipmaps levels. - for(i = 0, w = width, h = height; i < numLevels; i++) + for(i = 0, w = width, h = height; i < numLevels; ++i) { downMip8(image, faded, w, h, (i * 1.75f) / numLevels); // Go down one level. if(w > 1) - w >>= 1; + w /= 2; if(h > 1) - h >>= 1; + h /= 2; glTexImage2D(GL_TEXTURE_2D, i + 1, ChooseFormat(1), w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, faded); @@ -317,15 +299,23 @@ int grayMipmap(int format, int width, int height, void *data) return DGL_OK; } -//=========================================================================== -// DG_TexImage -// 'width' and 'height' must be powers of two. -// Give a negative 'genMips' to set a specific mipmap level. -//=========================================================================== +/** + * @param format DGL texture format symbolic, one of: + * DGL_RGB + * DGL_RGBA + * DGL_COLOR_INDEX_8 + * DGL_COLOR_INDEX_8_PLUS_A8 + * DGL_LUMINANCE + * @param width Width of the texture, must be power of two. + * @param height Height of the texture, must be power of two. + * @param genMips If negative, sets a specific mipmap level, + * e.g. -1 means mipmap level 1. + * @param data Ptr to the texture data. + */ int DG_TexImage(int format, int width, int height, int genMips, void *data) { - int mipLevel = 0; - byte *bdata = data; + int mipLevel = 0; + byte *bdata = data; // Negative genMips values mean that the specific mipmap level is // being uploaded. @@ -340,7 +330,7 @@ int DG_TexImage(int format, int width, int height, int genMips, void *data) return DGL_FALSE; // Check that the texture dimensions are valid. - if(width != Power2(width) || height != Power2(height)) + if(width != DG_Power2(width) || height != DG_Power2(height)) return DGL_FALSE; if(width > maxTexSize || height > maxTexSize) @@ -360,32 +350,31 @@ int DG_TexImage(int format, int width, int height, int genMips, void *data) if(usePalTex && format == DGL_COLOR_INDEX_8) { if(genMips && !extGenMip) - { - // Build mipmap textures. + { // Build mipmap textures. gluBuild2DMipmaps(GL_TEXTURE_2D, GL_COLOR_INDEX8_EXT, width, height, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data); } else - { - // The texture has no mipmapping. + { // The texture has no mipmapping. glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_COLOR_INDEX8_EXT, width, height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data); } - // Load palette, too (if not shared). + + // Load palette, too (if not shared). if(!sharedPalExtAvailable) loadPalette(false); } - else // Use true color textures. - { - int alphachannel = (format == DGL_RGBA) || - (format == DGL_COLOR_INDEX_8_PLUS_A8) || - (format == DGL_LUMINANCE_PLUS_A8); - int i, colorComps = alphachannel ? 4 : 3; - int numPixels = width * height; - byte *buffer; - byte *pixel, *in; - int needFree = DGL_FALSE; - int loadFormat = GL_RGBA; + else + { // Use true color textures. + int alphachannel = ((format == DGL_RGBA) || + (format == DGL_COLOR_INDEX_8_PLUS_A8) || + (format == DGL_LUMINANCE_PLUS_A8)); + int i, colorComps = alphachannel ? 4 : 3; + int numPixels = width * height; + byte *buffer; + byte *pixel, *in; + int needFree = DGL_FALSE; + int loadFormat = GL_RGBA; // Convert to either RGB or RGBA, if necessary. if(format == DGL_RGBA) @@ -399,14 +388,15 @@ int DG_TexImage(int format, int width, int height, int genMips, void *data) buffer = data; loadFormat = GL_RGB; } - else //// \fixme Needs converting. This adds some overhead. - { + else + { // Needs converting. + // \fixme This adds some overhead. needFree = DGL_TRUE; buffer = malloc(numPixels * 4); if(!buffer) return DGL_FALSE; - switch (format) + switch(format) { case DGL_RGB: for(i = 0, pixel = buffer, in = bdata; i < numPixels; @@ -459,28 +449,19 @@ int DG_TexImage(int format, int width, int height, int genMips, void *data) break; } } - if(genMips && !extGenMip) - { - // Build all mipmap levels. + + if(genMips && !extGenMip) + { // Build all mipmap levels. gluBuild2DMipmaps(GL_TEXTURE_2D, ChooseFormat(colorComps), width, height, loadFormat, GL_UNSIGNED_BYTE, buffer); } else - { - // The texture has no mipmapping, just one level. + { // The texture has no mipmapping, just one level. glTexImage2D(GL_TEXTURE_2D, mipLevel, ChooseFormat(colorComps), width, height, 0, loadFormat, GL_UNSIGNED_BYTE, buffer); } - /*if(dumpTextures && mipmap && loadFormat == GL_RGB) - { - char fn[100]; - sprintf(fn, "%03ic%iw%03ih%03i_m%i.tga", - currentTex, colorComps, width, height, mipmap); - TGA_Save24_rgb888(fn, width, height, buffer); - } */ - if(needFree) free(buffer); } @@ -489,19 +470,14 @@ int DG_TexImage(int format, int width, int height, int genMips, void *data) return DGL_OK; } -//=========================================================================== -// DG_DeleteTextures -//=========================================================================== void DG_DeleteTextures(int num, DGLuint *names) { if(!num || !names) return; - glDeleteTextures(num, (GLuint*) names); + + glDeleteTextures(num, (GLuint*) names); } -//=========================================================================== -// DG_TexParameter -//=========================================================================== void DG_TexParameter(int pname, int param) { GLenum mlevs[] = { GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, @@ -509,7 +485,7 @@ void DG_TexParameter(int pname, int param) GL_LINEAR_MIPMAP_LINEAR }; - switch (pname) + switch(pname) { default: glTexParameteri(GL_TEXTURE_2D, @@ -526,12 +502,9 @@ void DG_TexParameter(int pname, int param) } } -//=========================================================================== -// DG_GetTexParameterv -//=========================================================================== void DG_GetTexParameterv(int level, int pname, int *v) { - switch (pname) + switch(pname) { case DGL_WIDTH: glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, @@ -542,16 +515,17 @@ void DG_GetTexParameterv(int level, int pname, int *v) glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, (GLint*) v); break; + + default: + Con_Error("drOpenGL.GetTexParameterv: Unknown parameter %i.", pname); } } -//=========================================================================== -// DG_Palette -//=========================================================================== void DG_Palette(int format, void *data) { unsigned char *ptr = data; - int i, size = (format == DGL_RGBA ? 4 : 3); + int i; + size_t size = sizeof(unsigned char) *(format == DGL_RGBA ? 4 : 3); for(i = 0; i < 256; i++, ptr += size) { @@ -563,9 +537,6 @@ void DG_Palette(int format, void *data) loadPalette(sharedPalExtAvailable); } -//=========================================================================== -// DG_Bind -//=========================================================================== int DG_Bind(DGLuint texture) { glBindTexture(GL_TEXTURE_2D, texture); diff --git a/doomsday/plugins/opengl/unix/src/main.c b/doomsday/plugins/opengl/unix/src/main.c index 15d6988dab..a6f004a7ab 100644 --- a/doomsday/plugins/opengl/unix/src/main.c +++ b/doomsday/plugins/opengl/unix/src/main.c @@ -103,12 +103,7 @@ int DG_ChangeVideoMode(int width, int height, int bpp) return DGL_TRUE; } -/** - * Attempt to create a context for GL rendering. - * - * @return Non-zero= success. - */ -int initOpenGL(void) +static int initOpenGL(void) { // Attempt to set the video mode. if(!DG_ChangeVideoMode(screenWidth, screenHeight, screenBits)) @@ -187,7 +182,7 @@ int DG_CreateContext(int width, int height, int bpp, int mode) // Check the maximum texture size. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); - initExtensions(); + DG_InitExtensions(); if(firstTimeInit) { diff --git a/doomsday/plugins/opengl/win32/src/main.c b/doomsday/plugins/opengl/win32/src/main.c index 06ecc20309..5d052ea6f0 100644 --- a/doomsday/plugins/opengl/win32/src/main.c +++ b/doomsday/plugins/opengl/win32/src/main.c @@ -216,7 +216,7 @@ static void checkExtensions(void) // Check the maximum texture size. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); - initExtensions(); + DG_InitExtensions(); // Print some OpenGL information (console must be initialized by now). Con_Message("OpenGL information:\n");