← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2643: -Fix sphere rendering for closing/opening qtview (closing was deleting existing display lists, ne...

 

------------------------------------------------------------
revno: 2643
committer: Bruno Chareyre <bruno.chareyre@xxxxxxxxxxx>
branch nick: yade
timestamp: Tue 2011-01-11 15:47:55 +0100
message:
  -Fix sphere rendering for closing/opening qtview (closing was deleting existing display lists, new view was empty)
  -Make quality apply for striped spheres as well
  -Make it possible to turn duplicated spheres on/off in periodic BC
  -Separate GLUT and striped spheres functions for clarity
  -Optimize stripes rendering with GL_TRIANGLE_STRIP 
modified:
  pkg/common/Gl1_Sphere.cpp
  pkg/common/Gl1_Sphere.hpp
  pkg/common/OpenGLRenderer.cpp
  pkg/common/OpenGLRenderer.hpp
  pkg/dem/TriaxialTest.cpp


--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'pkg/common/Gl1_Sphere.cpp'
--- pkg/common/Gl1_Sphere.cpp	2010-12-28 16:01:44 +0000
+++ pkg/common/Gl1_Sphere.cpp	2011-01-11 14:47:55 +0000
@@ -20,7 +20,7 @@
 Real  Gl1_Sphere::quality;
 bool  Gl1_Sphere::localSpecView;
 vector<Vector3r> Gl1_Sphere::vertices, Gl1_Sphere::faces;
-int Gl1_Sphere::glSphereList=-1;
+int Gl1_Sphere::glStripedSphereList=-1;
 int Gl1_Sphere::glGlutSphereList=-1;
 Real  Gl1_Sphere::prevQuality=0;
 
@@ -28,19 +28,16 @@
 {
 	glClearDepth(1.0f);
 	glEnable(GL_NORMALIZE);
-	GLfloat glutMatSpecular[4]={0.5,0.5,0.5,1.0};
-	GLfloat glutMatEmit[4]={0.2,0.2,0.2,1.0};
-	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glutMatSpecular);
-	glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,glutMatEmit);
-	glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 80);
+
 	Real r=(static_cast<Sphere*>(cm.get()))->radius;
-
 	glColor3v(cm->color);
-	if (wire || wire2) glutWireSphere(r,glutSlices,glutStacks);
+	if (wire || wire2) glutWireSphere(r,quality*glutSlices,quality*glutStacks);
 	else {
-		initGlLists();
+		//Check if quality has been modified or if previous lists are invalidated (e.g. by creating a new qt view), then regenerate lists
+		bool somethingChanged = (abs(quality-prevQuality)>0.001 || glIsList(glStripedSphereList)!=GL_TRUE);
+		if (somethingChanged) {initStripedGlList(); initGlutGlList(); prevQuality=quality;}
 		glScalef(r,r,r);
-		if(stripes) glCallList(glSphereList);
+		if(stripes) glCallList(glStripedSphereList);
 		else glCallList(glGlutSphereList);
 	}
 	return;
