diff options
Diffstat (limited to 'Build/source/utils/asymptote/bezierpatch.cc')
-rw-r--r-- | Build/source/utils/asymptote/bezierpatch.cc | 348 |
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 |