diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/refresh/gl/images.c | 94 | ||||
-rw-r--r-- | src/refresh/gl/main.c | 4 | ||||
-rw-r--r-- | src/refresh/gl/qgl/dynamic.c | 17 | ||||
-rw-r--r-- | src/refresh/gl/qgl/dynamic.h | 7 | ||||
-rw-r--r-- | src/refresh/gl/qgl/fixed.c | 11 | ||||
-rw-r--r-- | src/refresh/gl/qgl/fixed.h | 7 |
6 files changed, 90 insertions, 50 deletions
diff --git a/src/refresh/gl/images.c b/src/refresh/gl/images.c index bf3a712..c1944e5 100644 --- a/src/refresh/gl/images.c +++ b/src/refresh/gl/images.c @@ -33,7 +33,6 @@ static qboolean upload_alpha; static cvar_t *gl_noscrap; static cvar_t *gl_round_down; static cvar_t *gl_picmip; -static cvar_t *gl_maxmip; static cvar_t *gl_downsample_skins; static cvar_t *gl_gamma_scale_pics; static cvar_t *gl_bilerp_chars; @@ -41,6 +40,7 @@ static cvar_t *gl_bilerp_pics; static cvar_t *gl_upscale_pcx; static cvar_t *gl_texturemode; static cvar_t *gl_texturebits; +static cvar_t *gl_texture_non_power_of_two; static cvar_t *gl_anisotropy; static cvar_t *gl_saturation; static cvar_t *gl_intensity; @@ -352,6 +352,19 @@ static qboolean GL_TextureHasAlpha(byte *data, int width, int height) return qfalse; } +static qboolean GL_MakePowerOfTwo(int *width, int *height) +{ + if (!(*width & (*width - 1)) && !(*height & (*height - 1))) + return qtrue; // already power of two + + if (AT_LEAST_OPENGL(3, 0) && gl_texture_non_power_of_two->integer) + return qfalse; // assume full NPOT texture support + + *width = npot32(*width); + *height = npot32(*height); + return qfalse; +} + /* =============== GL_Upload32 @@ -360,23 +373,13 @@ GL_Upload32 static void GL_Upload32(byte *data, int width, int height, int baselevel, imagetype_t type, imageflags_t flags) { byte *scaled; - int scaled_width, scaled_height, maxsize, comp; - qboolean quarter; + int scaled_width, scaled_height, comp; + qboolean power_of_two; - if (AT_LEAST_OPENGL(3, 0)) { - // assume full NPOT texture support - scaled_width = width; - scaled_height = height; - } else { - // find the next-highest power of two - scaled_width = npot32(width); - scaled_height = npot32(height); - } + scaled_width = width; + scaled_height = height; + power_of_two = GL_MakePowerOfTwo(&scaled_width, &scaled_height); - // save the flag indicating if costly resampling can be avoided - quarter = (scaled_width == width && scaled_height == height); - - maxsize = gl_config.maxTextureSize; if (type == IT_WALL || (type == IT_SKIN && gl_downsample_skins->integer)) { // round world textures down, if requested if (gl_round_down->integer) { @@ -389,17 +392,10 @@ static void GL_Upload32(byte *data, int width, int height, int baselevel, imaget // let people sample down the world textures for speed scaled_width >>= gl_picmip->integer; scaled_height >>= gl_picmip->integer; - - if (gl_maxmip->integer > 0) { - maxsize = 1 << Cvar_ClampInteger(gl_maxmip, 1, 12); - if (maxsize > gl_config.maxTextureSize) { - maxsize = gl_config.maxTextureSize; - } - } } // don't ever bother with >256 textures - while (scaled_width > maxsize || scaled_height > maxsize) { + while (scaled_width > gl_config.maxTextureSize || scaled_height > gl_config.maxTextureSize) { scaled_width >>= 1; scaled_height >>= 1; } @@ -420,7 +416,7 @@ static void GL_Upload32(byte *data, int width, int height, int baselevel, imaget if (scaled_width == width && scaled_height == height) { // optimized case, do nothing scaled = data; - } else if (quarter) { + } else if (power_of_two) { // optimized case, use faster mipmap operation scaled = data; while (width > scaled_width || height > scaled_height) { @@ -453,19 +449,23 @@ static void GL_Upload32(byte *data, int width, int height, int baselevel, imaget c.texUploads++; if (type == IT_WALL || type == IT_SKIN) { - int miplevel = 0; - - while (scaled_width > 1 || scaled_height > 1) { - IMG_MipMap(scaled, scaled, scaled_width, scaled_height); - scaled_width >>= 1; - scaled_height >>= 1; - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; - miplevel++; - qglTexImage2D(GL_TEXTURE_2D, miplevel, comp, scaled_width, - scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + if (qglGenerateMipmap) { + qglGenerateMipmap(GL_TEXTURE_2D); + } else { + int miplevel = 0; + + while (scaled_width > 1 || scaled_height > 1) { + IMG_MipMap(scaled, scaled, scaled_width, scaled_height); + scaled_width >>= 1; + scaled_height >>= 1; + if (scaled_width < 1) + scaled_width = 1; + if (scaled_height < 1) + scaled_height = 1; + miplevel++; + qglTexImage2D(GL_TEXTURE_2D, miplevel, comp, scaled_width, + scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + } } } @@ -486,10 +486,7 @@ static int GL_UpscaleLevel(int width, int height, imagetype_t type, imageflags_t if (!(flags & (IF_PALETTED | IF_SCRAP))) return 0; - if (!AT_LEAST_OPENGL(3, 0)) { - width = npot32(width); - height = npot32(height); - } + GL_MakePowerOfTwo(&width, &height); maxlevel = Cvar_ClampInteger(gl_upscale_pcx, 0, 2); while (maxlevel) { @@ -851,24 +848,31 @@ void GL_InitImages(void) gl_texturemode->changed = gl_texturemode_changed; gl_texturemode->generator = gl_texturemode_g; gl_texturebits = Cvar_Get("gl_texturebits", "0", CVAR_FILES); + gl_texture_non_power_of_two = Cvar_Get("gl_texture_non_power_of_two", "1", 0); gl_anisotropy = Cvar_Get("gl_anisotropy", "1", 0); gl_anisotropy->changed = gl_anisotropy_changed; gl_noscrap = Cvar_Get("gl_noscrap", "0", CVAR_FILES); gl_round_down = Cvar_Get("gl_round_down", "0", CVAR_FILES); gl_picmip = Cvar_Get("gl_picmip", "0", CVAR_FILES); - gl_maxmip = Cvar_Get("gl_maxmip", "0", CVAR_FILES); gl_downsample_skins = Cvar_Get("gl_downsample_skins", "1", CVAR_FILES); gl_gamma_scale_pics = Cvar_Get("gl_gamma_scale_pics", "0", CVAR_FILES); gl_upscale_pcx = Cvar_Get("gl_upscale_pcx", "0", CVAR_FILES); gl_saturation = Cvar_Get("gl_saturation", "1", CVAR_FILES); gl_intensity = Cvar_Get("intensity", "1", CVAR_FILES); gl_invert = Cvar_Get("gl_invert", "0", CVAR_FILES); + gl_gamma = Cvar_Get("vid_gamma", "1", CVAR_ARCHIVE); + if (r_config.flags & QVF_GAMMARAMP) { - gl_gamma = Cvar_Get("vid_gamma", "1", CVAR_ARCHIVE); gl_gamma->changed = gl_gamma_changed; gl_gamma->flags &= ~CVAR_FILES; } else { - gl_gamma = Cvar_Get("vid_gamma", "1", CVAR_ARCHIVE | CVAR_FILES); + gl_gamma->flags |= CVAR_FILES; + } + + if (AT_LEAST_OPENGL(3, 0)) { + gl_texture_non_power_of_two->flags |= CVAR_FILES; + } else { + gl_texture_non_power_of_two->flags &= ~CVAR_FILES; } IMG_Init(); diff --git a/src/refresh/gl/main.c b/src/refresh/gl/main.c index 4afa967..e2b0233 100644 --- a/src/refresh/gl/main.c +++ b/src/refresh/gl/main.c @@ -881,6 +881,10 @@ static qboolean GL_SetupConfig(void) Com_Printf("GL_EXT_texture_filter_anisotropic not found\n"); } + if (AT_LEAST_OPENGL(3, 0)) { + gl_config.ext_enabled |= QGL_3_0_core_functions; + } + QGL_InitExtensions(gl_config.ext_enabled); qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &integer); diff --git a/src/refresh/gl/qgl/dynamic.c b/src/refresh/gl/qgl/dynamic.c index 493a1c6..b3094dc 100644 --- a/src/refresh/gl/qgl/dynamic.c +++ b/src/refresh/gl/qgl/dynamic.c @@ -31,6 +31,8 @@ QGL_ARB_vertex_buffer_object_IMP QGL_EXT_compiled_vertex_array_IMP #undef QGL +qglGenerateMipmap_t qglGenerateMipmap; + // ========================================================== #ifdef _DEBUG @@ -634,10 +636,8 @@ void QGL_Shutdown(void) #define QGL(x) qgl##x = NULL #endif QGL_core_IMP - QGL_ARB_fragment_program_IMP - QGL_ARB_multitexture_IMP - QGL_ARB_vertex_buffer_object_IMP - QGL_EXT_compiled_vertex_array_IMP + + QGL_ShutdownExtensions(~0); } void QGL_ShutdownExtensions(unsigned mask) @@ -657,6 +657,10 @@ void QGL_ShutdownExtensions(unsigned mask) if (mask & QGL_EXT_compiled_vertex_array) { QGL_EXT_compiled_vertex_array_IMP } + + if (mask & QGL_3_0_core_functions) { + qglGenerateMipmap = NULL; + } #undef QGL } @@ -672,6 +676,7 @@ qboolean QGL_Init(void) #endif QGL_core_IMP #undef QGL + return qtrue; } @@ -697,6 +702,10 @@ void QGL_InitExtensions(unsigned mask) if (mask & QGL_EXT_compiled_vertex_array) { QGL_EXT_compiled_vertex_array_IMP } + + if (mask & QGL_3_0_core_functions) { + qglGenerateMipmap = GPA(GenerateMipmap); + } #undef QGL } diff --git a/src/refresh/gl/qgl/dynamic.h b/src/refresh/gl/qgl/dynamic.h index 19dfb69..1366799 100644 --- a/src/refresh/gl/qgl/dynamic.h +++ b/src/refresh/gl/qgl/dynamic.h @@ -151,6 +151,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #define QGL_EXT_compiled_vertex_array (1 << 3) #define QGL_EXT_texture_filter_anisotropic (1 << 4) +#define QGL_3_0_core_functions (1 << 31) + // ========================================================== // subset of OpenGL 1.1 core functions @@ -233,6 +235,9 @@ typedef void (APIENTRY * qglTranslatef_t)(GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRY * qglVertexPointer_t)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRY * qglViewport_t)(GLint x, GLint y, GLsizei width, GLsizei height); +// OpenGL 3.0 core function +typedef void (APIENTRY * qglGenerateMipmap_t)(GLenum target); + // GL_ARB_fragment_program typedef void (APIENTRY * qglProgramStringARB_t)(GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRY * qglBindProgramARB_t)(GLenum target, GLuint program); @@ -290,5 +295,7 @@ QGL_ARB_vertex_buffer_object_IMP QGL_EXT_compiled_vertex_array_IMP #undef QGL +extern qglGenerateMipmap_t qglGenerateMipmap; + #endif // QGL_H diff --git a/src/refresh/gl/qgl/fixed.c b/src/refresh/gl/qgl/fixed.c index ae8ec45..94f9f95 100644 --- a/src/refresh/gl/qgl/fixed.c +++ b/src/refresh/gl/qgl/fixed.c @@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc., // ========================================================== +// OpenGL 3.0 core function +PFNGLGENERATEMIPMAPPROC qglGenerateMipmap; + // GL_ARB_fragment_program PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; PFNGLBINDPROGRAMARBPROC qglBindProgramARB; @@ -76,6 +79,10 @@ void QGL_ShutdownExtensions(unsigned mask) qglLockArraysEXT = NULL; qglUnlockArraysEXT = NULL; } + + if (mask & QGL_3_0_core_functions) { + qglGenerateMipmap = NULL; + } } #define GPA(x) VID_GetProcAddr(x) @@ -108,6 +115,10 @@ void QGL_InitExtensions(unsigned mask) qglLockArraysEXT = GPA("glLockArraysEXT"); qglUnlockArraysEXT = GPA("glUnlockArraysEXT"); } + + if (mask & QGL_3_0_core_functions) { + qglGenerateMipmap = GPA("glGenerateMipmap"); + } } #undef GPA diff --git a/src/refresh/gl/qgl/fixed.h b/src/refresh/gl/qgl/fixed.h index 73b2669..31045ca 100644 --- a/src/refresh/gl/qgl/fixed.h +++ b/src/refresh/gl/qgl/fixed.h @@ -104,6 +104,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define qglVertexPointer glVertexPointer #define qglViewport glViewport +// OpenGL 3.0 core function +extern PFNGLGENERATEMIPMAPPROC qglGenerateMipmap; + // GL_ARB_fragment_program extern PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; extern PFNGLBINDPROGRAMARBPROC qglBindProgramARB; @@ -135,8 +138,10 @@ extern PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; #define QGL_EXT_compiled_vertex_array (1 << 3) #define QGL_EXT_texture_filter_anisotropic (1 << 4) +#define QGL_3_0_core_functions (1 << 31) + #define QGL_Init() qtrue -#define QGL_Shutdown() QGL_ShutdownExtensions(~0) +#define QGL_Shutdown() QGL_ShutdownExtensions(~0) void QGL_InitExtensions(unsigned mask); void QGL_ShutdownExtensions(unsigned mask); |