@@ -48,26 +45,44 @@
 YADE_PLUGIN((Gl1_Sphere));
 
 void Gl1_Sphere::subdivideTriangle(Vector3r& v1,Vector3r& v2,Vector3r& v3, int depth){
-	if (depth==0){
-		Vector3r v = (v1+v2+v3)/3.0;
-		Real angle = atan(v[2]/v[0])/v.norm();
+	Vector3r v;
+	//Change color only at the appropriate level, i.e. 8 times in total, since we draw 8 mono-color sectors one after another
+	if (depth==int(quality) || quality<=0){
+		v = (v1+v2+v3)/3.0;
 		GLfloat matEmit[4];
-		if (angle>-Mathr::PI/6.0 && angle<=Mathr::PI/6.0){
-			matEmit[0] = 0.4;
-			matEmit[1] = 0.4;
-			matEmit[2] = 0.4;
+		if (v[1]*v[0]*v[2]>0){
+			matEmit[0] = 0.3;
+			matEmit[1] = 0.3;
+			matEmit[2] = 0.3;
 			matEmit[3] = 1.f;
 		}else{
-			matEmit[0] = 0.2;
-			matEmit[1] = 0.2;
-			matEmit[2] = 0.2;
-			matEmit[3] = 1.f;
+			matEmit[0] = 0.15;
+			matEmit[1] = 0.15;
+			matEmit[2] = 0.15;
+			matEmit[3] = 0.2;
 		}
- 		glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matEmit);
+ 		glMaterialfv(GL_FRONT, GL_EMISSION, matEmit);
+	}
+	if (depth==1){//Then display 4 triangles
+		Vector3r v12 = v1+v2;
+		Vector3r v23 = v2+v3;
+		Vector3r v31 = v3+v1;
+		v12.normalize();
+		v23.normalize();
+		v31.normalize();
+		//Use TRIANGLE_STRIP for faster display of adjacent facets
+		glBegin(GL_TRIANGLE_STRIP);
+			glNormal3v(v1); glVertex3v(v1);
+			glNormal3v(v31); glVertex3v(v31);
+			glNormal3v(v12); glVertex3v(v12);
+			glNormal3v(v23); glVertex3v(v23);
+			glNormal3v(v2); glVertex3v(v2);
+		glEnd();
+		//terminate with this triangle left behind
 		glBegin(GL_TRIANGLES);
 			glNormal3v(v3); glVertex3v(v3);
-			glNormal3v(v2); glVertex3v(v2);
-			glNormal3v(v1); glVertex3v(v1);
+			glNormal3v(v23); glVertex3v(v23);
+			glNormal3v(v31); glVertex3v(v31);
 		glEnd();
 		return;
 	}
@@ -83,64 +98,85 @@
 	subdivideTriangle(v12,v23,v31,depth-1);
 }
 
-void Gl1_Sphere::initGlLists(){
-	//Generate the "stripes" dislpay list, only once
-	if (glSphereList<0) {
-		Real X = 0.525731112119133606;
-		Real Z = 0.850650808352039932;
-		vertices.push_back(Vector3r(-X,0,Z));
-		vertices.push_back(Vector3r(X,0,Z));
-		vertices.push_back(Vector3r(-X,0,-Z));
-		vertices.push_back(Vector3r(X,0,-Z));
-		vertices.push_back(Vector3r(0,Z,X));
-		vertices.push_back(Vector3r(0,Z,-X));
-		vertices.push_back(Vector3r(0,-Z,X));
-		vertices.push_back(Vector3r(0,-Z,-X));
-		vertices.push_back(Vector3r(Z,X,0));
-		vertices.push_back(Vector3r(-Z,X,0));
-		vertices.push_back(Vector3r(Z,-X,0));
-		vertices.push_back(Vector3r(-Z,-X,0));
-
-		faces.push_back(Vector3r(0,4,1));
-		faces.push_back(Vector3r(0,9,4));
-		faces.push_back(Vector3r(9,5,4));
-		faces.push_back(Vector3r(4,5,8));
-		faces.push_back(Vector3r(4,8,1));
-		faces.push_back(Vector3r(8,10,1));
-		faces.push_back(Vector3r(8,3,10));
-		faces.push_back(Vector3r(5,3,8));
-		faces.push_back(Vector3r(5,2,3));
-		faces.push_back(Vector3r(2,7,3));
-		faces.push_back(Vector3r(7,10,3));
-		faces.push_back(Vector3r(7,6,10));
-		faces.push_back(Vector3r(7,11,6));
-		faces.push_back(Vector3r(11,0,6));
-		faces.push_back(Vector3r(0,1,6));
-		faces.push_back(Vector3r(6,1,10));
-		faces.push_back(Vector3r(9,0,11));
-		faces.push_back(Vector3r(9,11,2));
-		faces.push_back(Vector3r(9,2,5));
-		faces.push_back(Vector3r(7,2,11));
-
-		glSphereList = glGenLists(1);
-		glNewList(glSphereList,GL_COMPILE);
-			glEnable(GL_LIGHTING);
-			glShadeModel(GL_SMOOTH);
-			// render the sphere now
-			for(int i=0;i<20;i++)
-				subdivideTriangle(vertices[(unsigned int)faces[i][0]],vertices[(unsigned int)faces[i][1]],vertices[(unsigned int)faces[i][2]],1);
-		glEndList();
+void Gl1_Sphere::initStripedGlList() {
+	if (!vertices.size()){//Fill vectors with vertices and facets
+		//Define 6 points for +/- coordinates
+		vertices.push_back(Vector3r(-1,0,0));//0
+		vertices.push_back(Vector3r(1,0,0));//1
+		vertices.push_back(Vector3r(0,-1,0));//2
+		vertices.push_back(Vector3r(0,1,0));//3
+		vertices.push_back(Vector3r(0,0,-1));//4
+		vertices.push_back(Vector3r(0,0,1));//5
+		//Define 8 sectors of the sphere
+		faces.push_back(Vector3r(3,4,1));
+		faces.push_back(Vector3r(3,0,4));
+		faces.push_back(Vector3r(3,5,0));
+		faces.push_back(Vector3r(3,1,5));
+		faces.push_back(Vector3r(2,1,4));
+		faces.push_back(Vector3r(2,4,0));
+		faces.push_back(Vector3r(2,0,5));
+		faces.push_back(Vector3r(2,5,1));
 	}
+	//Generate the list. Only once for each qtView, or more if quality is modified.
+	glDeleteLists(glStripedSphereList,1);
+	glStripedSphereList = glGenLists(1);
+	glNewList(glStripedSphereList,GL_COMPILE);
+	glEnable(GL_LIGHTING);
+	glShadeModel(GL_SMOOTH);
+	// render the sphere now
+	for (int i=0;i<8;i++)
+		subdivideTriangle(vertices[(unsigned int)faces[i][0]],vertices[(unsigned int)faces[i][1]],vertices[(unsigned int)faces[i][2]],1+ (int) quality);
+	glEndList();
+
+}
+
+void Gl1_Sphere::initGlutGlList(){
 	//Generate the "no-stripes" display list, each time quality is modified
-	if (glGlutSphereList<0 || abs(quality-prevQuality)>0.001 /*detect any meaningfull change in quality to regenerate GL primitives*/) {
-		glGlutSphereList = glGenLists(1);
-		glNewList(glGlutSphereList,GL_COMPILE);
-			glEnable(GL_LIGHTING);
-			glShadeModel(GL_SMOOTH);
-			glutSolidSphere(1.0,quality*glutSlices,quality*glutStacks);
-		glEndList();
-		prevQuality=quality;
-	}
+	glDeleteLists(glGlutSphereList,1);
+	glGlutSphereList = glGenLists(1);
+	glNewList(glGlutSphereList,GL_COMPILE);
+		glEnable(GL_LIGHTING);
+		glShadeModel(GL_SMOOTH);
+		glutSolidSphere(1.0,max(quality*glutSlices,2.),max(quality*glutStacks,3.));
+	glEndList();
 }
 
 #endif /* YADE_OPENGL */
+
+//      ///The old Galizzi's lists
+// 	if (!vertices.size()) {
+// 		Real X = 0.525731112119133606;
+// 		Real Z = 0.850650808352039932;
+// 		vertices.push_back(Vector3r(-X,0,Z));//0
+// 		vertices.push_back(Vector3r(X,0,Z));//1
+// 		vertices.push_back(Vector3r(-X,0,-Z));//2
+// 		vertices.push_back(Vector3r(X,0,-Z));//3
+// 		vertices.push_back(Vector3r(0,Z,X));//4
+// 		vertices.push_back(Vector3r(0,Z,-X));//5
+// 		vertices.push_back(Vector3r(0,-Z,X));//6
+// 		vertices.push_back(Vector3r(0,-Z,-X));//7
+// 		vertices.push_back(Vector3r(Z,X,0));//8
+// 		vertices.push_back(Vector3r(-Z,X,0));//9
+// 		vertices.push_back(Vector3r(Z,-X,0));//10
+// 		vertices.push_back(Vector3r(-Z,-X,0));//11
+// 		faces.push_back(Vector3r(0,4,1));
+// 		faces.push_back(Vector3r(0,9,4));
+// 		faces.push_back(Vector3r(9,5,4));
+// 		faces.push_back(Vector3r(4,5,8));
+// 		faces.push_back(Vector3r(4,8,1));
+// 		faces.push_back(Vector3r(8,10,1));
+// 		faces.push_back(Vector3r(8,3,10));
+// 		faces.push_back(Vector3r(5,3,8));
+// 		faces.push_back(Vector3r(5,2,3));
+// 		faces.push_back(Vector3r(2,7,3));
+// 		faces.push_back(Vector3r(7,10,3));
+// 		faces.push_back(Vector3r(7,6,10));
+// 		faces.push_back(Vector3r(7,11,6));
+// 		faces.push_back(Vector3r(11,0,6));
+// 		faces.push_back(Vector3r(0,1,6));
+// 		faces.push_back(Vector3r(6,1,10));
+// 		faces.push_back(Vector3r(9,0,11));
+// 		faces.push_back(Vector3r(9,11,2));
+// 		faces.push_back(Vector3r(9,2,5));
+// 		faces.push_back(Vector3r(7,2,11));}
+

=== modified file 'pkg/common/Gl1_Sphere.hpp'
--- pkg/common/Gl1_Sphere.hpp	2011-01-09 16:34:50 +0000
+++ pkg/common/Gl1_Sphere.hpp	2011-01-11 14:47:55 +0000
@@ -17,17 +17,20 @@
 	private:
 		// for stripes
 		static vector<Vector3r> vertices, faces;
-		static int glSphereList;
+		static int glStripedSphereList;
 		static int glGlutSphereList;
 		void subdivideTriangle(Vector3r& v1,Vector3r& v2,Vector3r& v3, int depth);
 // 		void drawSphere(const Vector3r& color);
-		void initGlLists();
+		//Generate GlList for GLUT sphere
+		void initGlutGlList();
+		//Generate GlList for sliced spheres
+		void initStripedGlList();
 		//for regenerating glutSphere list if needed
 		static Real prevQuality;
 	public:
 		virtual void go(const shared_ptr<Shape>&, const shared_ptr<State>&,bool,const GLViewInfo&);
 	YADE_CLASS_BASE_DOC_STATICATTRS(Gl1_Sphere,GlShapeFunctor,"Renders :yref:`Sphere` object",
-		((Real,quality,1.0,,"Change discretization level of spheres. quality>1  for better image quality, at the price of more cpu/gpu usage, 0<quality<1 for faster rendering. This unique factor mutiplies :yref:`Gl1_Sphere::glutSlices` and :yref:`Gl1_Sphere::glutStacks`"))
+		((Real,quality,1.0,,"Change discretization level of spheres. quality>1  for better image quality, at the price of more cpu/gpu usage, 0<quality<1 for faster rendering. If mono-color sphres are displayed (:yref:`Gl1_Sphere::stripes=False), quality mutiplies :yref:`Gl1_Sphere::glutSlices` and :yref:`Gl1_Sphere::glutStacks`. If striped spheres are displayed (:yref:`Gl1_Sphere::stripes=True), only integer increments are meaningfull : quality=1 and quality=1.9 will give the same result, quality=2 will give finer result."))
 		((bool,wire,false,,"Only show wireframe (controlled by ``glutSlices`` and ``glutStacks``."))
 		((bool,stripes,false,,"In non-wire rendering, show stripes clearly showing particle rotation."))
 		((bool,localSpecView,true,,"Compute specular light in local eye coordinate system."))

=== modified file 'pkg/common/OpenGLRenderer.cpp'
--- pkg/common/OpenGLRenderer.cpp	2010-12-28 16:01:44 +0000
+++ pkg/common/OpenGLRenderer.cpp	2011-01-11 14:47:55 +0000
@@ -29,6 +29,7 @@
 const int OpenGLRenderer::numClipPlanes;
 OpenGLRenderer::~OpenGLRenderer(){}
 
+
 void OpenGLRenderer::init(){
 	typedef std::pair<string,DynlibDescriptor> strDldPair; // necessary as FOREACH, being macro, cannot have the "," inside the argument (preprocessor does not parse templates)
 	FOREACH(const strDldPair& item, Omega::instance().getDynlibsDescriptor()){
@@ -130,11 +131,11 @@
 }
 
 void OpenGLRenderer::resetSpecularEmission(){
-	const GLfloat specular[4]={.3,.03,.03,0.1};
-	const GLfloat emission[4]={0,0,0,0};
-	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);
-	glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,emission);
-	glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+	glMateriali(GL_FRONT, GL_SHININESS, 80);
+	const GLfloat glutMatSpecular[4]={0.3,0.3,0.3,0.5};
+	const GLfloat glutMatEmit[4]={0.2,0.2,0.2,1.0};
+	glMaterialfv(GL_FRONT,GL_SPECULAR,glutMatSpecular);
+	glMaterialfv(GL_FRONT,GL_EMISSION,glutMatEmit);
 }
 
 void OpenGLRenderer::render(const shared_ptr<Scene>& _scene,Body::id_t selection){
@@ -203,17 +204,16 @@
 
 	glEnable(GL_CULL_FACE);
 	// http://www.sjbaker.org/steve/omniv/opengl_lighting.html
-	glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
+	glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
 	glEnable(GL_COLOR_MATERIAL);
 	//Shared material settings
-	glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40);
-
 	resetSpecularEmission();
 
 	drawPeriodicCell();
 
 	if (dof || id) renderDOF_ID();
 	if (bound) renderBound();
+
 	if (shape) renderShape();
 	if (intrAllWire) renderAllInteractionsWire();
 	if (intrGeom) renderIGeom();
@@ -379,7 +379,7 @@
 		}
 		// if the body goes over the cell margin, draw it in positions where the bbox overlaps with the cell in wire
 		// precondition: pos is inside the cell.
-		if(b->bound && scene->isPeriodic){
+		if(b->bound && scene->isPeriodic && displayGhosts){
 			const Vector3r& cellSize(scene->cell->getSize());
 			pos=scene->cell->unshearPt(pos); // remove the shear component
 			// traverse all periodic cells around the body, to see if any of them touches

=== modified file 'pkg/common/OpenGLRenderer.hpp'
--- pkg/common/OpenGLRenderer.hpp	2010-12-28 16:01:44 +0000
+++ pkg/common/OpenGLRenderer.hpp	2011-01-11 14:47:55 +0000
@@ -91,7 +91,7 @@
 		((Real,rotScale,((void)"disable scaling",1.),,"Artificially enlarge (scale) rotations of bodies relative to their :yref:`reference orientation<State.refOri>`, so the they are better visible."))
 		((Vector3r,lightPos,Vector3r(75,130,0),,"Position of OpenGL light source in the scene."))
 		((Vector3r,light2Pos,Vector3r(-130,75,30),,"Position of secondary OpenGL light source in the scene."))
-		((Vector3r,lightColor,Vector3r(0.8,0.8,0.8),,"Per-color intensity of primary light (RGB)."))
+		((Vector3r,lightColor,Vector3r(0.6,0.6,0.6),,"Per-color intensity of primary light (RGB)."))
 		((Vector3r,light2Color,Vector3r(0.5,0.5,0.1),,"Per-color intensity of secondary light (RGB)."))
 		((Vector3r,bgColor,Vector3r(.2,.2,.2),,"Color of the backgroud canvas (RGB)"))
 		((bool,wire,false,,"Render all bodies with wire only (faster)"))
@@ -104,6 +104,7 @@
 		((bool,intrWire,false,,"If rendering interactions, use only wires to represent them."))
 		((bool,intrGeom,false,,"Render :yref:`Interaction::geom` objects."))
 		((bool,intrPhys,false,,"Render :yref:`Interaction::phys` objects"))
+		((bool,displayGhosts,true,,"Render objects crossing periodic cell edges by cloning them in multiple places (periodic simulations only)."))
 		#ifdef YADE_SUBDOMAINS
 			((int,subDomMask,0,,"If non-zero, render shape only of particles that are inside respective domains - -they are counted from the left, i.e. 5 (binary 101) will show subdomains 1 and 3. If zero, render everything."))
 		#endif

=== modified file 'pkg/dem/TriaxialTest.cpp'
--- pkg/dem/TriaxialTest.cpp	2011-01-09 16:34:50 +0000
+++ pkg/dem/TriaxialTest.cpp	2011-01-11 14:47:55 +0000
@@ -211,6 +211,7 @@
 	iSphere->radius		= radius;
 	//iSphere->color	= Vector3r(0.4,0.1,0.1);
 	iSphere->color           = Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
+	iSphere->color.normalize();
 	body->shape	= iSphere;
 	body->bound	= aabb;
 	body->material	= mat;