Exemple #1
0
MFMatrix *MFRendererState::getDerivedMatrix(MFStateConstant_Matrix matrix)
{
	if(derivedMatrixDirty & MFBIT(matrix))
	{
		switch(matrix)
		{
			case MFSCM_View:
				pMatrixStatesSet[matrix]->Inverse(*pMatrixStates[MFSCM_Camera]);
				break;
			case MFSCM_WorldView:
				pMatrixStatesSet[matrix]->Multiply(*pMatrixStates[MFSCM_World], *getDerivedMatrix(MFSCM_View));
				break;
			case MFSCM_ViewProjection:
				pMatrixStatesSet[matrix]->Multiply4x4(*getDerivedMatrix(MFSCM_View), *pMatrixStates[MFSCM_Projection]);
				break;
			case MFSCM_WorldViewProjection:
				pMatrixStatesSet[matrix]->Multiply4x4(*pMatrixStates[MFSCM_World], *getDerivedMatrix(MFSCM_ViewProjection));
				break;
			case MFSCM_InverseWorld:
				pMatrixStatesSet[matrix]->Inverse(*pMatrixStates[MFSCM_World]);
				break;
			case MFSCM_InverseViewProjection:
				pMatrixStatesSet[matrix]->Inverse(*getDerivedMatrix(MFSCM_ViewProjection));
				break;
			default:
				MFDebug_Assert(false, "Not a derived matrix!");
		}

		derivedMatrixDirty ^= MFBIT(matrix);
	}

	return pMatrixStatesSet[matrix];
}
MF_API bool MFTexture_IsAvailable(int format)
{
	MFDisplayDrivers driver = MFTexture_GetCurrentDisplayDriver();
	if(driver == MFDD_Unknown)
		return format == TexFmt_A8R8G8B8;
	return (gMFTexturePlatformAvailability[format] & MFBIT(driver)) != 0;
}
Exemple #3
0
MF_API bool MFTexture_IsFormatAvailable(int format)
{
	MFRendererDrivers driver = MFTexture_GetCurrentDisplayDriver();
	if(driver == MFRD_Unknown)
		return format == ImgFmt_A8R8G8B8;
	return (gMFImagePlatformAvailability[format] & MFBIT(driver)) != 0;
}
Exemple #4
0
static void MFRenderer_CheckRequirements(MFRendererState &state, MFRenderElement &element)
{
	uint32 required[MFSB_CT_TypeCount] =
	{
		0, //MFSB_CT_Bool = 0,
		0, //MFSB_CT_Vector,
		0, //MFSB_CT_Matrix,
		MFBIT(MFSCRS_VertexDeclaration) | MFBIT(MFSCRS_BlendState) | MFBIT(MFSCRS_DepthStencilState) | MFBIT(MFSCRS_RasteriserState),
		0, //MFSB_CT_Texture,
		0, //MFSB_CT_Misc,
		0,
	};

	// add required vertex streams
	MFVertexDeclaration *pDecl = (MFVertexDeclaration*)state.pRenderStates[MFSCRS_VertexDeclaration];
	required[MFSB_CT_RenderState] |= pDecl->streamsUsed << MFSCRS_VertexBuffer0;

	// if we need an index buffer
	if(element.renderIndexed)
		required[MFSB_CT_RenderState] |= MFBIT(MFSCRS_IndexBuffer);

	// add misc requirements
	if(state.getBool(MFSCB_Animated))
		required[MFSB_CT_Misc] |= MFBIT(MFSCMisc_AnimationMatrices) | MFBIT(MFSCMisc_MatrixBatch);
	if(state.getBool(MFSCB_AlphaTest))
		required[MFSB_CT_Vector] |= MFBIT(MFSCV_RenderState);

	// add material requirements
	//...
	// HACK: hardcode the matrices for now...
	required[MFSB_CT_Matrix] |= MFBIT(MFSCM_World) | MFBIT(MFSCM_Camera) | MFBIT(MFSCM_Projection);

	// complain about missing states
	for(int a = 0; a < MFSB_CT_TypeCount; ++a)
	{
		uint32 missing = required[a] & ~state.rsSet[a];
		if(missing != 0)
			MissingStates((MFStateBlockConstantType)a, missing);
	}
}
int MFMat_Standard_Begin(MFMaterial *pMaterial, MFRendererState &state)
{
	MFMat_Standard_Data *pData = (MFMat_Standard_Data*)pMaterial->pInstanceData;

	MFEffectTechnique *pTechnique = NULL;
	if(pData->pEffect)
		pTechnique = MFEffect_GetTechnique(pData->pEffect, state);
	MFDebug_Assert(pTechnique, "No technique!");

	MFEffectData_OpenGL &techniqueData = *(MFEffectData_OpenGL*)pTechnique->pPlatformData;

	if(pTechnique != state.pTechniqueSet)
	{
		state.pTechniqueSet = pTechnique;
		glUseProgram(techniqueData.program);

		// need to clear all the cache states
		//... or ignore the state caching for now
	}

	// bools
/*	do a bitscan loop over the bool states
	uint32 boolState = state.bools & state.rsSet[MFSB_CT_Bool];

	uint32 req = pTechnique->renderStateRequirements[MFSB_CT_Bool];
	if(req)
	{
		uint32 vsReq = pVS->renderStateRequirements[MFSB_CT_Bool];
		uint32 psReq = pPS->renderStateRequirements[MFSB_CT_Bool];
		if((state.boolsSet & req) != (boolState & req))
		{
			BOOL bools[32];
			for(uint32 i=0, b=1; i<MFSCB_Max; ++i, b<<=1)
				bools[i] = (boolState & b) != 0;

			if((state.boolsSet & vsReq) != (boolState & vsReq))
				pd3dDevice->SetVertexShaderConstantB(0, bools,  32);
			if((state.boolsSet & psReq) != (boolState & psReq))
				pd3dDevice->SetPixelShaderConstantB(0, bools,  32);
		}
	}
*/

	// matrices
	uint32 req = pTechnique->renderStateRequirements[MFSB_CT_Matrix];
	uint32 i;
	while(MFUtil_BitScanReverse(req, &i))
	{
		uint32 b = MFBIT(i);
		req ^= b;

//		if(state.pMatrixStatesSet[i] != state.pMatrixStates[i])
		{
			MFMatrix *pM;
			if(i > MFSCM_DerivedStart)
				pM = state.getDerivedMatrix((MFStateConstant_Matrix)i);
			else
				pM = state.pMatrixStates[i];
//			state.pMatrixStatesSet[i] = pM;

			GLint uniform = techniqueData.uniformLocation[MFSB_CT_Matrix][i];
			glUniformMatrix4fv(uniform, 1, GL_TRUE, (float*)pM);
		}
	}

	// vectors
	req = pTechnique->renderStateRequirements[MFSB_CT_Vector];
	while(MFUtil_BitScanReverse(req, &i))
	{
		uint32 b = MFBIT(i);
		req ^= b;

//		if(state.pVectorStatesSet[i] != state.pVectorStates[i])
		{
			MFVector *pV = state.pVectorStates[i];
//			state.pVectorStatesSet[i] = pV;

			GLint uniform = techniqueData.uniformLocation[MFSB_CT_Vector][i];
			glUniform4fv(uniform, 1, (float*)pV);
		}
	}

	// textures
	req = pTechnique->renderStateRequirements[MFSB_CT_Texture];
	while(MFUtil_BitScanReverse(req, &i))
	{
		req ^= MFBIT(i);

		MFTexture *pT = state.pTextures[i];
		if(state.pTexturesSet[i] != pT)
		{
			state.pTexturesSet[i] = pT;
			glActiveTexture(GL_TEXTURE0 + i);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, (GLuint)(size_t)pT->pInternalData);
		}
/*
		else
		{
			glActiveTexture(GL_TEXTURE0 + i);
			glDisable(GL_TEXTURE_2D);
		}
*/

		MFSamplerState *pS = (MFSamplerState*)state.pRenderStates[MFSCRS_DiffuseSamplerState + i];
//		if(state.pRenderStatesSet[MFSCRS_DiffuseSamplerState + i] != pS)
		{
//			state.pRenderStatesSet[MFSCRS_DiffuseSamplerState + i] = pS;
			GLint uniform = techniqueData.uniformLocation[MFSB_CT_RenderState][MFSCRS_DiffuseSamplerState + i];
			GLint sampler = (GLint)(size_t)pS->pPlatformData;
			glUniform1i(uniform, i);
			glBindSampler(i, sampler);
		}
	}

	// blend state
	MFBlendState *pBlendState = (MFBlendState*)state.pRenderStates[MFSCRS_BlendState];
	if(state.pRenderStatesSet[MFSCRS_BlendState] != pBlendState)
	{
		state.pRenderStatesSet[MFSCRS_BlendState] = pBlendState;

		if(pBlendState->stateDesc.bIndependentBlendEnable)
		{
			for(int j=0; j<8; ++j)
			{
				MFBlendStateDesc::RenderTargetBlendDesc &target = pBlendState->stateDesc.renderTarget[j];
				if(target.bEnable)
				{
					glEnable(GL_BLEND);
					glBlendEquationSeparatei(j, glBlendOp[target.blendOp], glBlendOp[target.blendOpAlpha]);
					glBlendFuncSeparatei(j, glBlendArg[target.srcBlend], glBlendArg[target.destBlend], glBlendArg[target.srcBlendAlpha], glBlendArg[target.destBlendAlpha]);
				}
				else
					glDisable(GL_BLEND);
				glColorMaski(j, target.writeMask & MFColourWriteEnable_Red, target.writeMask & MFColourWriteEnable_Green, target.writeMask & MFColourWriteEnable_Blue, target.writeMask & MFColourWriteEnable_Alpha);
			}
		}
		else
		{
			MFBlendStateDesc::RenderTargetBlendDesc &target = pBlendState->stateDesc.renderTarget[0];
			if(target.bEnable)
			{
				glEnable(GL_BLEND);
				glBlendEquationSeparate(glBlendOp[target.blendOp], glBlendOp[target.blendOpAlpha]);
				glBlendFuncSeparate(glBlendArg[target.srcBlend], glBlendArg[target.destBlend], glBlendArg[target.srcBlendAlpha], glBlendArg[target.destBlendAlpha]);
			}
			else
				glDisable(GL_BLEND);
			glColorMask(target.writeMask & MFColourWriteEnable_Red, target.writeMask & MFColourWriteEnable_Green, target.writeMask & MFColourWriteEnable_Blue, target.writeMask & MFColourWriteEnable_Alpha);
		}
	}

	// rasteriser state
	MFRasteriserState *pRasteriserState = (MFRasteriserState*)state.pRenderStates[MFSCRS_RasteriserState];
	if(state.pRenderStatesSet[MFSCRS_RasteriserState] != pRasteriserState)
	{
		state.pRenderStatesSet[MFSCRS_RasteriserState] = pRasteriserState;

		switch(pRasteriserState->stateDesc.cullMode)
		{
			case MFCullMode_None:
				glDisable(GL_CULL_FACE);
				break;
			case MFCullMode_CCW:
				glEnable(GL_CULL_FACE);
				glFrontFace(GL_CW);
				glCullFace(GL_BACK);
				break;
			case MFCullMode_CW:
				glEnable(GL_CULL_FACE);
				glFrontFace(GL_CCW);
				glCullFace(GL_BACK);
				break;
			default:
				MFUNREACHABLE;
		}
	}

	// depth/stencil state
	MFDepthStencilState *pDSState = (MFDepthStencilState*)state.pRenderStates[MFSCRS_DepthStencilState];
	if(state.pRenderStatesSet[MFSCRS_DepthStencilState] != pDSState)
	{
		state.pRenderStatesSet[MFSCRS_DepthStencilState] = pDSState;

		if(pDSState->stateDesc.bDepthEnable)
		{
			glEnable(GL_DEPTH_TEST);
			glDepthFunc(glCompareFunc[pDSState->stateDesc.depthFunc]);
			glDepthMask(pDSState->stateDesc.depthWriteMask == MFDepthWriteMask_Zero ? GL_FALSE : GL_TRUE);
		}
		else
			glDisable(GL_DEPTH_TEST);
	}

	// setup alpha test
	if(state.boolChanged(MFSCB_AlphaTest) || (state.pVectorStatesSet[MFSCV_RenderState] != state.pVectorStates[MFSCV_RenderState] && state.getBool(MFSCB_AlphaTest)))
	{
		MFVector *pRS = state.pVectorStates[MFSCV_RenderState];
		state.pVectorStatesSet[MFSCV_RenderState] = pRS;
		state.boolsSet = (state.boolsSet & ~MFBIT(MFSCB_AlphaTest)) | (state.bools & MFBIT(MFSCB_AlphaTest));

#if !defined(MF_OPENGL_ES)
		if(state.getBool(MFSCB_AlphaTest))
		{
			glEnable(GL_ALPHA_TEST);
			glAlphaFunc(GL_GEQUAL, pRS->x);
		}
		else
			glDisable(GL_ALPHA_TEST);
#else
		// TODO: do something here...
		//I guess we need to implement the alpha test in the shader...
#endif
	}
