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.cc348
1 files changed, 257 insertions, 91 deletions
diff --git a/Build/source/utils/asymptote/bezierpatch.cc b/Build/source/utils/asymptote/bezierpatch.cc
index 34b80f05b6d..6e457643daf 100644
--- a/Build/source/utils/asymptote/bezierpatch.cc
+++ b/Build/source/utils/asymptote/bezierpatch.cc
@@ -13,23 +13,31 @@ namespace camp {
using ::orient2d;
using ::orient3d;
-size_t tstride;
+#ifdef HAVE_GL
-double viewpoint[3];
-#ifdef HAVE_GL
+//FIXME: Find a nicer way to pass the shader program number,
+// preferably without global variables...
+
+extern GLint noColorShader;
+extern GLint colorShader;
+extern void setUniforms(GLint shader);
-std::vector<GLfloat> BezierPatch::buffer;
-std::vector<GLfloat> BezierPatch::Buffer;
+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<GLfloat> BezierPatch::tbuffer;
-std::vector<GLuint> BezierPatch::tindices;
-std::vector<GLfloat> BezierPatch::tBuffer;
std::vector<GLuint> BezierPatch::tIndices;
-std::vector<GLuint>& I=BezierPatch::tIndices;
-std::vector<GLfloat>& V=BezierPatch::tBuffer;
+GLuint BezierPatch::nvertices=0;
+GLuint BezierPatch::Nvertices=0;
+GLuint BezierPatch::Ntvertices=0;
+
+//std::vector<GLuint>& I=BezierPatch::tIndices;
+//std::vector<VertexData>& V=BezierPatch::tVertexbuffer;
bool colors;
std::vector<GLfloat> zbuffer;
@@ -63,11 +71,6 @@ struct iz {
std::vector<iz> IZ;
-GLuint BezierPatch::nvertices=0;
-GLuint BezierPatch::ntvertices=0;
-GLuint BezierPatch::Nvertices=0;
-GLuint BezierPatch::Ntvertices=0;
-
extern const double Fuzz2;
const double FillFactor=0.1;
@@ -196,7 +199,6 @@ inline void cross(double *dest, const double *u, const double *v,
unsigned n;
unsigned int count;
-const size_t nbuffer=10000;
// Sort nonintersecting triangles by depth.
int compare(const void *p, const void *P)
@@ -249,6 +251,7 @@ int compare(const void *p, const void *P)
*/
}
+#if 0
void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
double *a, double *b, double *c, double *N, double *A) {
double td=intersect(a,b,N,A);
@@ -282,8 +285,8 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
id=BezierPatch::tVertex(d,nd,cd);
ie=BezierPatch::tVertex(e,ne,ce);
} else {
- id=BezierPatch::tvertex(d,nd);
- ie=BezierPatch::tvertex(e,ne);
+ id=BezierPatch::tVertex(d,nd);
+ ie=BezierPatch::tVertex(e,ne);
}
I[i3]=ia;
@@ -298,6 +301,7 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
I.push_back(ib);
I.push_back(ic);
}
+#endif
void BezierPatch::init(double res, const triple& Min, const triple& Max,
bool transparent, GLfloat *colors)
@@ -305,31 +309,27 @@ void BezierPatch::init(double res, const triple& Min, const triple& Max,
res2=res*res;
Res2=BezierFactor*BezierFactor*res2;
Epsilon=FillFactor*res;
+
this->Min=Min;
this->Max=Max;
-
- const size_t nbuffer=10000;
- indices.reserve(nbuffer);
+
if(transparent) {
- tbuffer.reserve(nbuffer);
- tindices.reserve(nbuffer);
- pindices=&tindices;
+ tVertexbuffer.reserve(nbuffer);
+ tIndices.reserve(nbuffer);
+ pindices=&tIndices;
pvertex=&tvertex;
- if(colors) {
- tBuffer.reserve(nbuffer);
- tIndices.reserve(nbuffer);
- pindices=&tIndices;
- pVertex=&tVertex;
- }
+ pVertex=&tVertex;
} else {
- buffer.reserve(nbuffer);
- pindices=&indices;
- pvertex=&vertex;
if(colors) {
- Buffer.reserve(nbuffer);
+ Vertexbuffer.reserve(nbuffer);
Indices.reserve(nbuffer);
pindices=&Indices;
pVertex=&Vertex;
+ } else {
+ vertexbuffer.reserve(nbuffer);
+ indices.reserve(nbuffer);
+ pindices=&indices;
+ pvertex=&vertex;
}
}
}
@@ -830,30 +830,32 @@ void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0)
}
}
-void transform(const std::vector<GLfloat>& b)
+void transform(const std::vector<VertexData>& b)
{
- unsigned n=b.size()/tstride;
+ unsigned n=b.size();
// xbuffer.resize(n);
// ybuffer.resize(n);
zbuffer.resize(n);
for(unsigned i=0; i < n; ++i) {
- unsigned j=tstride*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]*b[j]+Tz[1]*b[j+1]+Tz[2]*b[j+2];
+ zbuffer[i]=Tz[0]*v[0]+Tz[1]*v[1]+Tz[2]*v[2];
}
-
}
// precompute min and max bounds of each triangle
void bounds(const std::vector<GLuint>& I)
{
unsigned n=I.size()/3;
+/*
xmin.resize(n);
xmax.resize(n);
ymin.resize(n);
ymax.resize(n);
+*/
+
zmin.resize(n);
zmax.resize(n);
@@ -863,6 +865,8 @@ void bounds(const std::vector<GLuint>& I)
unsigned Ib=I[i3+1];
unsigned Ic=I[i3+2];
+
+ /*
double xa=xbuffer[Ia];
double xb=xbuffer[Ib];
double xc=xbuffer[Ic];
@@ -870,88 +874,250 @@ void bounds(const std::vector<GLuint>& I)
double ya=ybuffer[Ia];
double yb=ybuffer[Ib];
double yc=ybuffer[Ic];
+ */
double za=zbuffer[Ia];
double zb=zbuffer[Ib];
double zc=zbuffer[Ic];
+ /*
xmin[i]=min(xa,xb,xc);
xmax[i]=max(xa,xb,xc);
ymin[i]=min(ya,yb,yc);
ymax[i]=max(ya,yb,yc);
+ */
zmin[i]=min(za,zb,zc);
zmax[i]=max(za,zb,zc);
}
}
-void BezierPatch::draw()
+void BezierPatch::drawMaterials()
{
- if(nvertices == 0 && ntvertices == 0 && Nvertices == 0 && Ntvertices == 0)
+ if(nvertices == 0)
return;
- const size_t stride=6;
- const size_t Stride=10;
- const size_t size=sizeof(GLfloat);
- const size_t bytestride=stride*size;
- const size_t Bytestride=Stride*size;
+ 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(noColorShader);
+
+ const GLint posAttrib=glGetAttribLocation(noColorShader,"position");
+ const GLint normalAttrib=glGetAttribLocation(noColorShader,"normal");
+ const GLint materialAttrib=glGetAttribLocation(noColorShader,"material");
+
+ glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
+ glEnableVertexAttribArray(posAttrib);
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
+ 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);
- if(nvertices > 0) {
- glVertexPointer(3,GL_FLOAT,bytestride,&buffer[0]);
- glNormalPointer(GL_FLOAT,bytestride,&buffer[3]);
- glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,&indices[0]);
- }
+ nvertices=0;
+ vertexbuffer.clear();
+ indices.clear();
- if(Nvertices > 0) {
- glEnableClientState(GL_COLOR_ARRAY);
- glEnable(GL_COLOR_MATERIAL);
- glVertexPointer(3,GL_FLOAT,Bytestride,&Buffer[0]);
- glNormalPointer(GL_FLOAT,Bytestride,&Buffer[3]);
- glColorPointer(4,GL_FLOAT,Bytestride,&Buffer[6]);
- glDrawElements(GL_TRIANGLES,Indices.size(),GL_UNSIGNED_INT,&Indices[0]);
- glDisable(GL_COLOR_MATERIAL);
- glDisableClientState(GL_COLOR_ARRAY);
- }
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
+}
+
+void BezierPatch::drawColors(GLuint& Nvertices,
+ std::vector<VertexData>& Vertexbuffer,
+ std::vector<GLuint>& Indices)
+{
+ if(Nvertices == 0)
+ return;
+
+ static const size_t size=sizeof(GLfloat);
+ static const size_t bytestride=sizeof(VertexData);
+
+ GLuint vertsBufferIndex;
+ GLuint elemBufferIndex;
- if(ntvertices > 0) {
- tstride=stride;
- transform(tbuffer);
-// bounds(tindices);
+ GLuint vao;
+
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+
+ glGenBuffers(1,&vertsBufferIndex);
+ glGenBuffers(1,&elemBufferIndex);
+
+ registerBuffer(Vertexbuffer,vertsBufferIndex);
+ registerBuffer(Indices,elemBufferIndex);
+
+ 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");
+
+ 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);
- qsort(&tindices[0],tindices.size()/3,3*sizeof(GLuint),compare);
-
- glVertexPointer(3,GL_FLOAT,bytestride,&tbuffer[0]);
- glNormalPointer(GL_FLOAT,bytestride,&tbuffer[3]);
- glDrawElements(GL_TRIANGLES,tindices.size(),GL_UNSIGNED_INT,&tindices[0]);
- }
+ 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);
+ Nvertices=0;
+ Vertexbuffer.clear();
+ Indices.clear();
+
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
+}
+
+void BezierPatch::sortTriangles()
+{
if(Ntvertices > 0) {
- tstride=Stride;
- transform(tBuffer);
-// bounds(tIndices);
-
+ transform(tVertexbuffer);
+ bounds(tIndices);
qsort(&tIndices[0],tIndices.size()/3,3*sizeof(GLuint),compare);
-
- glEnableClientState(GL_COLOR_ARRAY);
- glEnable(GL_COLOR_MATERIAL);
- glVertexPointer(3,GL_FLOAT,Bytestride,&tBuffer[0]);
- glNormalPointer(GL_FLOAT,Bytestride,&tBuffer[3]);
- glColorPointer(4,GL_FLOAT,Bytestride,&tBuffer[6]);
- glDrawElements(GL_TRIANGLES,tIndices.size(),GL_UNSIGNED_INT,&tIndices[0]);
- glDisable(GL_COLOR_MATERIAL);
- glDisableClientState(GL_COLOR_ARRAY);
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
-
- clear();
}
+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;
+ }
+ nvertices += nP;
+ }
+ }
+}
+
#endif
} //namespace camp