예제 #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());
}
예제 #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);
						}
					}
				}
			}
		}
	}
}
예제 #3
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);
		}
	}
}
예제 #4
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);
		}
	}
}