void UniformHandler::BindFrameUniform(const Uniform& sUniform)
	{
		EUniformSemantic eSemantic = sUniform.getSemantic();
		unsigned int index = sUniform.getIdx();
		_ASSERT(getFlag(eSemantic,index));

		switch(eSemantic)
		{
		case eUsVIEW:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mView.f);
			}
			break;
		case eUsVIEWI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewI.f);
			}
			break;
		case eUsVIEWIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewIT.f);
			}
			break;
		case eUsPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjection.f);
			}
			break;
		case eUsPROJECTIONI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjectionI.f);
			}
			break;
		case eUsPROJECTIONIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjectionIT.f);
			}
			break;
		case eUsVIEWPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjection.f);
			}
			break;
		case eUsVIEWPROJECTIONI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjectionI.f);
			}
			break;
		case eUsVIEWPROJECTIONIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjectionIT.f);
			}
			break;
		case eUsLIGHTCOLOR:
			{
				glUniform3f(sUniform.getLocation(), m_pfLightColor[index][0],
					m_pfLightColor[index][1], m_pfLightColor[index][2]);
			}
			break;
		case eUsLIGHTPOSWORLD:
			{
				glUniform3f(sUniform.getLocation(), m_vLightPosWorld[index].x,
					m_vLightPosWorld[index].y, m_vLightPosWorld[index].z);
			}
			break;
		case eUsLIGHTPOSEYE:
			{
				glUniform3f(sUniform.getLocation(), m_vLightPosEye[index].x,
					m_vLightPosEye[index].y, m_vLightPosEye[index].z);
			}
			break;
		case eUsLIGHTDIRWORLD:
			{
				glUniform3f(sUniform.getLocation(), m_vLightDirWorld[index].x,
					m_vLightDirWorld[index].y, m_vLightDirWorld[index].z);
			}
			break;
		case eUsLIGHTDIREYE:
			{
				glUniform3f(sUniform.getLocation(), m_vLightDirEye[index].x,
					m_vLightDirEye[index].y, m_vLightDirEye[index].z);
			}
			break;
		case eUsEYEPOSWORLD:
			{
				glUniform3f(sUniform.getLocation(),
					m_vEyePositionWorld.x, m_vEyePositionWorld.y, m_vEyePositionWorld.z);
			}
			break;
		case eUsANIMATION:
			{
				glUniform1f(sUniform.getLocation(), m_fAnimation);
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-frame uniform being interpreted as frame uniform\n");
				return;
			}
		}
	}
	void UniformHandler::CalculateMeshUniform(const Uniform& sUniform, SPODMesh *pMesh, SPODNode *pNode)
	{
		switch(sUniform.getSemantic())
		{
		case eUsPosition:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsNormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsTangent:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sTangents.nStride, pMesh->sTangents.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBinormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->sBinormals.nStride, pMesh->sBinormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsUV:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneIndex:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneIdx.n, GL_UNSIGNED_BYTE, GL_FALSE, pMesh->sBoneIdx.nStride, pMesh->sBoneIdx.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneWeight:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneWeight.n, GL_FLOAT, GL_FALSE, pMesh->sBoneWeight.nStride, pMesh->sBoneWeight.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsWORLD:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorld.f);
			}
			break;
		case eUsWORLDI:
			{
				PVRTMat4 mWorldI;
				mWorldI =  m_mWorld.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldI.f);
			}
			break;
		case eUsWORLDIT:
			{
				PVRTMat3 mWorldIT;
				mWorldIT = m_mWorld.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldIT.f);
			}
			break;
		case eUsWORLDVIEW:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldView.f);
			}
			break;
		case eUsWORLDVIEWI:
			{
				PVRTMat4 mWorldViewI;
				mWorldViewI = m_mWorldView.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewI.f);
			}
			break;
		case eUsWORLDVIEWIT:
			{
				PVRTMat3 mWorldViewIT;
				mWorldViewIT = m_mWorldView.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewIT.f);
			}
			break;
		case eUsWORLDVIEWPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldViewProjection.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONI:
			{
				PVRTMat4 mWorldViewProjectionI = (m_mProjection * m_mWorldView ).inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionI.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONIT:
			{
				PVRTMat3 mWorldViewProjectionIT = (m_mProjection * m_mWorldView).inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionIT.f);
			}
			break;
		case eUsLIGHTPOSMODEL:
			{
				// Passes the light position in eye space to the shader
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypePoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				case eLightTypePODPoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPODPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				default:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						// if you hit this code then the types of your lights do not match the types expected by your shaders
						PVRTVec4 vLightPosModel = (((LightDirectional*)pLight)->getDirectionPVRTVec4()*c_fFarDistance) ;
						vLightPosModel.w = f2vt(1.0f);
						vLightPosModel = m_mWorld * vLightPosModel;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
				}
			}
			break;
		case eUsOBJECT:
			{
				// Scale
				PVRTMat4 mObject = m_psScene->GetScalingMatrix(*pNode);
				// Rotation
				mObject = m_psScene->GetRotationMatrix(*pNode) * mObject;
				// Translation
				mObject = m_psScene->GetTranslationMatrix(*pNode) * mObject;

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mObject.f);
			}
			break;
		case eUsOBJECTI:
			{
				if(!getFlag(eUsOBJECT))
				{
					// Scale
					m_mObject = m_psScene->GetScalingMatrix(*pNode);
					// Rotation
					m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
					// Translation
					m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
					setFlag(eUsOBJECT);
				}
				m_mObjectI = m_mObject.inverse();

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectI.f);
			}
			break;
		case eUsOBJECTIT:
			{
				if(!getFlag(eUsOBJECTI))
				{
					if(!getFlag(eUsOBJECT))
					{
						// Scale
						m_mObject = m_psScene->GetScalingMatrix(*pNode);
						// Rotation
						m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
						// Translation
						m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
						setFlag(eUsOBJECT);
					}
					m_mObjectI = m_mObject.inverse();
					setFlag(eUsOBJECTI);
				}

				m_mObjectIT = PVRTMat3(m_mObjectI).transpose();

				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectIT.f);
			}
			break;
		case eUsLIGHTDIRMODEL:
			{
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypeDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				case eLightTypePODDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				default:
					{	// could mimic point lights
						// calculate vector between light position and mesh

						// implemented by getting hold of the nice centre point I calculated for all these meshes and using this point
					}
				}
			}
			break;
		case eUsEYEPOSMODEL:
			{	
				m_vEyePositionModel = m_mWorld.inverse() * PVRTVec4(m_vEyePositionWorld,VERTTYPE(1.0f));
				glUniform3f(sUniform.getLocation(), m_vEyePositionModel.x, m_vEyePositionModel.y, m_vEyePositionModel.z);
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-mesh uniform being interpreted as mesh uniform\n");
				return;
			}
		}
	}
