Example #1
0
// Helper function which checks whether the current context is registered in an active renderer node
static inline bool IsContextRegistered(VisRenderContext_cl *pContext)
{
  for (int iRendererNode=0; iRendererNode<Vision::Renderer.GetRendererNodeCount(); iRendererNode++)
  {
    IVRendererNode *pNode = Vision::Renderer.GetRendererNode(iRendererNode);
    if (pNode)
    {
      if (pNode->IsContextRegistered(pContext))
        return true;
    }
  }

  return false;
}
void VTimeOfDayComponent::UpdateParent()
{
  IVTimeOfDay *pTimeOfDayInterface = Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);
  vDirection.normalizeIfNotZero();

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef sunColor = pTimeOfDayInterface->GetSunColor();

    bool bSwitchable = (AttachmentType == TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE);
    float fBelowHorizonMultiplier = hkvMath::pow (hkvMath::Max(-vDirection.z+0.1f, 0.0f), bSwitchable ? 1.0f : 0.1f);
    fBelowHorizonMultiplier = hkvMath::Min(1.0f, fBelowHorizonMultiplier);

    if (bSwitchable && fBelowHorizonMultiplier < 1.0f && fBelowHorizonMultiplier > 0.f)
    {
      pLight->SetColor(m_iColor);
      pLight->SetMultiplier(Intensity * (1.0f - fBelowHorizonMultiplier));
    }
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE)
    {
      pLight->SetColor(sunColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier);
    }
    else if ((AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE) ||
             (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE))
    {
      // TODO
      VColorRef negativeColor = V_RGBA_WHITE - sunColor;
      pLight->SetColor(negativeColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier * 0.333f);
    }  
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
    {
      hkvVec3 vSunColorFloat = sunColor.ToFloat();
      float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
      if (fLargestComponent <= 0.0f)
        fLargestComponent = 1.0f;
      sunColor.FromFloat(vSunColorFloat * (1.0f / fLargestComponent));

      pLight->SetColor(sunColor * fBelowHorizonMultiplier);
      pLight->SetMultiplier(0.0f);
    }
  }
}
Example #3
0
//Update, render and display the scene
bool VisionApp_cl::Run()
{
  static bool bInsideGameLoop = false;

  // Make sure the game loop isn't executed recursively. In Windows builds, this could for example happen if a shown message box triggers
  // a repaint message. This case needs to be handled by the code calling the game loop.
  if(bInsideGameLoop)
  {
    // We can't report this error in a form that could trigger a message box, so reporting a warning and breaking the debugger is the best we can do.
    Vision::Error.Warning("VisionApp_cl::Run called recursively! This is usually caused by triggering a repaint from inside the game loop.");

#if defined(HK_DEBUG)
    VDBGBREAK;
#endif

    // Just skip the game loop - this may invoke weird behavior if the calling code expects the game loop to complete, but is better
    // than recursing
    return true;
  }

  bInsideGameLoop = true;

  //Update the scene
  m_iUpdateSceneTickCount = 1; // by default one simulation tick per loop
  if (m_spUpdateSceneController!=NULL)
    m_iUpdateSceneTickCount = m_spUpdateSceneController->GetUpdateTickCount();

  for (int i=0;i<m_iUpdateSceneTickCount;i++)
  {
    OnUpdateScene();
    if (i<m_iUpdateSceneTickCount-1) // the last one is performed after rendering
    {
      OnFinishScene();
      UpdateTimer();
    }
  }

  // update everything that has to be done once per loop rather than per simulation steps
  OnFrameUpdatePreRender();

  Vision::Profiling.Update();

  VASSERT_MSG(Vision::Renderer.GetRendererNode(0) != NULL, "No renderer node is set. This isn't supported anymore. Use a VSimpleRendererNode instead of registering the main context globally.");

  // If in debug build, perform a sanity check - no context registered with the main context should also be registered
  // with a renderer node!
#ifdef HK_DEBUG_SLOW
  static bool bContextErrorShown = false;
  if (!bContextErrorShown)
  {
    int iContextCount = Vision::Contexts.GetContextCount();
    for (int iContext = 0; iContext < iContextCount; iContext++)
    {
      for (int iRendererNode=0; iRendererNode<V_MAX_RENDERER_NODES; iRendererNode++)
      {
        IVRendererNode *pNode = Vision::Renderer.GetRendererNode(iRendererNode);
        VisRenderContext_cl* pContext = Vision::Contexts.GetContext(iContext);
        if (pNode != NULL && pNode->IsContextRegistered(Vision::Contexts.GetContext(iContext)))
        {
          Vision::Error.Warning("Context %s (%p) is registered globally AND in renderer node %s (%p). This may be intended, but it is most likely a porting issue introduced by porting from a pre-8.0 version of the Vision Engine.",
            pContext->GetName(), pContext, pNode->GetTypeId()->m_lpszClassName, pNode);
          bContextErrorShown = true;
        }
      }
    }
  }
#endif

  {
    INSERT_PERF_MARKER_SCOPE("BeginRendering");

    // Inform the renderer that we are now going to start rendering
    Vision::Renderer.BeginRendering();
    Vision::Callbacks.BeginRendering.TriggerCallbacks();
  }


  Vision::Renderer.SetCurrentRendererNode(NULL);
  VisRendererNodeDataObject_cl data(&Vision::Callbacks.OnRendererNodeSwitching, NULL);
  Vision::Callbacks.OnRendererNodeSwitching.TriggerCallbacks(&data);


  {
    INSERT_PERF_MARKER_SCOPE("PreRendererNodeContexts");
    Vision::Contexts.PerformVisibilityTests();
    Vision::Contexts.RenderContexts(-FLT_MAX, VIS_RENDERCONTEXTPRIORITY_SCENE);
  }

  {
    for (int iRendererNode=0; iRendererNode<V_MAX_RENDERER_NODES; iRendererNode++)
    {
      IVRendererNode *pNode = Vision::Renderer.GetRendererNode(iRendererNode);

      if (pNode != NULL && pNode->GetRenderingEnabled())
      {
        char buffer[192];
        sprintf(buffer, "RendererNode %d (%s)", iRendererNode, pNode->GetTypeId()->m_lpszClassName);
        INSERT_PERF_MARKER_SCOPE(buffer);

        VASSERT_MSG(pNode->IsInitialized(), "Renderer Node is registered and enabled, but not initialized");
        pNode->Execute();
      }
    }
  }

  {
    INSERT_PERF_MARKER_SCOPE("PostRendererNodeContexts");
    Vision::Renderer.SetCurrentRendererNode(NULL);
    Vision::Contexts.RenderContexts(VIS_RENDERCONTEXTPRIORITY_SCENE, FLT_MAX);
  }

  {
    INSERT_PERF_MARKER_SCOPE("EndRendering");

    // Tell the renderer that we have finished rendering
    Vision::Callbacks.EndRendering.TriggerCallbacks();
    Vision::Renderer.EndRendering();
  }

  //Finish the scene - the last tick is performed here
  if (m_iUpdateSceneTickCount>0)
    OnFinishScene();

  // update everything that has to be done once per loop rather than per simulation steps
  OnFrameUpdatePostRender();

  //Display the scene
  Vision::Callbacks.OnBeforeSwapBuffers.TriggerCallbacks();
#ifdef WIN32
  if (m_bUpdateScreen) // only supported on win32
#endif
    Vision::Video.UpdateScreen();

  if (m_iUpdateSceneTickCount>0) // same as for OnFinishScene
    UpdateTimer();

  bInsideGameLoop = false;

  return !WantsToQuit();
}
void VTimeOfDayComponent::UpdateParent()
{
  VTimeOfDay *pTimeOfDayInterface = (VTimeOfDay*)Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);

  // The Moon and back light direction is calculated from the Sun direction
  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  // Set the color and intensity of the light
  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef color;
    float intensity = 0.0f;

    switch (AttachmentType)
    {
    case TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE:
      {
        color = m_iColor;
        const float fMarginNearHorizon = 0.1f; //10% - Margin above the horizon to switch lights ON/OFF
        const float fBelowHorizonMultiplier = hkvMath::Max(-vDirection.z + fMarginNearHorizon, 0.0f);
        intensity = 1.0f - hkvMath::Min(1.0f, fBelowHorizonMultiplier);
        break;
      }
    case TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        hkvVec3 vSunColorFloat = color.ToFloat();
        float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
        if (fLargestComponent > 0.0f)
        {
          color.FromFloat(vSunColorFloat / fLargestComponent);
        }      
        intensity = 0.0f;
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        intensity = pTimeOfDayInterface->GetSunIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetBackLightColor();
        intensity = pTimeOfDayInterface->GetBackLightIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetMoonColor();
        intensity = pTimeOfDayInterface->GetMoonIntensity();
        break;
      }
    default:
      VASSERT_MSG(0,"Unknown time of day attachment type");
    }

    pLight->SetColor(color);
    pLight->SetMultiplier(intensity * Intensity);    
  }
}