Пример #1
0
/////////////////////////////////////
// Name:	
// Purpose:	
// Output:	
// Return:	
/////////////////////////////////////
PUBLIC hMDL MDLGenMap(unsigned int newID, float mapSizeX, float mapSizeZ, float height, float r,
				 unsigned int numIter, hTXT texture, GFXMATERIAL *mat)
{
	int size = 1<<numIter;
	int numVtx = (size+1)*(size+1);

	//allocate the points
	float *points;

	//HACK for now...
	points = (float*)GFX_MALLOC(sizeof(float)*(numVtx+2));
	if(!points)
	{ ASSERT_MSG(0, "Unable to allocate points", "Error in MDLGenMap"); return 0; }

	//generate the points!
	_MapGeneratePoints(points, height, r, size);

	hMDL newMdl = (hMDL)GFX_MALLOC(sizeof(gfxModel));

	if(!newMdl)
	{ ASSERT_MSG(0, "Unable to allocate new model", "Error in ModelGenMap"); return 0; }

	//fill 'er up
	newMdl->ID = newID;
	newMdl->numMaterial = 1;

	if(texture)
	{
		newMdl->textures = (hTXT*)GFX_MALLOC(sizeof(hTXT)*newMdl->numMaterial);
		if(!newMdl->textures)
		{ ASSERT_MSG(0, "Unable to allocate model textures", "Error in ModelGenMap"); return 0; }

		newMdl->textures[0] = texture; 
		TextureAddRef(newMdl->textures[0]);
	}

	newMdl->materials = (GFXMATERIAL*)GFX_MALLOC(sizeof(GFXMATERIAL)*newMdl->numMaterial);
	if(!newMdl->materials)
	{ ASSERT_MSG(0, "Unable to allocate materials", "Error in ModelGenMap"); return 0; }

	if(!mat)
	{
		newMdl->materials[0].Diffuse.r = 1.0f;
		newMdl->materials[0].Diffuse.g = 1.0f;
		newMdl->materials[0].Diffuse.b = 1.0f;
		newMdl->materials[0].Diffuse.a = 1.0f;
		//newMdl->materials[0].Specular = newMdl->materials[0].Emissive = newMdl->materials[0].Ambient = newMdl->materials[0].Diffuse;
		newMdl->materials[0].Ambient = newMdl->materials[0].Diffuse;
		//newMdl->materials[0].Power = 1.0f;
	}
	else
		memcpy(newMdl->materials, mat, sizeof(GFXMATERIAL));	

	//////////////////////////////////////////////////////////////
	//now time to stuff it all in the D3D vertex buffer
	//create the mesh
	MeshCreate(&newMdl->mesh, 1, numVtx);
	MeshInitGroup(&newMdl->mesh, 0, "RANDOMMAP", 0, size*size*2);
	//////////////////////////////////////////////////////////////

	/////////////////
	//now fill 'er up
	gfxVtx *ptrVtx, *thisVtx;

	

	if(MeshLockVtx(&newMdl->mesh, 0, &ptrVtx) != RETCODE_SUCCESS)
	{ return 0; }

	int maxV = size+1;

	//fill in data, just go through the lists and fill in stuff
	for(int rowV = 0; rowV < maxV; rowV++)
	{
		for(int colV = 0; colV < maxV; colV++)
		{
			thisVtx = &CELL(ptrVtx, rowV, colV, maxV);

			thisVtx->x = colV*mapSizeX;
			thisVtx->y = CELL(points, rowV, colV, maxV);
			thisVtx->z = rowV*mapSizeZ;

			_GFXVtxSetTxtCoordAll(thisVtx, thisVtx->x/TextureGetWidth(texture), 
										   thisVtx->z/TextureGetHeight(texture));
		}
	}

	MeshUnlockVtx(&newMdl->mesh);
	/////////////////

	/////////////////
	//now fill the index buffer up
	unsigned short *ptrInd;

	if(MeshLockInd(&newMdl->mesh, 0, 0, &ptrInd) != RETCODE_SUCCESS)
	{ return 0; }

	//fill in data
	int numCol = size; //number of col
	int numRow = size; //number of row
	int max = numCol+1;
	int numDot = MeshGetNumVtx(&newMdl->mesh)-max; //number of dots to iterate (minus last row)
	int indIter = NUMPTFACE*2; //we are going to make two faces per cel

	for(int row = 0, ind = 0; row < numRow; row++)
	{
		for(int col = 0; col < numCol; col++)
		{
			/*
			0-----3
			|\    |
			|  \  |
			|    \|
			1-----2
			*/

			int dot = col+(row*max);
			
			//first face
			ptrInd[ind] = dot; ptrInd[ind+1] = dot+max; ptrInd[ind+2] = ptrInd[ind+1]+1;

			//second face
			ptrInd[ind+3] = ptrInd[ind+2]; ptrInd[ind+4] = dot+1; ptrInd[ind+5] = ptrInd[ind];
			
			ind += indIter;
		}
	}

	MeshUnlockInd(&newMdl->mesh, 0);
	/////////////////

	//This outta make lighting easy
	MeshComputeNormals(&newMdl->mesh);

	//clean up stuff
	GFX_FREE(points);

	//append to list
	g_MDLLIST.insert(g_MDLLIST.end(), (unsigned int)newMdl);

	return newMdl;
}
Пример #2
0
/* Convert a Mesh into linked list of PolyListNodes, subdivide
 * non-flat or concave quadrilaterals.
 */
