void Application::Render( void ) { if (!m_initialized) { return; } for (unsigned i = 0; i < m_sceneObjectList.size(); i++) { SceneObject* object = m_sceneObjectList[i]; Material* material = object->GetMaterial(); if (object->IsHidden()) { continue; } RenderUnit* renderUnit = new RenderUnit(); renderUnit->m_vb = object->GetMesh()->GetVertexBuffer(); renderUnit->m_ib = object->GetMesh()->GetIndexBuffer(); renderUnit->m_wireFrame = material->wireFrame; int vertexShaderId = m_renderer->GetShadeMode() == Renderer::SHADING_MODE_PHONG ? material->vertexShaderId : (material->vertexShaderId == VS_TANGENT_SPACE_LIGHTING_SC2_UV ? VS_FIXED_FUNCTION_ALT_UV : VS_FIXED_FUNCTION); int pixelShaderId = m_renderer->GetShadeMode() == Renderer::SHADING_MODE_PHONG ? material->pixelShaderId : PS_FIXED_FUNCTION; switch (vertexShaderId) { case VS_FIXED_FUNCTION: { VsFixedFunction* myVS = new VsFixedFunction(); renderUnit->m_vs = myVS; Matrix4 worldMatrix; object->GetWorldMatrix(worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; myVS->ambientColor = m_activeLight->ambientColor; myVS->diffuseColor = m_activeLight->diffuseColor; } break; case VS_FIXED_FUNCTION_ALT_UV: { VsFixedFunctionAltUv* myVS = new VsFixedFunctionAltUv(); renderUnit->m_vs = myVS; Matrix4 worldMatrix; object->GetWorldMatrix(worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; myVS->ambientColor = m_activeLight->ambientColor; myVS->diffuseColor = m_activeLight->diffuseColor; } break; case VS_TANGENT_SPACE_LIGHTING: { VsTangentSpaceLighting* myVS = new VsTangentSpaceLighting(); renderUnit->m_vs = myVS; object->GetWorldMatrix(myVS->worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, myVS->worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; } break; case VS_TANGENT_SPACE_LIGHTING_SC2_UV: { VsTangentSpaceLightingSc2Uv* myVS = new VsTangentSpaceLightingSc2Uv(); renderUnit->m_vs = myVS; object->GetWorldMatrix(myVS->worldMatrix); MatrixTranspose(myVS->inverseWorldMatrix, myVS->worldMatrix); // This only works when there is no translation // or scaling!!! MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldMatrix, m_activeCamera->GetViewMatrix()); MatrixMultiply(myVS->worldViewProjMatrix, myVS->worldViewProjMatrix, m_activeCamera->GetProjMatrix()); myVS->lightPosition = m_activeLight->position; } break; default: break; } switch (pixelShaderId) { case PS_FIXED_FUNCTION: { PsFixedFunction* myPS = new PsFixedFunction(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); } break; case PS_NORMAL_MAP: { PsNormalMap* myPS = new PsNormalMap(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); myPS->normalTexture = m_textureManager->GetTexture(material->bumpTextureId); myPS->diffuseColor = m_activeLight->diffuseColor; myPS->ambientColor = m_activeLight->ambientColor; } break; case PS_TOON_LIGHTING: { PsToonLighting* myPS = new PsToonLighting(); renderUnit->m_ps = myPS; myPS->baseTexture = m_textureManager->GetTexture(material->baseTextureId); myPS->diffuseColor = m_activeLight->diffuseColor; myPS->ambientColor = m_activeLight->ambientColor; } break; default: break; } m_renderer->AddRenderUnit(renderUnit); } m_backBuffer->Clear(); m_depthBuffer->Clear(); m_renderer->SetRenderTarget(m_backBuffer, m_depthBuffer); m_renderer->Render(); m_backBuffer->Present(); }
//----------------------------------------------------------------------------- // Returns the result of a ray intersection with the scene and all its objects. //----------------------------------------------------------------------------- bool SceneManager::RayIntersectScene( RayIntersectionResult *result, D3DXVECTOR3 rayPosition, D3DXVECTOR3 rayDirection, bool checkScene, SceneObject *thisObject, bool checkObjects ) { float hitDistance = 0.0f; // Check if the ray needs to check for intersection with the scene. if( checkScene == true ) { // Go through all the faces in the scene, check for intersection. for( unsigned long f = 0; f < m_totalFaces; f++ ) { // Skip this face if its material is set to ignore rays. if( m_faces[f].renderCache->GetMaterial()->GetIgnoreRay() == true ) continue; // Check the ray against this face. if( D3DXIntersectTri( (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex0], (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex1], (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex2], &rayPosition, &rayDirection, NULL, NULL, &hitDistance ) == TRUE ) { if( hitDistance < result->distance || result->material == NULL ) { ( *result ).distance = hitDistance; ( *result ).material = m_faces[f].renderCache->GetMaterial(); } } } } // Check if the ray needs to check for intersection with the objects. if( checkObjects == true ) { // Stores the ray in model space. D3DXVECTOR3 rp, rd; // Iterate all the objects in the scene, check for intersection. SceneObject *object = m_dynamicObjects->GetFirst(); while( object != NULL ) { // Only check this object if it is enabled, has a mesh and is not // the calling object. if( object->GetEnabled() == true && object->GetMesh() != NULL && object != thisObject ) { // Transform the ray into model space. D3DXMATRIX inverse; D3DXMatrixInverse( &inverse, NULL, object->GetWorldMatrix() ); D3DXVec3TransformCoord( &rp, &rayPosition, &inverse ); D3DXVec3TransformNormal( &rd, &rayDirection, &inverse ); // Go through the list of frames in the object's mesh. LinkedList< Frame > *frames = object->GetMesh()->GetFrameList(); frames->Iterate( true ); while( frames->Iterate() != NULL ) { // Ignore this frame if it has no mesh. if( frames->GetCurrent()->pMeshContainer == NULL ) continue; // Check the ray against this frame's mesh. BOOL hit; D3DXIntersect( frames->GetCurrent()->pMeshContainer->MeshData.pMesh, &rp, &rd, &hit, NULL, NULL, NULL, &hitDistance, NULL, NULL ); if( hit == TRUE && ( hitDistance < result->distance || result->material == NULL ) ) { ( *result ).distance = hitDistance; ( *result ).material = object->GetMesh()->GetStaticMesh()->materials[0]; ( *result ).hitObject = object; } } } // Go to the next object. object = m_dynamicObjects->GetNext( object ); } } // Return false if no intersection occured. if( result->material == NULL ) return false; // Calculate the point of intersection. ( *result ).point = rayPosition + rayDirection * result->distance; return true; }