From 513a1303eaa7231456ee65bd020a621331e88d2d Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Tue, 7 Nov 2006 08:17:10 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@518 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/rendercubes.cpp | 30 +++--- source/src/renderextras.cpp | 1 - source/src/rendergl.cpp | 190 +++++++++++++++++++----------------- source/src/tools.h | 3 +- source/src/worldio.cpp | 2 +- 5 files changed, 117 insertions(+), 109 deletions(-) diff --git a/source/src/rendercubes.cpp b/source/src/rendercubes.cpp index 95246c2b..e83aca42 100644 --- a/source/src/rendercubes.cpp +++ b/source/src/rendercubes.cpp @@ -27,7 +27,7 @@ void setarraypointers() int nquads; const float TEXTURESCALE = 32.0f; bool floorstrip = false, deltastrip = false; -int oh, oy, ox, ogltex; // the o* vars are used by the stripification +int oh, oy, ox, striptex; // the o* vars are used by the stripification int ol3r, ol3g, ol3b, ol4r, ol4g, ol4b; int firstindex; bool showm = false; @@ -37,7 +37,7 @@ void mipstats(int a, int b, int c) { if(showm) conoutf("1x1/2x2/4x4: %d / %d / % COMMAND(showmip, ARG_NONE); -#define stripend() { if(floorstrip || deltastrip) { addstrip(ogltex, firstindex, verts.length()-firstindex); floorstrip = deltastrip = false; }; }; +#define stripend() { if(floorstrip || deltastrip) { addstrip(striptex, firstindex, verts.length()-firstindex); floorstrip = deltastrip = false; }; }; void finishstrips() { stripend(); }; sqr sbright, sdark; @@ -48,7 +48,7 @@ void render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l2, sqr if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }; int sx, sy; - int gltex = lookuptexture(wtex, sx, sy); + lookuptexture(wtex, sx, sy); float xf = TEXTURESCALE/sx; float yf = TEXTURESCALE/sy; float xs = size*xf; @@ -56,13 +56,13 @@ void render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l2, sqr float xo = xf*x; float yo = yf*y; - bool first = !floorstrip || y!=oy+size || ogltex!=gltex || h!=oh || x!=ox; + bool first = !floorstrip || y!=oy+size || striptex!=wtex || h!=oh || x!=ox; if(first) // start strip here { stripend(); firstindex = verts.length(); - ogltex = gltex; + striptex = wtex; oh = h; ox = x; floorstrip = true; @@ -126,7 +126,7 @@ void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, floa if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }; int sx, sy; - int gltex = lookuptexture(wtex, sx, sy); + lookuptexture(wtex, sx, sy); float xf = TEXTURESCALE/sx; float yf = TEXTURESCALE/sy; float xs = size*xf; @@ -134,13 +134,13 @@ void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, floa float xo = xf*x; float yo = yf*y; - bool first = !deltastrip || y!=oy+size || ogltex!=gltex || x!=ox; + bool first = !deltastrip || y!=oy+size || striptex!=wtex || x!=ox; if(first) { stripend(); firstindex = verts.length(); - ogltex = gltex; + striptex = wtex; ox = x; deltastrip = true; if(isceil) @@ -181,23 +181,23 @@ void render_2tris(sqr *h, sqr *s, int x1, int y1, int x2, int y2, int x3, int y3 stripend(); int sx, sy; - int gltex = lookuptexture(h->ftex, sx, sy); + lookuptexture(h->ftex, sx, sy); float xf = TEXTURESCALE/sx; float yf = TEXTURESCALE/sy; vertf((float)x1, h->floor, (float)y1, l1, xf*x1, yf*y1); vertf((float)x2, h->floor, (float)y2, l2, xf*x2, yf*y2); vertf((float)x3, h->floor, (float)y3, l3, xf*x3, yf*y3); - addstrip(gltex, verts.length()-3, 3); + addstrip(h->ftex, verts.length()-3, 3); - gltex = lookuptexture(h->ctex, sx, sy); + lookuptexture(h->ctex, sx, sy); xf = TEXTURESCALE/sx; yf = TEXTURESCALE/sy; vertf((float)x3, h->ceil, (float)y3, l3, xf*x3, yf*y3); vertf((float)x2, h->ceil, (float)y2, l2, xf*x2, yf*y2); vertf((float)x1, h->ceil, (float)y1, l1, xf*x1, yf*y1); - addstrip(gltex, verts.length()-3, 3); + addstrip(h->ctex, verts.length()-3, 3); nquads++; }; @@ -222,7 +222,7 @@ void render_square(int wtex, float floor1, float floor2, float ceil1, float ceil if(showm) { l1 = &sbright; l2 = &sdark; }; int sx, sy; - int gltex = lookuptexture(wtex, sx, sy); + lookuptexture(wtex, sx, sy); float xf = TEXTURESCALE/sx; float yf = TEXTURESCALE/sy; float xs = size*xf; @@ -244,7 +244,7 @@ void render_square(int wtex, float floor1, float floor2, float ceil1, float ceil }; nquads++; - addstrip(gltex, verts.length()-4, 4); + addstrip(wtex, verts.length()-4, 4); }; int wx1, wy1, wx2, wy2; @@ -331,6 +331,8 @@ void addwaterquad(int x, int y, int size) // update bounding rect that con void resetcubes() { + verts.setsizenodelete(0); + floorstrip = deltastrip = false; wx1 = -1; nquads = 0; diff --git a/source/src/renderextras.cpp b/source/src/renderextras.cpp index 0dba5f7f..aff22b6e 100644 --- a/source/src/renderextras.cpp +++ b/source/src/renderextras.cpp @@ -360,7 +360,6 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat glEnable(GL_TEXTURE_2D); - char *command = getcurcommand(); dynent *player = playerincrosshair(); dynent *bot = botincrosshair(); if(getcurcommand()) rendercommand(20, 1570); diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index c1b26010..bc7701d6 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -12,8 +12,6 @@ bool hasoverbright = false; -void purgetextures(); - GLUquadricObj *qsphere = NULL; int glmaxtexsize = 256; @@ -49,8 +47,6 @@ void gl_init(int w, int h, int bpp, int depth, int fsaa) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glmaxtexsize); - purgetextures(); - if(!(qsphere = gluNewQuadric())) fatal("glu sphere"); gluQuadricDrawStyle(qsphere, GLU_FILL); gluQuadricOrientation(qsphere, GLU_INSIDE); @@ -83,14 +79,14 @@ bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp, bool high xs = s->w; ys = s->h; while(xs>glmaxtexsize || ys>glmaxtexsize) { xs /= 2; ys /= 2; }; + int mode = s->format->BitsPerPixel==24 ? GL_RGB : GL_RGBA; uchar *scaledimg = (uchar *)s->pixels; if(xs!=s->w) { conoutf("warning: quality loss: scaling %s", texname); // for voodoo cards under linux - scaledimg = new uchar[xs*ys*3]; - gluScaleImage(GL_RGB, s->w, s->h, GL_UNSIGNED_BYTE, s->pixels, xs, ys, GL_UNSIGNED_BYTE, scaledimg); + scaledimg = new uchar[xs*ys*s->format->BitsPerPixel/8]; + gluScaleImage(mode, s->w, s->h, GL_UNSIGNED_BYTE, s->pixels, xs, ys, GL_UNSIGNED_BYTE, scaledimg); }; - int mode = s->format->BitsPerPixel==24 ? GL_RGB : GL_RGBA; if(gluBuild2DMipmaps(GL_TEXTURE_2D, mode, xs, ys, mode, GL_UNSIGNED_BYTE, scaledimg)) fatal("could not build mipmaps"); if(xs!=s->w) delete[] scaledimg; SDL_FreeSurface(s); @@ -101,85 +97,81 @@ bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp, bool high // each texture slot can have multople texture frames, of which currently only the first is used // additional frames can be used for various shaders -const int MAXTEX = 1000; -int texx[MAXTEX]; // ( loaded texture ) -> ( name, size ) -int texy[MAXTEX]; -string texname[MAXTEX]; -int curtex = 0; const int FIRSTTEX = 160; // opengl id = loaded id + FIRSTTEX // std 1+, sky 14+, md3's 30+,md2's 40+ -const int MAXFRAMES = 2; // increase to allow more complex shader defs -int mapping[256][MAXFRAMES]; // ( cube texture, frame ) -> ( opengl id, name ) -string mapname[256][MAXFRAMES]; - -void purgetextures() -{ - loopi(256) loop(j,MAXFRAMES) mapping[i][j] = 0; +struct Texture +{ + string name; + int xs, ys; + GLuint id; }; - -int curtexnum = 0; - -void texturereset() { curtexnum = 0; }; +vector textures; + +Texture *textureload(const char *name) +{ + loopv(textures) + { + Texture *t = textures[i]; + if(!strcmp(t->name, name)) return t; + }; + int id = FIRSTTEX+textures.length(), xs, ys; + s_sprintfd(pname)("packages%ctextures%c%s", PATHDIV, PATHDIV, name); + if(!installtex(id, pname, xs, ys)) return NULL; + Texture *t = textures.add(new Texture); + s_strcpy(t->name, name); + t->xs = xs; + t->ys = ys; + t->id = id; + return t; +}; + +struct Slot +{ + string name; + Texture *tex; + bool loaded; +}; + +vector slots; + +void texturereset() { slots.setsizenodelete(0); }; void texture(char *aframe, char *name) -{ - int num = curtexnum++, frame = atoi(aframe); - if(num<0 || num>=256 || frame<0 || frame>=MAXFRAMES) return; - mapping[num][frame] = 1; - char *n = mapname[num][frame]; - s_strcpy(n, name); - path(n); +{ + Slot &s = slots.add(); + s_strcpy(s.name, name); + path(s.name); + s.tex = NULL; + s.loaded = false; }; COMMAND(texturereset, ARG_NONE); COMMAND(texture, ARG_2STR); int lookuptexture(int tex, int &xs, int &ys) -{ - int frame = 0; // other frames? - int tid = mapping[tex][frame]; - - if(tid>=FIRSTTEX) +{ + if(!slots.inrange(tex)) { - xs = texx[tid-FIRSTTEX]; - ys = texy[tid-FIRSTTEX]; - return tid; + xs = ys = 16; + return 1; // crosshair :) }; - xs = ys = 16; - if(!tid) return 1; // crosshair :) - - loopi(curtex) // lazily happens once per "texture" command, basically + Slot &s = slots[tex]; + if(!s.loaded) { - if(strcmp(mapname[tex][frame], texname[i])==0) - { - mapping[tex][frame] = tid = i+FIRSTTEX; - xs = texx[i]; - ys = texy[i]; - return tid; - }; + s.tex = textureload(s.name); + s.loaded = true; + }; + if(!s.tex) + { + xs = ys = 16; + return 1; // crosshair :) }; - if(curtex==MAXTEX) fatal("loaded too many textures"); - - int tnum = curtex+FIRSTTEX; - s_strcpy(texname[curtex], mapname[tex][frame]); - - s_sprintfd(name)("packages%ctextures%c%s", PATHDIV, PATHDIV, texname[curtex]); - - if(installtex(tnum, name, xs, ys)) - { - mapping[tex][frame] = tnum; - texx[curtex] = xs; - texy[curtex] = ys; - curtex++; - return tnum; - } - else - { - return mapping[tex][frame] = FIRSTTEX; // temp fix - }; + xs = s.tex->xs; + ys = s.tex->ys; + return s.tex->id; }; void setupworld() @@ -198,37 +190,59 @@ void setupworld() }; }; -int skyoglid; +struct strip { int start, num; }; -struct strip { int tex, start, num; }; -vector strips; +struct stripbatch +{ + int tex; + vector strips; +}; + +vector skystrips; +stripbatch stripbatches[256]; +uchar renderedtex[256]; +int renderedtexs = 0; void renderstripssky() { - glBindTexture(GL_TEXTURE_2D, skyoglid); - loopv(strips) if(strips[i].tex==skyoglid) glDrawArrays(GL_TRIANGLE_STRIP, strips[i].start, strips[i].num); + if(skystrips.empty()) return; + int xs, ys; + glBindTexture(GL_TEXTURE_2D, lookuptexture(DEFAULT_SKY, xs, ys)); + loopv(skystrips) glDrawArrays(GL_TRIANGLE_STRIP, skystrips[i].start, skystrips[i].num); + skystrips.setsizenodelete(0); }; void renderstrips() { - int lasttex = -1; - loopv(strips) if(strips[i].tex!=skyoglid) + int xs, ys; + loopj(renderedtexs) { - if(strips[i].tex!=lasttex) - { - glBindTexture(GL_TEXTURE_2D, strips[i].tex); - lasttex = strips[i].tex; - }; - glDrawArrays(GL_TRIANGLE_STRIP, strips[i].start, strips[i].num); - }; + stripbatch &sb = stripbatches[j]; + glBindTexture(GL_TEXTURE_2D, lookuptexture(sb.tex, xs, ys)); + loopv(sb.strips) glDrawArrays(GL_TRIANGLE_STRIP, sb.strips[i].start, sb.strips[i].num); + sb.strips.setsizenodelete(0); + }; + renderedtexs = 0; }; void overbright(float amount) { if(hasoverbright) glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, amount ); }; void addstrip(int tex, int start, int n) { - strip &s = strips.add(); - s.tex = tex; + if(tex==DEFAULT_SKY) + { + strip &s = skystrips.add(); + s.start = start; + s.num = n; + return; + }; + stripbatch *sb = &stripbatches[renderedtex[tex]]; + if(sb->tex!=tex || sb>=&stripbatches[renderedtexs]) + { + sb = &stripbatches[renderedtex[tex] = renderedtexs++]; + sb->tex = tex; + }; + strip &s = sb->strips.add(); s.start = start; s.num = n; }; @@ -345,15 +359,8 @@ void gl_drawframe(int w, int h, float changelod, float curfps) glEnable(GL_TEXTURE_2D); - int xs, ys; - skyoglid = lookuptexture(DEFAULT_SKY, xs, ys); - resetcubes(); - extern vector verts; - verts.setsizenodelete(0); - strips.setsizenodelete(0); - render_world(player1->o.x, player1->o.y, player1->o.z, changelod, (int)player1->yaw, (int)player1->pitch, (float)fov, w, h); finishstrips(); @@ -415,6 +422,7 @@ void gl_drawframe(int w, int h, float changelod, float curfps) glDisable(GL_TEXTURE_2D); + extern vector verts; gl_drawhud(w, h, (int)curfps, nquads, verts.length(), underwater); glEnable(GL_CULL_FACE); diff --git a/source/src/tools.h b/source/src/tools.h index e1aa6706..4085a273 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -184,9 +184,8 @@ template struct vector void *_realloc(void *p, int oldsize, int newsize) { void *np = new uchar[newsize]; - if(!oldsize) return np; memcpy(np, p, newsize>oldsize ? oldsize : newsize); - delete[] (char *)p; + delete[] (uchar *)p; return np; }; diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index a54632c9..69e11566 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -366,7 +366,7 @@ void load_world(char *mname) // still supports all map formats that have execfile(mcfname); int xs, ys; c2skeepalive(); - loopi(256) if(texuse) lookuptexture(i, xs, ys); + loopi(256) if(texuse[i]) lookuptexture(i, xs, ys); c2skeepalive(); preload_mapmodels(); c2skeepalive();