/*
	// set clour/alpha scales
	if(state.pVectorStatesSet[MFSCV_User0] != state.pVectorStates[MFSCV_User0])
	{
		MFVector *pMask = state.pVectorStates[MFSCV_User0];
		state.pVectorStatesSet[MFSCV_User0] = pMask;

//		pd3dDevice->SetVertexShaderConstantF(r_colourMask, (float*)pMask, 1);
	}
*/

	// set animation matrices
	if(state.getBool(MFSCB_Animated))
	{
		MFDebug_Assert(false, "TODO!");
//		for(uint32 b=0; b<state.matrixBatch.numMatrices; b++)
//			MFRendererPC_SetAnimationMatrix(b, state.animation.pMatrices[state.matrixBatch.pIndices[b]]);
	}

	// set viewport
	if(state.pViewportSet != state.pViewport)
	{
		if(!state.pViewport)
			MFRenderer_ResetViewport();
		else
			MFRenderer_SetViewport(state.pViewport);
		state.pViewportSet = state.pViewport;
	}

	MFCheckForOpenGLError(true);

	// update the bools 'set' state
	state.boolsSet = state.bools & state.rsSet[MFSB_CT_Bool];

	return 0;
}
Exemple #6
0
	"PVRTC2_4bpp",
	"ATCRGB",
	"ATCRGBA_EXPLICIT",
	"ATCRGBA",
	"ASTC",

	"PSP_DXT1",
	"PSP_DXT3",
	"PSP_DXT5",
};

