Beispiel #1
0
/* This function does the quicksort
   Arguments :
             array - the array to be sorted
             startIndex - index of the first element of the section
             endIndex - index of the last element of the section
   */
void QuickSort(int* array, int startIndex, int endIndex)
{
    int pivot = array[startIndex];                    //pivot element is the leftmost element
    int splitPoint;
    
    if(endIndex > startIndex)                         //if they are equal, it means there is
                                                      //only one element and quicksort's job
                                                      //here is finished
    {
        splitPoint = SplitArray(array, pivot, startIndex, endIndex);
                                                      //SplitArray() returns the position where
                                                      //pivot belongs to
        array[splitPoint] = pivot;
        QuickSort(array, startIndex, splitPoint-1);   //Quick sort first half
        QuickSort(array, splitPoint+1, endIndex);     //Quick sort second half
    }
}
void CUnit3DLoader::CreateArrays(UnitModel& model)
{
	UnitModelGeometry& geometry=*model.geometry;
	vector<ArrayVertex>& va=geometry.vertexSplitting;
	bool newSplit=false;


	if(va.empty()){
		newSplit=true;
		va.resize(geometry.vertex.size());

		for(int a=0;a<geometry.vertex.size();++a){
			ArrayVertex& v=va[a];
			ArrayVertexSub vs;
			vs.num=a;
			vs.texCoord[0]=-1;
			v.sub.push_back(vs);
		}
	} else {
		for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){
			for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){
				vsi->texCoord[0]=-1;
			}
		}
	}

	vector<Tri>::iterator ti;
	vector<TriTex>::iterator tti;
	int newNum=geometry.vertex.size();
	for(ti=geometry.tri.begin(),tti=model.triTex.begin();ti!=geometry.tri.end();++ti,++tti){	//split on texcoord
		for(int b=0;b<3;++b){
			ArrayVertex& v=va[ti->verteces[b]];
			vector<ArrayVertexSub>::iterator vi;
			bool createNew=true;
			for(vi=v.sub.begin();vi!=v.sub.end();++vi){
				if(vi->texCoord[0]==-1){
					vi->texCoord[0]=tti->texPos[b][0];
					vi->texCoord[1]=tti->texPos[b][1];
				}
				if(vi->texCoord[0]==tti->texPos[b][0] && vi->texCoord[0]==tti->texPos[b][0]){
					createNew=false;
					break;
				}
			}
			if(createNew){
				if(!newSplit){
					handleerror(0,"Impossible split","error in unit3dloader",0);
				}
				ArrayVertexSub vs;
				vs.num=newNum++;
				vs.texCoord[0]=tti->texPos[b][0];
				vs.texCoord[1]=tti->texPos[b][1];
				v.sub.push_back(vs);
			}
		}
	}

	if(newSplit){
		SplitArray(geometry.vertex,geometry.vertexSplitting);//split the main frame;
		for(map<string,Animation*>::iterator ai=geometry.animations.begin();ai!=geometry.animations.end();++ai){//split the animation frames
			for(vector<AnimFrame>::iterator fi=ai->second->frames.begin();fi!=ai->second->frames.end();++fi){
				SplitArray(fi->vertex,geometry.vertexSplitting);
			}
		}
	}

	if(!model.texCoordBuffer){
		glGenBuffersARB( 1, &model.texCoordBuffer );
		glBindBufferARB( GL_ARRAY_BUFFER_ARB, model.texCoordBuffer );
		glBufferDataARB( GL_ARRAY_BUFFER_ARB, geometry.vertex.size()*2*sizeof(float), 0, GL_STATIC_DRAW_ARB );

		float* texCoordBuf=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB);
		if(!texCoordBuf){
			handleerror(0,"glMapBuffer failed","Exiting",0);
			exit(0);
		}

		for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){
			for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){
				texCoordBuf[vsi->num*2]=vsi->texCoord[0];
				texCoordBuf[vsi->num*2+1]=vsi->texCoord[1];

			}
		}

		if(!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)){
			handleerror(0,"glUnmapBuffer failed","Exiting",0);
			exit(0);
		}
	}

	if(!geometry.indexBuffer){
		glGenBuffersARB( 1, &geometry.indexBuffer );
		glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, geometry.indexBuffer );
		glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, geometry.tri.size()*3*sizeof(unsigned short), 0, GL_STATIC_DRAW_ARB );
		
		unsigned short* indexBuf=(unsigned short*)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB);
		if(!indexBuf){
			handleerror(0,"glMapBuffer failed","Exiting",0);
			exit(0);
		}

		int ip=0;
		vector<Tri>::iterator ti;
		vector<TriTex>::iterator tti;
		for(ti=geometry.tri.begin(),tti=model.triTex.begin();ti!=geometry.tri.end();++ti,++tti){
			for(int a=0;a<3;++a){
				int vert=ti->verteces[a];
				vector<ArrayVertexSub>& avs=va[vert].sub;
				for(vector<ArrayVertexSub>::iterator vsi=avs.begin();vsi!=avs.end();++vsi){
					if(vsi->texCoord[0]==tti->texPos[a][0] && vsi->texCoord[1]==tti->texPos[a][1]){
						vert=vsi->num;
						break;
					}
				}
				indexBuf[ip++]=vert;
			}
		}
		if(!glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB)){
			handleerror(0,"glUnmapBuffer failed","Exiting",0);
			exit(0);
		}
		glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
	}

	if(!geometry.normalBuffer){
		glGenBuffersARB( 1, &geometry.normalBuffer );
		glBindBufferARB( GL_ARRAY_BUFFER_ARB, geometry.normalBuffer );
		glBufferDataARB( GL_ARRAY_BUFFER_ARB, geometry.vertex.size()*3*sizeof(float), 0, GL_STATIC_DRAW_ARB );
		
		float* normalBuf=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB);
		if(!normalBuf){
			handleerror(0,"glMapBuffer failed","Exiting",0);
			exit(0);
		}
		for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){
			int oldNum=vi->sub.begin()->num;
			for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){
				normalBuf[vsi->num*3+0]=geometry.vertexNormal[oldNum].x;	
				normalBuf[vsi->num*3+1]=geometry.vertexNormal[oldNum].y;	
				normalBuf[vsi->num*3+2]=geometry.vertexNormal[oldNum].z;	
			}
		}
		if(!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)){
			handleerror(0,"glUnmapBuffer failed","Exiting",0);
			exit(0);
		}
	}
	geometry.numVerteces=geometry.vertex.size();
	geometry.numIndeces=geometry.tri.size()*3;
	glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
}