// subdivide the triangle up to a certain depth void Plot3DWidget::subdivideTriangle(float* vertices, int& index, float *v1, float *v2, float *v3, int depth) { float v12[3]; float v13[3]; float v23[3]; if( depth == 0 ) { vertices[index++] = v1[0]; vertices[index++] = v1[1]; vertices[index++] = v1[2]; vertices[index++] = v2[0]; vertices[index++] = v2[1]; vertices[index++] = v2[2]; vertices[index++] = v3[0]; vertices[index++] = v3[1]; vertices[index++] = v3[2]; return; } for( int i = 0; i < 3; i++ ) { v12[i] = (v2[i] - v1[i])*0.5 + v1[i]; v13[i] = (v3[i] - v1[i])*0.5 + v1[i]; v23[i] = (v3[i] - v2[i])*0.5 + v2[i]; } subdivideTriangle(vertices, index, v1, v12, v13, depth - 1); subdivideTriangle(vertices, index, v12, v2, v23, depth - 1); subdivideTriangle(vertices, index, v13, v23, v3, depth - 1); subdivideTriangle(vertices, index, v13, v12, v23, depth - 1); }
void Gl1_Sphere::subdivideTriangle(Vector3r& v1,Vector3r& v2,Vector3r& v3, int depth){ 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 (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.15; matEmit[1] = 0.15; matEmit[2] = 0.15; matEmit[3] = 0.2; } 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(v23); glVertex3v(v23); glNormal3v(v31); glVertex3v(v31); glEnd(); return; } Vector3r v12 = v1+v2; Vector3r v23 = v2+v3; Vector3r v31 = v3+v1; v12.normalize(); v23.normalize(); v31.normalize(); subdivideTriangle(v1,v12,v31,depth-1); subdivideTriangle(v2,v23,v12,depth-1); subdivideTriangle(v3,v31,v23,depth-1); subdivideTriangle(v12,v23,v31,depth-1); }
void Plot3DWidget::makeGeodesicHemisphereVBO() { float* hemisphereVertices; int numSubdivisions = 6; int memIndex = 0; // allocate enough memory for all the vertices in the hemisphere numTrianglesInHemisphere = 40 * int(powf(4.0, float(numSubdivisions))); hemisphereVertices = new float[ numTrianglesInHemisphere * 3 * 3 ]; //printf( "numTrianglesInHemisphere: %d\n", numTrianglesInHemisphere ); // Generate and bind the vertex buffer object glGenBuffers( 1, &hemisphereVerticesVBO ); glBindBuffer( GL_ARRAY_BUFFER, hemisphereVerticesVBO ); // recursively divide the hemisphere triangles to get a nicely tessellated hemisphere for( int i = 0; i < 40; i++ ) { subdivideTriangle( hemisphereVertices, memIndex, geodesicHemisphereVerts[i][0], geodesicHemisphereVerts[i][1], geodesicHemisphereVerts[i][2], numSubdivisions ); } // copy the data into a buffer on the GPU glBufferData(GL_ARRAY_BUFFER, numTrianglesInHemisphere*sizeof(float)*9, hemisphereVertices, GL_STATIC_DRAW); // now that the hemisphere vertices are on the GPU, we're done with the local copy delete[] hemisphereVertices; }
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 generateSphereSamples(int NSAMPLE,vector<Vec3d> &sphereSamples) { double t=(1.0+sqrt(double(5)))/2.0; double a=sqrt(t)/pow(5.0,0.25); double b=1.0/(sqrt(t)*pow(5.0,0.25)); double vertexs[12][3]={{-a,0,b},{0,b,-a},{0,b,a},{a,0,-b}, {-b,-a,0},{-b,a,0},{0,-b,a},{b,a,0}, {0,-b,-a},{a,0,b},{b,-a,0},{-a,0,-b}};//vertexs coordinate int faces[20][3]={{9,2,6},{1,5,11},{11,1,8},{0,11,4},{3,7,1}, {3,1,8},{9,3,7},{0,2,6},{4,6,10},{1,7,5}, {7,2,5},{8,10,3},{4,11,8},{9,2,7},{10,6,9}, {0,11,5},{0,2,5},{8,10,4},{3,9,10},{6,4,0}};//faces with vertexs index double nsamplepertri=NSAMPLE/20.0;//number of samples in per triangle int level=ceil(log(nsamplepertri)/log(4.0));//levels of sampling in per triangle for(int i=0;i<20;i++) { vector<Vec3d> tri; tri.resize(3); for(int j=0;j<3;j++) for(int k=0;k<3;k++) tri[j][k]=vertexs[faces[i][j]][k]; subdivideTriangle(tri,level,sphereSamples); } //cout<<"Have Generated Sphere Samples!"<<endl; /*ofstream ofile("sphereSample.vw"); for(int i=0;i<sphereSamples.size();i++) { for(int j=0;j<3;j++) ofile<<sphereSamples[i][j]<<" "; ofile<<2<<endl; } ofile.close();*/ }