// (c) Tuomas J. Lukka #ifndef VOB_VOBS_PAPER_HXX #define VOB_VOBS_PAPER_HXX #ifndef VOB_DEFINED #define VOB_DEFINED(x) #endif #include #include #include #include namespace Vob { namespace Vobs { PREDBGVAR(dbg_paperquad); const int PAPERQUAD_CS2_TO_SCREEN = 1; const int PAPERQUAD_USE_VERTEX_PROGRAM = 2; /** # PaperQuad is a bit complicated: there are three coordinate # systems here: the window cs, the object cs and the paper cs. # cs1 is object => window, # and cs2 is paper => object, unless PAPERQUAD_CS2_TO_SCREEN is set, when it is # paper => window # Corners give the corners of the quad to render, in object # coordinates. */ class PaperQuad { public: enum { NTrans = 2 }; ::Vob::Paper::Paper *paper; float x0,y0,x1,y1; float scale; float dicefactor; int flags; template void params(F &f) { f(paper, x0, y0, x1, y1, scale, dicefactor, flags); } template void render(const T &coords1, const T &coords2) const { const int flags = this->flags; // object -> paper/window const Transform &coords2inv = coords2.getInverse(); GLERR ZPt paperorigin, paperx, papery; if(flags & PAPERQUAD_CS2_TO_SCREEN) { const Transform &coords1inv = coords1.getInverse(); paperorigin = coords1inv.transform(coords2.transform(ZPt(0, 0, 0))); paperx = coords1inv.transform(coords2.transform(ZPt(1, 0, 0))) - paperorigin; papery = coords1inv.transform(coords2.transform(ZPt(0, 1, 0))) - paperorigin; } else { paperorigin = coords2.transform(ZPt(0, 0, 0)); paperx = coords2.transform(ZPt(1, 0, 0)) - paperorigin; papery = coords2.transform(ZPt(0, 1, 0)) - paperorigin; } Paper::LightParam lightParam; // These are now irrelevant lightParam.orig = paperorigin-ZPt(0,0,0); lightParam.e0 = paperx * scale; lightParam.e1 = papery * scale; lightParam.e2 = ZVec(0,0,paperx.length()) * scale; lightParam.Light = ZVec(-1,-1,1); lightParam.Light_w = 0.0; DBG(dbg_paperquad) << "Paperquad: " << lightParam.orig << " " << lightParam.e0 << " " << lightParam.e1 << " " << lightParam.e2 << " " << "\\nCorners" << x0 << " " << y0 << " " << x1 << " " << y1 << " " << "\\n" ; GLERR ZPt ctr = ZPt(lerp(x0, x1, 0.5), lerp(y0, y1, 0.5), 0); double len = hypot(x1-x0, y1-y0) / 2; double nonl = coords1.nonlinearity(ctr, len); int dice = (int)(len * nonl * dicefactor) + 2; DBG(dbg_paperquad) << "Dice: " << dice <<"\\n"; if(dice < 0 || dice > 100) dice = 100; float *vertices = new float[dice * dice * 5]; int *indices = new int[(dice) * (2*dice)]; #define VERTICES3(x, y, z) vertices[((x)*dice + (y))*5 + (z)] #define VERTICES2(x, y) vertices[((x)*dice + (y))*5] #define INDICES2(x, y) indices[(x)*2*dice + (y)] #define INDICES1(x) indices[(x)*2*dice] int *indps[dice-1]; int counts[dice-1]; for(int ix = 0; ixbegin(); it != paper->end(); ++it) { DBG(dbg_paperquad) << "Pass\\n"; GLERR (*it).setUp_VP(&lightParam); DBG(dbg_paperquad) << "Going to multidraw\\n"; GLERR glMultiDrawElementsEXT(GL_QUAD_STRIP, counts, GL_UNSIGNED_INT, (const GLvoid **)indps, dice-1); DBG(dbg_paperquad) << "Teardown\\n"; GLERR (*it).tearDown_VP(); GLERR DBG(dbg_paperquad) << "Pass over\\n"; } glUnlockArraysEXT(); glPopClientAttrib(); } else { for(Paper::Paper::iterator it = paper->begin(); it != paper->end(); ++it) { DBG(dbg_paperquad) << "Pass\\n"; GLERR (*it).setUp_explicit(&lightParam); DBG(dbg_paperquad) << "Going to set texcoords explicit\\n"; GLERR for(int ix = 0; ix