CObject* build()
    {
      sys::info << "ogl::CBoxObjectBuilder::build()" << sys::endl;
    
      float dmax    = hasOption(CObjectBuilder::NORMALIZED) ? math::max(mWidth, math::max(mHeight, mDepth)) : 1.0f;
    
      float hwidth  = (mWidth  / 2.0f) / dmax;
      float hheight = (mHeight / 2.0f) / dmax;
      float hdepth  = (mDepth  / 2.0f) / dmax;
      
      const size_t nNumVertices = 24;
      const size_t nNumIndices  = 36;
      
      // bool bFlatface = hasOption(CObjectBuilder::FLATFACE);
      
      math::vec3* positions = new math::vec3[nNumVertices];
      positions[ 0] = math::vec3(-hwidth,-hheight, hdepth);
      positions[ 1] = math::vec3(-hwidth,-hheight, hdepth);
      positions[ 2] = math::vec3(-hwidth,-hheight, hdepth);
      positions[ 3] = math::vec3( hwidth,-hheight, hdepth);
      positions[ 4] = math::vec3( hwidth,-hheight, hdepth);
      positions[ 5] = math::vec3( hwidth,-hheight, hdepth);
      positions[ 6] = math::vec3( hwidth, hheight, hdepth);
      positions[ 7] = math::vec3( hwidth, hheight, hdepth);
      positions[ 8] = math::vec3( hwidth, hheight, hdepth);
      positions[ 9] = math::vec3(-hwidth, hheight, hdepth);
      positions[10] = math::vec3(-hwidth, hheight, hdepth);
      positions[11] = math::vec3(-hwidth, hheight, hdepth);
      positions[12] = math::vec3(-hwidth,-hheight,-hdepth);
      positions[13] = math::vec3(-hwidth,-hheight,-hdepth);
      positions[14] = math::vec3(-hwidth,-hheight,-hdepth);
      positions[15] = math::vec3( hwidth,-hheight,-hdepth);
      positions[16] = math::vec3( hwidth,-hheight,-hdepth);
      positions[17] = math::vec3( hwidth,-hheight,-hdepth);
      positions[18] = math::vec3( hwidth, hheight,-hdepth);
      positions[19] = math::vec3( hwidth, hheight,-hdepth);
      positions[20] = math::vec3( hwidth, hheight,-hdepth);
      positions[21] = math::vec3(-hwidth, hheight,-hdepth);
      positions[22] = math::vec3(-hwidth, hheight,-hdepth);
      positions[23] = math::vec3(-hwidth, hheight,-hdepth);
      
      math::vec2* texcoords = new math::vec2[nNumVertices];
      texcoords[ 0] = math::vec2(1.0f, 1.0f);
      texcoords[ 1] = math::vec2(0.0f, 1.0f);
      texcoords[ 2] = math::vec2(0.0f, 1.0f);
      texcoords[ 3] = math::vec2(0.0f, 1.0f);
      texcoords[ 4] = math::vec2(1.0f, 1.0f);
      texcoords[ 5] = math::vec2(1.0f, 1.0f);
      texcoords[ 6] = math::vec2(0.0f, 0.0f);
      texcoords[ 7] = math::vec2(1.0f, 0.0f);
      texcoords[ 8] = math::vec2(1.0f, 0.0f);
      texcoords[ 9] = math::vec2(1.0f, 0.0f);
      texcoords[10] = math::vec2(0.0f, 0.0f);
      texcoords[11] = math::vec2(0.0f, 0.0f);
      texcoords[12] = math::vec2(0.0f, 1.0f);
      texcoords[13] = math::vec2(1.0f, 1.0f);
      texcoords[14] = math::vec2(0.0f, 0.0f);
      texcoords[15] = math::vec2(1.0f, 1.0f);
      texcoords[16] = math::vec2(0.0f, 1.0f);
      texcoords[17] = math::vec2(1.0f, 0.0f);
      texcoords[18] = math::vec2(1.0f, 0.0f);
      texcoords[19] = math::vec2(0.0f, 0.0f);
      texcoords[20] = math::vec2(1.0f, 1.0f);
      texcoords[21] = math::vec2(0.0f, 0.0f);
      texcoords[22] = math::vec2(1.0f, 0.0f);
      texcoords[23] = math::vec2(0.0f, 1.0f);
      
      math::vec3* normals = new math::vec3[nNumVertices];
      normals[ 0] = math::vec3( 0.0f, 0.0f, 1.0f);
      normals[ 1] = math::vec3(-1.0f, 0.0f, 0.0f);
      normals[ 2] = math::vec3( 0.0f,-1.0f, 0.0f);
      normals[ 3] = math::vec3( 0.0f, 0.0f, 1.0f);
      normals[ 4] = math::vec3( 1.0f, 0.0f, 0.0f);
      normals[ 5] = math::vec3( 0.0f,-1.0f, 0.0f);
      normals[ 6] = math::vec3( 0.0f, 0.0f, 1.0f);
      normals[ 7] = math::vec3( 1.0f, 0.0f, 0.0f);
      normals[ 8] = math::vec3( 0.0f, 1.0f, 0.0f);
      normals[ 9] = math::vec3( 0.0f, 0.0f, 1.0f);
      normals[10] = math::vec3(-1.0f, 0.0f, 0.0f);
      normals[11] = math::vec3( 0.0f, 1.0f, 0.0f);
      normals[12] = math::vec3( 0.0f, 0.0f,-1.0f);
      normals[13] = math::vec3(-1.0f, 0.0f, 0.0f);
      normals[14] = math::vec3( 0.0f,-1.0f, 0.0f);
      normals[15] = math::vec3( 0.0f, 0.0f,-1.0f);
      normals[16] = math::vec3( 1.0f, 0.0f, 0.0f);
      normals[17] = math::vec3( 0.0f,-1.0f, 0.0f);
      normals[18] = math::vec3( 0.0f, 0.0f,-1.0f);
      normals[19] = math::vec3( 1.0f, 0.0f, 0.0f);
      normals[20] = math::vec3( 0.0f, 1.0f, 0.0f);
      normals[21] = math::vec3( 0.0f, 0.0f,-1.0f);
      normals[22] = math::vec3(-1.0f, 0.0f, 0.0f);
      normals[23] = math::vec3( 0.0f, 1.0f, 0.0f);

      static GLushort indices[] = {
         3,  0,  9, // triangle 0  // face 0 // +z
         3,  9,  6, // triangle 1  // face 0
        12, 15, 18, // triangle 2  // face 1 // -z
        12, 18, 21, // triangle 3  // face 1
         1, 13, 22, // triangle 4  // face 2 // -x
         1, 22, 10, // triangle 5  // face 2
        16,  4,  7, // triangle 6  // face 3 // +x
        16,  7, 19, // triangle 7  // face 4 
         2,  5, 17, // triangle 8  // face 5 // -y
         2, 17, 14, // triangle 9  // face 5 
        23, 20,  8, // triangle 10 // face 6 // +y
        23,  8, 11  // triangle 11 // face 7
      };
      
      math::vec3* tangents  = new math::vec3[nNumVertices];
      math::vec3* binormals = new math::vec3[nNumVertices];
      for(size_t i = 0; i < nNumIndices; i+=3) // for every triangle
      {
        ushort i0 = indices[i+0];
        ushort i1 = indices[i+1];
        ushort i2 = indices[i+2];

        math::vec3& p0 = positions[i0];
        math::vec3& p1 = positions[i1];
        math::vec3& p2 = positions[i2];
        
        math::vec2& t0 = texcoords[i0];
        math::vec2& t1 = texcoords[i1];
        math::vec2& t2 = texcoords[i2];
        
        math::vec3 dp1(p1 - p0); // e1
        math::vec3 dp2(p2 - p0); // e2
        
        math::vec3 normal = math::normalize(math::cross(dp2, dp1));
        normals[i0] += normal; // avarage the normals
        normals[i0]  = math::normalize(normals[i0]);
        normals[i1] += normal;
        normals[i1]  = math::normalize(normals[i1]);
        normals[i2] += normal;
        normals[i2]  = math::normalize(normals[i2]);
        
        math::vec2 dt1 = t1 - t0;
        math::vec2 dt2 = t2 - t0;
        
        float r = 1.0f / (dt1.x * dt2.y - dt1.y * dt2.x);
        math::vec3 ta = (dp1 * dt2.y - dp2 * dt1.y) * r;    // tangent
        math::vec3 bi = (dp2 * dt1.x - dp1 * dt2.x) * r;    // binormal
        
        tangents[i0] = ta;
        tangents[i1] = ta;
        tangents[i2] = ta;
        
        binormals[i0] = bi;
        binormals[i1] = bi;
        binormals[i2] = bi;
      }
      
      if(hasOption(CObjectBuilder::INVERTED)) 
      {
        for(size_t i = 0; i < nNumVertices; ++i)
        {
          normals[i]   *= -1.0f;
          tangents[i]  *= -1.0f;
          binormals[i] *= -1.0f;
        }
        
        for(ushort i = 0; i < nNumIndices; i+=3)
        {
          GLushort tmp = indices[i+1];
          indices[i+1] = indices[i+2];
          indices[i+2] = tmp;
        }
      }
      
      if(mTextureScale != 1.0f)
      {
        for(size_t i = 0; i < nNumVertices; ++i)
          texcoords[i] = texcoords[i] / mTextureScale;
      }
      
      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      CObject* pObject = new CObject;
      pObject->mNumVertices = nNumVertices;
      pObject->mNumIndices  = nNumIndices;
      
      pObject->setDrawStrategy(mDrawStrategy == nullptr ? new CDrawStrategy : mDrawStrategy);
      
      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      { // shapes
        CShape* pShape = new CShape;
        pShape->setVertexBufferRange(0, pObject->mNumVertices, GL_FLOAT);
        pShape->setIndexBufferRange(0, pObject->mNumIndices, GL_UNSIGNED_SHORT);
        
        CMaterial* pMaterial = new CMaterial;
        CDdsTextureBuilder* pTextureBuilder = new CDdsTextureBuilder;
        pTextureBuilder->setFile("notfound.dds");
        CTexture* pTexture = pTextureBuilder->build();
        pTexture->setFiltering(CTexture::EFiltering::TRILINEAR);
        delete pTextureBuilder;
        
        pMaterial->setTexture(CTexture::EScope::DIFFUSE, pTexture);
        pShape->setMaterial(pMaterial);
        
        pObject->addShape(pShape);
      }
      
      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      pObject->mBuffers.resize(5);
      
      glGenVertexArrays(1, &(pObject->mVAO));
      glBindVertexArray(pObject->mVAO);
      
      // indices
      glGenBuffers(1, &(pObject->mBuffers[INDEX_BUFFER_INDEX]));
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pObject->mBuffers[INDEX_BUFFER_INDEX]);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, nNumIndices * sizeof(GLushort), indices, GL_STATIC_DRAW);
      
      // positions
      glGenBuffers(1, &(pObject->mBuffers[POSITION_BUFFER_INDEX]));
      glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[POSITION_BUFFER_INDEX]);
      glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), positions, GL_STATIC_DRAW);
      
      glVertexAttribPointer(POSITION_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3),  (const GLvoid*)(0));
      glEnableVertexAttribArray(POSITION_ATTRIBUTE); // positions
      
      // texcoords
      glGenBuffers(1, &(pObject->mBuffers[TEXCOORD_BUFFER_INDEX]));
      glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[TEXCOORD_BUFFER_INDEX]);
      glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec2), texcoords, GL_STATIC_DRAW);
      
      glVertexAttribPointer(TEXCOORD_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, sizeof(math::vec2), (const GLvoid*)(0)); //(GLvoid*)((0 + 3) * sizeof(GLfloat)));
      glEnableVertexAttribArray(TEXCOORD_ATTRIBUTE); // texcoords
      
      // normals
      glGenBuffers(1, &(pObject->mBuffers[NORMAL_BUFFER_INDEX]));
      glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[NORMAL_BUFFER_INDEX]);
      glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), normals, GL_STATIC_DRAW);
      
      glVertexAttribPointer(NORMAL_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3), (const GLvoid*)(0)); //(GLvoid*)((0 + 3 + 2) * sizeof(GLfloat)));
      glEnableVertexAttribArray(NORMAL_ATTRIBUTE); // normals
      
      // tangents
      glGenBuffers(1, &(pObject->mBuffers[TANGENT_BUFFER_INDEX]));
      glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[TANGENT_BUFFER_INDEX]);
      glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), tangents, GL_STATIC_DRAW);
      
      glVertexAttribPointer(TANGENT_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3), (const GLvoid*)(0)); //(GLvoid*)((0 + 3 + 2) * sizeof(GLfloat)));
      glEnableVertexAttribArray(TANGENT_ATTRIBUTE); // tangents
      
      // clean
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
      glBindVertexArray(0);
      
      delete [] positions;
      delete [] texcoords;
      delete [] normals;
      delete [] tangents;
      delete [] binormals;
      
      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      return pObject;
    }
