summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/bezierpatch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/bezierpatch.cc')
-rw-r--r--Build/source/utils/asymptote/bezierpatch.cc620
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