//----------------------------------------------------------------------------- void CPUT_DX11::UpdatePerFrameConstantBuffer( double totalSeconds ) { if( mpPerFrameConstantBuffer ) { ID3D11Buffer *pBuffer = mpPerFrameConstantBuffer->GetNativeBuffer(); // update parameters of constant buffer D3D11_MAPPED_SUBRESOURCE mapInfo; mpContext->Map( pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo ); { // TODO: remove construction of XMM type CPUTFrameConstantBuffer *pCb = (CPUTFrameConstantBuffer*)mapInfo.pData; CPUTCamera *pCamera = gpSample->GetCamera(); if( pCamera ) { pCb->View = XMMATRIX((float*)pCamera->GetViewMatrix()); pCb->Projection = XMMATRIX((float*)pCamera->GetProjectionMatrix()); } pCb->LightColor = XMLoadFloat3(&XMFLOAT3((float*)&mLightColor)); // TODO: Get from light float totalSecondsFloat = (float)totalSeconds; pCb->TotalSeconds = XMLoadFloat(&totalSecondsFloat); pCb->AmbientColor = XMLoadFloat3(&XMFLOAT3((float*)&mAmbientColor)); } mpContext->Unmap(pBuffer,0); } }
CPUTCamera *CPUTAssetLibrary::GetCameraByName(const cString &name) { CPUTCamera *pCamera = (CPUTCamera *) FindAssetByName(name, mpCameraList); if (pCamera != NULL) { pCamera->AddRef(); return pCamera; } return NULL; }
//----------------------------------------------------------------------------- CPUTCamera *CPUTAssetLibrary::GetCamera(const cString &name) { // TODO: Should we prefix camera names with a path anyway? To keek them unique? // If we already have one by this name, then return it CPUTCamera *pCamera = FindCamera(name, true); if(NULL!=pCamera) { pCamera->AddRef(); return pCamera; } return NULL; }
// Set the render state before drawing this object //----------------------------------------------------------------------------- void CPUTModelDX11::UpdateShaderConstants(CPUTRenderParameters &renderParams) { ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext; D3D11_MAPPED_SUBRESOURCE mapInfo; pContext->Map( mpModelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo ); { CPUTModelConstantBuffer *pCb = (CPUTModelConstantBuffer*)mapInfo.pData; // TODO: remove construction of XMM type XMMATRIX world((float*)GetWorldMatrix()); pCb->World = world; CPUTCamera *pCamera = renderParams.mpCamera; XMVECTOR cameraPos = XMLoadFloat3(&XMFLOAT3( 0.0f, 0.0f, 0.0f )); if( pCamera ) { XMMATRIX view((float*)pCamera->GetViewMatrix()); XMMATRIX projection((float*)pCamera->GetProjectionMatrix()); float *pCameraPos = (float*)&pCamera->GetPosition(); cameraPos = XMLoadFloat3(&XMFLOAT3( pCameraPos[0], pCameraPos[1], pCameraPos[2] )); // Note: We compute viewProjection to a local to avoid reading from write-combined memory. // The constant buffer uses write-combined memory. We read this matrix when computing WorldViewProjection. // It is very slow to read it directly from the constant buffer. XMMATRIX viewProjection = view * projection; pCb->ViewProjection = viewProjection; pCb->WorldViewProjection = world * viewProjection; XMVECTOR determinant = XMMatrixDeterminant(world); pCb->InverseWorld = XMMatrixInverse(&determinant, XMMatrixTranspose(world)); } // TODO: Have the lights set their render states? XMVECTOR lightDirection = XMLoadFloat3(&XMFLOAT3( gLightDir.x, gLightDir.y, gLightDir.z )); pCb->LightDirection = XMVector3Normalize(lightDirection); pCb->EyePosition = cameraPos; float *bbCWS = (float*)&mBoundingBoxCenterWorldSpace; float *bbHWS = (float*)&mBoundingBoxHalfWorldSpace; float *bbCOS = (float*)&mBoundingBoxCenterObjectSpace; float *bbHOS = (float*)&mBoundingBoxHalfObjectSpace; pCb->BoundingBoxCenterWorldSpace = XMLoadFloat3(&XMFLOAT3( bbCWS[0], bbCWS[1], bbCWS[2] )); ; pCb->BoundingBoxHalfWorldSpace = XMLoadFloat3(&XMFLOAT3( bbHWS[0], bbHWS[1], bbHWS[2] )); ; pCb->BoundingBoxCenterObjectSpace = XMLoadFloat3(&XMFLOAT3( bbCOS[0], bbCOS[1], bbCOS[2] )); ; pCb->BoundingBoxHalfObjectSpace = XMLoadFloat3(&XMFLOAT3( bbHOS[0], bbHOS[1], bbHOS[2] )); ; // Shadow camera XMMATRIX shadowView, shadowProjection; CPUTCamera *pShadowCamera = gpSample->GetShadowCamera(); if( pShadowCamera ) { shadowView = XMMATRIX((float*)pShadowCamera->GetViewMatrix()); shadowProjection = XMMATRIX((float*)pShadowCamera->GetProjectionMatrix()); pCb->LightWorldViewProjection = world * shadowView * shadowProjection; } } pContext->Unmap(mpModelConstantBuffer,0); }
bool drawCallback(CPUTModel* pModel, CPUTRenderParameters &renderParams, CPUTMesh* pMesh, CPUTMaterialEffect* pMaterial, CPUTMaterialEffect* , void* ) { UINT mVertexCount = 0; UINT mIndexCount = 0; int index = 0; float rows = 0.0; float columns = 0.0; float instances = 0.0; float angle_value = 0.0; // Uniform locations GLint vpMatrixBufferLoc = -1; GLint worldMatrixBufferLoc = -1; float4x4 viewProj; float4x4 parents_world; rows = (float) currentRowCount; columns = (float) currentColCount; angle_value = 360.0 / columns; const int numInstances = (int)columns * (int) rows; pMaterial->SetRenderStates(renderParams); parents_world = pModel->GetParentsWorldMatrix(); CPUTCamera *pCamera = renderParams.mpCamera; // Set Uniform Data if(pCamera) { viewProj = *pCamera->GetViewMatrix() * *pCamera->GetProjectionMatrix(); } // Drawing mVertexCount = ((CPUTMeshOGL*)pMesh)->GetVertexCount(); mIndexCount = ((CPUTMeshOGL*)pMesh)->GetIndexCount(); CPUTBufferOGL * mpIndexBuffer = ((CPUTMeshOGL*)pMesh)->GetIndexBuffer(); if(mVertexCount == 0 && mIndexCount == 0) return false; ((CPUTMeshOGL*)pMesh)->EnableVertexArray(); CPUTMaterialEffectOGL *pMatEffect = (CPUTMaterialEffectOGL*) pMaterial; GLuint shaderProgID = pMatEffect->GetShaderID(); vpMatrixBufferLoc = glGetUniformLocation( shaderProgID, "viewProjMatrix" ); worldMatrixBufferLoc = glGetUniformLocation( shaderProgID, "worldMatrix" ); if( isInstanced ) { glUniformMatrix4fv( vpMatrixBufferLoc, 1, GL_FALSE, (const GLfloat *) &viewProj ); glUniformMatrix4fv( worldMatrixBufferLoc, numInstances, GL_FALSE, (const GLfloat *) &world[0] ); if(mpIndexBuffer != NULL) GL_CHECK(glDrawElementsInstancedEXT( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_INT, NULL, numInstances )); else GL_CHECK(glDrawArraysInstanced(GL_TRIANGLES, 0, numInstances, mVertexCount)); } else { index = 0; glUniformMatrix4fv( vpMatrixBufferLoc, 1, GL_FALSE, (const GLfloat *) &viewProj ); for (int i = 0; i < rows; ++i) { for (int j = 0; j < columns; ++j) { glUniformMatrix4fv( worldMatrixBufferLoc, 1, GL_FALSE, (const GLfloat *) &world[index] ); if(mpIndexBuffer != NULL) GL_CHECK(glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_INT, NULL)); else GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, mVertexCount)); ++index; } } } ((CPUTMeshOGL*)pMesh)->DisableVertexArray(); glUseProgram(0); return true; }
// Set the render state before drawing this object //----------------------------------------------------------------------------- void CPUTModelOGL::UpdateShaderConstants(CPUTRenderParameters &renderParams) { float4x4 world(*GetWorldMatrix()); float4x4 NormalMatrix(*GetWorldMatrix()); //Local transform if node baked into animation if(mSkeleton && mpCurrentAnimation) { world = GetParentsWorldMatrix(); NormalMatrix = GetParentsWorldMatrix(); } if( renderParams.mpPerModelConstants ) { CPUTBufferOGL *pBuffer = (CPUTBufferOGL*)(renderParams.mpPerModelConstants); CPUTModelConstantBuffer cb; cb.World = world; cb.InverseWorld = cb.World; cb.InverseWorld.invert(); CPUTCamera *pCamera = renderParams.mpCamera; if(pCamera) { cb.WorldViewProjection = cb.World * *pCamera->GetViewMatrix() * *pCamera->GetProjectionMatrix(); } float4x4 shadowView, shadowProjection; CPUTCamera *pShadowCamera = gpSample->GetShadowCamera(); if( pShadowCamera ) { shadowView = *pShadowCamera->GetViewMatrix(); shadowProjection = *pShadowCamera->GetProjectionMatrix(); cb.LightWorldViewProjection = cb.World * shadowView * shadowProjection; } cb.BoundingBoxCenterWorldSpace = float4(mBoundingBoxCenterWorldSpace, 0); cb.BoundingBoxHalfWorldSpace = float4(mBoundingBoxHalfWorldSpace, 0); cb.BoundingBoxCenterObjectSpace = float4(mBoundingBoxCenterObjectSpace, 0); cb.BoundingBoxHalfObjectSpace = float4(mBoundingBoxHalfObjectSpace, 0); //TODO: Should this process if object not visible? //Only do this if Model has a skin and is animated if(mSkeleton && mpCurrentAnimation) { ASSERT(0, _L("Skinning constant buffer temporarily disabled")); //ASSERT(mSkeleton->mNumberOfJoints < 255, _L("Skin Exceeds maximum number of allowable joints: 255")); //for(UINT i = 0; i < mSkeleton->mNumberOfJoints; ++i) //{ // CPUTJoint *pJoint = &mSkeleton->mJointsList[i]; // cb.SkinMatrix[i] = pJoint->mInverseBindPoseMatrix * pJoint->mScaleMatrix * pJoint->mRTMatrix; // float4x4 skinNormalMatrix = cb.SkinMatrix[i]; // skinNormalMatrix.invert(); skinNormalMatrix.transpose(); // cb.SkinNormalMatrix[i] = skinNormalMatrix; //} } #ifndef CPUT_FOR_OGLES2 pBuffer->SetSubData(0, sizeof(CPUTModelConstantBuffer), &cb); #else #warning "Need to do something with uniform buffers here" #endif } }