Esempio n. 2
0
void CDeform2d::doDeform(const TPoint2DVect &surf, IDriver *drv, IPerturbUV *uvp)
{

	nlassert(uvp);

	typedef CQuadEffect::TPoint2DVect TPoint2DVect;
	TPoint2DVect dest;

	CQuadEffect::processPoly(surf, (float) _XGranularity, (float) _YGranularity, dest);

	uint realWidth = NLMISC::raiseToNextPowerOf2(_Width);
	uint realHeight= NLMISC::raiseToNextPowerOf2(_Height);


	// draw the poly contour
	/*for (uint k = 0; k < dest.size(); ++k)
	{
		CDRU::drawLine(dest[k].x, dest[k].y, dest[(k + 1) % dest.size()].x, dest[(k + 1) % dest.size()].y, *drv, CRGBA::Red);
	}*/




	static CMaterial mat;
	mat.setDoubleSided(true);
	mat.setLighting(false);
	mat.setZFunc(CMaterial::always);
/*	mat.setColor(CRGBA::Red);
	mat.texEnvOpRGB(0, CMaterial::Add); */

	static CVertexBuffer  vb;
	vb.setName("CDeform2d");
	vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag);



	drv->setFrustum(0, (float) _Width, 0, (float) _Height, -1, 1, false);
	drv->setupViewMatrix(CMatrix::Identity);
	drv->setupModelMatrix(CMatrix::Identity);


	const float iDu = 1.f / _Width;
	const float iDv = 1.f / _Height;
	const float widthRatio = _Width / (float) realWidth;
	const float heightRatio = _Height / (float) realHeight;


	float u, u2, v;
	float du, dv;

	TPoint2DVect::const_iterator it;

	// get back datas from frame buffer
	for (it = dest.begin(); it != dest.end(); ++it)
	{
		// todo hulud use the new render to texture interface
		// drv->copyFrameBufferToTexture(_Tex, 0, (uint32) it->x,(uint32) it->y, (uint32) it->x, (uint32) it->y, _XGranularity, _YGranularity);
	}


	/** setup the whole vertex buffer
	  * we don't share vertices here, as we work with unaligned quads
	  */
	vb.setNumVertices((uint32)dest.size() << 2);
	mat.setTexture(0, _Tex);
	{
		CVertexBufferReadWrite vba;
		vb.lock (vba);

		uint k = 0; // current index in the vertex buffer
		for (it = dest.begin(); it != dest.end(); ++it, k += 4)
		{

			// \todo optimize this by a direct access to the vertex buffer (if needed)
			// blit data to frame buffer and apply deformations

			vba.setVertexCoord(k, NLMISC::CVector(it->x, 0, it->y));
			vba.setVertexCoord(k + 1, NLMISC::CVector(it->x + _XGranularity, 0, it->y));
			vba.setVertexCoord(k + 2, NLMISC::CVector(it->x + _XGranularity, 0, it->y + _YGranularity));
			vba.setVertexCoord(k + 3, NLMISC::CVector(it->x , 0, it->y + _YGranularity));

			// perturbation of the uv coordinates

			u =  it->x * iDu;
			v = it->y * iDv;
			uvp->perturbUV(u, v, du, dv);
			vba.setTexCoord(k, 0, (u + du) * widthRatio, (v + dv) * heightRatio );

			u2 =  (it->x + _XGranularity) * iDu;
			uvp->perturbUV(u2, v, du, dv);
			vba.setTexCoord(k + 1, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio );

			v =  (it->y + _YGranularity) * iDv;
			uvp->perturbUV(u2, v, du, dv);
			vba.setTexCoord(k + 2, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio );

			uvp->perturbUV(u, v, du, dv);
			vba.setTexCoord(k + 3, 0, (u + du) * widthRatio, (v + dv) * heightRatio );
		}
	}

	drv->activeVertexBuffer(vb);
	drv->renderRawQuads(mat, 0, (uint32)dest.size());
}
Esempio n. 3
0
bool readMaterialTexture(CMaterial& material, IOReadBase* pRead, const std::string& strFilename)
{
	std::string strCommand;
	std::vector<std::string> setWords;

	strCommand = getLineCommand(pRead,setWords);
	if ("{"!=strCommand)
	{
		return false;
	}

	std::string strTexture;
	bool bAdd = false;
	while (!pRead->IsEof())
	{
		strCommand = getLineCommand(pRead,setWords);
		if ("texture"==strCommand)
		{
			if (setWords.size()>0)
			{
				strTexture=GetParentPath(strFilename)+setWords[0];
				strTexture = ChangeExtension(strTexture,".dds");
			}
		}
		else if ("colour_op"==strCommand)
		{
			if (setWords.size()>0)
			{
				if ("add"==setWords[0])
				{
					bAdd = true;
				}
			}
		}
		else if ("scroll_anim"==strCommand)
		{
			if (setWords.size()==2)
			{
				material.vTexAnim.x=atof(setWords[0].c_str());
				material.vTexAnim.y=atof(setWords[1].c_str());
			}
		}
		else if ("}"==strCommand)
		{
			break;
		}
		else
		{
			MessageBoxA(NULL,strCommand.c_str(),"Unknon in texture_unit!",0);
		}
	}
	if (strTexture.length()>0)
	{
		if (bAdd)
		{
			//material.setEmissive(strTexture);
			material.setTexture(0,strTexture.c_str());
		}
		else
		{
			material.setTexture(0,strTexture.c_str());
		}
	}
	return true;
}
Esempio n. 4
0
// TMP TMP
void tempDumpColPolys()
{
	CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland();
	if (pw)
	{
		static CMaterial material;
		static CMaterial wiredMaterial;
		static CMaterial texturedMaterial;
		static CVertexBuffer vb;
		static bool initDone = false;
		if (!initDone)
		{
			vb.setVertexFormat(CVertexBuffer::PositionFlag);
			vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false);
			material.initUnlit();
			material.setDoubleSided(true);
			material.setZFunc(CMaterial::lessequal);
			wiredMaterial.initUnlit();
			wiredMaterial.setDoubleSided(true);
			wiredMaterial.setZFunc(CMaterial::lessequal);
			wiredMaterial.setColor(CRGBA(255, 255, 255, 250));
			wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace);
			wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha);
			wiredMaterial.setBlend(true);
			wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha);
			texturedMaterial.initUnlit();
			texturedMaterial.setDoubleSided(true);
			texturedMaterial.setZFunc(CMaterial::lessequal);
			initDone = true;
		}
		// just add a projected texture
		R2::getEditor().getIslandCollision().loadEntryPoints();
		R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance();
		CVectorD playerPos = UserEntity->pos();
		R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y));
		static CSString currIsland;
		if (island && island->Island != currIsland)
		{
			currIsland = island->Island;
			CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga");
			newTex->setWrapS(ITexture::Clamp);
			newTex->setWrapT(ITexture::Clamp);
			texturedMaterial.setTexture(0, newTex);
			texturedMaterial.texEnvOpRGB(0, CMaterial::Replace);
			texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
			texturedMaterial.setTexCoordGen(0, true);
			texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
			CMatrix mat;
			CVector scale((float) (island->XMax -  island->XMin),
						  (float) (island->YMax -  island->YMin), 0.f);
			scale.x = 1.f / favoid0(scale.x);
			scale.y = 1.f / favoid0(scale.y);
			scale.z = 0.f;
			mat.setScale(scale);
			mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f));
			//
			CMatrix uvScaleMat;
			//
			uint texWidth = (uint) (island->XMax -  island->XMin);
			uint texHeight = (uint) (island->YMax -  island->YMin);
			float UScale = (float) texWidth / 	raiseToNextPowerOf2(texWidth);
			float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight);
			//
			uvScaleMat.setScale(CVector(UScale, - VScale, 0.f));
			uvScaleMat.setPos(CVector(0.f, VScale, 0.f));
			//
			texturedMaterial.enableUserTexMat(0, true);
			texturedMaterial.setUserTexMat(0, uvScaleMat * mat);
		}
		const CFrustum &frust = MainCam.getFrustum();

		//
		IDriver *driver = ((CDriverUser  *) Driver)->getDriver();

		driver->enableFog(true);
		const CRGBA clearColor = CRGBA(0, 0, 127, 0);
		driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor);
		CViewport vp;
		vp.init(0.f, 0.f, 1.f, 1.f);
		driver->setupViewport(vp);
		CScissor scissor;
		viewportToScissor(vp, scissor);
		driver->setupScissor(scissor);
		//
		driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective);
		driver->setupViewMatrix(MainCam.getMatrix().inverted());
		driver->setupModelMatrix(CMatrix::Identity);
		//
		//
		const CVector localFrustCorners[8] =
		{
			CVector(frust.Left, frust.Near, frust.Top),
			CVector(frust.Right, frust.Near, frust.Top),
			CVector(frust.Right, frust.Near, frust.Bottom),
			CVector(frust.Left, frust.Near, frust.Bottom),
			CVector(frust.Left  * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near),
			CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near),
			CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near),
			CVector(frust.Left  * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near)
		};
		// roughly compute covered zones
		//
		/*
		sint frustZoneMinX = INT_MAX;
		sint frustZoneMaxX = INT_MIN;
		sint frustZoneMinY = INT_MAX;
		sint frustZoneMaxY = INT_MIN;
		for(uint k = 0; k < sizeofarray(localFrustCorners); ++k)
		{
			CVector corner = camMat * localFrustCorners[k];
			sint zoneX = (sint) (corner.x / 160.f) - zoneMinX;
			sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY;
			frustZoneMinX = std::min(frustZoneMinX, zoneX);
			frustZoneMinY = std::min(frustZoneMinY, zoneY);
			frustZoneMaxX = std::max(frustZoneMaxX, zoneX);
			frustZoneMaxY = std::max(frustZoneMaxY, zoneY);
		}
		*/

		const uint TRI_BATCH_SIZE = 10000; // batch size for rendering
		static std::vector<TPackedZoneBaseSPtr> zones;
		zones.clear();
		pw->getZones(zones);
		for(uint k = 0; k < zones.size(); ++k)
		{
			zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners);
		}
	}
}