diff options
author | Karl Berry <karl@freefriends.org> | 2019-03-27 22:27:57 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-03-27 22:27:57 +0000 |
commit | 9121faed0cf54a08882acf41120cf28fc3a32998 (patch) | |
tree | fe7f0c5e9ed02fe4a1fc389c27c88750c2807e43 /Build/source/utils/asymptote/drawsurface.cc | |
parent | b8e24fbf964b4030f68a8484a53d405869693266 (diff) |
asy 2.48 sources
git-svn-id: svn://tug.org/texlive/trunk@50622 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/drawsurface.cc')
-rw-r--r-- | Build/source/utils/asymptote/drawsurface.cc | 314 |
1 files changed, 85 insertions, 229 deletions
diff --git a/Build/source/utils/asymptote/drawsurface.cc b/Build/source/utils/asymptote/drawsurface.cc index 2b0b7fefa23..892e3de1eef 100644 --- a/Build/source/utils/asymptote/drawsurface.cc +++ b/Build/source/utils/asymptote/drawsurface.cc @@ -5,21 +5,34 @@ *****/ #include "drawsurface.h" +#include "drawpath3.h" #include "arrayop.h" #include <iostream> #include <iomanip> #include <fstream> -using namespace prc; +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> +using namespace prc; +#include "material.h" namespace camp { -const triple drawElement::zero; +#ifdef HAVE_GL +mem::vector<Material> drawElement::material; +MaterialMap drawElement::materialMap; +size_t drawElement::materialIndex; -//double Tx[3]; // x-component of current transform -//double Ty[3]; // y-component of current transform -double Tz[3]; // z-component of current transform +using gl::modelView; +//double* Tx=modelView.T; // x-component of current transform +//double* Ty=modelView.T+4; // y-component of current transform +double* Tz=modelView.T+8; // z-component of current transform + +#endif + +const triple drawElement::zero; using vm::array; @@ -46,63 +59,45 @@ void storecolor(GLfloat *colors, int i, const RGBAColour& p) colors[i+3]=p.A; } -void setcolors(bool colors, bool lighton, +void clearMaterialBuffer(bool draw) +{ + if(draw) drawBezierPatch::S.draw(); + drawElement::material.clear(); + drawElement::material.reserve(nmaterials); + drawElement::materialMap.clear(); + drawElement::materialIndex=0; +} + +void setcolors(bool colors, const RGBAColour& diffuse, const RGBAColour& ambient, const RGBAColour& emissive, const RGBAColour& specular, double shininess) { - static prc::RGBAColour lastdiffuse; - static prc::RGBAColour lastambient; - static prc::RGBAColour lastemissive; - static prc::RGBAColour lastspecular; - static double lastshininess=0.0; - static bool lastcolors=false; - - if(colors != lastcolors) { - drawBezierPatch::S.draw(); - lastcolors=colors; - } - - if(!colors && (diffuse != lastdiffuse || ambient != lastambient || - emissive != lastemissive || specular != lastspecular || - shininess != lastshininess)) { - drawBezierPatch::S.draw(); - lastdiffuse=diffuse; - lastambient=ambient; - lastemissive=emissive; - lastspecular=specular; - lastshininess=shininess; - } - + Material m; if(colors) { - if(!lighton) - glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION); - - GLfloat Black[]={0,0,0,(GLfloat) diffuse.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Black); - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Black); - glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Black); - } else { - GLfloat Diffuse[]={(GLfloat) diffuse.R,(GLfloat) diffuse.G, - (GLfloat) diffuse.B,(GLfloat) diffuse.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse); - - GLfloat Ambient[]={(GLfloat) ambient.R,(GLfloat) ambient.G, - (GLfloat) ambient.B,(GLfloat) ambient.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambient); - - GLfloat Emissive[]={(GLfloat) emissive.R,(GLfloat) emissive.G, - (GLfloat) emissive.B,(GLfloat) emissive.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emissive); - } - - if(lighton) { - GLfloat Specular[]={(GLfloat) specular.R,(GLfloat) specular.G, - (GLfloat) specular.B,(GLfloat) specular.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular); - - glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128.0*shininess); + static glm::vec4 Black(0.0,0.0,0.0,diffuse.A); + m=Material(Black,Black,Black, + glm::vec4(specular.R,specular.G,specular.B,specular.A), + shininess); + } else + m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A), + glm::vec4(ambient.R,ambient.G,ambient.B,ambient.A), + glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A), + glm::vec4(specular.R,specular.G,specular.B,specular.A), + shininess); + + MaterialMap::iterator p=drawElement::materialMap.find(m); + if(p != drawElement::materialMap.end()) + drawElement::materialIndex=p->second; + else { + drawElement::materialIndex=drawElement::material.size(); + if(drawElement::materialIndex >= nmaterials) + nmaterials=min(Maxmaterials,2*nmaterials); + if(drawElement::materialIndex >= Maxmaterials) + clearMaterialBuffer(true); + drawElement::material.push_back(m); + drawElement::materialMap[m]=drawElement::materialIndex; } } @@ -150,17 +145,17 @@ void drawBezierPatch::bounds(const double* t, bbox3& b) } double c0=cx[0]; - double fuzz=sqrtFuzz*run::norm(cx,16); + double fuzz=Fuzz*run::norm(cx,16); x=bound(cx,min,b.empty ? c0 : min(c0,b.left),fuzz,maxdepth); X=bound(cx,max,b.empty ? c0 : max(c0,b.right),fuzz,maxdepth); c0=cy[0]; - fuzz=sqrtFuzz*run::norm(cy,16); + fuzz=Fuzz*run::norm(cy,16); y=bound(cy,min,b.empty ? c0 : min(c0,b.bottom),fuzz,maxdepth); Y=boundtri(cy,max,b.empty ? c0 : max(c0,b.top),fuzz,maxdepth); c0=cz[0]; - fuzz=sqrtFuzz*run::norm(cz,16); + fuzz=Fuzz*run::norm(cz,16); z=bound(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth); Z=bound(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth); } @@ -247,10 +242,8 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&) return true; } -void drawBezierPatch::render(GLUnurbs *nurb, double size2, - const triple& b, const triple& B, - double perspective, bool lighton, - bool transparent) +void drawBezierPatch::render(double size2, const triple& b, const triple& B, + double perspective, bool transparent) { #ifdef HAVE_GL if(invisible || @@ -275,28 +268,9 @@ void drawBezierPatch::render(GLUnurbs *nurb, double size2, } const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); - - double t[16]; // current transform - glGetDoublev(GL_MODELVIEW_MATRIX,t); -// Like Fortran, OpenGL uses transposed (column-major) format! - run::transpose(t,4); -/* - Tx[0]=t[0]; - Tx[1]=t[1]; - Tx[2]=t[2]; - - Ty[0]=t[4]; - Ty[1]=t[5]; - Ty[2]=t[6]; -*/ - - Tz[0]=t[8]; - Tz[1]=t[9]; - Tz[2]=t[10]; - - run::inverse(t,4); + bbox3 box(m,M); - box.transform(t); + box.transform(modelView.Tinv); m=box.Min(); M=box.Max(); @@ -305,14 +279,14 @@ void drawBezierPatch::render(GLUnurbs *nurb, double size2, Max.getz() < m.getz() || Min.getz() > M.getz())) return; - setcolors(colors,lighton,diffuse,ambient,emissive,specular,shininess); + setcolors(colors,diffuse,ambient,emissive,specular,shininess); if(billboard) BB.init(center); - GLfloat v[16]; + GLfloat c[16]; if(colors) for(size_t i=0; i < 4; ++i) - storecolor(v,4*i,colors[i]); + storecolor(c,4*i,colors[i]); triple *Controls; triple Controls0[16]; @@ -335,9 +309,11 @@ void drawBezierPatch::render(GLUnurbs *nurb, double size2, C.draw(); } else { S.queue(Controls,straight,size3.length()/size2,m,M,transparent, - colors ? v : NULL); - if(!transparent) - S.draw(); + colors ? c : NULL); + if(BezierPatch::nvertices >= gl::maxvertices) + drawBezierPatch::S.drawMaterials(); + if(BezierPatch::Nvertices >= gl::maxvertices) + drawBezierPatch::S.drawColors(); } #endif } @@ -387,17 +363,17 @@ void drawBezierTriangle::bounds(const double* t, bbox3& b) } double c0=cx[0]; - double fuzz=sqrtFuzz*run::norm(cx,10); + double fuzz=Fuzz*run::norm(cx,10); x=boundtri(cx,min,b.empty ? c0 : min(c0,b.left),fuzz,maxdepth); X=boundtri(cx,max,b.empty ? c0 : max(c0,b.right),fuzz,maxdepth); c0=cy[0]; - fuzz=sqrtFuzz*run::norm(cy,10); + fuzz=Fuzz*run::norm(cy,10); y=boundtri(cy,min,b.empty ? c0 : min(c0,b.bottom),fuzz,maxdepth); Y=boundtri(cy,max,b.empty ? c0 : max(c0,b.top),fuzz,maxdepth); c0=cz[0]; - fuzz=sqrtFuzz*run::norm(cz,10); + fuzz=Fuzz*run::norm(cz,10); z=boundtri(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth); Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth); } @@ -485,10 +461,8 @@ bool drawBezierTriangle::write(prcfile *out, unsigned int *, double, return true; } -void drawBezierTriangle::render(GLUnurbs *nurb, double size2, - const triple& b, const triple& B, - double perspective, bool lighton, - bool transparent) +void drawBezierTriangle::render(double size2, const triple& b, const triple& B, + double perspective, bool transparent) { #ifdef HAVE_GL if(invisible || @@ -513,28 +487,9 @@ void drawBezierTriangle::render(GLUnurbs *nurb, double size2, } const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); - - double t[16]; // current transform - glGetDoublev(GL_MODELVIEW_MATRIX,t); -// Like Fortran, OpenGL uses transposed (column-major) format! - run::transpose(t,4); -/* - Tx[0]=t[0]; - Tx[1]=t[1]; - Tx[2]=t[2]; - - Ty[0]=t[4]; - Ty[1]=t[5]; - Ty[2]=t[6]; -*/ - - Tz[0]=t[8]; - Tz[1]=t[9]; - Tz[2]=t[10]; - run::inverse(t,4); bbox3 box(m,M); - box.transform(t); + box.transform(modelView.Tinv); m=box.Min(); M=box.Max(); @@ -543,7 +498,7 @@ void drawBezierTriangle::render(GLUnurbs *nurb, double size2, Max.getz() < m.getz() || Min.getz() > M.getz())) return; - setcolors(colors,lighton,diffuse,ambient,emissive,specular,shininess); + setcolors(colors,diffuse,ambient,emissive,specular,shininess); if(billboard) BB.init(center); @@ -569,12 +524,9 @@ void drawBezierTriangle::render(GLUnurbs *nurb, double size2, triple edge2[]={Controls[9],Controls[5],Controls[2],Controls[0]}; C.queue(edge2,straight,size3.length()/size2,m,M); C.draw(); - } else { + } else S.queue(Controls,straight,size3.length()/size2,m,M,transparent, colors ? v : NULL); - if(!transparent) - S.draw(); - } #endif } @@ -685,20 +637,15 @@ void drawNurbs::displacement() #endif } -void drawNurbs::render(GLUnurbs *nurb, double size2, - const triple& Min, const triple& Max, - double perspective, bool lighton, bool transparent) +void drawNurbs::render(double size2, const triple& Min, const triple& Max, + double perspective, bool transparent) { #ifdef HAVE_GL if(invisible || ((colors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0 : diffuse.A < 1.0) ^ transparent)) return; - - double t[16]; // current transform - glGetDoublev(GL_MODELVIEW_MATRIX,t); - run::transpose(t,4); bbox3 B(this->Min,this->Max); - B.transform(t); + B.transform(modelView.T); triple m=B.Min(); triple M=B.Max(); @@ -718,27 +665,8 @@ void drawNurbs::render(GLUnurbs *nurb, double size2, M.getz() < Min.getz() || m.getz() > Max.getz()) return; } - setcolors(colors,lighton,diffuse,ambient,emissive,specular,shininess); - - gluBeginSurface(nurb); - int uorder=udegree+1; - int vorder=vdegree+1; - size_t stride=weights ? 4 : 3; - gluNurbsSurface(nurb,uorder+nu,uKnots,vorder+nv,vKnots,stride*nv,stride, - Controls,uorder,vorder, - weights ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3); - if(lighton) - gluNurbsCallback(nurb,GLU_NURBS_NORMAL,(_GLUfuncptr) glNormal3fv); - - if(colors) { - static GLfloat linear[]={0.0,0.0,1.0,1.0}; - gluNurbsSurface(nurb,4,linear,4,linear,8,4,colors,2,2,GL_MAP2_COLOR_4); - } - - gluEndSurface(nurb); - - if(colors) - glDisable(GL_COLOR_MATERIAL); + setcolors(colors,diffuse,ambient,emissive,specular,shininess); +// TODO: implement NURBS renderer #endif } @@ -898,49 +826,6 @@ bool drawTube::write(prcfile *out, unsigned int *, double, groupsmap&) return true; } -bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&) -{ - if(invisible) - return true; - - out->addPoint(v,c,width); - - return true; -} - -void drawPixel::render(GLUnurbs *nurb, double size2, - const triple& Min, const triple& Max, - double perspective, bool lighton, bool transparent) -{ -#ifdef HAVE_GL - if(invisible) - return; - - GLfloat V[4]; - - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION); - - static GLfloat Black[]={0,0,0,1}; - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Black); - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Black); - glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Black); - glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,0.0); - - glPointSize(1.0+width); - - glBegin(GL_POINT); - storecolor(V,0,c); - glColor4fv(V); - store(V,v); - glVertex3fv(V); - glEnd(); - - glPointSize(1.0); - glDisable(GL_COLOR_MATERIAL); -#endif -} - const string drawBaseTriangles::wrongsize= "triangle indices require 3 components"; const string drawBaseTriangles::outofrange="index out of range"; @@ -993,7 +878,7 @@ bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&) if(invisible) return true; - if (nC) { + if(nC) { const RGBAColour white(1,1,1,opacity); const RGBAColour black(0,0,0,opacity); const PRCmaterial m(black,white,black,specular,opacity,PRCshininess); @@ -1006,8 +891,8 @@ bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&) return true; } -void drawTriangles::render(GLUnurbs *nurb, double size2, const triple& Min, - const triple& Max, double perspective, bool lighton, +void drawTriangles::render(double size2, const triple& Min, + const triple& Max, double perspective, bool transparent) { #ifdef HAVE_GL @@ -1017,12 +902,9 @@ void drawTriangles::render(GLUnurbs *nurb, double size2, const triple& Min, if(invisible || ((diffuse.A < 1.0) ^ transparent)) return; triple m,M; - double t[16]; // current transform - glGetDoublev(GL_MODELVIEW_MATRIX,t); - run::transpose(t,4); bbox3 B(this->Min,this->Max); - B.transform(t); + B.transform(modelView.T); m=B.Min(); M=B.Max(); @@ -1044,34 +926,8 @@ void drawTriangles::render(GLUnurbs *nurb, double size2, const triple& Min, return; } - setcolors(nC,!nC,diffuse,ambient,emissive,specular,shininess); - if(!nN) lighton=false; - - glBegin(GL_TRIANGLES); - for(size_t i=0; i < nI; i++) { - const uint32_t *pi=PI[i]; - const uint32_t *ni=NI[i]; - const uint32_t *ci=nC ? CI[i] : 0; - if(lighton) - glNormal3f(N[ni[0]].getx(),N[ni[0]].gety(),N[ni[0]].getz()); - if(nC) - glColor4f(C[ci[0]].R,C[ci[0]].G,C[ci[0]].B,C[ci[0]].A); - glVertex3f(P[pi[0]].getx(),P[pi[0]].gety(),P[pi[0]].getz()); - if(lighton) - glNormal3f(N[ni[1]].getx(),N[ni[1]].gety(),N[ni[1]].getz()); - if(nC) - glColor4f(C[ci[1]].R,C[ci[1]].G,C[ci[1]].B,C[ci[1]].A); - glVertex3f(P[pi[1]].getx(),P[pi[1]].gety(),P[pi[1]].getz()); - if(lighton) - glNormal3f(N[ni[2]].getx(),N[ni[2]].gety(),N[ni[2]].getz()); - if(nC) - glColor4f(C[ci[2]].R,C[ci[2]].G,C[ci[2]].B,C[ci[2]].A); - glVertex3f(P[pi[2]].getx(),P[pi[2]].gety(),P[pi[2]].getz()); - } - glEnd(); - - if(nC) - glDisable(GL_COLOR_MATERIAL); + setcolors(nC,diffuse,ambient,emissive,specular,shininess); + R.queue(nP,P,nN,N,nC,C,nI,PI,NI,CI,transparent); #endif } |