Esempio n. 1
0
/**
*
* Renders the Final Texture into the game window.
*
* @author Jade Abbott
* @return Void.
*
*/
void
CRadialMenu::RenderFinalTextureToScreen()
{
	assert(m_pRenderer);
	assert(m_iFinalTextureID != Utility::INVALID_ID);
	assert(m_uiVertexBufferQuadID != Utility::INVALID_ID);

	// Prepare the vertices on the quad for rendering.
	CVertexBuffer* pVertexBuffer = m_pRenderer->GetVertexBufferManager().GetVertexBuffer(m_uiVertexBufferQuadID);
	assert(pVertexBuffer);

	if (pVertexBuffer->IsVerticesDynamic())
	{
		CVertex1TexSCSP* pVertices = reinterpret_cast<CVertex1TexSCSP*>(pVertexBuffer->GetDynamicVertices());
		assert(pVertices);

		float fRadius = (m_uiDiameter * 0.5f) + 0.5f;	// + 0.5f for rasterisation rules.

		pVertices[0].SetPos(m_fDrawPositionX - fRadius, m_fDrawPositionY - fRadius);
		pVertices[1].SetPos(m_fDrawPositionX + fRadius, m_fDrawPositionY - fRadius);
		pVertices[2].SetPos(m_fDrawPositionX - fRadius, m_fDrawPositionY + fRadius);
		pVertices[3].SetPos(m_fDrawPositionX + fRadius, m_fDrawPositionY + fRadius);

		pVertexBuffer->UpdateDynamicVertices();
	}

	// Set the texture to render with.
	m_pRenderer->GetTextureManager().SetTexture(m_iFinalTextureID);

	// Render the quad.
	EnsureTexturedAlphaBlending();

	pVertexBuffer->Render(m_pRenderer->GetDeviceManager());
}
Esempio n. 2
0
/**
*
* ITS = Into Target Surface (render target).
* The icons for each button are drawn into the render target surface.
*
* @author Jade Abbott
* @return Void.
*
*/
void
CRadialMenu::DrawIconsITS()
{
	assert(m_pRenderer);
	assert(m_ucNumButtons);

	if (m_arrButtonData)
	{
		if (m_uiVertexBufferQuadID != Utility::INVALID_ID)
		{
			CVertexBuffer* pBuffer = m_pRenderer->GetVertexBufferManager().GetVertexBuffer(m_uiVertexBufferQuadID);
			assert(pBuffer);

			if (pBuffer->IsVerticesDynamic())
			{
				CVertex1TexSCSP* pVertices = reinterpret_cast<CVertex1TexSCSP*>(pBuffer->GetDynamicVertices());
				assert(pVertices);

				CTextureManager& rTextureManager = m_pRenderer->GetTextureManager();
				CDeviceManager& rDeviceManager = m_pRenderer->GetDeviceManager();
				PrepareDeviceData(true);
				EnsureTexturedAlphaBlending();
				rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x0);
				
				float fAngle = (2.0f * MathUtility::PI) / m_ucNumButtons;
				float fRadius = m_uiDiameter * 0.5f;
				float fHalfScale = m_uiDiameter * 0.0625f;	// If diameter is 512, this equals 32 (for 64x64 images).

				for (unsigned char uc = 0; uc < m_ucNumButtons; ++uc)
				{
					if (m_arrButtonData[uc].m_pkReferenceData)
					{
						if (m_arrButtonData[uc].m_pkReferenceData->m_iIconTextureID != Utility::INVALID_ID)
						{
							float fDistance = m_fInnerRadius + ((fRadius - m_fInnerRadius) * 0.5f);
							float fPosX = fRadius + (cosf((fAngle * uc) + (fAngle * 0.5f)) * fDistance);
							float fPosY = fRadius - (sinf((fAngle * uc) + (fAngle * 0.5f)) * fDistance);

							pVertices[0].SetPos(fPosX - fHalfScale, fPosY - fHalfScale);
							pVertices[1].SetPos(fPosX + fHalfScale, fPosY - fHalfScale);
							pVertices[2].SetPos(fPosX - fHalfScale, fPosY + fHalfScale);
							pVertices[3].SetPos(fPosX + fHalfScale, fPosY + fHalfScale);

							rTextureManager.SetTexture(m_arrButtonData[uc].m_pkReferenceData->m_iIconTextureID);

							pBuffer->UpdateDynamicVertices();
							pBuffer->Render(rDeviceManager);
						}
					}
				}
			}
		}
	}
}
Esempio n. 3
0
// ***************************************************************************
void		CFarVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb, bool forVertexProgram)
{
	VertexFormat= vb.getVertexFormat();
	VertexSize= vb.getVertexSize();
	NumVertices= vb.getNumVertices();

	if(NumVertices==0)
	{
		setupNullPointers();
		return;
	}

	vb.lock (Accessor);
	VertexCoordPointer = Accessor.getVertexCoordPointer();

	if(forVertexProgram)
	{
		// With VertexCoordPointer setuped, init for VP.
		TexCoordOff0= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_TEX0);				// v[8]= Tex0.
		TexCoordOff1= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_TEX1);				// v[9]= Tex1.
		GeomInfoOff= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO);			// v[10]= GeomInfos.
		DeltaPosOff= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS);			// v[11]= EndPos-StartPos
		// Init Alpha Infos only if enabled (enabled if Value 5 are).
		AlphaInfoOff= 0;
		if( vb.getVertexFormat() & (1<<NL3D_LANDSCAPE_VPPOS_ALPHAINFO) )
			AlphaInfoOff= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_ALPHAINFO);		// v[12]= AlphaInfos

		// update Ptrs.
		setupPointersForVertexProgram();
	}
	else
	{
		TexCoordOff0= vb.getTexCoordOff(0);
		TexCoordOff1= vb.getTexCoordOff(1);
		TexCoordPointer0= Accessor.getTexCoordPointer(0, 0);
		TexCoordPointer1= Accessor.getTexCoordPointer(0, 1);

		// In Far0, we don't have Color component.
		if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
		{
			ColorOff= vb.getColorOff();
			// todo hulud d3d vertex color RGBA / BGRA
			ColorPointer= Accessor.getColorPointer();
		}
		else
		{
			ColorOff= 0;
			ColorPointer= NULL;
		}
	}

}
Esempio n. 4
0
	// -----------------------------------------------------
	void CGraphicsRenderer::RenderScene()
	{
		// render scene to diffuse RT
		CRenderer::cGraphicsDevice()->BeginRendering(1, m_mrt_diffuse);
		//CRenderer::cGraphicsDevice()->Clear(ColorRGB(0,1,1));

		for (unsigned int i=0; i<m_chunks.Size(); i++)
		{
			const GeometryChunk& chunk = m_chunks[i];

			CIndexBuffer* ib = CRenderer::cGraphicsManager()->GetCachedIndexBuffer(chunk.Data->ibId);
			CVertexBuffer* vb = CRenderer::cGraphicsManager()->GetCachedVertexBuffer(chunk.Data->vbId);

			ib->Use();
			vb->Use();

			// OPTIM: if we ensure valid pointer every time, remove this if-s
			if (chunk.Subset->materialPtr)
			{
				CShader *vs = (CShader*)chunk.Subset->materialPtr->vsPtr;
				CShader *ps = (CShader*)chunk.Subset->materialPtr->psPtr;

				if (ps) 
					ps->Use();

				if (vs)
				{
					vs->Use();
				}
			}


			vb->RenderIndexed(P3DPT_TRIANGLELIST, chunk.Subset->StartIndex, chunk.Subset->NumTriangles);
			
		}

		CRenderer::cGraphicsDevice()->EndRendering();

		// render diffuse RT on standard backbuffer
		CRenderer::cGraphicsDevice()->BeginRendering();
			
			CRenderer::cPrimitiveRenderer()->AddRectangleRel(Vec2(0.0f, 0.0f), Vec2(1.0f, -1.0f), ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f), m_mrt_diffuse);
			CRenderer::cPrimitiveRenderer()->Render();

		CRenderer::cGraphicsDevice()->EndRendering();
	}
