/[gzz]/gzz/gfx/librenderables/Renderables.hxx
ViewVC logotype

Diff of /gzz/gfx/librenderables/Renderables.hxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by jvk, Tue Sep 17 11:14:05 2002 UTC revision 1.13 by tjl, Wed Sep 25 14:45:43 2002 UTC
# Line 14  Line 14 
14  #include "libcolor/spaces.hxx"  #include "libcolor/spaces.hxx"
15  #include "libtext/Text.hxx"  #include "libtext/Text.hxx"
16    
17    #include "libcoords/Coords.hxx"
18    
19  //#include <map> // XXX: used by ../demo/clamptexture.cxx hack  //#include <map> // XXX: used by ../demo/clamptexture.cxx hack
20    
21  #define GLERR { int er = glGetError(); if(er != GL_NO_ERROR) \  #define GLERR { int er = glGetError(); if(er != GL_NO_ERROR) \
# Line 98  namespace Renderables { Line 100  namespace Renderables {
100    
101      void setStandardCoordinates(Vec windowSize);      void setStandardCoordinates(Vec windowSize);
102    
     /** A general affine coordinate system.  
      */  
     struct AffineCoords {  
         Pt center;  
         Vec x;  
         Vec y;  
         float z;  
         AffineCoords() { }  
         AffineCoords(Pt center, Vec x, Vec y) : center(center), x(x), y(y) {}  
   
         /** Create a new affinecoords that contains an orthogonal transformation before  
          * the coords.  
          */  
         AffineCoords(float wmult, float hmult, float xoffs, float yoffs, float zoffs, AffineCoords &other) {  
             center = other.center; center += xoffs * other.x; center += yoffs * other.y;  
             x = wmult * other.x;  
             y = hmult * other.y;  
             z = other.z + zoffs;  
         }  
   
         /** Return the inverse of this coordinate system  
          */  
         AffineCoords getInverse() const {  
           float m = 1.0 / (x.x * y.y - x.y * y.x);  
           AffineCoords r(Pt(0, 0), Vec(m * y.y, -m * x.y), Vec(-m * y.x, m * x.x));  
           r.center -= center.x * r.x + center.y * r.y;  
           r.z = -z;  
           return r;  
         }  
   
         void dump() {  
             cout << "Affinecoords: ";  
             cout << center << " " << x << " " << y << " " << z <<"\n\n";  
         }  
   
         enum { nFloatParams = 7 };  
         void load(float *f) {  
             center = Pt(f[0], f[1]);  
             x = Vec(f[2], f[3]);  
             y = Vec(f[4], f[5]);  
             z = f[6];  
         }  
   
         void vertex(const ZPt &p) const {  
             ZPt tmp = transform(p);  
             // std::cout << "Affine vertex: "<<tmp<<" z "<<z<<"\n";  
             glVertex3f(tmp.x, tmp.y, tmp.z);  
         }  
         void vertex(const Pt &p) const {  
             ZPt tmp = transform(p);  
             // std::cout << "Affine vertex: "<<tmp<<" z "<<z<<"\n";  
             glVertex3f(tmp.x, tmp.y, tmp.z);  
         }  
         ZPt transform(const Pt &p) const {  
             Pt tmp = center + x * p.x + y * p.y;  
             return ZPt(tmp.x, tmp.y, z);  
         }  
         ZPt transform(const ZPt &p) const {  
             Pt tmp = center + x * p.x + y * p.y;  
             return ZPt(tmp.x, tmp.y, z + p.z);  
         }  
         Vec transform(const Vec &p) const {  
             return x * p.x + y * p.y;  
         }  
   
         void performGL_xy() {  
             GLfloat matrix[16] = {  
                 x.x, x.y, 0, 0,  
                 y.x, y.y, 0, 0,  
                 0,   0,   1, 0,  
                 center.x,   center.y,   0, 1  
             };  
             glMultMatrixf(matrix);  
         }  
   
         void performGL() {  
             GLfloat matrix[16] = {  
                 x.x, x.y, 0, 0,  
                 y.x, y.y, 0, 0,  
                 0,   0,   1, 0,  
                 center.x,   center.y,   z, 1  
             };  
             glMultMatrixf(matrix);  
         }  
   
     };  
   
     /* A coordinate system which only translates  
      * and scales.  
      */  
     /*  
     struct OrthoCoords {  
         Pt center;  
         float xScale;  
         float yScale;  
         float z;  
         OrthoCoords() { }  
         OrthoCoords(Pt center, float xScale, float yScale)  
                 : center(center), xScale(xScale), yScale(yScale) {}  
         void load(float *f) {  
             center = Pt(f[0], f[1]);  
             xScale = f[2];  
             yScale = f[3];  
             z = f[4];  
         }  
         void vertex(const ZPt &p) const {  
             Pt tmp = center + Vec(xScale * p.x, yScale * p.y);  
             // std::cout << "Ortho vertex: "<<tmp<<" z "<<z<<"\n";  
             glVertex3f(tmp.x, tmp.y, z + p.z);  
         }  
         void vertex(const Pt &p) const {  
             Pt tmp = center + Vec(xScale * p.x, yScale * p.y);  
             // std::cout << "Ortho vertex: "<<tmp<<" z "<<z<<"\n";  
             glVertex3f(tmp.x, tmp.y, z);  
         }  
         ZPt transform(const Pt &p) const {  
             return ZPt(center.x + xScale * p.x,  
                             center.y + yScale*p.y,  
                             z);  
         }  
     };  
     */  
   