static PolyListNode *
MeshToLinkedPolyList(Transform T, Transform Tdual, Transform TxT,
		     const void **tagged_app, PolyListNode **plistp,
		     Mesh *mesh, struct obstack *scratch)
{
  PolyListNode *plist = NULL;
  Poly *qpoly;
  int v0 = 1, prev0v = 0;
  int u0 = 1, prev0u = 0;
  int u, v, prevu, prevv;
  int concave;
  int i;

  if (!plistp) {
    plistp = &plist;
  }

  MeshComputeNormals(mesh, MESH_N);

  if(mesh->geomflags & MESH_UWRAP) {
    v0 = 0, prev0v = mesh->nv-1;
  }
  if(mesh->geomflags & MESH_VWRAP) {
    u0 = 0, prev0u = mesh->nu-1;
  }

#define MESHIDX(u, v, mesh) ((v)*(mesh)->nu + (u))
  qpoly = NULL;
  for(prevv = prev0v, v = v0; v < mesh->nv; prevv = v, v++) {
    for(prevu = prev0u, u = u0; u < mesh->nu; prevu = u, u++) {
      /* First try to create a single polygon, if that mesh-cell is
       * non-flat or concave, then sub-divide it.
       */
      if (!qpoly) {
	qpoly = new_poly(4, NULL, scratch);
	for (i = 0; i < 4; i++) {
	  qpoly->v[i] = obstack_alloc(scratch, sizeof(Vertex));
	}
      }
      if (T && T != TM_IDENTITY) {
	meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[0], mesh,
			     MESHIDX(prevu, prevv, mesh));
	meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[1], mesh,
			     MESHIDX(u, prevv, mesh));
	meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[2], mesh,
			     MESHIDX(u, v, mesh));
	meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[3], mesh,
			     MESHIDX(prevu, v, mesh));
      } else {
	meshv_to_polyv(qpoly->v[0], mesh, MESHIDX(prevu, prevv, mesh));
	meshv_to_polyv(qpoly->v[1], mesh, MESHIDX(u, prevv, mesh));
	meshv_to_polyv(qpoly->v[2], mesh, MESHIDX(u, v, mesh));
	meshv_to_polyv(qpoly->v[3], mesh, MESHIDX(prevu, v, mesh));
      }

      if (mesh->geomflags & MESH_C) {
	qpoly->flags |= PL_HASVCOL;
      }
      if (mesh->geomflags & COLOR_ALPHA) {
	qpoly->flags |= COLOR_ALPHA;
      }
      if (mesh->geomflags & MESH_N) {
	qpoly->flags |= PL_HASVN;
      }
      if (mesh->geomflags & MESH_U) {
	qpoly->flags |= PL_HASST;
      }

      PolyNormal(qpoly, &qpoly->pn, mesh->geomflags & VERT_4D, false,
		 &qpoly->flags, &concave);
      qpoly->flags |= PL_HASPN;
      if (qpoly->flags & POLY_NOPOLY) {
	/* polygon is degenerated, we just do NOT draw it, edges are
	 * drawn by other methods. Just do nothing, qpoly will be
	 * re-used for the next quad.
	 */
	qpoly->flags = 0;
      } else if (qpoly->flags & (POLY_CONCAVE|POLY_NONFLAT)) {
	/* we need to split it */
	split_quad_poly(concave, qpoly, plistp, tagged_app, scratch);
	qpoly = NULL;
      } else {
	PolyListNode *new_pn;
	
	new_pn = new_poly_list_node(tagged_app, scratch);
	new_pn->poly = qpoly;
	ListPush(*plistp, new_pn);
	qpoly = NULL;
      }
    }
  }

#undef MESHIDX
  
  return *plistp;
}