Esempio n. 5
0
/**
*
* ITS = Into Target Surface (render target).
* The radiant light surface is drawn into the render target surface, using the stencil surface for masking.
* m_ucButtonSelected is then highlighted (Utility::INVALID_ID highlights the centre).
*
* @author Jade Abbott
* @return Void.
*
*/ 
void
CRadialMenu::DrawRadianceITS()
{
	assert(m_pRenderer);
	assert(m_uiVertexBufferQuadID != Utility::INVALID_ID);

	// Replace the backbuffer with the Radial Menu's render target and stencil, disabling Z-buffer and enabling stencil.
	PrepareDeviceData(true);

	CDeviceManager& rDeviceManager = m_pRenderer->GetDeviceManager();

	// Set render states that will prevent drawing of the radiant light where the stencil has been marked out.
	rDeviceManager.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER);	// Greater is less, and less is greater (no friggin idea why).
	rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x2);	// When less than 0x2...
	rDeviceManager.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);	// Do not edit stencil, just draw.

	// Render the radiant light surface on to the back buffer.
	m_pRenderer->GetTextureManager().SetTexture(m_iRadiantTextureID);	// Set the texture to the radiant light.

	CVertexBufferManager& rBufferManager = m_pRenderer->GetVertexBufferManager();

	CVertexBuffer* pBuffer = rBufferManager.GetVertexBuffer(m_uiVertexBufferQuadID);	// Get the dynamic quad mesh.
	if (pBuffer)
	{
		if (pBuffer->IsVerticesDynamic())
		{
			// Update the position of each vertex in the mesh.
			CVertex1TexSCSP* pVertices = reinterpret_cast<CVertex1TexSCSP*>(pBuffer->GetDynamicVertices());

			// Rasterisation rules require minimum values have 0.5 subtracted, and maximum values have 0.5 added.
			float fDiameter = static_cast<float>(m_uiDiameter) + 0.5f;
			pVertices[0].SetPos(-0.5f, -0.5f);
			pVertices[1].SetPos(fDiameter, -0.5f);
			pVertices[2].SetPos(-0.5f, fDiameter);
			pVertices[3].SetPos(fDiameter, fDiameter);

			pBuffer->UpdateDynamicVertices();	// Will update the mesh only when necessary.
		}

		rDeviceManager.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);	// Have the radiant light replace the entire image.

		rBufferManager.Render(m_uiVertexBufferQuadID);
	}
}
Esempio n. 6
0
	// -----------------------------------------------------
	void CGraphicsRenderer::RenderScene(sFrameBufferUnit *FBUnits, UINT numUnits)
	{
		if(FBUnits != NULL) 
		{
			//TODO: setup the appropriate render targets
			CRenderer::cGraphicsDevice()->BeginRendering(1, m_mrt_diffuse);
			//CRenderer::cGraphicsDevice()->Clear(ColorRGB(0,1,1));
		}
		else CRenderer::cGraphicsDevice()->BeginRendering(); //render to back buffer

		for (unsigned int i=0; i<m_chunks.Size(); i++)
		{
			const GeometryChunk& chunk = m_chunks[i];

			CIndexBuffer* ib = CRenderer::cGraphicsManager()->GetCachedIndexBuffer(chunk.Data->ibId);
			CVertexBuffer* vb = CRenderer::cGraphicsManager()->GetCachedVertexBuffer(chunk.Data->vbId);

			ib->Use();
			vb->Use();

			// OPTIM: if we ensure valid pointer every time, remove this if-s
			if (chunk.Subset->materialPtr)
			{
				CShader *vs = (CShader*)chunk.Subset->materialPtr->vsPtr;
				CShader *ps = (CShader*)chunk.Subset->materialPtr->psPtr;

				if (ps) 
					ps->Use();

				if (vs)
				{
					vs->Use();
				}
			}


			vb->RenderIndexed(P3DPT_TRIANGLELIST, chunk.Subset->StartIndex, chunk.Subset->NumTriangles);

		}

		CRenderer::cGraphicsDevice()->EndRendering();

	}
Esempio n. 7
0
// ***************************************************************************
void		CNearVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb, bool forVertexProgram)
{
	VertexFormat= vb.getVertexFormat();
	VertexSize= vb.getVertexSize();
	NumVertices= vb.getNumVertices();

	if(NumVertices==0)
	{
		setupNullPointers();
		return;
	}

	vb.lock (Accessor);
	VertexCoordPointer= Accessor.getVertexCoordPointer();

	if(forVertexProgram)
	{
		// With VertexCoordPointer setuped, init for VP.
		TexCoordOff0= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_TEX0);				// v[8]= Tex0.
		TexCoordOff1= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_TEX1);				// v[9]= Tex1.
		TexCoordOff2= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_TEX2);				// v[13]= Tex1.
		GeomInfoOff= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO);			// v[10]= GeomInfos.
		DeltaPosOff= vb.getValueOffEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS);			// v[11]= EndPos-StartPos

		// update Ptrs.
		setupPointersForVertexProgram();
	}
	else
	{
		TexCoordPointer0= Accessor.getTexCoordPointer(0, 0);
		TexCoordPointer1= Accessor.getTexCoordPointer(0, 1);
		TexCoordPointer2= Accessor.getTexCoordPointer(0, 2);

		TexCoordOff0= vb.getTexCoordOff(0);
		TexCoordOff1= vb.getTexCoordOff(1);
		TexCoordOff2= vb.getTexCoordOff(2);
	}
}
Esempio n. 8
0
///////////////////////////////////////////////////////////////////////////////
// Allocate: try to allocate a buffer of given number of vertices (each of 
// given size), with the given type, and using the given texture - return null 
// if no free chunks available
CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore)
{
	CVertexBuffer::VBChunk* result=0;

	ENSURE(usage == GL_STREAM_DRAW || usage == GL_STATIC_DRAW || usage == GL_DYNAMIC_DRAW);

	ENSURE(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);

	if (CVertexBuffer::UseStreaming(usage))
		ENSURE(backingStore != NULL);

	// TODO, RC - run some sanity checks on allocation request

	typedef std::list<CVertexBuffer*>::iterator Iter;

#if DUMP_VB_STATS
	debug_printf("\n============================\n# allocate vsize=%d nverts=%d\n\n", vertexSize, numVertices);
	for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter) {
		CVertexBuffer* buffer = *iter;
		if (buffer->CompatibleVertexType(vertexSize, usage, target))
		{
			debug_printf("%p\n", buffer);
			buffer->DumpStatus();
		}
	}
