diff --git a/source/src/protos.h b/source/src/protos.h index b61fa73d..1d95318c 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -267,13 +267,14 @@ struct Texture { char *name; int xs, ys, bpp, clamp; + bool mipmap, canreduce; GLuint id; }; extern Texture *notexture, *noworldtexture; extern void scaletexture(uchar *src, uint sw, uint sh, uint bpp, uchar *dst, uint dw, uint dh); -extern void createtexture(int tnum, int w, int h, void *pixels, int clamp, bool mipmap, GLenum format); -extern Texture *textureload(const char *name, int clamp = 0); +extern void createtexture(int tnum, int w, int h, void *pixels, int clamp, bool mipmap, bool canreduce, GLenum format); +extern Texture *textureload(const char *name, int clamp = 0, bool mipmap = true, bool canreduce = false); extern Texture *lookuptexture(int tex, Texture *failtex = notexture); extern bool reloadtexture(Texture &t); extern bool reloadtexture(const char *name); diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 3c3fb4d7..b3109390 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -593,12 +593,12 @@ void drawreflection(float hf, int w, int h, float changelod, bool refract) if(!reflecttex) { glGenTextures(1, &reflecttex); - createtexture(reflecttex, size, size, NULL, 3, false, GL_RGB); + createtexture(reflecttex, size, size, NULL, 3, false, false, GL_RGB); } if(!refracttex) { glGenTextures(1, &refracttex); - createtexture(refracttex, size, size, NULL, 3, false, GL_RGB); + createtexture(refracttex, size, size, NULL, 3, false, false, GL_RGB); } reflectlastsize = size; } @@ -734,7 +734,7 @@ void drawminimap(int w, int h) if(!minimaptex) { glGenTextures(1, &minimaptex); - createtexture(minimaptex, size, size, NULL, 3, false, GL_RGB); + createtexture(minimaptex, size, size, NULL, 3, false, false, GL_RGB); minimaplastsize = size; } diff --git a/source/src/renderparticles.cpp b/source/src/renderparticles.cpp index b1b85c1e..f8b373ae 100644 --- a/source/src/renderparticles.cpp +++ b/source/src/renderparticles.cpp @@ -65,7 +65,7 @@ GLuint createexpmodtex(int size, float minval) } GLuint tex = 0; glGenTextures(1, &tex); - createtexture(tex, size, size, data, 3, true, GL_ALPHA); + createtexture(tex, size, size, data, 3, true, false, GL_ALPHA); delete[] data; return tex; } diff --git a/source/src/texture.cpp b/source/src/texture.cpp index 54cba4e9..eb370167 100644 --- a/source/src/texture.cpp +++ b/source/src/texture.cpp @@ -67,6 +67,7 @@ hashtable textures; VAR(hwtexsize, 1, 0, 0); VARFP(maxtexsize, 0, 0, 1<<12, initwarning("texture quality", INIT_LOAD)); +VARFP(texreduce, 0, 0, 3, initwarning("texture quality", INIT_LOAD)); VARFP(trilinear, 0, 1, 1, initwarning("texture filtering", INIT_LOAD)); VARFP(bilinear, 0, 1, 1, initwarning("texture filtering", INIT_LOAD)); @@ -83,10 +84,15 @@ int formatsize(GLenum format) } } -void resizetexture(int w, int h, bool mipmap, GLenum target, int &tw, int &th) +void resizetexture(int w, int h, bool mipmap, bool canreduce, GLenum target, int &tw, int &th) { int hwlimit = hwtexsize, sizelimit = mipmap && maxtexsize ? min(maxtexsize, hwlimit) : hwlimit; + if(canreduce) loopi(texreduce) + { + if(w > 1) w /= 2; + if(h > 1) h /= 2; + } w = min(w, sizelimit); h = min(h, sizelimit); if(mipmap || w&(w-1) || h&(h-1)) @@ -127,7 +133,7 @@ void uploadtexture(GLenum target, GLenum internal, int tw, int th, GLenum format if(buf) delete[] buf; } -void createtexture(int tnum, int w, int h, void *pixels, int clamp, bool mipmap, GLenum format) +void createtexture(int tnum, int w, int h, void *pixels, int clamp, bool mipmap, bool canreduce, GLenum format) { glBindTexture(GL_TEXTURE_2D, tnum); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -142,7 +148,7 @@ void createtexture(int tnum, int w, int h, void *pixels, int clamp, bool mipmap, (bilinear ? GL_LINEAR : GL_NEAREST)); int tw = w, th = h; - if(pixels) resizetexture(w, h, mipmap, GL_TEXTURE_2D, tw, th); + if(pixels) resizetexture(w, h, mipmap, canreduce, GL_TEXTURE_2D, tw, th); uploadtexture(GL_TEXTURE_2D, format, tw, th, format, GL_UNSIGNED_BYTE, pixels, w, h, mipmap); } @@ -173,7 +179,7 @@ SDL_Surface *texdecal(SDL_Surface *s) return m; } -GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp) +GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = 0, bool mipmap = true, bool canreduce = false) { const char *file = texname; if(texname[0]=='<') @@ -208,7 +214,7 @@ GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp) GLuint tnum; glGenTextures(1, &tnum); - createtexture(tnum, s->w, s->h, s->pixels, clamp, true, format); + createtexture(tnum, s->w, s->h, s->pixels, clamp, mipmap, canreduce, format); xs = s->w; ys = s->h; bpp = s->format->BitsPerPixel; @@ -220,7 +226,7 @@ GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp) // each texture slot can have multople texture frames, of which currently only the first is used // additional frames can be used for various shaders -Texture *textureload(const char *name, int clamp) +Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce) { string pname; s_strcpy(pname, name); @@ -228,7 +234,7 @@ Texture *textureload(const char *name, int clamp) Texture *t = textures.access(pname); if(t) return t; int xs, ys, bpp; - GLuint id = loadsurface(pname, xs, ys, bpp, clamp); + GLuint id = loadsurface(pname, xs, ys, bpp, clamp, mipmap, canreduce); if(!id) return notexture; char *key = newstring(pname); t = &textures[key]; @@ -237,6 +243,8 @@ Texture *textureload(const char *name, int clamp) t->ys = ys; t->bpp = bpp; t->clamp = clamp; + t->mipmap = mipmap; + t->canreduce = canreduce; t->id = id; return t; } @@ -273,7 +281,7 @@ Texture *lookuptexture(int tex, Texture *failtex) if(!s.loaded) { s_sprintfd(pname)("packages/textures/%s", s.name); - s.tex = textureload(pname); + s.tex = textureload(pname, 0, true, true); if(s.tex==notexture) s.tex = failtex; s.loaded = true; } @@ -293,7 +301,7 @@ bool reloadtexture(Texture &t) { if(t.id) return true; int xs = 1, ys = 1, bpp = 0; - t.id = loadsurface(t.name, xs, ys, bpp, t.clamp); + t.id = loadsurface(t.name, xs, ys, bpp, t.clamp, t.mipmap, t.canreduce); t.xs = xs; t.ys = ys; t.bpp = bpp; diff --git a/source/src/vertmodel.h b/source/src/vertmodel.h index d70a1b8e..ec7b1d4d 100644 --- a/source/src/vertmodel.h +++ b/source/src/vertmodel.h @@ -1011,7 +1011,7 @@ struct vertmodel : model int texsize = min(aasize, 1<