103      /** An OpenGL thing that can be rendered without a coordinate      /** An OpenGL thing that can be rendered without a coordinate
104       * system.       * system.
105       */       */
# Line 236  namespace Renderables { Line 115  namespace Renderables {
115       */       */
116      struct Renderable1 {      struct Renderable1 {
117          virtual ~Renderable1() { }          virtual ~Renderable1() { }
118          virtual void render(AffineCoords &c) = 0;          virtual void render(Coords::CoordSys &c) = 0;
         // virtual void render(OrthoCoords &c) = 0;  
119      };      };
120    
121  #define IMPLEMENTRENDER1 \  #define IMPLEMENTRENDER1 \
122          void render(AffineCoords &c) { renderImpl(c); }          void render(Coords::CoordSys &c) { renderImpl(c); }
123    
124    
         // void render(OrthoCoords &c) { renderImpl(c); }  
125    
126      /** An OpenGL thing which starts in one coordinate      /** An OpenGL thing which starts in one coordinate
127       * system and ends in another. Used for connections.       * system and ends in another. Used for connections.
128       */       */
129      struct Renderable2 {      struct Renderable2 {
130          virtual ~Renderable2() { }          virtual ~Renderable2() { }
131          virtual void render(AffineCoords &c1, AffineCoords &c2) = 0;          virtual void render(Coords::CoordSys &c1, Coords::CoordSys &c2) = 0;
         // virtual void render(OrthoCoords &c1, OrthoCoords &c2) = 0;  
132      };      };
133    
134  #define IMPLEMENTRENDER2 \  #define IMPLEMENTRENDER2 \
135          virtual void render(AffineCoords &c1, AffineCoords &c2) \          virtual void render(Coords::CoordSys &c1, Coords::CoordSys &c2) \
136              { renderImpl(c1, c2); } \              { renderImpl(c1, c2); } \
137                    
         // virtual void render(OrthoCoords &c1, OrthoCoords &c2)  
         //     { renderImpl(c1, c2); }  
138    
         // XXX Move  
     inline float lerp(float a, float b, float fract) {  
         return a + fract * (b-a);  
     }  