Beispiel #3
0
void Mesh::draw()
{

    //TODO: not get stuff out of Material and use, but tell Material to init instead
    UniformHandler *pUniformHandler = m_pMaterial->getUniformHandler();

    switch(m_eDrawMode)
    {
    case eNormal:
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_gluBuffer);
        // activates all frame and material uniforms required for mesh
        if(!m_pMaterial->activate())
            ConsoleLog::inst().log("Material %s failed to activate",m_pMaterial->getName().c_str());

        dynamicArray<Uniform> *pdaMeshUniforms = m_pMaterial->getMeshUniforms();
        for(int i=0; i<pdaMeshUniforms->getSize(); i++)
        {
            pUniformHandler->CalculateMeshUniform((*pdaMeshUniforms)[i],m_psMesh, m_psNode);
        }
        if(m_pMaterial->getSkinned())
            DrawSkinned();
        else
            DrawMesh();
        m_pMaterial->deactivateArrays();

    }
    break;
    case eWireframe:
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_gluBuffer);
        // activates all frame and material uniforms required for mesh
        if(!m_pMaterial->activate())
            ConsoleLog::inst().log("Material %s failed to activate",m_pMaterial->getName().c_str());

        dynamicArray<Uniform> *pdaMeshUniforms = m_pMaterial->getMeshUniforms();
        for(int i=0; i<pdaMeshUniforms->getSize(); i++)
        {
            pUniformHandler->CalculateMeshUniform((*pdaMeshUniforms)[i],m_psMesh);
        }
        DrawWireframeMesh();
        m_pMaterial->deactivateArrays();

    }
    break;
    case eWireframeNoFX:
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_gluBuffer);
        // activates all frame and material uniforms required for mesh
        Material *pMaterial = m_pMaterial->getMaterialManager()->getFlatMaterial();
        if(!pMaterial->activate())
            ConsoleLog::inst().log("Material %s failed to activate",m_pMaterial->getName().c_str());

        dynamicArray<Uniform> *pdaMeshUniforms = pMaterial->getMeshUniforms();
        for(int i=0; i<pdaMeshUniforms->getSize(); i++)
        {
            pUniformHandler->CalculateMeshUniform((*pdaMeshUniforms)[i],m_psMesh);
        }
        DrawWireframeMesh();
        pMaterial->deactivateArrays();
    }
    break;
    case eNoFX:
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_gluBuffer);
        // activates all frame and material uniforms required for mesh
        Material *pMaterial = m_pMaterial->getMaterialManager()->getFlatMaterial();
        if(!pMaterial->activate())
            ConsoleLog::inst().log("Material %s failed to activate",m_pMaterial->getName().c_str());

        dynamicArray<Uniform> *pdaMeshUniforms = pMaterial->getMeshUniforms();
        for(int i=0; i<pdaMeshUniforms->getSize(); i++)
        {
            pUniformHandler->CalculateMeshUniform((*pdaMeshUniforms)[i],m_psMesh);
        }
        DrawMesh();
        pMaterial->deactivateArrays();
    }
    break;
    case eBounds:	// always uses flat material so I can hardwire stuff
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_gluBoundsBuffer);
        // activates all frame and material uniforms required for mesh
        Material *pMaterial = m_pMaterial->getMaterialManager()->getFlatMaterial();
        if(!pMaterial->activate())
            ConsoleLog::inst().log("Material %s failed to activate",m_pMaterial->getName().c_str());
        dynamicArray<Uniform> *pdaMeshUniforms = pMaterial->getMeshUniforms();
        for(int i=0; i<pdaMeshUniforms->getSize(); i++)
        {
            Uniform sUniform = (*pdaMeshUniforms)[i];
            if(sUniform.getSemantic()!=eUsPosition)
            {
                pUniformHandler->CalculateMeshUniform(sUniform,m_psMesh);
            }
            else
            {
                glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, 0, NULL);
                glEnableVertexAttribArray(sUniform.getLocation());
            }
        }
        DrawBounds();
        pMaterial->deactivateArrays();
    }
    break;
    default:
    {
        ConsoleLog::inst().log("Unrecognised drawing mode\n");
    }
    }

}