home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / rendercubes.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-05-30  |  16.3 KB  |  590 lines

  1. // rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills the vertex array for different cube surfaces.
  2.  
  3. #include "cube.h"
  4.  
  5. vector<vertex> verts;
  6.  
  7. void finishstrips();
  8.  
  9. void setupstrips()
  10. {
  11.     finishstrips();
  12.  
  13.     glEnableClientState(GL_VERTEX_ARRAY);
  14.     glEnableClientState(GL_COLOR_ARRAY);
  15.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  16.  
  17.     vertex *buf = verts.getbuf();
  18.     glVertexPointer(3, GL_FLOAT, sizeof(vertex), &buf->x);
  19.     glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), &buf->r);
  20.     glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), &buf->u);
  21. }
  22.  
  23. struct strips { vector<GLint> first; vector<GLsizei> count; };
  24.  
  25. struct stripbatch
  26. {
  27.     int tex;
  28.     strips tris, tristrips, quads;   
  29. };
  30.  
  31. stripbatch skystrips = { DEFAULT_SKY };
  32. stripbatch stripbatches[256];
  33. uchar renderedtex[256];
  34. int renderedtexs = 0;
  35.  
  36. #define RENDERSTRIPS(strips, type) \
  37.     if(strips.first.length()) \
  38.     { \
  39.         if(hasMDA) glMultiDrawArrays_(type, strips.first.getbuf(), strips.count.getbuf(), strips.first.length()); \
  40.         else loopv(strips.first) glDrawArrays(type, strips.first[i], strips.count[i]); \
  41.         strips.first.setsizenodelete(0); \
  42.         strips.count.setsizenodelete(0); \
  43.     }
  44.  
  45. void renderstripssky()
  46. {
  47.     if(skystrips.tris.first.empty() && skystrips.tristrips.first.empty() && skystrips.quads.first.empty()) return;
  48.     int xs, ys;
  49.     glBindTexture(GL_TEXTURE_2D, lookuptexture(DEFAULT_SKY, xs, ys));
  50.     RENDERSTRIPS(skystrips.tris, GL_TRIANGLES);
  51.     RENDERSTRIPS(skystrips.tristrips, GL_TRIANGLE_STRIP);
  52.     RENDERSTRIPS(skystrips.quads, GL_QUADS);
  53. }
  54.  
  55. void renderstrips()
  56. {
  57.     int xs, ys;
  58.     loopj(renderedtexs)
  59.     {
  60.         stripbatch &sb = stripbatches[j];
  61.         glBindTexture(GL_TEXTURE_2D, lookuptexture(sb.tex, xs, ys));
  62.         RENDERSTRIPS(sb.tris, GL_TRIANGLES);
  63.         RENDERSTRIPS(sb.tristrips, GL_TRIANGLE_STRIP);
  64.         RENDERSTRIPS(sb.quads, GL_QUADS);
  65.     }
  66.     renderedtexs = 0;
  67.  
  68.     glDisableClientState(GL_VERTEX_ARRAY);
  69.     glDisableClientState(GL_COLOR_ARRAY);
  70.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  71. }
  72.  
  73. void addstrip(int type, int tex, int start, int n)
  74. {
  75.     stripbatch *sb = NULL;
  76.     if(tex==DEFAULT_SKY)
  77.     {
  78.         if(minimap) return;
  79.         sb = &skystrips;
  80.     }
  81.     else
  82.     {
  83.         sb = &stripbatches[renderedtex[tex]];
  84.         if(sb->tex!=tex || sb>=&stripbatches[renderedtexs])
  85.         {
  86.             sb = &stripbatches[renderedtex[tex] = renderedtexs++];
  87.             sb->tex = tex;
  88.         }
  89.     }
  90.     strips &s = (type==GL_QUADS ? sb->quads : (type==GL_TRIANGLES ? sb->tris : sb->tristrips));
  91.     if(type!=GL_TRIANGLE_STRIP && s.first.length() && s.first.last()+s.count.last() == start)
  92.     {
  93.         s.count.last() += n;
  94.         return;
  95.     }
  96.     s.first.add(start);
  97.     s.count.add(n);
  98. }
  99.  
  100. // generating the actual vertices is done dynamically every frame and sits at the
  101. // leaves of all these functions, and are part of the cpu bottleneck on really slow
  102. // machines, hence the macros.
  103.  
  104. #define vert(v1, v2, v3, ls, t1, t2) { \
  105.     vertex &v = verts.add(); \
  106.     v.u = t1; v.v = t2; \
  107.     v.x = (float)(v1); v.y = (float)(v2); v.z = (float)(v3); \
  108.     v.r = ls->r; v.g = ls->g; v.b = ls->b; v.a = 255; \
  109. }
  110.  
  111. int nquads;
  112. const float TEXTURESCALE = 32.0f;
  113. bool floorstrip = false, deltastrip = false;
  114. int oh, oy, ox, striptex;                         // the o* vars are used by the stripification
  115. int ol3r, ol3g, ol3b, ol4r, ol4g, ol4b;      
  116. int firstindex;
  117. bool showm = false;
  118.  
  119. void showmip() { showm = !showm; }
  120. void mipstats(int a, int b, int c) { if(showm) conoutf("1x1/2x2/4x4: %d / %d / %d", a, b, c); }
  121.  
  122. COMMAND(showmip, ARG_NONE);
  123.  
  124. VAR(mergestrips, 0, 1, 1);
  125.  
  126. #define stripend() \
  127.     if(floorstrip || deltastrip) { \
  128.         int type = GL_TRIANGLE_STRIP, len = verts.length()-firstindex; \
  129.         if(mergestrips) switch(len) { \
  130.             case 3: type = GL_TRIANGLES; break; \
  131.             case 4: type = GL_QUADS; swap(vertex, verts.last(), verts[verts.length()-2]); break; \
  132.          } \
  133.          addstrip(type, striptex, firstindex, len); \
  134.          floorstrip = deltastrip = false; \
  135.     }
  136.  
  137. void finishstrips() { stripend(); }
  138.  
  139. sqr sbright, sdark;
  140. VARP(lighterror,1,8,100);
  141.  
  142. void render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l2, sqr *l3, sqr *l4, bool isceil)  // floor/ceil quads
  143. {
  144.     if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }
  145.  
  146.     int sx, sy;
  147.     lookuptexture(wtex, sx, sy);
  148.     float xf = TEXTURESCALE/sx;
  149.     float yf = TEXTURESCALE/sy;
  150.     float xs = size*xf;
  151.     float ys = size*yf;
  152.     float xo = xf*x;
  153.     float yo = yf*y;
  154.  
  155.     bool first = !floorstrip || y!=oy+size || striptex!=wtex || h!=oh || x!=ox;
  156.  
  157.     if(first)       // start strip here
  158.     {
  159.         stripend();
  160.         firstindex = verts.length();
  161.         striptex = wtex;
  162.         oh = h;
  163.         ox = x;
  164.         floorstrip = true;
  165.         if(isceil)
  166.         {
  167.             vert(x+size, y, h, l2, xo+xs, yo);
  168.             vert(x,      y, h, l1, xo, yo);
  169.         }
  170.         else
  171.         {
  172.             vert(x,      y, h, l1, xo,    yo);
  173.             vert(x+size, y, h, l2, xo+xs, yo);
  174.         }
  175.         ol3r = l1->r;
  176.         ol3g = l1->g;
  177.         ol3b = l1->b;
  178.         ol4r = l2->r;
  179.         ol4g = l2->g;
  180.         ol4b = l2->b;
  181.     }
  182.     else        // continue strip
  183.     {
  184.         int lighterr = lighterror*2;
  185.         if((abs(ol3r-l3->r)<lighterr && abs(ol4r-l4->r)<lighterr        // skip vertices if light values are close enough
  186.         &&  abs(ol3g-l3->g)<lighterr && abs(ol4g-l4->g)<lighterr
  187.         &&  abs(ol3b-l3->b)<lighterr && abs(ol4b-l4->b)<lighterr) || !wtex)   
  188.         {
  189.             verts.setsizenodelete(verts.length()-2);
  190.             nquads--;
  191.         }
  192.         else
  193.         {
  194.             uchar *p3 = (uchar *)(&verts[verts.length()-1].r);
  195.             ol3r = p3[0];  
  196.             ol3g = p3[1];  
  197.             ol3b = p3[2];
  198.             uchar *p4 = (uchar *)(&verts[verts.length()-2].r);  
  199.             ol4r = p4[0];
  200.             ol4g = p4[1];
  201.             ol4b = p4[2];
  202.         }
  203.     }
  204.  
  205.     if(isceil)
  206.     {
  207.         vert(x+size, y+size, h, l3, xo+xs, yo+ys);
  208.         vert(x,      y+size, h, l4, xo,    yo+ys); 
  209.     }
  210.     else
  211.     {
  212.         vert(x,      y+size, h, l4, xo,    yo+ys);
  213.         vert(x+size, y+size, h, l3, xo+xs, yo+ys); 
  214.     }
  215.  
  216.     oy = y;
  217.     nquads++;
  218. }
  219.  
  220. void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, float h3, float h4, sqr *l1, sqr *l2, sqr *l3, sqr *l4, bool isceil)  // floor/ceil quads on a slope
  221. {
  222.     if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }
  223.  
  224.     int sx, sy;
  225.     lookuptexture(wtex, sx, sy);
  226.     float xf = TEXTURESCALE/sx;
  227.     float yf = TEXTURESCALE/sy;
  228.     float xs = size*xf;
  229.     float ys = size*yf;
  230.     float xo = xf*x;
  231.     float yo = yf*y;
  232.  
  233.     bool first = !deltastrip || y!=oy+size || striptex!=wtex || x!=ox; 
  234.  
  235.     if(first) 
  236.     {
  237.         stripend();
  238.         firstindex = verts.length();
  239.         striptex = wtex;
  240.         ox = x;
  241.         deltastrip = true;
  242.         if(isceil)
  243.         {
  244.             vert(x+size, y, h2, l2, xo+xs, yo);
  245.             vert(x,      y, h1, l1, xo,    yo);
  246.         }
  247.         else
  248.         {
  249.             vert(x,      y, h1, l1, xo,    yo);
  250.             vert(x+size, y, h2, l2, xo+xs, yo);
  251.         }
  252.         ol3r = l1->r;
  253.         ol3g = l1->g;
  254.         ol3b = l1->b;
  255.         ol4r = l2->r;
  256.         ol4g = l2->g;
  257.         ol4b = l2->b;
  258.     }
  259.  
  260.     if(isceil)
  261.     {
  262.         vert(x+size, y+size, h3, l3, xo+xs, yo+ys); 
  263.         vert(x,      y+size, h4, l4, xo,    yo+ys);
  264.     }
  265.     else
  266.     {
  267.         vert(x,      y+size, h4, l4, xo,    yo+ys);
  268.         vert(x+size, y+size, h3, l3, xo+xs, yo+ys); 
  269.     }
  270.  
  271.     oy = y;
  272.     nquads++;
  273. }
  274.  
  275. void render_2tris(sqr *h, sqr *s, int x1, int y1, int x2, int y2, int x3, int y3, sqr *l1, sqr *l2, sqr *l3)   // floor/ceil tris on a corner cube
  276. {
  277.     stripend();
  278.  
  279.     int sx, sy;
  280.     lookuptexture(h->ftex, sx, sy);
  281.     float xf = TEXTURESCALE/sx;
  282.     float yf = TEXTURESCALE/sy;
  283.  
  284.     vert(x1, y1, h->floor, l1, xf*x1, yf*y1);
  285.     vert(x2, y2, h->floor, l2, xf*x2, yf*y2);
  286.     vert(x3, y3, h->floor, l3, xf*x3, yf*y3);
  287.     addstrip(mergestrips ? GL_TRIANGLES : GL_TRIANGLE_STRIP, h->ftex, verts.length()-3, 3);
  288.  
  289.     lookuptexture(h->ctex, sx, sy);
  290.     xf = TEXTURESCALE/sx;
  291.     yf = TEXTURESCALE/sy;
  292.  
  293.     vert(x3, y3, h->ceil, l3, xf*x3, yf*y3);
  294.     vert(x2, y2, h->ceil, l2, xf*x2, yf*y2);
  295.     vert(x1, y1, h->ceil, l1, xf*x1, yf*y1);
  296.     addstrip(mergestrips ? GL_TRIANGLES : GL_TRIANGLE_STRIP, h->ctex, verts.length()-3, 3);
  297.     nquads++;
  298. }
  299.  
  300. void render_tris(int x, int y, int size, bool topleft,
  301.                  sqr *h1, sqr *h2, sqr *s, sqr *t, sqr *u, sqr *v)
  302. {
  303.     if(topleft)
  304.     {
  305.         if(h1) render_2tris(h1, s, x+size, y+size, x, y+size, x, y, u, v, s);
  306.         if(h2) render_2tris(h2, s, x, y, x+size, y, x+size, y+size, s, t, v);
  307.     }
  308.     else
  309.     {
  310.         if(h1) render_2tris(h1, s, x, y, x+size, y, x, y+size, s, t, u);
  311.         if(h2) render_2tris(h2, s, x+size, y, x+size, y+size, x, y+size, t, u, v);
  312.     }
  313. }
  314.  
  315. void render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2, int x1, int y1, int x2, int y2, int size, sqr *l1, sqr *l2, bool flip)   // wall quads
  316. {
  317.     stripend();
  318.     if(showm) { l1 = &sbright; l2 = &sdark; }
  319.  
  320.     int sx, sy;
  321.     lookuptexture(wtex, sx, sy);
  322.     float xf = TEXTURESCALE/sx;
  323.     float yf = TEXTURESCALE/sy;
  324.     float xs = size*xf;
  325.     float xo = xf*(x1==x2 ? min(y1,y2) : min(x1,x2));
  326.  
  327.     if(!flip)
  328.     {
  329.         vert(x2, y2, ceil2, l2, xo+xs, -yf*ceil2);
  330.         vert(x1, y1, ceil1, l1, xo,    -yf*ceil1);
  331.         if(mergestrips) vert(x1, y1, floor1, l1, xo, -floor1*yf);
  332.         vert(x2, y2, floor2, l2, xo+xs, -floor2*yf);
  333.         if(!mergestrips) vert(x1, y1, floor1, l1, xo, -floor1*yf);
  334.     }
  335.     else
  336.     {
  337.         vert(x1, y1, ceil1, l1, xo,    -yf*ceil1);
  338.         vert(x2, y2, ceil2, l2, xo+xs, -yf*ceil2);
  339.         if(mergestrips) vert(x2, y2, floor2, l2, xo+xs, -floor2*yf);
  340.         vert(x1, y1, floor1, l1, xo,    -floor1*yf);
  341.         if(!mergestrips) vert(x2, y2, floor2, l2, xo+xs, -floor2*yf);
  342.     }
  343.     addstrip(mergestrips ? GL_QUADS : GL_TRIANGLE_STRIP, wtex, verts.length()-4, 4);
  344.     nquads++;
  345. }
  346.  
  347. int wx1, wy1, wx2, wy2;
  348.  
  349. VARP(watersubdiv, 1, 4, 64);
  350. VARF(waterlevel, -128, -128, 127, if(!noteditmode()) hdr.waterlevel = waterlevel);
  351.  
  352. void setwatercolor(char *r, char *g, char *b, char *a)
  353. {
  354.     if(r[0])
  355.     {
  356.         hdr.watercolor[0] = ATOI(r);
  357.         hdr.watercolor[1] = ATOI(g);
  358.         hdr.watercolor[2] = ATOI(b);
  359.         hdr.watercolor[3] = a[0] ? ATOI(a) : 178;
  360.     }
  361.     else
  362.     {
  363.         hdr.watercolor[0] = 25;
  364.         hdr.watercolor[1] = 76;
  365.         hdr.watercolor[2] = 102;
  366.         hdr.watercolor[3] = 178;
  367.     }
  368. }
  369.  
  370. COMMANDN(watercolour, setwatercolor, ARG_4STR);
  371.  
  372. // renders water for bounding rect area that contains water... simple but very inefficient
  373.  
  374. #define VERTW(vertw, body) \
  375.     inline void vertw(float v1, float v2, float v3, float t) \
  376.     { \
  377.         float angle = v1*v2*0.1f + t; \
  378.         float h = 0.3f*sinf(angle); \
  379.         body; \
  380.         glVertex3f(v1, v2, v3+h); \
  381.     }
  382. #define VERTWT(vertwt, body) VERTW(vertwt, { float v = cosf(angle); float duv = 0.2f*v; body; })
  383. VERTW(vertw, {})
  384. VERTW(vertwc, {
  385.     float v = cosf(angle);
  386.     glColor4ub(hdr.watercolor[0], hdr.watercolor[1], hdr.watercolor[2], (uchar)(hdr.watercolor[3] + (max(v, 0) - 0.5f)*51.0f));
  387. })
  388. VERTWT(vertwt, {
  389.     glTexCoord3f(v1+duv, v2+duv, v3+h);
  390. })
  391. VERTWT(vertwtc, {
  392.     glColor4f(1, 1, 1, 0.15f + max(v, 0)*0.15f);
  393.     glTexCoord3f(v1+duv, v2+duv, v3+h);
  394. })
  395. VERTWT(vertwmtc, {
  396.     glColor4f(1, 1, 1, 0.15f + max(v, 0)*0.15f);
  397.     glMultiTexCoord3f_(GL_TEXTURE0_ARB, v1-duv, v2+duv, v3+h);
  398.     glMultiTexCoord3f_(GL_TEXTURE1_ARB, v1+duv, v2+duv, v3+h);
  399. })
  400.  
  401. #define renderwaterstrips(vertw, hf, t) \
  402.     for(int x = wx1; x<wx2; x += watersubdiv) \
  403.     { \
  404.         glBegin(GL_TRIANGLE_STRIP); \
  405.         vertw(x,             wy1, hf, t); \
  406.         vertw(x+watersubdiv, wy1, hf, t); \
  407.         for(int y = wy1; y<wy2; y += watersubdiv) \
  408.         { \
  409.             vertw(x,             y+watersubdiv, hf, t); \
  410.             vertw(x+watersubdiv, y+watersubdiv, hf, t); \
  411.         } \
  412.         glEnd(); \
  413.         nquads += (wy2-wy1-1)/watersubdiv; \
  414.     }
  415.  
  416. void setprojtexmatrix()
  417. {
  418.     GLfloat pm[16], mm[16];
  419.     glGetFloatv(GL_PROJECTION_MATRIX, pm);
  420.     glGetFloatv(GL_MODELVIEW_MATRIX, mm);
  421.  
  422.     glMatrixMode(GL_TEXTURE);
  423.     glLoadIdentity();
  424.     glTranslatef(0.5f, 0.5f, 0.5f);
  425.     glScalef(0.5f, 0.5f, 0.5f);
  426.     glMultMatrixf(pm);
  427.     glMultMatrixf(mm);
  428. }
  429.  
  430. void setupmultitexrefract(GLuint reflecttex, GLuint refracttex)
  431. {
  432.     setuptmu(0, "K , T @ Ka");
  433.     
  434.     colortmu(0, hdr.watercolor[0]/255.0f, hdr.watercolor[1]/255.0f, hdr.watercolor[2]/255.0f, hdr.watercolor[3]/255.0f);
  435.  
  436.     glBindTexture(GL_TEXTURE_2D, refracttex);
  437.     setprojtexmatrix();
  438.  
  439.     glActiveTexture_(GL_TEXTURE1_ARB);
  440.     glEnable(GL_TEXTURE_2D);
  441.     
  442.     setuptmu(1, "P , T @ C~a");
  443.    
  444.     glBindTexture(GL_TEXTURE_2D, reflecttex);
  445.     setprojtexmatrix();
  446.  
  447.     glActiveTexture_(GL_TEXTURE0_ARB);
  448. }
  449.  
  450. void setupmultitexreflect(GLuint reflecttex)
  451. {
  452.     setuptmu(0, "T , K @ Ca", "Ka * P~a");
  453.     
  454.     float a = hdr.watercolor[3]/255.0f;
  455.     colortmu(0, hdr.watercolor[0]/255.0f*a, hdr.watercolor[1]/255.0f*a, hdr.watercolor[2]/255.0f*a, 1.0f-a);
  456.  
  457.     glBindTexture(GL_TEXTURE_2D, reflecttex);
  458.     setprojtexmatrix();
  459. }
  460.  
  461. void cleanupmultitex(GLuint reflecttex, GLuint refracttex)
  462. {
  463.     resettmu(0);
  464.     glLoadIdentity();
  465.    
  466.     if(refracttex)
  467.     { 
  468.         glActiveTexture_(GL_TEXTURE1_ARB);
  469.         glDisable(GL_TEXTURE_2D);
  470.         resettmu(1);
  471.         glLoadIdentity();
  472.         glActiveTexture_(GL_TEXTURE0_ARB);
  473.     }
  474.     glMatrixMode(GL_MODELVIEW);
  475. }
  476.  
  477. VARP(mtwater, 0, 1, 1);
  478.  
  479. int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
  480. {
  481.     if(wx1<0) return nquads;
  482.     
  483.     wx1 -= wx1%watersubdiv;
  484.     wy1 -= wy1%watersubdiv;
  485.  
  486.     float t = lastmillis/300.0f;
  487.  
  488.     if(mtwater && maxtmus>=2 && reflecttex)
  489.     {
  490.         if(refracttex)
  491.         {
  492.             setupmultitexrefract(reflecttex, refracttex);        
  493.             renderwaterstrips(vertwmtc, hf, t);
  494.         }
  495.         else
  496.         {
  497.             setupmultitexreflect(reflecttex);
  498.             glDepthMask(GL_FALSE);
  499.             glEnable(GL_BLEND);
  500.             glBlendFunc(GL_ONE, GL_SRC_ALPHA);
  501.             renderwaterstrips(vertwtc, hf, t);
  502.             glDisable(GL_BLEND);
  503.             glDepthMask(GL_TRUE);
  504.         }
  505.         cleanupmultitex(reflecttex, refracttex);
  506.         
  507.         return nquads;
  508.     }
  509.  
  510.     if(!refracttex) 
  511.     {
  512.         glDisable(GL_TEXTURE_2D);
  513.         glEnable(GL_BLEND);
  514.     }
  515.     glDepthMask(GL_FALSE);
  516.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  517.  
  518.     if(reflecttex)
  519.     {
  520.         if(!refracttex)
  521.         {
  522.             glColor4ubv(hdr.watercolor);
  523.             renderwaterstrips(vertw, hf, t);
  524.         
  525.             glEnable(GL_TEXTURE_2D);
  526.         }
  527.  
  528.         setprojtexmatrix();
  529.  
  530.         glBindTexture(GL_TEXTURE_2D, refracttex ? refracttex : reflecttex);
  531.     }
  532.  
  533.     if(refracttex) 
  534.     {
  535.         glColor3f(1, 1, 1);
  536.         renderwaterstrips(vertwt, hf, t);
  537.         glEnable(GL_BLEND);
  538.  
  539.         glBindTexture(GL_TEXTURE_2D, reflecttex);
  540.         glDepthMask(GL_TRUE);
  541.     }
  542.     if(reflecttex) { renderwaterstrips(vertwtc, hf, t); }
  543.     else { renderwaterstrips(vertwc, hf, t); }
  544.  
  545.     if(reflecttex)
  546.     {
  547.         glLoadIdentity();
  548.         glMatrixMode(GL_MODELVIEW);
  549.     }
  550.     else glEnable(GL_TEXTURE_2D);
  551.  
  552.     glDisable(GL_BLEND);
  553.     if(!refracttex) glDepthMask(GL_TRUE);
  554.    
  555.     return nquads;
  556. }
  557.  
  558. void addwaterquad(int x, int y, int size)       // update bounding rect that contains water
  559. {
  560.     int x2 = x+size;
  561.     int y2 = y+size;
  562.     if(wx1<0)
  563.     {
  564.         wx1 = x;
  565.         wy1 = y;
  566.         wx2 = x2;
  567.         wy2 = y2;
  568.     }
  569.     else
  570.     {
  571.         if(x<wx1) wx1 = x;
  572.         if(y<wy1) wy1 = y;
  573.         if(x2>wx2) wx2 = x2;
  574.         if(y2>wy2) wy2 = y2;
  575.     }
  576. }
  577.  
  578. void resetcubes()
  579. {
  580.     verts.setsizenodelete(0);
  581.  
  582.     floorstrip = deltastrip = false;
  583.     if(!reflecting) wx1 = -1;
  584.     nquads = 0;
  585.     sbright.r = sbright.g = sbright.b = 255;
  586.     sdark.r = sdark.g = sdark.b = 0;
  587. }
  588.  
  589.  
  590.