139    
140      using std::vector;      using std::vector;
141    
142      /** Render renderables in interpolated coordinate systems      class Renderer {
143       * from lists of integers.          Coords::CoordSet coordset;
144       */      public:
145      template<class CoordsType> class Renderer {          void setPoints( int ninds,
146          vector<float> floatBuffer;                                   int *inds1, float *points1,
147          vector<CoordsType> coordsBuffer;                                   int *interpinds,
148          vector<bool> coordsValid;                                   int *inds2, float *points2,
149                                     float fract, bool show1) {
150          public:              coordset.clean();
151          Renderer() : floatBuffer(), coordsBuffer() { }              coordset.setPoints(ninds, inds1, points1, interpinds, inds2, points2, fract, show1);
   
         void setPoints(int npts, float *points1,  
                                 int *indices2,  
                                 float *points2, float fract,  
                                 bool showFinal) {  
             floatBuffer.reserve(npts);  
             coordsValid.reserve(npts / CoordsType::nFloatParams);  
             for(int i=0; i<npts; i++)  {  
                 int ind2 = i / CoordsType::nFloatParams;  
                 if(indices2) {  
                     if(indices2[i / CoordsType::nFloatParams] <= 0)  {  
                         if(showFinal) {  
                             coordsValid[i / CoordsType::nFloatParams] = true;  
                             floatBuffer[i] = points1[i];  
                         } else {  
                             coordsValid[i / CoordsType::nFloatParams] = false;  
                         }  
                         continue;  
                     } else {  
                         coordsValid[i / CoordsType::nFloatParams] = true;  
                         ind2 = indices2[i / CoordsType::nFloatParams];  
                     }  
                 } else  
                     coordsValid[i / CoordsType::nFloatParams] = true;  
   
                 floatBuffer[i] = lerp(points1[i],  
                             points2[ind2 * CoordsType::nFloatParams +  
                                 i % CoordsType::nFloatParams],  
                                         fract);  
             }  
             int ncoords = npts / CoordsType::nFloatParams;  
             coordsBuffer.reserve(ncoords);  
             for(int i=0; i<ncoords; i++)  
                 coordsBuffer[i].load( & floatBuffer[i * CoordsType::nFloatParams] );  
152          }          }
153    
154          void setPoints(int npts, float *points1) {          void setPoints( int ninds, int *inds1, float *points1) {
155              floatBuffer.reserve(npts);              coordset.clean();
156              coordsValid.reserve(npts / CoordsType::nFloatParams);              coordset.setPoints(ninds, inds1, points1, 0, 0, 0, 0, true);
             for(int i=0; i<npts; i++)  {  
                 floatBuffer[i] = points1[i];  
                 coordsValid[i / CoordsType::nFloatParams] = true;  
             }  
             int ncoords = npts / CoordsType::nFloatParams;  
             coordsBuffer.reserve(ncoords);  
             for(int i=0; i<ncoords; i++)  
                 coordsBuffer[i].load( & floatBuffer[i * CoordsType::nFloatParams] );  
157          }          }
   
         /** Render the scene specified.  
          * This method is called once per each frame to render  
          * everything. The list of integers given is interpreted as  
          * indices of renderables and coordinate systems, with  
          * the following formats:  
          * <pre>  
          *      renderable0id | RENDERABLE0  
          *  
          *      renderable1id | RENDERABLE1  
          *      coordinatesystemId  
          *  
          *      renderable2id | RENDERABLE2  
          *      coordinatesystemId  
          *      coordinatesystemId  
          * </pre>  
          * where '|' is bitwise or.  
          * Each renderable is only rendered if each of its  
          * coordinate systems is valid (set in setPoints).  
          * @param codes The identifiers of the objects to render.  
          */  
158          void renderScene(int *codes,          void renderScene(int *codes,
159                                  ObjectStorer<Renderable0> &r0s,                                  ObjectStorer<Renderable0> &r0s,
160                                  ObjectStorer<Renderable1> &r1s,                                  ObjectStorer<Renderable1> &r1s,
# Line 365  namespace Renderables { Line 172  namespace Renderables {
172                  }                  }
173                  else if(codes[i] & RENDERABLE1) {                  else if(codes[i] & RENDERABLE1) {
174                      if(dbg) std::cout << "rend1 "<<r1s[code]<<"\n";                      if(dbg) std::cout << "rend1 "<<r1s[code]<<"\n";
175                      if(coordsValid[codes[i+1]])                      Coords::CoordSys *cs1 = coordset.get(codes[i+1]);
176                          r1s[code]->render(coordsBuffer[codes[i+1]]);                      if(cs1)
177                            r1s[code]->render(*cs1);
178                      i += 2;                      i += 2;
179                  }                  }
180                  else if(codes[i] & RENDERABLE2) {                  else if(codes[i] & RENDERABLE2) {
181                      if(dbg) std::cout << "rend2 "<<r2s[code]<<"\n";                      if(dbg) std::cout << "rend2 "<<r2s[code]<<"\n";
182                      if(coordsValid[codes[i+1]] &&                      Coords::CoordSys *cs1 = coordset.get(codes[i+1]);
183                         coordsValid[codes[i+2]])                      Coords::CoordSys *cs2 = coordset.get(codes[i+2]);
184                          r2s[code]->render(coordsBuffer[codes[i+1]],                      if(cs1 && cs2)
185                                      coordsBuffer[codes[i+2]]);                          r2s[code]->render(*cs1, *cs2);
186                      i += 3;                      i += 3;
187                  }                  }
188                  else {                  else {

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26