コード例 #1
0
ファイル: builder_zone.cpp プロジェクト: mixxit/solinia
// ---------------------------------------------------------------------------
void CBuilderZone::render (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax)
{
	sint32 i, zoneSelected;

	DWORD backgroundColor = GetSysColor (COLOR_WINDOW);
 
	// Reset the cache
	for (i = 0; i < (CACHE_RENDER_SIZE); ++i)
	{
		_CacheRender[i].VB.setNumVertices (0);
		_CacheRender[i].PB.setNumIndexes (0);
		_CacheRender[i].Used = false;
	}

	// Select all blocks visible
	float minx = floorf(viewMin.x/_Display->_CellSize)*_Display->_CellSize;
	float miny = floorf(viewMin.y/_Display->_CellSize)*_Display->_CellSize;
	float maxx = ceilf(viewMax.x/_Display->_CellSize)*_Display->_CellSize;
	float maxy = ceilf(viewMax.y/_Display->_CellSize)*_Display->_CellSize;
	CVector pos1, pos2, pos3, pos4;
	CUV uvMin, uvMax;
	sint32 x, y;
	ITexture *pTexture;
	
	while (minx < maxx)
	{
		miny = floorf(viewMin.y/_Display->_CellSize)*_Display->_CellSize;
		while (miny < maxy)
		{
			x = (sint32)floor(minx / _Display->_CellSize);
			y = (sint32)floor(miny / _Display->_CellSize);

			i = 0;
			string sZone = STRING_OUT_OF_BOUND;
			zoneSelected = 0;
			for (i = 0; i < (sint32)_ZoneRegions.size(); ++i)
			{
				const string &rSZone = getDocument ()->getZoneRegion (i).getName (x, y);
				if ((sZone == STRING_OUT_OF_BOUND) && (rSZone == STRING_UNUSED))
				{
					sZone = STRING_UNUSED;
					zoneSelected = i;
				}
				if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
				{
					sZone = rSZone;
					zoneSelected = i;
				}
			}
			CZoneBankElement *pZBE = _ZoneBank.getElementByZoneName (sZone);

			if (pZBE == NULL)
				pTexture = _DataBase.getTexture (sZone, 0, 0, uvMin, uvMax);
			else
				pTexture = _DataBase.getTexture (sZone, getDocument ()->getZoneRegion (zoneSelected).getPosX(x, y), 
												getDocument ()->getZoneRegion (zoneSelected).getPosY(x, y), uvMin, uvMax);

			// Look if already existing texture exists in the cache
			for (i = 0; i < (CACHE_RENDER_SIZE); ++i)
			if (_CacheRender[i].Used)
				if (_CacheRender[i].Mat.getTexture(0) == pTexture)
					break;

			if (i == (CACHE_RENDER_SIZE))
			{
				// Use a new CacheRender slot
				for (i = 0; i < (CACHE_RENDER_SIZE); ++i)
					if (!_CacheRender[i].Used)
						break;
				nlassert(i<(CACHE_RENDER_SIZE));
				_CacheRender[i].Used = true;
				_CacheRender[i].Mat.setTexture (0, pTexture);
			}

			pos1.x = (minx-viewMin.x)/(viewMax.x-viewMin.x);
			pos1.y = 0.0f;
			pos1.z = (miny-viewMin.y)/(viewMax.y-viewMin.y);

			pos2.x = (_Display->_CellSize+minx-viewMin.x)/(viewMax.x-viewMin.x);
			pos2.y = 0.0f;
			pos2.z = (miny-viewMin.y)/(viewMax.y-viewMin.y);

			pos3.x = (_Display->_CellSize+minx-viewMin.x)/(viewMax.x-viewMin.x);
			pos3.y = 0.0f;
			pos3.z = (_Display->_CellSize+miny-viewMin.y)/(viewMax.y-viewMin.y);

			pos4.x = (minx-viewMin.x)/(viewMax.x-viewMin.x);
			pos4.y = 0.0f;
			pos4.z = (_Display->_CellSize+miny-viewMin.y)/(viewMax.y-viewMin.y);

			uint32 nBasePt = _CacheRender[i].VB.getNumVertices();
			_CacheRender[i].VB.setNumVertices (nBasePt+4);
			CVertexBufferReadWrite vba;
			_CacheRender[i].VB.lock (vba);
			vba.setVertexCoord (nBasePt+0, pos1);
			vba.setVertexCoord (nBasePt+1, pos2);
			vba.setVertexCoord (nBasePt+2, pos3);
			vba.setVertexCoord (nBasePt+3, pos4);


			uint32 nBaseTri = _CacheRender[i].PB.getNumIndexes ();
			_CacheRender[i].PB.setNumIndexes (nBaseTri+6);
			CIndexBufferReadWrite iba;
			_CacheRender[i].PB.lock (iba);
			iba.setTri (nBaseTri+0, nBasePt+0, nBasePt+1, nBasePt+2);
			iba.setTri (nBaseTri+3, nBasePt+0, nBasePt+2, nBasePt+3);

			if ((zoneSelected>=0)&&(zoneSelected<(sint32)_ZoneRegions.size()))
			{
				const CZoneRegion *pBZR = &(getDocument ()->getZoneRegion (zoneSelected));
				if (pBZR->getFlip (x, y) == 1)
				{
					float rTmp = uvMin.U;
					uvMin.U = uvMax.U;
					uvMax.U = rTmp;
				}

				vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+0)%4, 0, CUV(uvMin.U, uvMin.V));
				vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+1)%4, 0, CUV(uvMax.U, uvMin.V));
				vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+2)%4, 0, CUV(uvMax.U, uvMax.V));
				vba.setTexCoord (nBasePt+(pBZR->getRot (x, y)+3)%4, 0, CUV(uvMin.U, uvMax.V));
			}
			else
			{
				vba.setTexCoord (nBasePt+0, 0, CUV(uvMin.U, uvMin.V));
				vba.setTexCoord (nBasePt+1, 0, CUV(uvMax.U, uvMin.V));
				vba.setTexCoord (nBasePt+2, 0, CUV(uvMax.U, uvMax.V));
				vba.setTexCoord (nBasePt+3, 0, CUV(uvMin.U, uvMax.V));
			}

			NLMISC::CRGBA color;

			if ((zoneSelected>=0)&&(zoneSelected<(sint32)_ZoneRegions.size()))
			{
				if (getZoneMask(x,y))
					color = NLMISC::CRGBA(255, 255, 255, 255);
				else
					color = NLMISC::CRGBA(127, 127, 127, 255);
			}
			else
				color = NLMISC::CRGBA(255, 255, 255, 255);

			if (pTexture == NULL)
				color = _Display->_BackgroundColor;

			vba.setColor (nBasePt+0, color);
			vba.setColor (nBasePt+1, color);
			vba.setColor (nBasePt+2, color);
			vba.setColor (nBasePt+3, color);

			miny += _Display->_CellSize;
		}
		minx += _Display->_CellSize;
	}

	//MessageBox(NULL, "CBuilderZone::render", "3", MB_OK);

	if (DontUse3D)
		return;

	// Flush the cache to the screen
	CMatrix mtx;
	mtx.identity();
	CNELU::Driver->setupViewport (CViewport());
	CNELU::Driver->setupViewMatrix (mtx);
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);

	//MessageBox(NULL, "CBuilderZone::render", "4", MB_OK);

	for (i = 0; i < (CACHE_RENDER_SIZE); ++i)
	if (_CacheRender[i].Used)
	{
		// Render with driver
		CNELU::Driver->activeVertexBuffer (_CacheRender[i].VB);
		CNELU::Driver->activeIndexBuffer (_CacheRender[i].PB);
		CNELU::Driver->renderTriangles (_CacheRender[i].Mat, 0, _CacheRender[i].PB.getNumIndexes()/3);
	}
}
コード例 #2
0
ファイル: deform_2d.cpp プロジェクト: mixxit/solinia
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());
}