diff options
author | Karl Berry <karl@freefriends.org> | 2019-10-06 17:17:34 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-10-06 17:17:34 +0000 |
commit | 7f9f7dad00ea5f025578c491005835740f9ffd90 (patch) | |
tree | 011a87a78042a82ea3a18f5c08e60f6a3930bf0b /Build/source/utils/asymptote/bezierpatch.cc | |
parent | 37d8fb68e502daabe6aa5f5ae9fb78191f275742 (diff) |
asy 2.56 sources
git-svn-id: svn://tug.org/texlive/trunk@52300 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/bezierpatch.cc')
-rw-r--r-- | Build/source/utils/asymptote/bezierpatch.cc | 620 |
1 files changed, 229 insertions, 391 deletions
diff --git a/Build/source/utils/asymptote/bezierpatch.cc b/Build/source/utils/asymptote/bezierpatch.cc index b2201754687..a79749af696 100644 --- a/Build/source/utils/asymptote/bezierpatch.cc +++ b/Build/source/utils/asymptote/bezierpatch.cc @@ -15,33 +15,18 @@ using ::orient3d; #ifdef HAVE_GL -extern GLint materialShader; -extern GLint colorShader; -extern void setUniforms(GLint shader); +int MaterialIndex; -const size_t nbuffer=10000; // Initial size of dynamic buffers - -std::vector<vertexData> BezierPatch::vertexbuffer; -std::vector<VertexData> BezierPatch::Vertexbuffer; -std::vector<VertexData> BezierPatch::tVertexbuffer; -std::vector<GLuint> BezierPatch::indices; -std::vector<GLuint> BezierPatch::Indices; -std::vector<GLuint> BezierPatch::tIndices; - -GLuint BezierPatch::nvertices=0; -GLuint BezierPatch::Nvertices=0; -GLuint BezierPatch::Ntvertices=0; - -//std::vector<GLuint>& I=BezierPatch::tIndices; -//std::vector<VertexData>& V=BezierPatch::tVertexbuffer; +//std::vector<GLuint>& I=transparentData.Indices; +//std::vector<VertexData>& V=transparentData.Vertices; bool colors; std::vector<GLfloat> zbuffer; std::vector<GLfloat> xbuffer; std::vector<GLfloat> ybuffer; -std::vector<GLfloat> xmin,ymin,zmin; -std::vector<GLfloat> xmax,ymax,zmax; +//std::vector<GLfloat> xmin,ymin,zmin; +//std::vector<GLfloat> xmax,ymax,zmax; std::vector<GLfloat> zsum; inline double min(double a, double b, double c) @@ -276,11 +261,11 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic, interp(cd,ca,cb,td); interp(ce,ca,cc,te); - id=BezierPatch::tVertex(d,nd,cd); - ie=BezierPatch::tVertex(e,ne,ce); + id=data.Vertex(d,nd,cd); + ie=data.Vertex(e,ne,ce); } else { - id=BezierPatch::tVertex(d,nd); - ie=BezierPatch::tVertex(e,ne); + id=data.Vertex(d,nd); + ie=data.Vertex(e,ne); } I[i3]=ia; @@ -297,37 +282,96 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic, } #endif -void BezierPatch::init(double res, const triple& Min, const triple& Max, - bool transparent, GLfloat *colors) +void BezierPatch::init(double res) { res2=res*res; Res2=BezierFactor*BezierFactor*res2; Epsilon=FillFactor*res; - this->Min=Min; - this->Max=Max; + MaterialIndex=transparent ? + (color ? -1-materialIndex : 1+materialIndex) : materialIndex; + + pvertex=transparent ? &vertexBuffer::tvertex : &vertexBuffer::vertex; +} + +void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) +{ + triple p0=p[0]; + epsilon=0; + for(unsigned i=1; i < 16; ++i) + epsilon=max(epsilon,abs2(p[i]-p0)); + epsilon *= Fuzz4; + + triple p3=p[3]; + triple p12=p[12]; + triple p15=p[15]; - if(transparent) { - tVertexbuffer.reserve(nbuffer); - tIndices.reserve(nbuffer); - pindices=&tIndices; - pvertex=&tvertex; - pVertex=&tVertex; + triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12); + if(n0 == 0.0) { + n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15); + if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12); + } + + triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15); + if(n1 == 0.0) { + n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3); + if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15); + } + + triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3); + if(n2 == 0.0) { + n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0); + if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3); + } + + triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0); + if(n3 == 0.0) { + n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12); + if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0); + } + + GLuint i0,i1,i2,i3; + if(color) { + GLfloat *c1=c0+4; + GLfloat *c2=c0+8; + GLfloat *c3=c0+12; + + i0=data.Vertex(p0,n0,c0); + i1=data.Vertex(p12,n1,c1); + i2=data.Vertex(p15,n2,c2); + i3=data.Vertex(p3,n3,c3); + + if(!straight) + render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false, + c0,c1,c2,c3); } else { - if(colors) { - Vertexbuffer.reserve(nbuffer); - Indices.reserve(nbuffer); - pindices=&Indices; - pVertex=&Vertex; - } else { - vertexbuffer.reserve(nbuffer); - indices.reserve(nbuffer); - pindices=&indices; - pvertex=&vertex; + i0=(data.*pvertex)(p0,n0); + i1=(data.*pvertex)(p12,n1); + i2=(data.*pvertex)(p15,n2); + i3=(data.*pvertex)(p3,n3); + + if(!straight) + render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false); + } + + if(straight) { + std::vector<GLuint> &q=data.indices; + triple Pa[]={p0,p12,p15}; + if(!offscreen(3,Pa)) { + q.push_back(i0); + q.push_back(i1); + q.push_back(i2); + } + triple Pb[]={p0,p15,p3}; + if(!offscreen(3,Pb)) { + q.push_back(i0); + q.push_back(i2); + q.push_back(i3); } } + append(); } - + // Use a uniform partition to draw a Bezier patch. // p is an array of 16 triples representing the control points. // Pi are the (possibly) adjusted vertices indexed by Ii. @@ -338,19 +382,22 @@ void BezierPatch::render(const triple *p, bool flat0, bool flat1, bool flat2, bool flat3, GLfloat *C0, GLfloat *C1, GLfloat *C2, GLfloat *C3) { - if(Distance(p) < res2) { // Patch is flat - triple P[]={P0,P1,P2,P3}; - if(!offscreen(4,P)) { - std::vector<GLuint> &p=*pindices; - p.push_back(I0); - p.push_back(I1); - p.push_back(I2); - p.push_back(I0); - p.push_back(I2); - p.push_back(I3); + if(Distance(p) < res2) { // Bezier patch is flat + triple Pa[]={P0,P1,P2}; + std::vector<GLuint> &q=data.indices; + if(!offscreen(3,Pa)) { + q.push_back(I0); + q.push_back(I1); + q.push_back(I2); + } + triple Pb[]={P0,P2,P3}; + if(!offscreen(3,Pb)) { + q.push_back(I0); + q.push_back(I2); + q.push_back(I3); } } else { // Patch is not flat - if(offscreen(16,p)) return; + if(offscreen(16,p)) return; /* Control points are indexed as follows: Coordinate @@ -484,7 +531,7 @@ void BezierPatch::render(const triple *p, else m3=s3[0]; } - if(C0) { + if(color) { GLfloat c0[4],c1[4],c2[4],c3[4],c4[4]; for(size_t i=0; i < 4; ++i) { c0[i]=0.5*(C0[i]+C1[i]); @@ -494,11 +541,12 @@ void BezierPatch::render(const triple *p, c4[i]=0.5*(c0[i]+c2[i]); } - GLuint i0=pVertex(m0,n0,c0); - GLuint i1=pVertex(m1,n1,c1); - GLuint i2=pVertex(m2,n2,c2); - GLuint i3=pVertex(m3,n3,c3); - GLuint i4=pVertex(m4,n4,c4); + GLuint i0=data.Vertex(m0,n0,c0); + GLuint i1=data.Vertex(m1,n1,c1); + GLuint i2=data.Vertex(m2,n2,c2); + GLuint i3=data.Vertex(m3,n3,c3); + GLuint i4=data.Vertex(m4,n4,c4); + render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3, C0,c0,c4,c3); render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false, @@ -508,11 +556,12 @@ void BezierPatch::render(const triple *p, render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3, c3,c4,c2,C3); } else { - GLuint i0=pvertex(m0,n0); - GLuint i1=pvertex(m1,n1); - GLuint i2=pvertex(m2,n2); - GLuint i3=pvertex(m3,n3); - GLuint i4=pvertex(m4,n4); + GLuint i0=(data.*pvertex)(m0,n0); + GLuint i1=(data.*pvertex)(m1,n1); + GLuint i2=(data.*pvertex)(m2,n2); + GLuint i3=(data.*pvertex)(m3,n3); + GLuint i4=(data.*pvertex)(m4,n4); + render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3); render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false); render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false); @@ -521,68 +570,52 @@ void BezierPatch::render(const triple *p, } } -void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) +void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0) { triple p0=p[0]; epsilon=0; - for(unsigned i=1; i < 16; ++i) + for(int i=1; i < 10; ++i) epsilon=max(epsilon,abs2(p[i]-p0)); epsilon *= Fuzz4; - triple p3=p[3]; - triple p12=p[12]; - triple p15=p[15]; - - triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12); - if(n0 == 0.0) n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15); - if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12); - - triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15); - if(n1 == 0.0) n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3); - if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15); - - triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3); - if(n2 == 0.0) n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0); - if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3); - - triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0); - if(n3 == 0.0) n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12); - if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0); + triple p6=p[6]; + triple p9=p[9]; - GLuint I0,I1,I2,I3; + triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6); + triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9); + triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0); - if(c0) { + GLuint i0,i1,i2; + if(color) { GLfloat *c1=c0+4; GLfloat *c2=c0+8; - GLfloat *c3=c0+12; - I0=pVertex(p0,n0,c0); - I1=pVertex(p12,n1,c1); - I2=pVertex(p15,n2,c2); - I3=pVertex(p3,n3,c3); - + i0=data.Vertex(p0,n0,c0); + i1=data.Vertex(p6,n1,c1); + i2=data.Vertex(p9,n2,c2); + if(!straight) - render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false, - c0,c1,c2,c3); + render(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2); } else { - I0=pvertex(p0,n0); - I1=pvertex(p12,n1); - I2=pvertex(p15,n2); - I3=pvertex(p3,n3); + i0=(data.*pvertex)(p0,n0); + i1=(data.*pvertex)(p6,n1); + i2=(data.*pvertex)(p9,n2); if(!straight) - render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false); + render(p,i0,i1,i2,p0,p6,p9,false,false,false); } if(straight) { - pindices->push_back(I0); - pindices->push_back(I1); - pindices->push_back(I2); - pindices->push_back(I0); - pindices->push_back(I2); - pindices->push_back(I3); + triple P[]={p0,p6,p9}; + if(!offscreen(3,P)) { + std::vector<GLuint> &q=data.indices; + q.push_back(i0); + q.push_back(i1); + q.push_back(i2); + } } + append(); } // Use a uniform partition to draw a Bezier triangle. @@ -595,13 +628,13 @@ void BezierTriangle::render(const triple *p, bool flat0, bool flat1, bool flat2, GLfloat *C0, GLfloat *C1, GLfloat *C2) { - if(Distance(p) < Res2) { // Triangle is flat + if(Distance(p) < Res2) { // Bezier triangle is flat triple P[]={P0,P1,P2}; if(!offscreen(3,P)) { - std::vector<GLuint> &p=*pindices; - p.push_back(I0); - p.push_back(I1); - p.push_back(I2); + std::vector<GLuint> &q=data.indices; + q.push_back(I0); + q.push_back(I1); + q.push_back(I2); } } else { // Triangle is not flat if(offscreen(10,p)) return; @@ -727,103 +760,59 @@ void BezierTriangle::render(const triple *p, // A kludge to remove subdivision cracks, only applied the first time // an edge is found to be flat before the rest of the subpatch is. - triple p0=0.5*(P1+P2); + triple m0=0.5*(P1+P2); if(!flat0) { if((flat0=Straightness(r300,p210,p120,u030) < res2)) - p0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+ + m0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+ derivative(c[0],c[1],c[3],c[6])); - else p0=r030; + else m0=r030; } - triple p1=0.5*(P2+P0); + triple m1=0.5*(P2+P0); if(!flat1) { if((flat1=Straightness(l003,p012,p021,u030) < res2)) - p1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+ + m1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+ derivative(c[6],c[7],c[8],c[9])); - else p1=l030; + else m1=l030; } - triple p2=0.5*(P0+P1); + triple m2=0.5*(P0+P1); if(!flat2) { if((flat2=Straightness(l003,p102,p201,r300) < res2)) - p2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+ + m2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+ derivative(c[9],c[5],c[2],c[0])); - else p2=l300; + else m2=l300; } - if(C0) { + if(color) { GLfloat c0[4],c1[4],c2[4]; for(int i=0; i < 4; ++i) { c0[i]=0.5*(C1[i]+C2[i]); - c1[i]=0.5*(C0[i]+C2[i]); + c1[i]=0.5*(C2[i]+C0[i]); c2[i]=0.5*(C0[i]+C1[i]); } - GLuint i0=pVertex(p0,n0,c0); - GLuint i1=pVertex(p1,n1,c1); - GLuint i2=pVertex(p2,n2,c2); + GLuint i0=data.Vertex(m0,n0,c0); + GLuint i1=data.Vertex(m1,n1,c1); + GLuint i2=data.Vertex(m2,n2,c2); - render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2,C0,c2,c1); - render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2,c2,C1,c0); - render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false,c1,c0,C2); - render(c,i0,i1,i2,p0,p1,p2,false,false,false,c0,c1,c2); + render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1); + render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0); + render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2); + render(c,i0,i1,i2,m0,m1,m2,false,false,false,c0,c1,c2); } else { - GLuint i0=pvertex(p0,n0); - GLuint i1=pvertex(p1,n1); - GLuint i2=pvertex(p2,n2); + GLuint i0=(data.*pvertex)(m0,n0); + GLuint i1=(data.*pvertex)(m1,n1); + GLuint i2=(data.*pvertex)(m2,n2); - render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2); - render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2); - render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false); - render(c,i0,i1,i2,p0,p1,p2,false,false,false); + render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2); + render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2); + render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false); + render(c,i0,i1,i2,m0,m1,m2,false,false,false); } } } -void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0) -{ - triple p0=p[0]; - epsilon=0; - for(int i=1; i < 10; ++i) - epsilon=max(epsilon,abs2(p[i]-p0)); - - epsilon *= Fuzz4; - - GLuint I0,I1,I2; - - triple p6=p[6]; - triple p9=p[9]; - - triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6); - triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9); - triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0); - - if(c0) { - GLfloat *c1=c0+4; - GLfloat *c2=c0+8; - - I0=pVertex(p0,n0,c0); - I1=pVertex(p6,n1,c1); - I2=pVertex(p9,n2,c2); - - if(!straight) - render(p,I0,I1,I2,p0,p6,p9,false,false,false,c0,c1,c2); - } else { - I0=pvertex(p0,n0); - I1=pvertex(p6,n1); - I2=pvertex(p9,n2); - - if(!straight) - render(p,I0,I1,I2,p0,p6,p9,false,false,false); - } - - if(straight) { - pindices->push_back(I0); - pindices->push_back(I1); - pindices->push_back(I2); - } -} - void transform(const std::vector<VertexData>& b) { unsigned n=b.size(); @@ -833,12 +822,11 @@ void transform(const std::vector<VertexData>& b) for(unsigned i=0; i < n; ++i) { const GLfloat *v=b[i].position; -// xbuffer[i]=Tx[0]*b[j]+Tx[1]*b[j+1]+Tx[2]*b[j+2]; -// ybuffer[i]=Ty[0]*b[j]+Ty[1]*b[j+1]+Ty[2]*b[j+2]; - zbuffer[i]=Tz[0]*v[0]+Tz[1]*v[1]+Tz[2]*v[2]; + zbuffer[i]=TransformZ(triple(v[0],v[1],v[2]),gl::dprojView); } } +#if 0 // precompute min and max bounds of each triangle void bounds(const std::vector<GLuint>& I) { @@ -886,222 +874,72 @@ void bounds(const std::vector<GLuint>& I) zmax[i]=max(za,zb,zc); } } +#endif -void BezierPatch::drawMaterials() +void sortTriangles() { - if(indices.size() == 0) - return; - - static const size_t size=sizeof(GLfloat); - static const size_t bytestride=sizeof(vertexData); - - GLuint vertsBufferIndex; - GLuint elemBufferIndex; - - GLuint vao; - - glGenVertexArrays(1,&vao); - glBindVertexArray(vao); - - glGenBuffers(1,&vertsBufferIndex); - glGenBuffers(1,&elemBufferIndex); - - registerBuffer(vertexbuffer,vertsBufferIndex); - registerBuffer(indices,elemBufferIndex); - - camp::setUniforms(materialShader); - - const GLint posAttrib=glGetAttribLocation(materialShader,"position"); - const GLint normalAttrib=glGetAttribLocation(materialShader,"normal"); - const GLint materialAttrib=glGetAttribLocation(materialShader,"material"); - - glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex); - - glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0); - glEnableVertexAttribArray(posAttrib); - - glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride, - (void *) (3*size)); - glEnableVertexAttribArray(normalAttrib); - - glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride, - (void *) (6*size)); - glEnableVertexAttribArray(materialAttrib); - - glFlush(); // Workaround broken MSWindows drivers for Intel GPU - glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,(void *) 0); - - glDisableVertexAttribArray(posAttrib); - glDisableVertexAttribArray(normalAttrib); - glDisableVertexAttribArray(materialAttrib); - - glBindBuffer(GL_ARRAY_BUFFER,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); - glUseProgram(0); - - glBindVertexArray(0); - glDeleteVertexArrays(1,&vao); - - glDeleteBuffers(1,&vertsBufferIndex); - glDeleteBuffers(1,&elemBufferIndex); + if(!transparentData.indices.empty()) { + transform(transparentData.Vertices); +// bounds(tIndices); + qsort(&transparentData.indices[0],transparentData.indices.size()/3, + 3*sizeof(GLuint),compare); + } } -void BezierPatch::drawColors(GLuint& Nvertices, - std::vector<VertexData>& Vertexbuffer, - std::vector<GLuint>& Indices) +void Triangles::queue(size_t nP, const triple* P, size_t nN, const triple* N, + size_t nC, const prc::RGBAColour* C, size_t nI, + const uint32_t (*PP)[3], const uint32_t (*NN)[3], + const uint32_t (*CC)[3], bool Transparent) { - if(Indices.size() == 0) - return; - - static const size_t size=sizeof(GLfloat); - static const size_t bytestride=sizeof(VertexData); - - GLuint vertsBufferIndex; - GLuint elemBufferIndex; - - GLuint vao; - - glGenVertexArrays(1,&vao); - glBindVertexArray(vao); - - glGenBuffers(1,&vertsBufferIndex); - glGenBuffers(1,&elemBufferIndex); - - registerBuffer(Vertexbuffer,vertsBufferIndex); - registerBuffer(Indices,elemBufferIndex); + if(!nN) return; - camp::setUniforms(colorShader); - - const GLint posAttrib=glGetAttribLocation(colorShader,"position"); - const GLint normalAttrib=glGetAttribLocation(colorShader,"normal"); - const GLint colorAttrib=glGetAttribLocation(colorShader,"color"); - const GLint materialAttrib=glGetAttribLocation(colorShader,"material"); + data.clear(); + Onscreen=true; + transparent=Transparent; - glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex); - - glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride, - (void *) 0); - glEnableVertexAttribArray(posAttrib); - - glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride, - (void *) (3*size)); - glEnableVertexAttribArray(normalAttrib); - - glVertexAttribIPointer(colorAttrib,1,GL_UNSIGNED_INT,bytestride, - (void *) (6*size)); - glEnableVertexAttribArray(colorAttrib); - - glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride, - (void *) (6*size+sizeof(GLuint))); - glEnableVertexAttribArray(materialAttrib); - - glFlush(); // Workaround broken MSWindows drivers for Intel GPU - glDrawElements(GL_TRIANGLES,Indices.size(),GL_UNSIGNED_INT,(void *) 0); - - glDisableVertexAttribArray(posAttrib); - glDisableVertexAttribArray(normalAttrib); - glDisableVertexAttribArray(colorAttrib); - glDisableVertexAttribArray(materialAttrib); - - glBindBuffer(GL_ARRAY_BUFFER,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); - glUseProgram(0); - - glBindVertexArray(0); - glDeleteVertexArrays(1,&vao); + data.Vertices.resize(nP); + data.indices.resize(3*nI); - glDeleteBuffers(1,&vertsBufferIndex); - glDeleteBuffers(1,&elemBufferIndex); -} - -void BezierPatch::sortTriangles() -{ - if(Ntvertices > 0) { - transform(tVertexbuffer); - bounds(tIndices); - qsort(&tIndices[0],tIndices.size()/3,3*sizeof(GLuint),compare); - } -} - -void Triangles::queue(size_t nP, triple* P, size_t nN, triple* N, - size_t nC, prc::RGBAColour* C, size_t nI, - uint32_t (*PI)[3], uint32_t (*NI)[3], uint32_t (*CI)[3], - bool transparent) -{ - if(!nN) return; - const size_t indexstride=3; - size_t nindices=indexstride*nI; - size_t index0; - - if(transparent) { - tVertexbuffer.reserve(nbuffer); - tVertexbuffer.resize(Ntvertices+nP); - tIndices.reserve(nbuffer); - index0=tIndices.size(); - tIndices.resize(index0+nindices); - } else { - if(nC) { - Vertexbuffer.reserve(nbuffer); - Vertexbuffer.resize(Nvertices+nP); - Indices.reserve(nbuffer); - index0=Indices.size(); - Indices.resize(index0+nindices); - } else { - vertexbuffer.reserve(nbuffer); - vertexbuffer.resize(nvertices+nP); - indices.reserve(nbuffer); - index0=indices.size(); - indices.resize(index0+nindices); - } - } - - uint32_t *P0=(uint32_t *) PI; - uint32_t *N0=(uint32_t *) NI; - uint32_t *C0=(uint32_t *) CI; - - if(transparent) { - if(nC) { - for(size_t i=0; i < nindices; ++i) { - uint32_t i0=P0[i]; - prc::RGBAColour c=C[C0[i]]; - GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B,(GLfloat) c.A}; - GLuint index=Ntvertices+i0; - tVertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0); - tIndices[index0+i]=index; - } - } else { - for(size_t i=0; i < nindices; ++i) { - uint32_t i0=P0[i]; - GLuint index=Ntvertices+i0; - tVertexbuffer[index]=VertexData(P[i0],N[N0[i]]); - tIndices[index0+i]=index; - } - } - Ntvertices += nP; - } else { - if(nC) { - for(size_t i=0; i < nindices; ++i) { - uint32_t i0=P0[i]; - prc::RGBAColour c=C[C0[i]]; - GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B, - (GLfloat) c.A}; - GLuint index=Nvertices+i0; - Vertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0); - Indices[index0+i]=index; - } - Nvertices += nP; - } else { - for(size_t i=0; i < nindices; ++i) { - uint32_t i0=P0[i]; - GLuint index=nvertices+i0; - vertexbuffer[index]=vertexData(P[i0],N[N0[i]]); - indices[index0+i]=index; + MaterialIndex=nC ? -1-materialIndex : 1+materialIndex; + + for(size_t i=0; i < nI; ++i) { + const uint32_t *PI=PP[i]; + uint32_t PI0=PI[0]; + uint32_t PI1=PI[1]; + uint32_t PI2=PI[2]; + triple P0=P[PI0]; + triple P1=P[PI1]; + triple P2=P[PI2]; + triple Q[]={P0,P1,P2}; + if(!offscreen(3,Q)) { + const uint32_t *NI=NN[i]; + if(nC) { + const uint32_t *CI=CC[i]; + prc::RGBAColour C0=C[CI[0]]; + prc::RGBAColour C1=C[CI[1]]; + prc::RGBAColour C2=C[CI[2]]; + GLfloat c0[]={(GLfloat) C0.R,(GLfloat) C0.G,(GLfloat) C0.B, + (GLfloat) C0.A}; + GLfloat c1[]={(GLfloat) C1.R,(GLfloat) C1.G,(GLfloat) C1.B, + (GLfloat) C1.A}; + GLfloat c2[]={(GLfloat) C2.R,(GLfloat) C2.G,(GLfloat) C2.B, + (GLfloat) C2.A}; + transparent |= c0[3]+c1[3]+c2[3] < 765; + data.Vertices[PI0]=VertexData(P0,N[NI[0]],c0); + data.Vertices[PI1]=VertexData(P1,N[NI[1]],c1); + data.Vertices[PI2]=VertexData(P2,N[NI[2]],c2); + } else { + data.Vertices[PI0]=VertexData(P0,N[NI[0]]); + data.Vertices[PI1]=VertexData(P1,N[NI[1]]); + data.Vertices[PI2]=VertexData(P2,N[NI[2]]); } - nvertices += nP; + size_t i3=3*i; + data.indices[i3]=PI0; + data.indices[i3+1]=PI1; + data.indices[i3+2]=PI2; } } + append(); } #endif |