uint8 gMFImagePlatformAvailability[4][ImgFmt_Max] =
{
	// normalised
	{
		MFBIT(MFRD_D3D9)|MFBIT(MFRD_D3D11)|MFBIT(MFRD_OpenGL)|MFBIT(MFRD_XBox),		// ImgFmt_A8R8G8B8
		MFBIT(MFRD_D3D9)|MFBIT(MFRD_D3D11)|MFBIT(MFRD_OpenGL)|MFBIT(MFRD_X360)|MFBIT(MFRD_XBox)|MFBIT(MFRD_PSP)|MFBIT(MFRD_PS2),	// ImgFmt_A8B8G8R8
		MFBIT(MFRD_XBox)|MFBIT(MFRD_OpenGL),										// ImgFmt_B8G8R8A8
		MFBIT(MFRD_XBox)|MFBIT(MFRD_OpenGL),										// ImgFmt_R8G8B8A8

		MFBIT(MFRD_D3D9),															// ImgFmt_R8G8B8
		0,																			// ImgFmt_B8G8R8

		MFBIT(MFRD_D3D11)|MFBIT(MFRD_X360),											// ImgFmt_G8R8

		MFBIT(MFRD_D3D9)|MFBIT(MFRD_D3D11)|MFBIT(MFRD_X360),						// ImgFmt_L8
		MFBIT(MFRD_D3D9)|MFBIT(MFRD_D3D11)|MFBIT(MFRD_X360),						// ImgFmt_A8
		MFBIT(MFRD_D3D9)|MFBIT(MFRD_X360),											// ImgFmt_A8L8

		MFBIT(MFRD_D3D9)|MFBIT(MFRD_D3D11)|MFBIT(MFRD_OpenGL)|MFBIT(MFRD_X360)|MFBIT(MFRD_XBox),	// ImgFmt_R5G6B5
		MFBIT(MFRD_X360)|MFBIT(MFRD_XBox),											// ImgFmt_R6G5B5
MF_API bool MFTexture_IsAvailableOnPlatform(int format, int platform)
{
	return (gMFTexturePlatformAvailability[format] & MFBIT(platform)) != 0;
}
	"PSP_A8B8G8R8s",
	"PSP_B5G6R5s",
	"PSP_A1B5G5R5s",
	"PSP_A4B4G4R4s",

	"PSP_I8s",
	"PSP_I4s",

	"PSP_DXT1s",
	"PSP_DXT3s",
	"PSP_DXT5s",
};

static uint32 gMFTexturePlatformAvailability[TexFmt_Max] =
{
	MFBIT(MFDD_D3D9)|MFBIT(MFDD_D3D11)|MFBIT(MFDD_XBox)|MFBIT(MFDD_OpenGL),		// TexFmt_A8R8G8B8
	MFBIT(MFDD_PSP)|MFBIT(MFDD_D3D11)|MFBIT(MFDD_XBox)|MFBIT(MFDD_OpenGL)|MFBIT(MFDD_PS2),	// TexFmt_A8B8G8R8
	MFBIT(MFDD_XBox)|MFBIT(MFDD_OpenGL),										// TexFmt_B8G8R8A8
	MFBIT(MFDD_XBox)|MFBIT(MFDD_OpenGL),										// TexFmt_R8G8B8A8

	MFBIT(MFDD_D3D9),															// TexFmt_R8G8B8
	0,																			// TexFmt_B8G8R8

	MFBIT(MFDD_D3D9)|MFBIT(MFDD_OpenGL),										// TexFmt_A2R10G10B10
	MFBIT(MFDD_D3D9)|MFBIT(MFDD_D3D11)|MFBIT(MFDD_OpenGL),						// TexFmt_A2B10G10R10

	MFBIT(MFDD_D3D9)|MFBIT(MFDD_D3D11)|MFBIT(MFDD_OpenGL),						// TexFmt_A16B16G16R16

	MFBIT(MFDD_D3D9)|MFBIT(MFDD_D3D11)|MFBIT(MFDD_XBox)|MFBIT(MFDD_OpenGL),		// TexFmt_R5G6B5
	MFBIT(MFDD_XBox),															// TexFmt_R6G5B5
	MFBIT(MFDD_OpenGL)|MFBIT(MFDD_PSP),											// TexFmt_B5G6R5
MF_API MFVertexDeclaration *MFVertex_CreateVertexDeclaration(const MFVertexElement *pElementArray, int elementCount)
{
	// assign the auto format components before calculating the hash
	MFVertexElement elements[16];
	MFCopyMemory(elements, pElementArray, sizeof(MFVertexElement)*elementCount);
	for(int e=0; e<elementCount; ++e)
	{
		if(pElementArray[e].format == MFVDF_Auto)
			elements[e].format = MFVertex_ChoooseVertexDataTypePlatformSpecific(pElementArray[e].type, pElementArray[e].componentCount);
	}

	uint32 hash = MFUtil_HashBuffer(elements, sizeof(MFVertexElement)*elementCount);

	MFVertexDeclaration *pDecl = (MFVertexDeclaration*)MFResource_Find(hash);
	if(!pDecl)
	{
		pDecl = (MFVertexDeclaration*)MFHeap_AllocAndZero(sizeof(MFVertexDeclaration) + (sizeof(MFVertexElement) + sizeof(MFVertexElementData))*elementCount);

		pDecl->numElements = elementCount;
		pDecl->pElements = (MFVertexElement*)&pDecl[1];
		pDecl->pElementData = (MFVertexElementData*)&pDecl->pElements[elementCount];

		MFCopyMemory(pDecl->pElements, elements, sizeof(MFVertexElement)*elementCount);

		int streamOffsets[16];
		MFZeroMemory(streamOffsets, sizeof(streamOffsets));

		// set the element data and calculate the strides
		for(int e=0; e<elementCount; ++e)
		{
			pDecl->pElementData[e].offset = streamOffsets[elements[e].stream];
			pDecl->pElementData[e].stride = 0;

			streamOffsets[elements[e].stream] += gVertexDataStride[elements[e].format];
			pDecl->streamsUsed |= MFBIT(elements[e].stream);
		}

		// set the strides for each component
		for(int e=0; e<elementCount; ++e)
			pDecl->pElementData[e].stride = streamOffsets[elements[e].stream];

		if(!MFVertex_CreateVertexDeclarationPlatformSpecific(pDecl))
		{
			MFHeap_Free(pDecl);
			return NULL;
		}

		MFResource_AddResource(pDecl, MFRT_VertexDecl, hash);

		if(pDecl->streamsUsed != 1)
		{
			// create the stream declarations...
			MFVertexElement streamElements[64];
			for(int s=0; s<16; ++s)
			{
				if(!(pDecl->streamsUsed & (1 << s)))
					continue;

				int numStreamElements = 0;
				for(int e=0; e<elementCount; ++e)
				{
					if(elements[e].stream == s)
					{
						streamElements[numStreamElements] = elements[e];
						streamElements[numStreamElements].stream = 0;
						++numStreamElements;
					}
				}

				if(numStreamElements)
					pDecl->pStreamDecl[s] = MFVertex_CreateVertexDeclaration(streamElements, numStreamElements);
			}
		}
	}

	return pDecl;
}
int MFMat_Standard_Begin(MFMaterial *pMaterial, MFRendererState &state)
{
//	MFMat_Standard_Data_D3D11 *pData = (MFMat_Standard_Data_D3D11*)pMaterial->pInstanceData;

	if(state.pMatrixStatesSet[MFSCM_WorldViewProjection] != state.pMatrixStates[MFSCM_WorldViewProjection])
	{
		MFMatrix *pWVP = state.getDerivedMatrix(MFSCM_WorldViewProjection);
		state.pMatrixStates[MFSCM_WorldViewProjection] = pWVP;

		// ???
	}

	if(state.pMatrixStatesSet[MFSCM_UV0] != state.pMatrixStates[MFSCM_UV0])
	{
		MFMatrix *pUV0 = state.pMatrixStates[MFSCM_UV0];
		state.pMatrixStatesSet[MFSCM_UV0] = pUV0;

		// ???
	}

	if(state.pVectorStatesSet[MFSCV_MaterialDiffuseColour] != state.pVectorStates[MFSCV_MaterialDiffuseColour])
	{
		MFVector *pDiffuseColour = state.pVectorStates[MFSCV_MaterialDiffuseColour];
		state.pVectorStatesSet[MFSCV_MaterialDiffuseColour] = pDiffuseColour;

		// ???
	}

	bool bDetailPresent = state.isSet(MFSB_CT_Bool, MFSCB_DetailMapSet);
	bool bDiffusePresent = state.isSet(MFSB_CT_Bool, MFSCB_DiffuseSet);

	if(bDetailPresent)
	{
		// set detail map
		MFTexture *pDetail = state.pTextures[MFSCT_DetailMap];
		if(state.pTexturesSet[MFSCT_DetailMap] != pDetail)
		{
			state.pTexturesSet[MFSCT_DetailMap] = pDetail;

			// ???
//			ID3D11ShaderResourceView *pSRV = (ID3D11ShaderResourceView*)pData->textures[pData->diffuseMapIndex].pTexture->pInternalData;
//			g_pImmediateContext->PSSetShaderResources(0, 1, &pSRV);
		}

		// set detail map sampler
		MFSamplerState *pDetailSamp = (MFSamplerState*)state.pRenderStates[MFSCRS_DetailMapSamplerState];
		if(state.pRenderStatesSet[MFSCRS_DetailMapSamplerState] != pDetailSamp)
		{
			state.pRenderStatesSet[MFSCRS_DetailMapSamplerState] = pDetailSamp;

			// ???
//			ID3D11ShaderResourceView *pSRV = (ID3D11ShaderResourceView*)pData->textures[pData->diffuseMapIndex].pTexture->pInternalData;
//			g_pImmediateContext->PSSetShaderResources(0, 1, &pSRV);
		}
	}
	else
	{
		if(state.pTexturesSet[MFSCT_DetailMap] != NULL)
		{
			state.pTexturesSet[MFSCT_DetailMap] = NULL;

			// ???
//			pd3dDevice->SetTexture(1, NULL);
		}
	}

	if(bDiffusePresent)
	{
		// set diffuse map
		MFTexture *pDiffuse = state.pTextures[MFSCT_Diffuse];
		if(state.pTexturesSet[MFSCT_Diffuse] != pDiffuse)
		{
			state.pTexturesSet[MFSCT_Diffuse] = pDiffuse;

			// ???
//			ID3D11ShaderResourceView *pSRV = (ID3D11ShaderResourceView*)pData->textures[pData->diffuseMapIndex].pTexture->pInternalData;
//			g_pImmediateContext->PSSetShaderResources(0, 1, &pSRV);
		}

		// set diffuse map sampler
		MFSamplerState *pDiffuseSamp = (MFSamplerState*)state.pRenderStates[MFSCRS_DiffuseSamplerState];
		if(state.pRenderStatesSet[MFSCRS_DiffuseSamplerState] != pDiffuseSamp)
		{
			state.pRenderStatesSet[MFSCRS_DiffuseSamplerState] = pDiffuseSamp;

			// ???
//			MFMat_Standard_SetSamplerState(0, pDiffuseSamp);
		}
	}
	else
	{
		if(state.pTexturesSet[MFSCT_Diffuse] != NULL)
		{
			state.pTexturesSet[MFSCT_Diffuse] = NULL;

			// ???
//			pd3dDevice->SetTexture(0, NULL);
		}
	}

	// configure the texture combiner (can we cache this?)
	if(state.boolChanged(MFSCB_DetailMapSet) || state.boolChanged(MFSCB_DiffuseSet) || state.boolChanged(MFSCB_User0))
	{
		const uint32 mask = MFBIT(MFSCB_DetailMapSet) | MFBIT(MFSCB_DiffuseSet) | MFBIT(MFSCB_User0);
		state.boolsSet = (state.boolsSet & ~mask) | (state.bools & mask);

		g_pImmediateContext->PSSetShader(gpPixelShader, NULL, 0);
/*
		if(bDetailPresent)
		{
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

			pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
			pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
			pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
			pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
		}
		else
		{
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);

			if(state.getBool(MFSCB_User0))
			{
				// we need to scale the colour intensity by the vertex alpha since it wont happen during the blend.
				pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
				pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

//				pd3dDevice->SetTextureStageState(1, D3DTSS_CONSTANT, 0);

				pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
				pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEMP);
				pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
			}
			else
			{
				pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
				pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
			}
		}
*/
	}

	// blend state
	MFBlendState *pBlendState = (MFBlendState*)state.pRenderStates[MFSCRS_BlendState];
	if(state.pRenderStatesSet[MFSCRS_BlendState] != pBlendState)
	{
		state.pRenderStatesSet[MFSCRS_BlendState] = pBlendState;

		float blend[4] = { 0, 0, 0, 0 };
		ID3D11BlendState *pBS = (ID3D11BlendState*)pBlendState->pPlatformData;
		g_pImmediateContext->OMSetBlendState(pBS, blend, 0xFFFFFFFF);
	}

	// rasteriser state
	MFRasteriserState *pRasteriserState = (MFRasteriserState*)state.pRenderStates[MFSCRS_RasteriserState];
	if(state.pRenderStatesSet[MFSCRS_RasteriserState] != pRasteriserState)
	{
		state.pRenderStatesSet[MFSCRS_RasteriserState] = pRasteriserState;

		ID3D11RasterizerState *pRS = (ID3D11RasterizerState*)pRasteriserState->pPlatformData;
		g_pImmediateContext->RSSetState(pRS);
	}

	// depth/stencil state
	MFDepthStencilState *pDSState = (MFDepthStencilState*)state.pRenderStates[MFSCRS_DepthStencilState];
	if(state.pRenderStatesSet[MFSCRS_DepthStencilState] != pDSState)
	{
		state.pRenderStatesSet[MFSCRS_DepthStencilState] = pDSState;

		ID3D11DepthStencilState *pDSS = (ID3D11DepthStencilState*)pDSState->pPlatformData;
		g_pImmediateContext->OMSetDepthStencilState(pDSS, 0);
	}

	// set animation matrices
	if(state.getBool(MFSCB_Animated))
	{
		MFDebug_Assert(false, "Animation not yet supported! :(");

//		for(int b=0; b<gNumBonesInBatch; b++)
//			MFRendererPC_SetAnimationMatrix(b, pAnimMats[pCurrentBatch[b]]);

//		pd3dDevice->SetVertexShader(pVS_a);
	}
	else
		g_pImmediateContext->VSSetShader(gpVertexShader, NULL, 0);




/*
	g_pImmediateContext->VSSetShader(pVertexShader, NULL, 0);
	g_pImmediateContext->PSSetShader(pPixelShader, NULL, 0);

	if(pSetMaterial != pMaterial)
	{
		bool premultipliedAlpha = false;

		static const float blend[4] = {0.0f, 0.0f, 0.0f, 0.0f};

		g_pImmediateContext->RSSetState(pData->pRasterizerState);
		g_pImmediateContext->OMSetBlendState(pData->pBlendState, blend, 0xFFFFFFFF);
		g_pImmediateContext->VSSetSamplers(0, 1, &pData->pSamplerState);
		g_pImmediateContext->PSSetSamplers(0, 1, &pData->pSamplerState);

		g_pImmediateContext->UpdateSubresource(pData->pConstantBuffer, 0, NULL, &pData->cbMaterial, 0, 0);

		g_pImmediateContext->VSSetConstantBuffers(n_cbMaterial, 1, &pData->pConstantBuffer);
		g_pImmediateContext->PSSetConstantBuffers(n_cbMaterial, 1, &pData->pConstantBuffer);

		//// set some render states
		//if(pData->detailMapIndex)
		//{
		//	// HACK: for compound multitexturing
		//	IDirect3DTexture9 *pDiffuse = (IDirect3DTexture9*)pData->pTextures[pData->diffuseMapIndex]->pInternalData;
		//	IDirect3DTexture9 *pDetail = (IDirect3DTexture9*)pData->pTextures[pData->detailMapIndex]->pInternalData;

		//	MFRendererPC_SetTexture(0, pDetail);
		//	MFRendererPC_SetTexture(1, pDiffuse);

		//	MFRendererPC_SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		//	MFRendererPC_SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		//	MFRendererPC_SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
		//	MFRendererPC_SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		//	MFRendererPC_SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		//	MFRendererPC_SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

		//	MFRendererPC_SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		//	MFRendererPC_SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
		//	MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
		//	MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
		//	MFRendererPC_SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
		//	MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

		//	MFRendererPC_SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		//	MFRendererPC_SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
		//	MFRendererPC_SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
		//	MFRendererPC_SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
		//	MFRendererPC_SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

		//	MFRendererPC_SetTextureMatrix(pData->textureMatrix);
		//}
		//else
		if(pData->textures[pData->diffuseMapIndex].pTexture)
		{
			ID3D11ShaderResourceView *pSRV = (ID3D11ShaderResourceView*)pData->textures[pData->diffuseMapIndex].pTexture->pInternalData;

			g_pImmediateContext->PSSetShaderResources(0, 1, &pSRV);

			//MFRendererPC_SetTexture(0, pTexture);
			//MFRendererPC_SetTexture(1, NULL);

			//MFRendererPC_SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
			//MFRendererPC_SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
			//MFRendererPC_SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

			//MFRendererPC_SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			//MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
			//MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
			//MFRendererPC_SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);

			//MFRendererPC_SetTextureMatrix(pData->textureMatrix);

			//premultipliedAlpha = !!(pData->pTextures[pData->diffuseMapIndex]->pTemplateData->flags & TEX_PreMultipliedAlpha);

			if(premultipliedAlpha)
			{
//				// we need to scale the colour intensity by the vertex alpha since it wont happen during the blend.
//				MFRendererPC_SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
//				MFRendererPC_SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
//
////				MFRendererPC_SetTextureStageState(1, D3DTSS_CONSTANT, 0);
//
//				MFRendererPC_SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
//				MFRendererPC_SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEMP);
//				MFRendererPC_SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
			}
			else
			{
				//MFRendererPC_SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
				//MFRendererPC_SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
			}
		}
		else
		{
			//MFRendererPC_SetTexture(0, NULL);
		}

		//switch (pData->materialType&MF_BlendMask)
		//{
		//	case 0:
		//		MFRendererPC_SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
		//		break;
		//	case MF_AlphaBlend:
		//		MFRendererPC_SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		//		MFRendererPC_SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
		//		MFRendererPC_SetRenderState(D3DRS_SRCBLEND, premultipliedAlpha ? D3DBLEND_ONE : D3DBLEND_SRCALPHA);
		//		MFRendererPC_SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
		//		break;
		//	case MF_Additive:
		//		MFRendererPC_SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		//		MFRendererPC_SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
		//		MFRendererPC_SetRenderState(D3DRS_SRCBLEND, premultipliedAlpha ? D3DBLEND_ONE : D3DBLEND_SRCALPHA);
		//		MFRendererPC_SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		//		break;
		//	case MF_Subtractive:
		//		MFRendererPC_SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		//		MFRendererPC_SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
		//		MFRendererPC_SetRenderState(D3DRS_SRCBLEND, premultipliedAlpha ? D3DBLEND_ONE : D3DBLEND_SRCALPHA);
		//		MFRendererPC_SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		//		break;
		//}

		//if (pData->materialType & MF_Mask)
		//{
		//	MFRendererPC_SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
		//	MFRendererPC_SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
		//	MFRendererPC_SetRenderState(D3DRS_ALPHAREF, 0xFF);
		//}
		//else
		//{
		//	MFRendererPC_SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
		//}

		//switch (pData->materialType&MF_CullMode)
		//{
		//	case 0<<6:
		//		MFRendererPC_SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
		//		break;
		//	case 1<<6:
		//		MFRendererPC_SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
		//		break;
		//	case 2<<6:
		//		MFRendererPC_SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
		//		break;
		//	case 3<<6:
		//		// 'default' ?
		//		MFRendererPC_SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
		//		break;
		//}

		//if(!(pData->materialType&MF_NoZRead) || !(pData->materialType&MF_NoZWrite))
		//{
		//	MFRendererPC_SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
		//	MFRendererPC_SetRenderState(D3DRS_ZWRITEENABLE, (pData->materialType&MF_NoZWrite) ? FALSE : TRUE);
		//	MFRendererPC_SetRenderState(D3DRS_ZFUNC, (pData->materialType&MF_NoZRead) ? D3DCMP_ALWAYS : D3DCMP_LESSEQUAL);
		//}
		//else
		//{
		//	MFRendererPC_SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
		//}
	}

	//MFRendererPC_SetColourMask(1, 0, 1, 0);

	//// set animation matrices...
	//if (pAnimMats && pCurrentBatch)
	//{
	//	for(int b=0; b<gNumBonesInBatch; b++)
	//		MFRendererPC_SetAnimationMatrix(b, pAnimMats[pCurrentBatch[b]]);
	//}

	//if(MFRendererPC_GetNumWeights() > 0)
	//	MFRendererPC_SetVertexShader(pVS_a);
	//else
	//	MFRendererPC_SetVertexShader(pVS_s);
*/

	// update the bools 'set' state
	state.boolsSet = state.bools & state.rsSet[MFSB_CT_Bool];

	return 0;
}
Exemple #11
0
static void MFRenderer_RenderElements(MFRendererState &state, MFRenderElement *pElements, int numElements)
{
	// set and mask the Layer + Override states
	MFRenderer_ApplyRenderStates(state, state.pStateBlocks + MFSBT_Layer, MFSBT_Max - MFSBT_Layer);
	MFCopyMemory(state.rsMask, state.rsSet, sizeof(state.rsMask));

	// for each render element
	for(int e=0; e<numElements; ++e)
	{
		MFRenderElement &element = pElements[e];

		// collect state blocks
		state.pStateBlocks[MFSBT_View] = element.pViewState;
		state.pStateBlocks[MFSBT_Entity] = element.pEntityState;
		state.pStateBlocks[MFSBT_Material] = element.pMaterialState;
		state.pStateBlocks[MFSBT_Geometry] = element.pGeometryState;
		state.pStateBlocks[MFSBT_MaterialOverride] = element.pMaterialOverrideState;

		// gather render states
		MFRenderer_ApplyRenderStates(state, state.pStateBlocks, MFSBT_Layer);

		// select the technique here? or do it inside RenderElement()?
		//...
		// selection criteria:
		//  - animation
		//  - lights
		//  - constants present
		//  - values of constants?

#if defined(DEBUG)
		// check that all required states are set
		MFRenderer_CheckRequirements(state, element);
#endif

		// apply render state
		element.pMaterial->pType->materialCallbacks.pBegin(element.pMaterial, state);

		// set geometry buffers
		MFVertexDeclaration *pDecl = (MFVertexDeclaration*)state.pRenderStates[MFSCRS_VertexDeclaration];
		if(state.pRenderStatesSet[MFSCRS_VertexDeclaration] != pDecl)
		{
			state.pRenderStatesSet[MFSCRS_VertexDeclaration] = pDecl;
			MFVertex_SetVertexDeclaration(pDecl);
		}

		for(int vb = 0; vb < 8; ++vb)
		{
			if(pDecl->streamsUsed & MFBIT(vb))
			{
				MFVertexBuffer *pVB = (MFVertexBuffer*)state.pRenderStates[MFSCRS_VertexBuffer(vb)];
				if(state.pRenderStatesSet[MFSCRS_VertexBuffer(vb)] != pVB)
				{
					state.pRenderStatesSet[MFSCRS_VertexBuffer(vb)] = pVB;
					MFVertex_SetVertexStreamSource(vb, pVB);
				}
			}
		}

		// render
		if(element.renderIndexed)
		{
			if(state.pRenderStatesSet[MFSCRS_IndexBuffer] != state.pRenderStates[MFSCRS_IndexBuffer])
			{
				MFIndexBuffer *pIB = (MFIndexBuffer*)state.pRenderStates[MFSCRS_IndexBuffer];
				state.pRenderStatesSet[MFSCRS_IndexBuffer] = pIB;
				MFVertex_SetIndexBuffer(pIB);
			}

			MFVertexBuffer *pVB = (MFVertexBuffer*)state.pRenderStates[MFSCRS_VertexBuffer0];
			int numVertices = pVB->numVerts - (int)element.vertexBufferOffset;

			MFVertex_RenderIndexedVertices(state.pTechniqueSet, (MFPrimType)element.primType, element.vertexBufferOffset, element.indexBufferOffset, numVertices, element.vertexCount);
		}
		else
		{
			MFVertex_RenderVertices(state.pTechniqueSet, (MFPrimType)element.primType, element.vertexBufferOffset, element.vertexCount);
		}
	}
}
Exemple #12
0
static void MFRenderer_ApplyRenderStates(MFRendererState &state, const MFStateBlock **ppStateBlocks, int numStateBlocks)
{
	// prime 'set' flags from mask
	MFCopyMemory(state.rsSet, state.rsMask, sizeof(state.rsSet));

	// for each stateblock in order of precedence
	for(int sb = numStateBlocks-1; sb >= 0; --sb)
	{
		const MFStateBlock *pSB = ppStateBlocks[sb];
		if(!pSB)
			continue;

		// get a mask of the bools that have not been set
		uint32 boolsToSet = pSB->boolsSet & ~state.rsSet[MFSB_CT_Bool];

		// mark bools as set
		state.rsSet[MFSB_CT_Bool] |= boolsToSet;

		// set the bool states
		state.bools = (state.bools & ~boolsToSet) | (pSB->bools & boolsToSet);

		// set render states
		const MFStateBlock::MFStateBlockStateChange *pStateChanges = pSB->GetStateChanges();
		for(int s = 0; s < pSB->numStateChanges; ++s)
		{
			const MFStateBlock::MFStateBlockStateChange &sc = pStateChanges[s];

			// if the state was cleared, of already set, skip it...
			if(!sc.stateSet || state.isSet(sc.constantType, sc.constant))
				continue;

			// mark as set
			state.rsSet[sc.constantType] |= MFBIT(sc.constant);

			// set the state
			const void *pData = pSB->GetStateData(sc.offset*4);

			switch(sc.constantType)
			{
				case MFSB_CT_Vector:
					if(state.pVectorStates[sc.constant] != (MFVector*)pData)
						state.pVectorStates[sc.constant] = (MFVector*)pData;
					break;
				case MFSB_CT_Matrix:
					if(state.pMatrixStates[sc.constant] != (MFMatrix*)pData)
					{
						state.pMatrixStates[sc.constant] = (MFMatrix*)pData;

						// ** HACK ** - Managed matrices need to dirty the derived matrices!
						if(sc.constant >= MFSCM_ManagedStart && sc.constant < MFSCM_ManagedStart + MFSCM_NumManaged)
						{
							switch(sc.constant)
							{
								case MFSCM_World:
									state.derivedMatrixDirty |= MFBIT(MFSCM_WorldView) | MFBIT(MFSCM_WorldViewProjection) | MFBIT(MFSCM_InverseWorld);
									state.pMatrixStates[MFSCM_WorldView] = NULL;
									state.pMatrixStates[MFSCM_WorldViewProjection] = NULL;
									state.pMatrixStates[MFSCM_InverseWorld] = NULL;
									break;
								case MFSCM_Camera:
									state.derivedMatrixDirty |= MFBIT(MFSCM_View) | MFBIT(MFSCM_WorldView) | MFBIT(MFSCM_ViewProjection) | MFBIT(MFSCM_WorldViewProjection) | MFBIT(MFSCM_InverseViewProjection);
									state.pMatrixStates[MFSCM_View] = NULL;
									state.pMatrixStates[MFSCM_WorldView] = NULL;
									state.pMatrixStates[MFSCM_ViewProjection] = NULL;
									state.pMatrixStates[MFSCM_WorldViewProjection] = NULL;
									state.pMatrixStates[MFSCM_InverseViewProjection] = NULL;
									break;
								case MFSCM_Projection:
									state.derivedMatrixDirty |= MFBIT(MFSCM_ViewProjection) | MFBIT(MFSCM_WorldViewProjection) | MFBIT(MFSCM_InverseViewProjection);
									state.pMatrixStates[MFSCM_ViewProjection] = NULL;
									state.pMatrixStates[MFSCM_WorldViewProjection] = NULL;
									state.pMatrixStates[MFSCM_InverseViewProjection] = NULL;
									break;
								default:
									MFUNREACHABLE;
									break;
							}
						}
					}
					break;
				case MFSB_CT_Texture:
					if(state.pTextures[sc.constant] != *(MFTexture**)pData)
						state.pTextures[sc.constant] = *(MFTexture**)pData;
					break;
				case MFSB_CT_RenderState:
					if(state.pRenderStates[sc.constant] != *(void**)pData)
						state.pRenderStates[sc.constant] = *(void**)pData;
					break;
				case MFSB_CT_Misc:
					switch(sc.constant)
					{
						case MFSCMisc_AnimationMatrices:
							state.animation = *(MFStateConstant_AnimationMatrices*)pData;
							break;
						case MFSCMisc_MatrixBatch:
							state.matrixBatch = *(MFStateConstant_MatrixBatch*)pData;
							break;
						case MFSCMisc_Viewport:
							state.pViewport = (MFRect*)pData;
							break;
						default:
							MFUNREACHABLE;
							break;
					}
					break;
				default:
					continue;
			}
		}
	}
}