#endif

	// iterate through all existing buffers testing for one that'll 
	// satisfy the allocation
	for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter) {
		CVertexBuffer* buffer = *iter;
		result = buffer->Allocate(vertexSize, numVertices, usage, target, backingStore);
		if (result)
			return result;
	}

	// got this far; need to allocate a new buffer
	CVertexBuffer* buffer = new CVertexBuffer(vertexSize, usage, target);
	m_Buffers.push_front(buffer);
	result = buffer->Allocate(vertexSize, numVertices, usage, target, backingStore);
	
	if (!result)
	{
		LOGERROR("Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices);
	}

	return result;
}
Esempio n. 9
0
// ---------------------------------------------------------------------------
void CBuilderZone::displayGrid (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax)
{
	// Select all blocks visible
	float rMinX = floorf (viewMin.x / _Display->_CellSize)*_Display->_CellSize;
	float rMinY = floorf (viewMin.y / _Display->_CellSize)*_Display->_CellSize;
	float rMaxX = ceilf  (viewMax.x / _Display->_CellSize)*_Display->_CellSize;
	float rMaxY = ceilf  (viewMax.y / _Display->_CellSize)*_Display->_CellSize;

	sint32 nMinX = (sint32)floor (rMinX / _Display->_CellSize);
	sint32 nMinY = (sint32)floor (rMinY / _Display->_CellSize);
	sint32 nMaxX = (sint32)floor (rMaxX / _Display->_CellSize);
	sint32 nMaxY = (sint32)floor (rMaxY / _Display->_CellSize);

	static vector<uint8> vBars;
	sint32 nBarsW = (nMaxX-nMinX)+1;
	sint32 nBarsH = (nMaxY-nMinY)+1;
	vBars.resize (nBarsW*nBarsH);
	sint32 x, y, i, j, zoneSelected;
	for (i = 0; i < nBarsW*nBarsH; ++i)
		vBars[i] = 0;


	for (y = nMinY; y <= nMaxY; ++y)
	for (x = nMinX; x <= nMaxX; ++x)
	{

		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;
			}
		}


		//const string &sZone = _ZoneRegion.getName (x, y);
		CZoneBankElement *pZBE = _ZoneBank.getElementByZoneName (sZone);
		if (pZBE != NULL)
		if ((pZBE->getSizeX() > 1) || (pZBE->getSizeY() > 1))
		{
			const CZoneRegion *pSelected = &(getDocument ()->getZoneRegion (zoneSelected));
			sint32 sizeX = pZBE->getSizeX(), sizeY = pZBE->getSizeY();
			sint32 posX = pSelected->getPosX (x, y), posY = pSelected->getPosY (x, y);
			uint8 rot = pSelected->getRot (x, y);
			uint8 flip = pSelected->getFlip (x, y);
			sint32 deltaX, deltaY;
		
			if (flip == 0)
			{
				switch (rot)
				{
					case 0: deltaX = -posX; deltaY = -posY; break;
					case 1: deltaX = -(sizeY-1-posY); deltaY = -posX; break;
					case 2: deltaX = -(sizeX-1-posX); deltaY = -(sizeY-1-posY); break;
					case 3: deltaX = -posY; deltaY = -(sizeX-1-posX); break;
				}
			}
			else
			{
				switch (rot)
				{
					case 0: deltaX = -(sizeX-1-posX); deltaY = -posY; break;
					case 1: deltaX = -(sizeY-1-posY); deltaY = -(sizeX-1-posX); break;
					case 2: deltaX = -posX; deltaY = -(sizeY-1-posY); break;
					case 3: deltaX = -posY; deltaY = -posX; break;
				}
			}

			static SPiece sMask;
			sMask.Tab.resize (sizeX*sizeY);
			for(i = 0; i < sizeX*sizeY; ++i)
				sMask.Tab[i] = pZBE->getMask()[i];
			sMask.w = sizeX;
			sMask.h = sizeY;
			sMask.rotFlip (rot, flip);

			for (j = 0; j < sMask.h; ++j)
			for (i = 0; i < sMask.w; ++i)
			if (sMask.Tab[i+j*sMask.w])
			{
				if (((x+deltaX+i-nMinX)>=0) && ((x+deltaX+i-nMinX)<nBarsW) &&
					((y+deltaY+j-nMinY)>=0) && ((y+deltaY+j-nMinY)<nBarsH))
				{
					if ((i > 0) && (sMask.Tab[i-1+j*sMask.w]))
						vBars[x+deltaX+i-nMinX + (y+deltaY+j-nMinY)*nBarsW] |= 1;

					if ((j > 0) && (sMask.Tab[i+(j-1)*sMask.w]))
						vBars[x+deltaX+i-nMinX + (y+deltaY+j-nMinY)*nBarsW] |= 2;
				}
			}
		}
	}

	CVertexBuffer VB;
	CIndexBuffer PB;
	CMaterial Mat;

	Mat.initUnlit ();
	Mat.setBlend (false);
	VB.setVertexFormat (CVertexBuffer::PositionFlag);
	VB.setNumVertices ((nBarsW+1)*(nBarsH+1));
	CVertexBufferReadWrite vba;
	VB.lock (vba);
	
	for (y = nMinY; y <= nMaxY+1; ++y)
	for (x = nMinX; x <= nMaxX+1; ++x)
	{
		CVector pos;

		pos.x = (x*_Display->_CellSize - viewMin.x)/(viewMax.x-viewMin.x);
		pos.y = 0.0f;
		pos.z = (y*_Display->_CellSize - viewMin.y)/(viewMax.y-viewMin.y);
		vba.setVertexCoord (x-nMinX+(y-nMinY)*(nBarsW+1), pos);
	}

	PB.setNumIndexes (nBarsW*nBarsH*2*2);
	CIndexBufferReadWrite iba;
	PB.lock (iba);
	uint32 nNbLine = 0;
	for (y = 0; y < nBarsH; ++y)
	for (x = 0; x < nBarsW; ++x)
	{
		// Vertical Line ?
		if ((vBars[x+y*nBarsW] & 1) == 0)
		{
			iba.setLine (nNbLine*2, x+y*(nBarsW+1), x+(y+1)*(nBarsW+1));
			++nNbLine;
		}

		// Horizontal Line ?
		if ((vBars[x+y*nBarsW] & 2) == 0)
		{
			iba.setLine (nNbLine*2, x+y*(nBarsW+1), (x+1)+y*(nBarsW+1));
			++nNbLine;
		}
	}
	iba.unlock();
	PB.setNumIndexes (nNbLine*2);

	if (DontUse3D)
		return;

	// Render with driver
	CMatrix mtx;
	mtx.identity();
	vba.unlock();
	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);
	CNELU::Driver->activeVertexBuffer (VB);
	CNELU::Driver->activeIndexBuffer (PB);
	CNELU::Driver->renderLines (Mat, 0, PB.getNumIndexes()/2);
	
}
Esempio n. 10
0
// ---------------------------------------------------------------------------
void CBuilderZone::renderTransition (const NLMISC::CVector &viewMin, const NLMISC::CVector &viewMax)
{
	// Selected ?
	if (_ZoneRegionSelected != -1)
	{
		// Select all blocks visible
		float rMinX = floorf (viewMin.x / _Display->_CellSize)*_Display->_CellSize;
		float rMinY = floorf (viewMin.y / _Display->_CellSize)*_Display->_CellSize;
		float rMaxX = ceilf  (viewMax.x / _Display->_CellSize)*_Display->_CellSize;
		float rMaxY = ceilf  (viewMax.y / _Display->_CellSize)*_Display->_CellSize;

		sint32 nMinX = (sint32)floor (rMinX / _Display->_CellSize);
		sint32 nMinY = (sint32)floor (rMinY / _Display->_CellSize);
		sint32 nMaxX = (sint32)floor (rMaxX / _Display->_CellSize);
		sint32 nMaxY = (sint32)floor (rMaxY / _Display->_CellSize);

		CVertexBuffer VB , VBSel;
		CIndexBuffer PB, PBSel;
		CMaterial Mat, MatSel;

		Mat.initUnlit ();
		Mat.setBlend (false);
		MatSel.initUnlit ();
		MatSel.setBlend (false);
		MatSel.setColor(NLMISC::CRGBA(255,0,0,0));
		VB.setVertexFormat (CVertexBuffer::PositionFlag);
		VB.reserve ((nMaxX-nMinX+1)*(nMaxY-nMinY+1)*4*2);
		VBSel.setVertexFormat (CVertexBuffer::PositionFlag);
		VBSel.reserve ((nMaxX-nMinX+1)*(nMaxY-nMinY+1)*4*2);

		CVertexBufferReadWrite vba;
		VB.lock (vba);
		CVertexBufferReadWrite vbaSel;
		VBSel.lock (vbaSel);
		
		sint32 nVertCount = 0;
		sint32 nVertCountSel = 0;
		sint32 x, y, k;
		CVector worldPos, screenPos;
		for (y = nMinY; y <= nMaxY; ++y)
		for (x = nMinX; x <= nMaxX; ++x)
		{
			const CZoneRegion *pBZR = &(getDocument ()->getZoneRegion (_ZoneRegionSelected));
			uint8 ceUp = pBZR->getCutEdge (x, y, 0);
			uint8 ceLeft = pBZR->getCutEdge (x, y, 2);

			if ((ceUp > 0) && (ceUp < 3))
			for (k = 0; k < 2; ++k)
			{
				if (ceUp == 1)
					worldPos.x = x * _Display->_CellSize + 3.0f * _Display->_CellSize / 12.0f;
				else
					worldPos.x = x * _Display->_CellSize + 7.0f * _Display->_CellSize / 12.0f;
				worldPos.y = (y+1)*_Display->_CellSize + _Display->_CellSize / 12.0f;
				worldPos.z = 0;
				// World -> Screen conversion
				screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x);
				screenPos.y = 0.0f;
				screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				worldPos.y = (y+1)*_Display->_CellSize - _Display->_CellSize / 12.0f;
				screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				if (ceUp == 1)
					worldPos.x = x * _Display->_CellSize + 5.0f * _Display->_CellSize / 12.0f;
				else
					worldPos.x = x * _Display->_CellSize + 9.0f * _Display->_CellSize / 12.0f;
				screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				worldPos.y = (y+1)*_Display->_CellSize + _Display->_CellSize / 12.0f;
				screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}
				ceUp = 3 - ceUp;
			}

			if ((ceLeft > 0) && (ceLeft < 3))
			for (k = 0; k < 2; ++k)
			{
				worldPos.x = x * _Display->_CellSize - _Display->_CellSize / 12.0f;
				if (ceLeft == 1)
					worldPos.y = y * _Display->_CellSize + 3.0f * _Display->_CellSize / 12.0f;
				else
					worldPos.y = y * _Display->_CellSize + 7.0f * _Display->_CellSize / 12.0f;
				worldPos.z = 0;
				// World -> Screen conversion
				screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x);
				screenPos.y = 0.0f;
				screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				worldPos.x = x * _Display->_CellSize + _Display->_CellSize / 12.0f;
				screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				if (ceLeft == 1)
					worldPos.y = y * _Display->_CellSize + 5.0f * _Display->_CellSize / 12.0f;
				else
					worldPos.y = y * _Display->_CellSize + 9.0f * _Display->_CellSize / 12.0f;
				screenPos.z = (worldPos.y - viewMin.y) / (viewMax.y - viewMin.y);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}

				worldPos.x = x * _Display->_CellSize - _Display->_CellSize / 12.0f;
				screenPos.x = (worldPos.x - viewMin.x) / (viewMax.x - viewMin.x);
				if (k == 0)
				{
					vba.setVertexCoord (nVertCount, screenPos);
					++nVertCount;
				}
				else
				{
					vbaSel.setVertexCoord (nVertCountSel, screenPos);
					++nVertCountSel;
				}
				ceLeft = 3 - ceLeft;
			}
		}

		vba.unlock();
		VB.setNumVertices (nVertCount);
		PB.setNumIndexes (nVertCount*2);
		CIndexBufferReadWrite iba;
		PB.lock (iba);
		for (x = 0; x < (nVertCount/4); ++x)
		{
			iba.setLine (x*4+0, x*4+0, x*4+1);
			iba.setLine (x*4+1, x*4+1, x*4+2);
			iba.setLine (x*4+2, x*4+2, x*4+3);
			iba.setLine (x*4+3, x*4+3, x*4+0);
		}
		iba.unlock();

		vbaSel.unlock();
		VBSel.setNumVertices (nVertCountSel);
		PBSel.setNumIndexes (nVertCountSel*2);
		CIndexBufferReadWrite ibaSel;
		PBSel.lock (ibaSel);
		for (x = 0; x < (nVertCountSel/4); ++x)
		{
			ibaSel.setLine (x*4+0, x*4+0, x*4+1);
			ibaSel.setLine (x*4+1, x*4+1, x*4+2);
			ibaSel.setLine (x*4+2, x*4+2, x*4+3);
			ibaSel.setLine (x*4+3, x*4+3, x*4+0);
		}
		ibaSel.unlock();

		if (DontUse3D)
			return;

		// Render
		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);
		CNELU::Driver->activeVertexBuffer (VB);
		CNELU::Driver->activeIndexBuffer (PB);
		CNELU::Driver->renderLines (Mat, 0, PB.getNumIndexes()/2);
		CNELU::Driver->activeVertexBuffer (VBSel);
		CNELU::Driver->activeIndexBuffer (PBSel);
		CNELU::Driver->renderLines (MatSel, 0, PBSel.getNumIndexes()/2);
	}
}
Esempio n. 11
0
// ---------------------------------------------------------------------------
// main
// ---------------------------------------------------------------------------
int main(int nNbArg, char **ppArgs)
{
	
	if (nNbArg <3 || nNbArg >5)
	{
		outString ("ERROR : Wrong number of arguments\n");
		outString ("USAGE : lightmap_optimizer <path_lightmaps> <path_shapes> [path_tags] [path_flag8bit]\n");
		return -1;
	}
	
	vector<string> AllShapeNames;
	vector<CMeshBase*> AllShapes;
	std::vector<std::string> tags;	
	char sLMPDir[MAX_PATH];
	char sSHPDir[MAX_PATH];

	
	GetCurrentDirectory (MAX_PATH, sExeDir);

	
	// Get absolute directory for lightmaps
	if (!SetCurrentDirectory(ppArgs[1]))
	{
		outString (string("ERROR : directory ") + ppArgs[1] + " do not exists\n");
		return -1;
	}
	GetCurrentDirectory (MAX_PATH, sLMPDir);
	SetCurrentDirectory (sExeDir);
	// Get absolute directory for shapes
	if (!SetCurrentDirectory(ppArgs[2]))
	{
		outString (string("ERROR : directory ") + ppArgs[2] + " do not exists\n");
		return -1;
	}
	GetCurrentDirectory (MAX_PATH, sSHPDir);
	dir ("*.shape", AllShapeNames, false);
	registerSerial3d ();
	for (uint32 nShp = 0; nShp < AllShapeNames.size(); ++nShp)
	{
		try
		{
			CShapeStream mesh;
			NLMISC::CIFile meshfile (AllShapeNames[nShp]);
			meshfile.serial( mesh );
			meshfile.close();

			// Add the shape to the map.
			CMeshBase *pMB = dynamic_cast<CMeshBase*>(mesh.getShapePointer());
			AllShapes.push_back (pMB);
		}
		catch (NLMISC::EPathNotFound &e)
		{
			outString(string("ERROR: shape not found ")+AllShapeNames[nShp]+" - "+e.what());
			return -1;
		}
	}

	if (nNbArg > 3 && ppArgs[3] && strlen(ppArgs[3]) > 0)
	{
		SetCurrentDirectory (sExeDir);
		if (!SetCurrentDirectory(ppArgs[3]))
		{
			outString (string("ERROR : directory ") + ppArgs[3] + " do not exists\n");
			return -1;
		}
		dir ("*.tag", tags, false);
		for(uint k = 0; k < tags.size(); ++k)
		{
			std::string::size_type pos = tags[k].find('.');
			if (pos != std::string::npos)
			{
				tags[k] = tags[k].substr(0, pos);
			}
		}
	}


	// **** Parse all mesh loaded, to flag each lightmap if 8 bit or not (NB: all layers should be same mode)
	std::set<string>	setLM8Bit;
	for(uint i=0;i<AllShapes.size();i++)
	{
		CMeshBase *pMB= AllShapes[i];
		if(!pMB)
			continue;

		uint32		nbMat= pMB->getNbMaterial();
		for (uint32 m = 0; m < nbMat; ++m)
		{
			CMaterial& rMat = const_cast<CMaterial&>(pMB->getMaterial (m));
			if (rMat.getShader() == CMaterial::LightMap)
			{
				// Begin with stage 0
				uint8 stage = 0;
				while (rMat.getLightMap(stage) != NULL)
				{
					ITexture *pIT = rMat.getLightMap (stage);
					CTextureFile *pTF = dynamic_cast<CTextureFile*>(pIT);
					if (pTF != NULL)
					{
						string sTexName = NLMISC::strlwr(pTF->getFileName());
						if(pTF->getUploadFormat()==ITexture::Luminance)
							setLM8Bit.insert(sTexName);
					}
					++stage;
				}
			}
		}
	}


	// **** Parse all lightmaps, sorted by layer, and 8 or 16 bit mode
	SetCurrentDirectory (sExeDir);
	for (uint32 lmc8bitMode = 0; lmc8bitMode < 2; ++lmc8bitMode)
	for (uint32 nNbLayer = 0; nNbLayer < 256; ++nNbLayer)
	{
		// Get all lightmaps with same number of layer == nNbLayer
		// merge lightmaps only if they are in same mode (8bits or 16 bits)

		vector<string> AllLightmapNames;
		vector<sint>   AllLightmapTags;
		vector<NLMISC::CBitmap*> AllLightmaps;
		sint32 i, j, k, m, n;
		string sFilter;

		// **** Get All Lightmaps that have this number of layer, and this mode
		sFilter = "*_" + NLMISC::toString(nNbLayer) + ".tga";
		SetCurrentDirectory (sLMPDir);
		dir (sFilter, AllLightmapNames, false);

		// filter by layer
		vector<string>		tmpLMs;
		tmpLMs.reserve(AllLightmapNames.size());
		for (i = 0; i < (sint32)AllLightmapNames.size(); ++i)
		{
			string sTmp2 = getBaseName (AllLightmapNames[i]);
			sTmp2 += NLMISC::toString(nNbLayer+1) + ".tga";
			// if not More layer than expected, ok
			if (!fileExist(sTmp2))
			{	
				tmpLMs.push_back(AllLightmapNames[i]);
			}
		}
		AllLightmapNames= tmpLMs;
	
		// filter by 8bit or not mode.
		tmpLMs.clear();
		for (i = 0; i < (sint32)AllLightmapNames.size(); ++i)
		{
			bool	lm8Bit= setLM8Bit.find( NLMISC::strlwr(AllLightmapNames[i]) ) !=setLM8Bit.end();
			// if same mode
			if( lm8Bit == (lmc8bitMode==1) )
			{
				tmpLMs.push_back(AllLightmapNames[i]);
			}
		}
		AllLightmapNames= tmpLMs;

		
		// **** Build tag info
		/*
		for(uint k = 0; k < tags.size(); ++k)
		{
			nlinfo("tag %d = %s", (int) k, tags[k].c_str());
		}
		*/
		AllLightmapTags.resize(AllLightmapNames.size());
		for(uint k = 0; k < AllLightmapNames.size(); ++k)
		{
			nlinfo("k = %d", (int) k);
			AllLightmapTags[k] = -1;
			// search for longest tag that match
			uint bestLength = 0;
			for(uint l = 0; l < tags.size(); ++l)
			{
				if (AllLightmapNames[k].size() > tags[l].size())
				{
					if (tags[l].size() > bestLength)
					{					
						std::string start = AllLightmapNames[k].substr(0, tags[l].size());
						if (NLMISC::nlstricmp(start, tags[l]) == 0)
						{
							bestLength = (uint)tags[l].size();
							// the tag matchs
							AllLightmapTags[k] = l;						
						}
					}
				}
			}						
			if (AllLightmapTags[k] == -1)
			{
				nlinfo(NLMISC::toString("Lightmap %s has no tag", AllLightmapNames[k].c_str()).c_str());
			}
			else
			{			
				nlinfo(NLMISC::toString("Lightmap %s has tag %d : %s", AllLightmapNames[k].c_str(), (int) AllLightmapTags[k], tags[AllLightmapTags[k]].c_str()).c_str());
			}			
		}




		// Check if all layer of the same lightmap has the same size
		if (nNbLayer > 0)
		for (i = 0; i < (sint32)AllLightmapNames.size(); ++i)
		{
			string sTmp2;
			sTmp2 = getBaseName (AllLightmapNames[i]) + "0.tga";
			uint32 wRef, hRef;
			try
			{
				NLMISC::CIFile inFile;
				inFile.open(sTmp2);
				CBitmap::loadSize(inFile, wRef, hRef);
			}
			catch (NLMISC::Exception &e)
			{
				outString (string("ERROR :") + e.what());
				return -1;
			}

			bool bFound = false;
			for (k = 1; k <= (sint32)nNbLayer; ++k)
			{
				string sTmp3 = getBaseName (AllLightmapNames[i]) + NLMISC::toString(k) + ".tga";
				uint32 wCur = wRef, hCur = hRef;
				try
				{
					NLMISC::CIFile inFile;
					inFile.open(sTmp3);
					CBitmap::loadSize(inFile, wCur, hCur);
				}
				catch (NLMISC::Exception &)
				{
				}

				if ((wCur != wRef) || (hCur != hRef))
				{
					bFound = true;
					break;
				}
			}
			// Should delete all layers of this lightmap (in fact in lightmapnames list we have
			// only the name of the current layer)
			if (bFound)
			{
				sTmp2 = getBaseName (AllLightmapNames[i]);
				outString(string("ERROR: lightmaps ")+sTmp2+"*.tga not all the same size\n");
				for (k = 0; k < (sint32)AllLightmapNames.size(); ++k)
				{
					if (strnicmp(AllLightmapNames[k].c_str(), sTmp2.c_str(), sTmp2.size()) == 0)
					{
						for (j = k+1; j < (sint32)AllLightmapNames.size(); ++j)
						{
							AllLightmapNames[j-1] = AllLightmapNames[j];
							AllLightmapTags[j - 1] = AllLightmapTags[j];
						}
						AllLightmapNames.resize (AllLightmapNames.size()-1);
						AllLightmapTags.resize(AllLightmapTags.size()  - 1);
						k = -1;
						i = -1;
					}
				}
			}
		}
		
		if (AllLightmapNames.size() == 0)
			continue;
		
		// Load all the lightmaps
		AllLightmaps.resize (AllLightmapNames.size());
		for (i = 0; i < (sint32)AllLightmaps.size(); ++i)
		{
			try
			{
				NLMISC::CBitmap *pBtmp = new NLMISC::CBitmap;
				NLMISC::CIFile inFile;
				inFile.open(AllLightmapNames[i]);
				pBtmp->load(inFile);
				AllLightmaps[i] = pBtmp;
			}
			catch (NLMISC::Exception &e)
			{
				outString (string("ERROR :") + e.what());
				return -1;
			}
		}

		// Sort all lightmaps by decreasing size
		for (i = 0; i < (sint32)(AllLightmaps.size()-1); ++i)
		for (j = i+1; j < (sint32)AllLightmaps.size(); ++j)
		{
			NLMISC::CBitmap *pBI = AllLightmaps[i];
			NLMISC::CBitmap *pBJ = AllLightmaps[j];
			if ((pBI->getWidth()*pBI->getHeight()) < (pBJ->getWidth()*pBJ->getHeight()))
			{
				NLMISC::CBitmap *pBTmp = AllLightmaps[i];
				AllLightmaps[i] = AllLightmaps[j];
				AllLightmaps[j] = pBTmp;

				string sTmp = AllLightmapNames[i];
				AllLightmapNames[i] = AllLightmapNames[j];
				AllLightmapNames[j] = sTmp;

				sint tagTmp = AllLightmapTags[i];
				AllLightmapTags[i] = AllLightmapTags[j];
				AllLightmapTags[j] = tagTmp;
			}
		}
		nlassert(AllLightmapTags.size() == AllLightmapNames.size());
		for (i = 0; i < (sint32)AllLightmapNames.size(); ++i)
		{
			outString(NLMISC::toString("%d / %d\n", (int) i, (int) AllLightmapNames.size()));
			bool bAssigned = false;
			for (j = 0; j < i; ++j)
			{				
				// Tags of both textures must match. We don't want to spread lightmap chunk in bitmap whose other part aren't used by current ig lightmaps (this wastes vram for nothing)
				if (AllLightmapTags[i] != AllLightmapTags[j]) continue;

				// Try to place the texture i into the texture j
				// This can be done only if texture was exported from the same zone. To ensure that, check 
				NLMISC::CBitmap *pBI = AllLightmaps[i];
				NLMISC::CBitmap *pBJ = AllLightmaps[j];
				sint32 x, y;
				if (tryAllPos (pBI, pBJ, x, y))
				{
					bAssigned = true;

					if (!putIn (pBI, pBJ, x, y))
					{
						outString (string("ERROR : cannot put reference lightmap ")+AllLightmapNames[i]+
									" in "+AllLightmapNames[j]);
						return -1;
					}
					// Put texture i into texture j for all layers of the lightmap !
					for (k = 0; k <= (sint32)nNbLayer; ++k)
					{
						string sTexNameI = getBaseName (AllLightmapNames[i]) + NLMISC::toString(k) + ".tga";
						string sTexNameJ = getBaseName (AllLightmapNames[j]) + NLMISC::toString(k) + ".tga";
						NLMISC::CBitmap BitmapI;
						NLMISC::CBitmap BitmapJ;
						NLMISC::CIFile inFile;

						outString (NLMISC::toString("INFO : Transfering %s (tag = %d) in %s (tag = %d)", 
													sTexNameI.c_str(), (int) AllLightmapTags[i],
													sTexNameJ.c_str(), (int) AllLightmapTags[j]) +
													" at ("+NLMISC::toString(x)+","+NLMISC::toString(y)+")\n");

						try
						{
							inFile.open (sTexNameI);
							BitmapI.load (inFile);
							inFile.close ();
							inFile.open (sTexNameJ);
							BitmapJ.load (inFile);
							inFile.close ();
						}
						catch (NLMISC::Exception &e)
						{
							outString (string("ERROR :") + e.what());
							return -1;
						}
						
						if (!putIn (&BitmapI, &BitmapJ, x, y))
						{
							outString (string("ERROR : cannot put lightmap ")+sTexNameI+" in "+sTexNameJ+"\n");
							return -1;
						}

						// Delete File
						DeleteFile (sTexNameI.c_str());
						outString (string("INFO : Deleting file ")+sTexNameI+"\n");

						// Save destination image
						NLMISC::COFile outFile;
						outFile.open (sTexNameJ);
						BitmapJ.writeTGA (outFile, 32);
						outString (string("INFO : Saving file ")+sTexNameJ+"\n");
					}

					// Change shapes uvs related and names to the lightmap
					// ---------------------------------------------------

					SetCurrentDirectory (sSHPDir);

					for (k = 0; k < (sint32)AllShapes.size(); ++k)
					{
						CMeshBase *pMB = AllShapes[k];
						if (!pMB)
							continue;

						uint nNbMat = pMB->getNbMaterial ();
						vector< vector<bool> > VerticesNeedRemap;
						bool bMustSave = false;
						// Initialize all VerticesNeedRemap
						CMesh *pMesh = dynamic_cast<CMesh*>(pMB);
						CMeshMRM *pMeshMRM = dynamic_cast<CMeshMRM*>(pMB);
						CMeshMultiLod *pMeshML = dynamic_cast<CMeshMultiLod*>(pMB);

						if (pMesh != NULL)
						{
							VerticesNeedRemap.resize(1); // Only one meshgeom
							vector<bool> &rVNR = VerticesNeedRemap[0];
							rVNR.resize (pMesh->getMeshGeom().getVertexBuffer().getNumVertices(), false);
						}
						else if (pMeshMRM != NULL)
						{
							VerticesNeedRemap.resize(1); // Only one meshmrmgeom
							vector<bool> &rVNR = VerticesNeedRemap[0];
							rVNR.resize (pMeshMRM->getMeshGeom().getVertexBuffer().getNumVertices(), false);
						}
						else if (pMeshML != NULL)
						{
							sint32 nNumSlot = pMeshML->getNumSlotMesh();
							VerticesNeedRemap.resize(nNumSlot);
							for (m = 0; m < nNumSlot; ++m)
							{
								vector<bool> &rVNR = VerticesNeedRemap[m];
								const CMeshGeom *pMG = dynamic_cast<const CMeshGeom*>(&pMeshML->getMeshGeom(m));
								if (pMG != NULL)
									rVNR.resize (pMG->getVertexBuffer().getNumVertices(), false);
								else
									rVNR.resize(0);
							}
						}
						else continue; // Next mesh
						

						// All materials must have the lightmap names changed
						for (m = 0; m < (sint32)nNbMat; ++m)
						{
							bool bMustRemapUV = false;
							CMaterial& rMat = const_cast<CMaterial&>(pMB->getMaterial (m));
							if (rMat.getShader() == CMaterial::LightMap)
							{
								// Begin with stage 0
								uint8 stage = 0;
								while (rMat.getLightMap(stage) != NULL)
								{
									ITexture *pIT = rMat.getLightMap (stage);
									CTextureFile *pTF = dynamic_cast<CTextureFile*>(pIT);
									if (pTF != NULL)
									{
										string sTexName = NLMISC::strlwr(getBaseName(pTF->getFileName()));
										string sTexNameMoved = NLMISC::strlwr(getBaseName(AllLightmapNames[i]));
										if (sTexName == sTexNameMoved)
										{
											// We must remap the name and indicate to remap uvs
											bMustRemapUV = true;
											//string sNewTexName = NLMISC::strlwr(getBaseName(AllLightmapNames[j]));
											//sNewTexName += NLMISC::toString(getLayerNb(pTF->getFileName())) + ".tga";
											//pTF->setFileName (sNewTexName);
										}
									}
									++stage;
								}
							}
							// We have to remap the uvs of this mesh for this material
							if (bMustRemapUV) // Flaggage of the vertices to remap
							{
								if (pMesh != NULL)
								{
									// Flag all vertices linked to face with material m
									FlagVertices (const_cast<CMeshGeom&>(pMesh->getMeshGeom()), m, VerticesNeedRemap[0]);
								}
								else if (pMeshMRM != NULL)
								{
									FlagVerticesMRM (const_cast<CMeshMRMGeom&>(pMeshMRM->getMeshGeom()), m, VerticesNeedRemap[0]);
								}
								else if (pMeshML != NULL)
								{
									sint32 nNumSlot = pMeshML->getNumSlotMesh();
									for (n = 0; n < nNumSlot; ++n)
									{
										// Get the mesh geom
										CMeshGeom *pMG = const_cast<CMeshGeom*>(dynamic_cast<const CMeshGeom*>(&pMeshML->getMeshGeom(n)));
										if (pMG)
										{
											// Flag the vertices
											FlagVertices (*pMG, m, VerticesNeedRemap[n]);
										}
										else
										{
											// Get the mesh MRM geom
											CMeshMRMGeom *pMMRMG = const_cast<CMeshMRMGeom*>(dynamic_cast<const CMeshMRMGeom*>(&pMeshML->getMeshGeom(n)));
											if (pMMRMG)
											{
												// Flag the vertices
												FlagVerticesMRM (*pMMRMG, m, VerticesNeedRemap[n]);
											}
										}
									}
								}
							}
						}

						// Change lightmap names
						for (m = 0; m < (sint32)nNbMat; ++m)
						{
							CMaterial& rMat = const_cast<CMaterial&>(pMB->getMaterial (m));
							if (rMat.getShader() == CMaterial::LightMap)
							{
								// Begin with stage 0
								uint8 stage = 0;
								while (rMat.getLightMap(stage) != NULL)
								{
									ITexture *pIT = rMat.getLightMap (stage);
									CTextureFile *pTF = dynamic_cast<CTextureFile*>(pIT);
									if (pTF != NULL)
									{
										string sTexName = NLMISC::strlwr(getBaseName(pTF->getFileName()));
										string sTexNameMoved = NLMISC::strlwr(getBaseName(AllLightmapNames[i]));
										if (sTexName == sTexNameMoved)
										{
											string sNewTexName = NLMISC::strlwr(getBaseName(AllLightmapNames[j]));
											sNewTexName += NLMISC::toString(getLayerNb(pTF->getFileName())) + ".tga";
											pTF->setFileName (sNewTexName);
										}
									}
									++stage;
								}
							}
						}

						// We have now the list of vertices to remap for all material that have been changed
						// So parse this list and apply the transformation : (uv * TexSizeI + decalXY) / TexSizeJ
						for (m = 0; m < (sint32)VerticesNeedRemap.size(); ++m)
						{
							CVertexBuffer *pVB;							
							if (pMesh != NULL)
							{
								pVB = const_cast<CVertexBuffer*>(&pMesh->getMeshGeom().getVertexBuffer());
							}
							else if (pMeshMRM != NULL)
							{
								pVB = const_cast<CVertexBuffer*>(&pMeshMRM->getMeshGeom().getVertexBuffer());
							}
							else if (pMeshML != NULL)
							{
								const CMeshGeom *pMG = dynamic_cast<const CMeshGeom*>(&pMeshML->getMeshGeom(m));
								pVB = const_cast<CVertexBuffer*>(&pMG->getVertexBuffer());
							}
							CVertexBufferReadWrite vba; 
							pVB->lock (vba);

							vector<bool> &rVNR = VerticesNeedRemap[m];
							for (n = 0; n < (sint32)rVNR.size(); ++n)
							if (rVNR[n])
							{
								CUV *pUV = (CUV*)vba.getTexCoordPointer (n,1);
								pUV->U = (pUV->U*pBI->getWidth() + x) / pBJ->getWidth();
								pUV->V = (pUV->V*pBI->getHeight() + y) / pBJ->getHeight();
								bMustSave = true;
							}
						}

						if (bMustSave)
						{
							try
							{
								if (AllShapes[k])
								{
									CShapeStream mesh;
									mesh.setShapePointer (AllShapes[k]);
									NLMISC::COFile meshfile (AllShapeNames[k]);
									meshfile.serial (mesh);
									meshfile.close ();
								}
							}
							catch (NLMISC::EPathNotFound &e)
							{
								outString(string("ERROR: cannot save shape ")+AllShapeNames[k]+" - "+e.what());
								return -1;
							}
						}
					}

					SetCurrentDirectory (sLMPDir);

					// Get out of the j loop
					break;
				}
			}		
			// if assigned to another bitmap -> delete the bitmap i
			if (bAssigned)
			{
				// Delete Names && tags
				for (j = i+1; j < (sint32)AllLightmapNames.size(); ++j)
				{
					AllLightmapNames[j-1] = AllLightmapNames[j];
					AllLightmapTags[j-1] = AllLightmapTags[j];
				}
				AllLightmapNames.resize (AllLightmapNames.size()-1);
				AllLightmapTags.resize (AllLightmapTags.size()-1);
				// Delete Lightmaps
				delete AllLightmaps[i];
				for (j = i+1; j < (sint32)AllLightmaps.size(); ++j)
					AllLightmaps[j-1] = AllLightmaps[j];
				AllLightmaps.resize (AllLightmaps.size()-1);
				i = i - 1;
			}
		}

	}
	

	// **** Additionally, output or clear a "flag file" in a dir to info if a 8bit lihgtmap or not
	if (nNbArg >=5 && ppArgs[4] && strlen(ppArgs[4]) > 0)
	{
		SetCurrentDirectory (sExeDir);

		// out a text file, with list of
		FILE	*out= fopen(ppArgs[4], "wt");
		if(!out)
		{
			outString(string("ERROR: cannot save ")+ppArgs[4]);
		}

		set<string>::iterator	it(setLM8Bit.begin()), end(setLM8Bit.end());
		for(;it!=end;it++)
		{
			string	temp= (*it);
			temp+= "\n";
			fputs(temp.c_str(), out);
		}

		fclose(out);
	}

	return 0;
}
Esempio n. 12
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. 13
0
/*********************************************************\
					displayOrientation()
\*********************************************************/
void displayOrientation()
{
	float x = 0.9f*4.f/3.f;
	float y = 0.1f;
	float radius = 0.015f;

	// Triangle
	CMaterial mat;
	mat.initUnlit();
	mat.setSrcBlend(CMaterial::srcalpha);
	mat.setDstBlend(CMaterial::invsrcalpha);
	mat.setBlend(true);
	
	CVertexBuffer vb;
	vb.setVertexFormat (CVertexBuffer::PositionFlag);
	vb.setNumVertices (7);
	{
		CVertexBufferReadWrite vba;
		vb.lock(vba);
		
		// tri
		vba.setVertexCoord (0, CVector (-radius, 0, 0));
		vba.setVertexCoord (1, CVector (radius, 0, 0));
		vba.setVertexCoord (2, CVector (0, 0, 3*radius));

		// quad
		vba.setVertexCoord (3, CVector (-radius, 0, -radius));
		vba.setVertexCoord (4, CVector (radius, 0, -radius));
		vba.setVertexCoord (5, CVector (radius, 0, radius));
		vba.setVertexCoord (6, CVector (-radius, 0, radius));
	}
	
	CNELU::Driver->activeVertexBuffer(vb);

	CIndexBuffer pbTri;
	pbTri.setNumIndexes (3);
	{
		CIndexBufferReadWrite iba;
		pbTri.lock (iba);
		iba.setTri (0, 0, 1, 2);
	}
	
	CIndexBuffer pbQuad;
	pbQuad.setNumIndexes (6);
	{
		CIndexBufferReadWrite iba;
		pbQuad.lock(iba);
		iba.setTri (0, 3, 4, 5);
		iba.setTri (3, 5, 6, 3);
	}
	
	CNELU::Driver->setFrustum (0.f, 4.f/3.f, 0.f, 1.f, -1.f, 1.f, false);
	CMatrix mtx;
	mtx.identity();
	CNELU::Driver->setupViewMatrix (mtx);

	mat.setColor(CRGBA(50,255,255,150));

	// up
	mtx.identity();
	mtx.translate(CVector(x,0,y));
	mtx.rotateY(MoveListener.getRotZ() );
	mtx.translate(CVector(0,0,radius));
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->activeVertexBuffer(vb);
	CNELU::Driver->activeIndexBuffer(pbTri);
	CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3);

	mat.setColor(CRGBA(50,50,255,150));

	// down
	mtx.identity();
	mtx.translate(CVector(x,0,y));
	mtx.rotateY(MoveListener.getRotZ() + (float)Pi);
	mtx.translate(CVector(0,0,radius));
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3);

	// left
	mtx.identity();
	mtx.translate(CVector(x,0,y));
	mtx.rotateY(MoveListener.getRotZ() - (float)Pi/2);
	mtx.translate(CVector(0,0,radius));
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3);

	// right
	mtx.identity();
	mtx.translate(CVector(x,0,y));
	mtx.rotateY(MoveListener.getRotZ() + (float)Pi/2);
	mtx.translate(CVector(0,0,radius));
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->renderTriangles(mat, 0, pbTri.getNumIndexes()/3);
	
	// center
	mtx.identity();
	mtx.translate(CVector(x,0,y));
	mtx.rotateY(MoveListener.getRotZ());
	CNELU::Driver->setupModelMatrix (mtx);
	CNELU::Driver->activeIndexBuffer(pbQuad);
	CNELU::Driver->renderTriangles(mat, 0, pbQuad.getNumIndexes()/3);	
}
Esempio n. 14
0
/**
*
* Sets up the stencil for the number of buttons provided.
* Should only be called in Draw().
* Invalidates the render target surface, as redrawing with the new stencil will not overwrite all of the old image.
*
* @author Jade Abbott
* @return Void.
*
*/
void
CRadialMenu::AssembleStencil()
{
	assert(m_ucNumButtons);	// Must be non-zero.
	assert(m_pLine);
	assert(m_pRenderer);
	assert(m_uiNumLineVertices >= 2);
	assert(m_pLineVertices);
	assert(m_ucFlags & FLG_RAD_REDOSTENCIL);	// Should only be called when the stencil needs updating.

	m_ucFlags = m_ucFlags ^ FLG_RAD_REDOSTENCIL;	// Turn off flag.

	// Set the render target, stencil surface, and render states.
	PrepareDeviceData(true);
	
	// Clear all surfaces, as a change in stencil requires a redraw of everything.
	CDeviceManager& rDeviceManager = m_pRenderer->GetDeviceManager();
	rDeviceManager.DeviceClear(true, false, true, 0x00000000, 0.0f, 0);

	rDeviceManager.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);	// Always...
	rDeviceManager.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);	// Replace the existing stencil values.
	
	const float kfFraction((2.0f * MathUtility::PI) / (m_uiNumLineVertices - 1));	// m_uiNumVertices guaranteed >= 2, so no div/0.
	const float kfOuterRadius(0.5f * m_uiDiameter);

	// Draw lines into the stencil.
	if(SUCCEEDED(m_pLine->Begin()))
	{
		// Set render states so the line can draw into the stencil.
		rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x2);	// With 0x2.

		// Draw shapes into stencil, beginning with the circle.

		for (unsigned int ui = 0; ui < m_uiNumLineVertices; ++ui)
		{
			m_pLineVertices[ui].x = kfOuterRadius + (cosf(kfFraction * ui) * m_fInnerRadius);
			m_pLineVertices[ui].y = kfOuterRadius + (sinf(kfFraction * ui) * m_fInnerRadius);
		}

		// Draw circle.
		m_pLine->Draw(m_pLineVertices, m_uiNumLineVertices, 0x00000000);	// Writes 0x2 into the stencil.

		// Draw each dividing line, if greater than one.
		if (m_ucNumButtons > 1)
		{
			const float kfFraction((2.0f * MathUtility::PI) / m_ucNumButtons);	// m_ucNumButtons guaranteed non-zero.

			for (unsigned char uc = 0; uc < m_ucNumButtons; ++uc)
			{
				m_pLineVertices[0].x = kfOuterRadius + (cosf(kfFraction * uc) * m_fInnerRadius);
				m_pLineVertices[0].y = kfOuterRadius + (sinf(kfFraction * uc) * m_fInnerRadius);

				m_pLineVertices[1].x = kfOuterRadius + (cosf(kfFraction * uc) * kfOuterRadius);
				m_pLineVertices[1].y = kfOuterRadius + (sinf(kfFraction * uc) * kfOuterRadius);

				m_pLine->Draw(m_pLineVertices, 2, 0x00000000);	// Writes 0x2 into the stencil.
			}
		}
		// Else there is only one button, so do not draw any dividers.

		m_pLine->End();
	}

	// Draw stencil'd circle in the middle.
	CVertexBuffer* pBuffer = m_pRenderer->GetVertexBufferManager().GetVertexBuffer(m_uiVertexBufferMaskID);
	if (pBuffer)
	{
		if (pBuffer->IsVerticesDynamic())
		{
			CVertexSCSP* pVertices = reinterpret_cast<CVertexSCSP*>(pBuffer->GetDynamicVertices());
			assert(pVertices);
			
			pVertices->SetPos(m_uiDiameter * 0.5f, m_uiDiameter * 0.5f);

			for (unsigned int ui = 1; ui < pBuffer->GetVertexBufferData().m_uiNumVerts; ++ui)
			{
				pVertices[ui].SetPos(kfOuterRadius + (cosf(kfFraction * ui) * m_fInnerRadius), kfOuterRadius + (sinf(kfFraction * ui) * m_fInnerRadius));
			}
			
			rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x1);
			pBuffer->UpdateDynamicVertices();
			pBuffer->Render(rDeviceManager);
		}
	}
}
Esempio n. 15
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);
		}
	}
}
Esempio n. 16
0
INT __stdcall CFontObject::DrawText(TCHAR* str,DWORD dwLen,RECT* pRect,DWORD dwColor,CHAR_CODE_TYPE type,DWORD dwFlag,void* sprite)
{
	INT			iResult = 0xffffffff;
	BOOL		bHasCRLF = RemoveCRLF(str,dwLen);
	
	
#ifdef	_DEBUG
	char	txt[2048];
	DWORD	dwAddr;

	if (bHasCRLF)
	{
		memset(txt,0,sizeof(txt));
		wsprintf(txt,"Fail to RenderFont(), string has CR or LF or HT!! %s\n",str);
		GetEIP(&dwAddr);
		g_pErrorHandleFunc(ERROR_TYPE_PARAMETER_INVALID,1,(void*)dwAddr,txt);
	}
	
	if (0 == pRect->right - pRect->left)
	{
		memset(txt,0,sizeof(txt));
		wsprintf(txt,"Fail to RenderFont(), rect's width zero!! %s\n",str);
		GetEIP(&dwAddr);
		g_pErrorHandleFunc(ERROR_TYPE_PARAMETER_INVALID,0,(void*)dwAddr,txt);
	}
	if (0 == pRect->bottom - pRect->top)
	{
		memset(txt,0,sizeof(txt));
		wsprintf(txt,"Fail to RenderFont(), rect's height zero!! %s\n",str);
		GetEIP(&dwAddr);
		g_pErrorHandleFunc(ERROR_TYPE_PARAMETER_INVALID,0,(void*)dwAddr,txt);
	}
	if (pRect->right - pRect->left > m_pFontCache->GetMaxWidth())
	{
		memset(txt,0,sizeof(txt));
		wsprintf(txt,"Fail to RenderFont(), rect's width too large!! %s\n",str);
		GetEIP(&dwAddr);
		g_pErrorHandleFunc(ERROR_TYPE_PARAMETER_INVALID,0,(void*)dwAddr,txt);
	}
	if (pRect->bottom - pRect->top > m_pFontCache->GetMaxWidth())
	{
		memset(txt,0,sizeof(txt));
		wsprintf(txt,"Fail to RenderFont(), rect's height too large!! %s\n",str);
		GetEIP(&dwAddr);
		g_pErrorHandleFunc(ERROR_TYPE_PARAMETER_INVALID,0,(void*)dwAddr,txt);
	}
#endif

	if (!dwLen)
		goto lb_return;


	LPDIRECT3DDEVICE9 pDevice;
	
	pDevice = m_pRenderer->GetDevice();
	pDevice->SetRenderState(D3DRS_ZWRITEENABLE ,FALSE);
	pDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE);

	pDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT);
	pDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT);
	
	VECTOR2	v2Pos;
	v2Pos.x = (float)pRect->left;
	v2Pos.y = (float)pRect->top;

	pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,0);


	pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP );
	pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP );
	pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE);
	pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
	pDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE  );
	
	CVertexBuffer*	pVB;
	CIndexBuffer*	pIB;
	LPDIRECT3DTEXTURE9	pTex;
	
	m_propertyDesc.pszString = str;
	m_propertyDesc.dwStrLen = dwLen;
	m_propertyDesc.dwColor = dwColor;

	m_pFontCache->GetResource(&pTex,&pVB,&pIB,pRect,&m_propertyDesc);

	/// LeHide Edit, Check - FVF형을 정확히 알아야 함 폰트는 빌보드로 돼 있을까/ 여튼 현재 잘 돌아간다
	pDevice->SetVertexShader(NULL);
	pDevice->SetFVF(pVB->GetVertexShader());
	//pDevice->SetFVF(D3DFVF_D3DTLVERTEX);

	pDevice->SetStreamSource( 0, pVB->GetVertexBuffer(), 0, pVB->GetVertexSize());

	pDevice->SetTexture(0,pTex);
	 
	DWORD dwAlpha;
	dwAlpha = (dwColor & 0xff000000)>>24;

	
	//trustpak

	EnableAlphaSetting(pDevice, 0, dwAlpha);

	//BeginAlphaMeshObject(pDevice,0,255,dwAlpha);		
	
	//pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
	//pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	//pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);	
	
	//trustpak
		
