summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/refresh/gl/images.c94
-rw-r--r--src/refresh/gl/main.c4
-rw-r--r--src/refresh/gl/qgl/dynamic.c17
-rw-r--r--src/refresh/gl/qgl/dynamic.h7
-rw-r--r--src/refresh/gl/qgl/fixed.c11
-rw-r--r--src/refresh/gl/qgl/fixed.h7
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);