//	pDevice->SetRenderState(D3DRS_FILLMODE,RENDER_MODE_WIREFRAME);

	pDevice->SetIndices(pIB->GetIndexBuffer());

	HRESULT l_RetValue = pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pVB->GetStartIndex(), 0, 4, pIB->GetStartIndex(), 2);

	if(D3D_OK != l_RetValue)
	{
		goto lb_return;
	}
	
	EndAlphaMeshObject(pDevice);	
	
//	pDevice->SetRenderState(D3DRS_FILLMODE,RENDER_MODE_SOLID);


	pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE );

	pDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);
	pDevice->SetRenderState(D3DRS_ZWRITEENABLE ,TRUE);
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	pDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
	pDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);

//	__asm
//	{
//		rdtsc
//		pop		ecx
//		pop		ebx
//		sub		edx,ecx
//		sub		eax,ebx
//		nop
//	}

lb_return:
	return iResult;
}
Esempio n. 17
0
/**
*
* ITS = Into Target Surface (render target).
* This highlights the current button selected.
*
* @author Jade Abbott
* @return Void.
*
*/
void
CRadialMenu::DrawHighlightITS()
{
	assert(m_pRenderer);
	assert(m_uiVertexBufferMaskID != Utility::INVALID_ID);

	// Replace the backbuffer with the Radial Menu's render target and stencil, disabling Z-buffer and enabling stencil.
	PrepareDeviceData(true);

	CDeviceManager& rDeviceManager = m_pRenderer->GetDeviceManager();

	CVertexBuffer* pBuffer = m_pRenderer->GetVertexBufferManager().GetVertexBuffer(m_uiVertexBufferMaskID);
	assert(pBuffer);

	if (pBuffer->IsVerticesDynamic())
	{
		CVertexSCSP* pVertices = reinterpret_cast<CVertexSCSP*>(pBuffer->GetDynamicVertices());
		assert(pVertices);

		// Set render states.
		rDeviceManager.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);	// When equal to the value previously provided...
		rDeviceManager.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);	// Do not edit stencil, just draw.
		rDeviceManager.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);	// Allow blending.
		rDeviceManager.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);	// Merge colour components for a highlight effect.
		rDeviceManager.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_ADD);	// Merge alpha components as well, so more of the button is lit.
		rDeviceManager.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);	// To the Radial Menu's colour (make brighter).

		unsigned int uiNumVerts = 0;	// Used later in the for loop.
		float fRadius = m_uiDiameter * 0.5f;	// fRadius == centre of image
		
		// Count the number of disabled buttons there are, create a highlight for each, the apply the selection highlight.
		for (unsigned char ucButton = 0; ucButton <= m_ucNumButtons; ++ucButton)
		{
			unsigned char ucButtonToHighlight = MathUtility::kMaxUC;

			if (ucButton == m_ucNumButtons)	// If this is the final run...
			{
				ucButtonToHighlight = m_ucButtonSelected;	// Apply highlight to the button the user has selected.
				rDeviceManager.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);	// Blend the Radial Menu's colour...
			}
			else if (m_arrButtonData[ucButton].m_bDisabled)
			{
				ucButtonToHighlight = ucButton;	// Apply highlight to the disabled button.
				rDeviceManager.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);	// Blend the colourless mask...
			}
			else
			{
				continue;	// This button is neither disabled nor selected.
			}

			if (ucButtonToHighlight == MathUtility::kMaxUC || m_ucNumButtons == 1)
			{
				if (ucButtonToHighlight == MathUtility::kMaxUC)
					rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x1);	// The value of the centre button.
				else
					rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x0);	// The value of an ordinary button.

				// Highlight the entire area.
				uiNumVerts = 4;
				pVertices[0].SetPos(-0.5f, -0.5f);
				pVertices[1].SetPos(m_uiDiameter + 0.5f, -0.5f);
				pVertices[2].SetPos(m_uiDiameter + 0.5f, m_uiDiameter + 0.5f);
				pVertices[3].SetPos(-0.5f, m_uiDiameter + 0.5f);
			}
			else
			{
				rDeviceManager.SetRenderState(D3DRS_STENCILREF, 0x0);	// The value of an ordinary button.

				if (m_ucNumButtons == 2)	// Highlight either the top half or bottom half.
				{
					uiNumVerts = 4;
					float fTop = ucButtonToHighlight == 0 ? -0.5f : fRadius;
					float fBottom = ucButtonToHighlight == 0 ? fRadius : m_uiDiameter + 0.5f;
					pVertices[0].SetPos(-0.5f, fTop);
					pVertices[1].SetPos(m_uiDiameter + 0.5f, fTop);
					pVertices[2].SetPos(m_uiDiameter + 0.5f, fBottom);
					pVertices[3].SetPos(-0.5f, fBottom);
				}
				else	// A slice of pie.
				{
					uiNumVerts = 3;
					float fFraction = (2.0f * MathUtility::PI) / m_ucNumButtons;	// fFraction = radians per button.
					pVertices[0].SetPos(fRadius, fRadius);

					float fY = -sinf(fFraction * (ucButtonToHighlight + 1)) * m_fOuterPlanarLength;
					pVertices[1].SetPos(fRadius + (cosf(fFraction * (ucButtonToHighlight + 1)) * m_fOuterPlanarLength),
										fRadius + fY);

					fY = -sinf(fFraction * ucButtonToHighlight) * m_fOuterPlanarLength;
					pVertices[2].SetPos(fRadius + (cosf(fFraction * ucButtonToHighlight) * m_fOuterPlanarLength),
										fRadius + fY);
				}
			}

			pBuffer->UpdateDynamicVertices(uiNumVerts);
			pBuffer->Render(rDeviceManager, uiNumVerts);
		}
	}
}