int VMobileForwardRenderLoop::GetLightInfluenceArea(VisLightSource_cl *pLight)
{
  VASSERT(pLight != NULL);

  VisRenderContext_cl *pContext = VisRenderContext_cl::GetCurrentContext();
  int iScreenWidth,iScreenHeight;
  pContext->GetSize(iScreenWidth, iScreenHeight);
  if (pLight->GetType() == VIS_LIGHT_DIRECTED)
  {
    // directional lights influence the whole screen
    return (iScreenWidth*iScreenHeight); 
  }

  hkvMat4 projMatrix = pContext->GetViewProperties()->getProjectionMatrix(hkvClipSpaceYRange::MinusOneToOne);
  hkvMat4 viewMatrix = pContext->GetCamera()->GetWorldToCameraTransformation();

  // get position/ radius of bounding sphere
  hkvVec3 vPosition;
  float fRadius = 0.0f;
  if (pLight->GetType() == VIS_LIGHT_POINT)
  {
    vPosition = pLight->GetPosition();
    fRadius = pLight->GetRadius();
  }
  else if (pLight->GetType() == VIS_LIGHT_SPOTLIGHT)
  {
    hkvAlignedBBox bBox;
    pLight->GetBoundingBox(bBox);
    vPosition = bBox.getBoundingSphere().m_vCenter;
    fRadius = bBox.getBoundingSphere().m_fRadius;
  }
  else
    VASSERT_MSG(false, "Unsupported light type"); 
  
  // get corners of bounding rectangle in view space
  hkvVec4 vPositionVS = viewMatrix*vPosition.getAsVec4(1.0f);
  hkvVec4 vCorners[4];
  vCorners[0] = vPositionVS+hkvVec4(-fRadius, -fRadius, 0.0f, 0.0f);
  vCorners[1] = vPositionVS+hkvVec4(fRadius, -fRadius, 0.0f, 0.0f);
  vCorners[2] = vPositionVS+hkvVec4(fRadius, fRadius, 0.0f, 0.0f);
  vCorners[3] = vPositionVS+hkvVec4(-fRadius, fRadius, 0.0f, 0.0f); 

  // get corners of bounding rectangle in normalized device coordinates
  for (int i=0;i<4;i++)
  {
    vCorners[i] = projMatrix*vCorners[i];
    vCorners[i] /= vCorners[i].w;
  }

  // clip corners of bounding rectangle
  hkvVec2 vMin(vCorners[0].x, vCorners[0].y); 
  vMin.clampTo(hkvVec2(-1.0f, -1.0f), hkvVec2(1.0f, 1.0f));
  hkvVec2 vMax(vCorners[2].x, vCorners[2].y); 
  vMax.clampTo(hkvVec2(-1.0f, -1.0f), hkvVec2(1.0f, 1.0f));

  // calculate influence area 
  int iWidth = (int)((vMax.x-vMin.x)*0.5f*iScreenWidth);
  int iHeight = (int)((vMax.y-vMin.y)*0.5f*iScreenHeight);
  return (iWidth*iHeight);
}
void VVirtualThumbStick::SetValidArea(const VRectanglef& validArea)
{
  VRectanglef finalValidArea = validArea;
  if (!finalValidArea.IsValid())
  {
    // default area: square (width is 50% of screen height)
    const float fScreenWidth = static_cast<float>(Vision::Video.GetXRes());
    const float fScreenHeight = static_cast<float>(Vision::Video.GetYRes());
    const float fSquareWidth = hkvMath::Min(fScreenHeight, fScreenWidth) * 0.5f;

    finalValidArea.Set(
      hkvVec2(0.0f, fScreenHeight - fSquareWidth), 
      hkvVec2(fSquareWidth, fScreenHeight));
  }

  // create /resize touch area
  if (m_spTouchArea == NULL)
  {
    IVMultiTouchInput& inputDevice = static_cast<IVMultiTouchInput&>(
      VInputManager::GetInputDevice(INPUT_DEVICE_TOUCHSCREEN));
    VASSERT(&inputDevice != &VInputManager::s_NoInputDevice);

    m_spTouchArea = new VTouchArea(inputDevice, finalValidArea, -1500.0f);
  }
  else
  {
    m_spTouchArea->SetArea(finalValidArea);
  }

  m_validArea = finalValidArea;

  Reset();
}
void VSimpleCopyPostprocess::Execute()
{
  if (!IsActive() || !m_bIsInitialized)
    return;

  INSERT_PERF_MARKER_SCOPE("VSimpleCopyPostprocess");

  RenderingOptimizationHelpers_cl::SetShaderPreference(112);

  int iWidth, iHeight;
  VisRenderContext_cl *pContext = VisRenderContext_cl::GetCurrentContext();
  pContext->GetSize(iWidth, iHeight);

  Vision::RenderLoopHelper.SetScissorRect(NULL);
  Vision::RenderLoopHelper.ClearScreen();

  // On DX9 a half pixel shift is required for the copy full screen pass.
#if defined(_VR_DX9)
  const hkvVec2 texelShift(1.0f / (float)(iWidth*2), 1.0f / (float)(iHeight*2));
#else
  const hkvVec2 texelShift(0.0f, 0.0f);
#endif

  VSimpleRenderState_t iState(VIS_TRANSP_NONE,RENDERSTATEFLAG_FRONTFACE|RENDERSTATEFLAG_ALWAYSVISIBLE|RENDERSTATEFLAG_NOWIREFRAME|RENDERSTATEFLAG_NOMULTISAMPLING);
  IVRender2DInterface *pRI = Vision::RenderLoopHelper.BeginOverlayRendering();
  pRI->DrawTexturedQuad(hkvVec2(0.f,0.f), hkvVec2((float)iWidth, (float)iHeight), m_spSourceTextures[0], hkvVec2(0.0f) + texelShift, hkvVec2(1.0f) + texelShift, V_RGBA_WHITE, iState);
  Vision::RenderLoopHelper.EndOverlayRendering();
}
예제 #4
0
VRectanglef VDialogFrame::GetClientRect() const
{
  VASSERT(m_pOwner);
  VRectanglef rect = m_pOwner->GetBoundingBox();
  rect.m_vMin += hkvVec2(m_fBorderLeft,m_fBorderTop);
  rect.m_vMax -= hkvVec2(m_fBorderRight,m_fBorderBottom);
  return rect;
}
hkvVec2 VImageState::GetSize() const
{
  if (!m_spTexture)
    return hkvVec2(0,0);
  return hkvVec2(
    (float)m_spTexture->GetTextureWidth() * texCoord.GetSizeX(),
    (float)m_spTexture->GetTextureHeight() * texCoord.GetSizeY()
    );
}
void RPG_GuiManager_VisionGUI::InitializeMinimapDefinitions()
{
  const RPG_LevelInfo* levelInfo = RPG_GameManager::s_instance.GetLevelInfo();
  if (levelInfo)
  {
    // Set the minimap's image path to the path specified in the levelInfo object
    VString m_minimapTextureFilename = levelInfo->GetMinimapImagePath();
    m_minimapTexture = Vision::TextureManager.Load2DTexture(m_minimapTextureFilename.AsChar());
    VASSERT_MSG(m_minimapTexture, "m_minimapTexture failed to load.");
    VASSERT_MSG(m_minimapTexture->IsTexturePowerOfTwo(), "m_minimapTexture's dimensions must be a power of two.");

    VString m_minimapMaskTextureFilename = "GUI/Textures/minimap_mask.tga";
    m_minimapMaskTexture = Vision::TextureManager.Load2DTexture(m_minimapMaskTextureFilename.AsChar());
    VASSERT_MSG(m_minimapMaskTexture, "m_minimapMaskTexture failed to load.");
    VASSERT_MSG(m_minimapMaskTexture->IsTexturePowerOfTwo(), "m_minimapMaskTexture's dimensions must be a power of two.");

    VString m_minimapFrameTextureFilename = "GUI/Textures/minimap_frame.tga";
    m_minimapFrameTexture = Vision::TextureManager.Load2DTexture(m_minimapFrameTextureFilename.AsChar());
    VASSERT_MSG(m_minimapFrameTexture, "m_minimapFrameTexture failed to load.");
    VASSERT_MSG(m_minimapFrameTexture->IsTexturePowerOfTwo(), "m_minimapFrameTexture's dimensions must be a power of two.");

    VString m_minimapPlayerTextureFilename = "GUI/Textures/minimap_player.tga";
    m_minimapPlayerTexture = Vision::TextureManager.Load2DTexture(m_minimapPlayerTextureFilename.AsChar());
    VASSERT_MSG(m_minimapPlayerTexture, "m_minimapPlayerTexture failed to load.");
    VASSERT_MSG(m_minimapPlayerTexture->IsTexturePowerOfTwo(), "m_minimapPlayerTexture's dimensions must be a power of two.");

    // Minimap position and size	
    if (Vision::Video.GetUse2xAssetsForCurrentConfig())
    {
      m_minimapSize = hkvVec2(256.f, 256.f);
      m_minimapPosition = hkvVec2(Vision::Video.GetXRes() - m_minimapSize.x - 64.f, 64.f);
    }
    else
    {
      const float smallScreenOffset = Vision::Video.GetYRes() > SMALLSCREENSIZELIMIT ? 20.f : 0.f;
      m_minimapSize = hkvVec2(128.f, 128.f);
      m_minimapPosition = hkvVec2(Vision::Video.GetXRes() - m_minimapSize.x - (12.f + smallScreenOffset), 12.f + smallScreenOffset);
    }
    
    // Minimap image relative origin (we need this value in the range 0..1 in order to add the character position)
    hkvVec2 minimapImageDimensions = levelInfo->GetMinimapImageDimensions();
    hkvVec2 minimapImageOrigin = levelInfo->GetMinimapImageOriginPosition();
    m_minimapRelativeOrigin.x = (minimapImageOrigin.x / minimapImageDimensions.x) - (m_minimapZoomFactor * 0.5f);
    m_minimapRelativeOrigin.y = (minimapImageOrigin.y / minimapImageDimensions.y) - (m_minimapZoomFactor * 0.5f);

    // Minimap scale factor (depending on the maximum extents either horizontally or vertically)
    hkvAlignedBBox scenebox;
    Vision::GetSceneManager()->GetSceneExtents(scenebox);
    if (scenebox.getSizeX() > scenebox.getSizeY())
      m_minimapScaleFactor = (1.f / scenebox.getSizeX());
    else
      m_minimapScaleFactor = (1.f / scenebox.getSizeY());
  }
}
void RPG_GuiManager_VisionGUI::UpdateMinimap(const RPG_Character* characterEntity, const float deltaTime)
{
  if (m_minimap)
  {
    hkvVec2 pos = hkvVec2(characterEntity->GetPosition().x, characterEntity->GetPosition().y);
    float relX = m_minimapRelativeOrigin.x + (pos.x * m_minimapScaleFactor);
    float relY = m_minimapRelativeOrigin.y - (pos.y * m_minimapScaleFactor);
    m_minimap->SetTransform(hkvVec4(m_minimapZoomFactor, m_minimapZoomFactor, relX, relY));

    m_minimapPlayer->Image().m_States->CreateTransformation(m_minimapPlayerRotation, hkvVec2(0.5f, 0.5f), characterEntity->GetOrientation().x - 90.f);
    m_minimapPlayer->Image().SetTransformation(m_minimapPlayerRotation.getPointer(), NULL); 
  }
}
예제 #8
0
void VUINodeImage::OnVariableValueChanged(VisVariable_cl *pVar, const char * value)
{
	VASSERT (pVar);
	VASSERT (value);

	if (pVar->name && strcmp(pVar->name, "Texture") == 0)
	{
		VTextureObject* spTexture = Vision::TextureManager.Load2DTexture( value );
		Image().SetTexture( spTexture );
	}	
	else if (pVar->name && strcmp(pVar->name, "m_eTransp") == 0)
	{		
		sscanf(value,"%d",&m_eTransp);
		Image().SetTransparency(m_eTransp);
	}
	else if (pVar->name && strcmp(pVar->name, "m_eStretcheMode") == 0)
	{
		sscanf(value,"%d",&m_eStretcheMode);	
		Image().SetStretchMode( m_eStretcheMode );
	}
	else if (pVar->name && strcmp(pVar->name, "ShaderEffect") == 0)
	{
	

	//	Image().SetTechnique( spTexture );
	}
	else if (pVar->name && strcmp(pVar->name, "TextureRange") == 0)
	{
		float fComponents[4];
		int iCount = sscanf(value,"%f/%f/%f/%f",&fComponents[0],&fComponents[1],&fComponents[2],&fComponents[3]);
	
		VRectanglef coord;
		coord.Add( hkvVec2(fComponents[0],fComponents[1]));
		coord.Add( hkvVec2(fComponents[2],fComponents[3]));

		Image().SetTextureRange( coord );
	}
	else if (pVar->name && strcmp(pVar->name, "Color") == 0)
	{
		int iComponents[4];
		int iCount = sscanf(value,"%i/%i/%i/%i",&iComponents[0],&iComponents[1],&iComponents[2],&iComponents[3]);

		VColorRef color(iComponents[0],iComponents[1],iComponents[2],iComponents[3]);	
		SetColor( color );
	}	
}
예제 #9
0
// Read the mapped absolute touch position on mobile, mouse cursor pos on desktop
hkvVec2 PlayerUIDialog::GetCursorPosition(IVGUIContext const *context) const
{
#if defined(_VISION_MOBILE)
  float const touchX = m_inputMap->GetTrigger(PI_PrimaryActionX);
  float const touchY = m_inputMap->GetTrigger(PI_PrimaryActionY);
  return hkvVec2(touchX, touchY);
#else
  return context->GetCurrentMousePos();
#endif
}
hkvVec2 VTextState::GetSize(VRectanglef *pRect) const
{
  VRectanglef rc(false);
  if (!pRect)
    pRect = &rc;
  if (!m_spFont->GetTextDimension(m_pStringPtr->GetSafeStr(), *pRect))
    return hkvVec2();
  return pRect->m_vMax * m_fFontScaling; // otherwise we have a wrong offset
//  return pRect->GetSize();
}
예제 #11
0
void VInfoDialog::DoLayout()
{
  const float fResX = (float)Vision::Video.GetXRes();
  const float fResY = (float)Vision::Video.GetYRes();
  const float fOuterBorderWidth = VUISharedData::GetOuterBorderWidth();
  const hkvVec2 buttonSize = hkvVec2(fResX * 0.25f - fOuterBorderWidth * 1.5f, VUISharedData::GetIconSize());

  {
    VRectanglef textDimensions;
    m_pTextLabel->Text().GetFont()->GetTextDimension(m_pTextLabel->GetText(), textDimensions);

    float fTextArea = textDimensions.GetArea() * m_pTextLabel->Text().GetScaling() * m_pTextLabel->Text().GetScaling();

    // Estimate suitable text width based on text area
    float fTextWidth = hkvMath::clamp(1.4f * hkvMath::sqrt(fTextArea), fResX * 0.5f, fResX * 0.8f);

    // Set initial dialog size estimate
    SetSize(fTextWidth, fTextWidth);

    // Paint once without graphics to compute actual text size
    VTextState &state(m_pTextLabel->Text().m_States[m_pTextLabel->GetCurrentState()]);
    state.Paint(NULL, this, V_RGBA_WHITE);
    
    float fTextHeight = state.GetHeight() * m_pTextLabel->Text().GetScaling();

    // Reinvalidate computed line wrapping etc.
    state.UpdateAlignment();

    // Set final size
    float fDialogWidth = fTextWidth + fOuterBorderWidth * 2;
    float fDialogHeight = hkvMath::Min(fTextHeight + buttonSize.y + fOuterBorderWidth * 3, fResY * 0.8f);
    SetSize(fDialogWidth, fDialogHeight);
  }

  const hkvVec2 dialogSize = GetSize();

  SetPosition((fResX - dialogSize.x) * 0.5f, (fResY - dialogSize.y) * 0.5f);

  m_pTextLabel->SetSize(dialogSize.x - fOuterBorderWidth * 2, dialogSize.y - buttonSize.y - fOuterBorderWidth * 3);
  m_pTextLabel->SetPosition(fOuterBorderWidth, fOuterBorderWidth);

  const float fOkButtonWidth = m_pCancelButton->IsVisible() ? buttonSize.x : dialogSize.x - fOuterBorderWidth * 2;
  m_pOKButton->SetSize(fOkButtonWidth, buttonSize.y);
  m_pOKButton->SetPosition(fOuterBorderWidth, dialogSize.y - buttonSize.y - fOuterBorderWidth);

  m_pCancelButton->SetSize(buttonSize.x, buttonSize.y);
  m_pCancelButton->SetPosition(fOuterBorderWidth * 2 + buttonSize.x, dialogSize.y - buttonSize.y - fOuterBorderWidth);
}
void RPG_GuiManager_VisionGUI::InitializeHealthAndManaBarDefinitions()
{
  int textureSizeX, textureSizeY, textureDepth;

  m_indicatorBarTrackTextureFilename  = "GUI/Textures/ind_track.tga";
  m_indicatorBarFlareTextureFilename  = "GUI/Textures/track_flare.tga";
  m_healthBarTextureFilename          = "GUI/Textures/ind_health.tga";
  m_healthBarGlowTextureFilename      = "GUI/Textures/ind_health_glow.tga";
  m_manaBarTextureFilename            = "GUI/Textures/ind_mana.tga";
  m_manaBarGlowTextureFilename        = "GUI/Textures/ind_mana_glow.tga";

  const float offset = Vision::Video.GetUse2xAssetsForCurrentConfig() ? 32.f : 0.f;
  const float multiplier = Vision::Video.GetUse2xAssetsForCurrentConfig() ? 2.f : 1.f;
  const float smallScreenOffset = Vision::Video.GetYRes() > SMALLSCREENSIZELIMIT ? 30.f : 0.f;
  m_indicatorBarFlareOrigin = hkvVec2(72.f, 16.f) * multiplier;
  m_healthBarPosition = hkvVec2(22.f + smallScreenOffset + offset, 22.f + smallScreenOffset + offset);
  m_manaBarPosition = hkvVec2(22.f + smallScreenOffset + offset, 54.f + smallScreenOffset + offset + offset);

  m_indicatorBarTrackTexture = Vision::TextureManager.Load2DTexture(m_indicatorBarTrackTextureFilename.AsChar());
  VASSERT_MSG(m_indicatorBarTrackTexture, "m_indicatorBarTrackTexture failed to load.");
  VASSERT_MSG(m_indicatorBarTrackTexture->IsTexturePowerOfTwo(), "m_indicatorBarTrackTexture's dimensions must be a power of two.");
  m_indicatorBarTrackTexture->GetTextureDimensions(textureSizeX, textureSizeY, textureDepth);
  m_indicatorBarTrackSize = hkvVec2(static_cast<float>(textureSizeX), static_cast<float>(textureSizeY));

  m_indicatorBarFlareTexture = Vision::TextureManager.Load2DTexture(m_indicatorBarFlareTextureFilename.AsChar());
  VASSERT_MSG(m_indicatorBarFlareTexture, "m_indicatorBarFlareTexture failed to load.");
  VASSERT_MSG(m_indicatorBarFlareTexture->IsTexturePowerOfTwo(), "m_indicatorBarFlareTexture's dimensions must be a power of two.");
  m_indicatorBarFlareTexture->GetTextureDimensions(textureSizeX, textureSizeY, textureDepth);
  m_indicatorBarFlareSize = hkvVec2(static_cast<float>(textureSizeX), static_cast<float>(textureSizeY));

  m_healthBarTexture = Vision::TextureManager.Load2DTexture(m_healthBarTextureFilename.AsChar());
  VASSERT_MSG(m_healthBarTexture, "m_healthBarGlowTexture failed to load.");
  VASSERT_MSG(m_healthBarTexture->IsTexturePowerOfTwo(), "m_healthBarGlowTexture's dimensions must be a power of two.");
  m_healthBarTexture->GetTextureDimensions(textureSizeX, textureSizeY, textureDepth);
  m_indicatorBarSize = hkvVec2(static_cast<float>(textureSizeX), static_cast<float>(textureSizeY));

  m_healthBarGlowTexture = Vision::TextureManager.Load2DTexture(m_healthBarGlowTextureFilename.AsChar());
  VASSERT_MSG(m_healthBarGlowTexture, "m_healthBarGlowTexture failed to load.");
  VASSERT_MSG(m_healthBarGlowTexture->IsTexturePowerOfTwo(), "m_healthBarGlowTexture's dimensions must be a power of two.");
  m_healthBarGlowTexture->GetTextureDimensions(textureSizeX, textureSizeY, textureDepth);
  m_indicatorBarGlowSize = hkvVec2(static_cast<float>(textureSizeX), static_cast<float>(textureSizeY));

  m_manaBarTexture = Vision::TextureManager.Load2DTexture(m_manaBarTextureFilename.AsChar());
  VASSERT_MSG(m_manaBarTexture, "m_manaBarTexture failed to load.");
  VASSERT_MSG(m_manaBarTexture->IsTexturePowerOfTwo(), "m_manaBarTexture's dimensions must be a power of two.");

  m_manaBarGlowTexture = Vision::TextureManager.Load2DTexture(m_manaBarGlowTextureFilename.AsChar());
  VASSERT_MSG(m_manaBarGlowTexture, "m_manaBarGlowTexture failed to load.");
  VASSERT_MSG(m_manaBarGlowTexture->IsTexturePowerOfTwo(), "m_manaBarGlowTexture's dimensions must be a power of two.");
}
예제 #13
0
VExitDialog::VExitDialog() : VDialog(), m_bExitTriggered(false), m_bUnlockInput(false)
{
  const float fScale = VAppHelper::GetUIScalingFactor();

  const hkvVec2 vSize= hkvVec2(400.0f, 75.0f) * fScale;     ///< Size of the exit dialog
  const float fTextAreaHeight = 0.42f;                      ///< Height of the label text area in percent (height in pixel = vSize.y*fTextAreaHeight)
  const float fInnerBorder = hkvMath::ceil(1.5f * fScale);  ///< Width of the button's border
  const float fOuterBorder = 3.0f * fScale;                 ///< Width of the border between the dialogs edges and the buttons
  const float fFontScale = 0.76f * fScale;

  m_iBackColor = VAppMenuColors::GetColor(VAppMenuColors::COLOR_DIALOG_BG);
  SetSize(vSize.x, vSize.y);
  SetPosition((static_cast<float>(Vision::Video.GetXRes()) - vSize.x)*0.5f, (static_cast<float>(Vision::Video.GetYRes()) - vSize.y)*0.5f);

  VisFontPtr spFont = Vision::Fonts.LoadFont("Fonts/OpenSans_22.fnt");
  VASSERT(spFont != NULL);

  m_pLabel = new VTextLabel();
  m_pLabel->SetText("Are you sure you want to exit?");
  m_pLabel->Text().SetFont(spFont);
  m_pLabel->Text().m_States[VWindowBase::NORMAL].SetColor(VAppMenuColors::GetColor(VAppMenuColors::COLOR_LIST_ITEM_TEXT_NORMAL));
  m_pLabel->Text().m_States[VWindowBase::MOUSEOVER].SetColor(VAppMenuColors::GetColor(VAppMenuColors::COLOR_LIST_ITEM_TEXT_NORMAL));
  m_pLabel->Text().m_States[VWindowBase::SELECTED].SetColor(VAppMenuColors::GetColor(VAppMenuColors::COLOR_LIST_ITEM_TEXT_NORMAL));
  m_pLabel->Text().SetScaling(fFontScale);
  m_pLabel->Text().SetHorizontalAlignment(VisFont_cl::ALIGN_CENTER);
  m_pLabel->Text().SetVerticalAlignment(VisFont_cl::ALIGN_CENTER);
  m_pLabel->SetSize(vSize.x, vSize.y*fTextAreaHeight);
  m_pLabel->SetPosition(0.0f, 0.0f);
  m_pLabel->Text().FinishSetup();
  AddControl(m_pLabel);

  const float fInvTextAreaHeight = 1.0f - fTextAreaHeight;

  m_pCancelButton = new VStyledButton("Cancel", true, spFont, fScale, fInnerBorder, fFontScale);
  m_pCancelButton->SetSize(vSize.x*0.5f - fOuterBorder*1.5f, vSize.y*fInvTextAreaHeight - fOuterBorder*2.0f);
  m_pCancelButton->SetPosition(fOuterBorder, vSize.y*fTextAreaHeight + fOuterBorder);
  AddControl(m_pCancelButton);

  m_pExitButton = new VStyledButton("Exit", true, spFont, fScale, fInnerBorder, fFontScale);
  m_pExitButton->SetSize(vSize.x*0.5f - fOuterBorder*1.5f, vSize.y*fInvTextAreaHeight - fOuterBorder*2.0f);
  m_pExitButton->SetPosition(vSize.x*0.5f + fOuterBorder*0.5f, vSize.y*fTextAreaHeight + fOuterBorder);
  AddControl(m_pExitButton);

  m_bExitTriggered = false;

  SetDialogFlags(DIALOGFLAGS_MODAL);
}
예제 #14
0
void VRTLSupport_cl::PrintText(IVRender2DInterface *pRI, hkvVec2 vPos, VColorRef iColor ,
                                  VSimpleRenderState_t &iState, float fScaling, VRectanglef *pClipRect, float fZCoord) const
{
  //render line per line in order to adjust the x-value for RTL font
  for(int i=0;i<m_iTextLines;i++) 
  {
    //skip empty lines
    if(m_ppTextLines[i]!=NULL)
    {
      m_pFont->PrintText(pRI, hkvVec2(vPos.x+DistanceToRightAlignment(m_pFont, m_ppTextLines[i]), vPos.y),
        m_ppTextLines[i], iColor, iState, fScaling, pClipRect, fZCoord);
    }

    //inc value for next line
    vPos.y += m_pFont->GetFontHeight();
  }
}
  inline void PrintAt(float x, float y, const char * szLine, VColorRef color = V_RGBA_WHITE, const char * szFont=NULL)
  {
    if(m_bEnabled)
    {
      if(szFont!=NULL)
      {
        VisFont_cl *pFont = Vision::Fonts.LoadFont(szFont);
        
        if(pFont!=NULL)
        {
          pFont->PrintText(NULL, hkvVec2(x,y),szLine, color);
          return;
        }
      }

      Vision::Message.SetTextColor(color);
      Vision::Message.Print(1, (int)x, (int)y, szLine);
    }
  }
예제 #16
0
float VAppHelper::GetUIScalingFactor()
{
  const float fReferenceResolution = 1280.0f;
  const float fReferenceDisplaySize = 4.6f;
  const float fKernscheFakeKonstante = 1.73f;
  const float fBagarscherFakeExponent = 0.2f;

  float fScale = 1.0f;
  const hkvVec2 vRes = hkvVec2((float)Vision::Video.GetXRes(), (float)Vision::Video.GetYRes());

#if defined(_VISION_MOBILE) || defined (_VISION_PSP2)  
  const float fDisplaySizeInInch = vRes.getLength() / Vision::Video.GetDeviceDpi();  

  fScale = (vRes.x / fReferenceResolution) * fKernscheFakeKonstante * hkvMath::pow(fReferenceDisplaySize / fDisplaySizeInInch, fBagarscherFakeExponent);

#elif !defined(_VISION_WIN32)
  fScale = vRes.x / fReferenceResolution;

#endif

  return hkvMath::Max(fScale, 0.5f);
}
  inline void PrintAt(const hkvVec3* pPos, const char * szLine, VColorRef color = V_RGBA_WHITE, const char * szFont=NULL)
  {
    if(m_bEnabled && pPos!=NULL)
    {
      if(szFont!=NULL)
      {
        float x,y;
        if(Vision::Contexts.GetCurrentContext()->Project2D(*pPos,x,y))
        {
          VisFont_cl *pFont = Vision::Fonts.LoadFont(szFont);

          if(pFont!=NULL)
          {
            pFont->PrintText(NULL, hkvVec2(x,y),szLine, color);
            return;
          }
        }
      }

      Vision::Message.SetTextColor(color);
      Vision::Message.DrawMessage3D(szLine, *pPos, 1);
    }
  }
void RPG_GuiManager_VisionGUI::InitializeButtonDefinitions()
{
  RPG_SkillButtons_e skillbutton;
  int textureSizeX, textureSizeY, textureDepth;
  const float multiplier = Vision::Video.GetUse2xAssetsForCurrentConfig() ? 2.f : 1.f;
  const float offset = Vision::Video.GetUse2xAssetsForCurrentConfig() ? 96.f : 0.f;
  const float smallScreenOffsetX = Vision::Video.GetYRes() > SMALLSCREENSIZELIMIT ? 28.f : 0.f;
  const float smallScreenOffsetY = Vision::Video.GetYRes() > SMALLSCREENSIZELIMIT ? 80.f : 0.f;

  skillbutton = BTN_RangedAttack;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_rangedAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerLeft;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((20.f + smallScreenOffsetX) * multiplier, 282.f + smallScreenOffsetY + offset * 3.f);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  skillbutton = BTN_PowerAttack;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_powerAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerLeft;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((20.f + smallScreenOffsetX) * multiplier, 194.f + smallScreenOffsetY + offset * 2.f);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  skillbutton = BTN_AoeAttack;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_aoeAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerLeft;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((20.f + smallScreenOffsetX) * multiplier, 106.f + smallScreenOffsetY + offset);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  skillbutton = BTN_RangedAttackAlt;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_rangedAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerRight;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((100.f + smallScreenOffsetX) * multiplier, 282.f + smallScreenOffsetY + offset * 3.f);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  skillbutton = BTN_PowerAttackAlt;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_powerAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerRight;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((100.f + smallScreenOffsetX) * multiplier, 194.f + smallScreenOffsetY + offset * 2.f);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  skillbutton = BTN_AoeAttackAlt;
  {
    m_skillButtonDefinitions[skillbutton].m_imageFileName = "GUI/Textures/btn_aoeAttack.tga";
    m_skillButtonDefinitions[skillbutton].m_positionCorner = CORNER_LowerRight;
    m_skillButtonDefinitions[skillbutton].m_positionOffsetFromCorner = hkvVec2((100.f + smallScreenOffsetX) * multiplier, 106.f + smallScreenOffsetY + offset);
    m_skillButtonDefinitions[skillbutton].m_initiallyVisible = true;
  }

  // load the textures and set sizes
  for (int i = 0; i < BTN_Count; ++i)
  {
    if (!m_skillButtonDefinitions[i].m_imageFileName.IsEmpty())
    {
      m_skillButtonDefinitions[i].m_textureObject = Vision::TextureManager.Load2DTexture(m_skillButtonDefinitions[i].m_imageFileName.AsChar());
      VASSERT(m_skillButtonDefinitions[i].m_textureObject);
      VASSERT(m_skillButtonDefinitions[i].m_textureObject->IsTexturePowerOfTwo());
      m_skillButtonDefinitions[i].m_textureObject->GetTextureDimensions(textureSizeX, textureSizeY, textureDepth);
      m_skillButtonDefinitions[i].m_size = hkvVec2(static_cast<float>(textureSizeX), static_cast<float>(textureSizeY));
    }
  }
}
예제 #19
0
// TODO: This doesn't handle opaque fullbright surfaces correctly yet, and translucent fullbright surfaces are simply ignored.
void MirrorRenderLoop_cl::OnDoRenderLoop(void *pUserData)
{
  INSERT_PERF_MARKER_SCOPE("MirrorRenderLoop_cl::OnDoRenderLoop");

#if defined (WIN32) || defined (_VISION_XENON) || defined (_VISION_PS3) || defined(_VISION_PSP2) || defined(_VISION_WIIU)
  if (Vision::Editor.GetIgnoreAdvancedEffects())
  {
    // force a black reflection because it won't work with orthographic views
    Vision::RenderLoopHelper.ClearScreen(VisRenderLoopHelper_cl::VCTF_All, V_RGBA_BLACK);
    return;
  }
#endif

  VisRenderContext_cl *pContext = Vision::Contexts.GetCurrentContext();

  const int iRenderFlags = pContext->GetRenderFlags();

  const float fFarClipDist = m_pMirror->GetActualFarClipDistance();

  const VFogParameters &fog = Vision::World.GetFogParameters();
  VColorRef clearColor = (fog.depthMode != VFogParameters::Off) ? fog.iDepthColor : Vision::Renderer.GetDefaultClearColor();
  Vision::RenderLoopHelper.ClearScreen(VisRenderLoopHelper_cl::VCTF_All, clearColor);

  // set the oblique clipping plane...
  pContext->SetCustomProjectionMatrix (m_pMirror->GetObliqueClippingProjection().getPointer ());

  const VisStaticGeometryInstanceCollection_cl *pVisibleGeoInstancesPrimaryOpaquePass;
  const VisStaticGeometryInstanceCollection_cl *pVisibleGeoInstancesSecondaryOpaquePass;
  const VisStaticGeometryInstanceCollection_cl *pVisibleGeoInstancesTransparentPass;
  const VisEntityCollection_cl *pVisEntities;


  // === Visibility Determination ===

  IVisVisibilityCollector_cl *pVisColl = VisRenderContext_cl::GetCurrentContext()->GetVisibilityCollector();
  if (pVisColl == NULL)
    return;
  const VisVisibilityObjectCollection_cl *pVisObjectCollection = pVisColl->GetVisibleVisObjects();

  hkvAlignedBBox box;
  int iVoCount = m_pMirror->GetVisibilityObjectCount();
  int iFrustumCount = 0;
  bool bUseCommonFrustum = false;

  // === Determine Scissor Rect ===
  hkvVec2 vMinScreenSpace, vMaxScreenSpace;
  const hkvAlignedBBox &worldSpaceBox = m_pMirror->GetBoundingBox();

  hkvVec3 vCorners[8];
  worldSpaceBox.getCorners (vCorners);

  VRectanglef scissorRect;
  bool bUseScissorRect = true;
  for (int i=0; i<8; i++)
  {
    float x2d, y2d;
    BOOL bInFrontOfCamera = pContext->Project2D(vCorners[i], x2d, y2d);
    if (bInFrontOfCamera)
    {
      scissorRect.Add(hkvVec2(x2d, y2d));
    }
    else
    {
      bUseScissorRect = false;
      break;
    }
  }

  if (bUseScissorRect)
    Vision::RenderLoopHelper.SetScissorRect(&scissorRect);

  for (int iVo = 0; iVo < iVoCount; iVo++)
  {
    VisVisibilityObject_cl *pVisObj = m_pMirror->GetVisibilityObject(iVo);
    if (pVisObj != NULL && pVisObj->WasVisibleInAnyLastFrame())
    {
      if (iFrustumCount <= MAX_SEPARATE_FRUSTA)
      {
        const hkvAlignedBBox &voBox = pVisObj->GetWorldSpaceBoundingBox();
        box.expandToInclude(voBox);
        if (m_Frustum[iFrustumCount].Set(pContext->GetCamera()->GetPosition(), voBox, true, fFarClipDist))
        {
          iFrustumCount++;
        }
        else
        {
          bUseCommonFrustum = true;
        }
      }
      else
      {
        const hkvAlignedBBox &voBox = pVisObj->GetWorldSpaceBoundingBox();
        box.expandToInclude(voBox);
        bUseCommonFrustum = true;
      }
    }
  }

  if (bUseCommonFrustum)
  {
    iFrustumCount = 1;
    if (!m_Frustum[0].Set(pContext->GetCamera()->GetPosition(), box, true, fFarClipDist))
      iFrustumCount = 0;
  }

  if (iFrustumCount>0)
  {
    for (int i=0; i<iFrustumCount; i++)
    {
      m_visiblePrimaryOpaquePassGeoInstances.Clear();
      m_visibleSecondaryOpaquePassGeoInstances.Clear();
      m_visibleTransparentOpaquePassGeoInstances.Clear();
      m_visEntities.Clear();
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_PrimaryOpaquePass)->DetermineEntriesTouchingFrustum(m_Frustum[i], m_visiblePrimaryOpaquePassGeoInstances);
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_SecondaryOpaquePass)->DetermineEntriesTouchingFrustum(m_Frustum[i], m_visibleSecondaryOpaquePassGeoInstances);
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_TransparentPass)->DetermineEntriesTouchingFrustum(m_Frustum[i], m_visibleTransparentOpaquePassGeoInstances);
      pVisColl->GetVisibleEntities()->DetermineEntriesTouchingFrustum(m_Frustum[i], m_visEntities);
      if (iFrustumCount == 1)
        break;
      m_visiblePrimaryOpaquePassGeoInstances.TagEntries();
      m_visibleSecondaryOpaquePassGeoInstances.TagEntries();
      m_visibleTransparentOpaquePassGeoInstances.TagEntries();
      m_visEntities.TagEntries();
    }
    if (iFrustumCount > 1)
    {
      m_visiblePrimaryOpaquePassGeoInstances.Clear();
      m_visibleSecondaryOpaquePassGeoInstances.Clear();
      m_visibleTransparentOpaquePassGeoInstances.Clear();
      m_visEntities.Clear();
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_PrimaryOpaquePass)->GetTaggedEntries(m_visiblePrimaryOpaquePassGeoInstances);
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_SecondaryOpaquePass)->GetTaggedEntries(m_visibleSecondaryOpaquePassGeoInstances);
      pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_TransparentPass)->GetTaggedEntries(m_visibleTransparentOpaquePassGeoInstances);
      pVisColl->GetVisibleEntities()->GetTaggedEntries(m_visEntities);
    }
    pVisibleGeoInstancesPrimaryOpaquePass = &m_visiblePrimaryOpaquePassGeoInstances;
    pVisibleGeoInstancesSecondaryOpaquePass = &m_visibleSecondaryOpaquePassGeoInstances;
    pVisibleGeoInstancesTransparentPass = &m_visibleTransparentOpaquePassGeoInstances;
    pVisEntities = &m_visEntities;
  }
  else
  {
    pVisibleGeoInstancesPrimaryOpaquePass = pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_PrimaryOpaquePass);
    pVisibleGeoInstancesSecondaryOpaquePass = pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_SecondaryOpaquePass);
    pVisibleGeoInstancesTransparentPass = pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_TransparentPass);
    pVisEntities = pVisColl->GetVisibleEntities();
  }

  // === End Visibility Determination ===

  if (m_pMirror->GetExecuteRenderHooks())
  {
    VisRenderHookDataObject_cl data(&Vision::Callbacks.OnRenderHook,VRH_PRE_PRIMARY_OPAQUE_PASS_GEOMETRY);
    Vision::Callbacks.OnRenderHook.TriggerCallbacks(&data);
  }

  // Render opaque static geometry
  VASSERT(m_spDefaultLightMapping->m_Shaders.Count()==1);

  TRIGGER_MIRROR_HOOK(VRH_PRE_PRIMARY_OPAQUE_PASS_GEOMETRY)
  VisMirror_cl::VReflectionShaderSets_e shaderMode = m_pMirror->m_eReflectionShaderMode;
  DrawStaticGeometry(*pVisibleGeoInstancesPrimaryOpaquePass, VPT_PrimaryOpaquePass);
  DrawStaticGeometry(*pVisibleGeoInstancesSecondaryOpaquePass, VPT_SecondaryOpaquePass);

  // Render entities
  const VisEntityCollection_cl *pEntities = pVisEntities;
  int iCount = pEntities->GetNumEntries();
  VASSERT(m_spDefaultLightGrid->m_Shaders.Count()==1);
  //VCompiledShaderPass *pLightgridShader = m_spDefaultLightGrid->m_Shaders.GetAt(0);
  int i;
  //bool bUseSimpleShader = shaderMode==VisMirror_cl::AlwaysSimple;

  Vision::RenderLoopHelper.BeginEntityRendering();

  for (i=0;i<iCount;i++)
  { 
    VisBaseEntity_cl *pEnt = pEntities->GetEntry(i);

//    Vision::RenderLoopHelper.TrackLightGridInfo(pEnt);  // important: need to be done in RenderEntityWithSurfaceShaderList

    //if (bUseSimpleShader)
    //{
    //  Vision::RenderLoopHelper.RenderEntityWithShaders(pEnt,1,&pLightgridShader);
    //}
    //else
    {
      VisDrawCallInfo_t surfaceShaderList[RLP_MAX_ENTITY_SURFACES];
      VDynamicMesh *pMesh = pEnt->GetMesh();
      VisSurface_cl **ppSurfaces = pEnt->GetSurfaceArray();
      int iNumSubmeshes = pMesh->GetSubmeshCount();
      for (int j=0; j<iNumSubmeshes; j++)
      {
        VisDrawCallInfo_t &info(surfaceShaderList[j]);
        VBaseSubmesh* pSubmesh = pMesh->GetSubmesh(j);
        VisSurface_cl* pSurface = ppSurfaces[pSubmesh->m_iMaterialIndex];
        info.Set(pSubmesh, pSurface, GetMirrorShader (pSurface, shaderMode));
      }

      Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(pEnt, iNumSubmeshes, surfaceShaderList);
    }
  }

  Vision::RenderLoopHelper.EndEntityRendering();

  // Render Sky
  if (VSky::IsVisible())
  {
    // The sky has to be rendered without oblique clipping
    pContext->SetCustomProjectionMatrix(NULL);
    Vision::RenderLoopHelper.RenderSky();
    // set the oblique clipping plane after sky...
    pContext->SetCustomProjectionMatrix (m_pMirror->GetObliqueClippingProjection().getPointer ());
  }

  if (m_pMirror->GetExecuteRenderHooks())
  {
    VisRenderHookDataObject_cl data(&Vision::Callbacks.OnRenderHook,VRH_PRE_OCCLUSION_TESTS);
    Vision::Callbacks.OnRenderHook.TriggerCallbacks(&data);
  }

  // Render Coronas / Lens Flares
  VisRenderHookDataObject_cl data(&Vision::Callbacks.OnRenderHook,VRH_CORONAS_AND_FLARES);
  Vision::Callbacks.OnRenderHook.TriggerCallbacks(&data);
  TRIGGER_MIRROR_HOOK(VRH_PRE_OCCLUSION_TESTS)  

  if (iRenderFlags&VIS_RENDERCONTEXT_FLAG_USE_OCCLUSIONQUERY)
    Vision::RenderLoopHelper.PerformHardwareOcclusionQuery();

  if (iRenderFlags&VIS_RENDERCONTEXT_FLAG_USE_PIXELCOUNTER)
    Vision::RenderLoopHelper.PerformHardwarePixelCounterQuery();

  DrawDynamicLight();

  TRIGGER_MIRROR_HOOK(VRH_DECALS)
  TRIGGER_MIRROR_HOOK(VRH_CORONAS_AND_FLARES)

  TRIGGER_MIRROR_HOOK(VRH_PRE_TRANSPARENT_PASS_GEOMETRY)
  DrawStaticGeometry(*pVisibleGeoInstancesTransparentPass, VPT_TransparentPass);
  TRIGGER_MIRROR_HOOK(VRH_POST_TRANSPARENT_PASS_GEOMETRY)

  if (bUseScissorRect)
    Vision::RenderLoopHelper.SetScissorRect(NULL);
}
예제 #20
0
void VDebugOptions::OnHandleCallback(IVisCallbackDataObject_cl* pData)
{
  if (pData->m_pSender == &Vision::Callbacks.OnUpdateSceneBegin)
  {
#if defined(WIN32)
    if (GetParent()->GetInputMap()->GetTrigger(TOGGLE_FPS))
    {
      SetFrameRateVisible(!IsFrameRateVisible());
    }
    else if (GetParent()->GetInputMap()->GetTrigger(TOGGLE_WIREFRAME))
    {
      SetWireframe(!IsWireframe());
    }
#endif

    // FPS accumulation
    {
      m_iFrameCounter++;
      m_fTimeAccumulator += Vision::GetUITimer()->GetTimeDifference();

      if (m_fTimeAccumulator >= 1.0f)
      {
        m_fCurrentFrameTime = m_fTimeAccumulator / m_iFrameCounter;
        m_fCurrentFps = m_iFrameCounter / m_fTimeAccumulator;

        m_fTimeAccumulator = 0.0f;
        m_iFrameCounter = 0;
      }
    }

    if (m_bFpsVisible)
      Vision::Message.Print(1, 10, Vision::Video.GetYRes() - 35, "FPS : %.1f\nFrame Time : %.2f", m_fCurrentFps, m_fCurrentFrameTime * 1000.0f);
  }
  else if (pData->m_pSender == &Vision::Callbacks.OnBeforeSwapBuffers)
  {
    if (m_bSaveScreenshot)
    {
      VScreenShotHelper helper;
      helper.Capture();
      if (helper.PendingDataInBuffer())
      {
        if (helper.SaveBufferToFile("", NULL, 1.0f, 1.0f))
          Vision::Message.Add(0, "Screenshot saved to \"%s\".\n", helper.GetScreenShotPath());
        else
          Vision::Message.Add(0, "Screenshot could not be saved.\n");
      }

      // Re-enable the VAppMenu again
      VAppMenu* pMainMenu = GetParent()->GetAppModule<VAppMenu>();
      if (pMainMenu)
        pMainMenu->SetVisible(true);

      m_bSaveScreenshot = false;
    }
  }
  else if (pData->m_pSender == &Vision::Callbacks.OnRenderHook)
  {
    VisRenderHookDataObject_cl *pRenderHookData = (VisRenderHookDataObject_cl *)pData;
    if (pRenderHookData->m_iEntryConst == VRH_PRE_SCREENMASKS)
    {
      // Debug drawing of all visible touch areas.
#if defined(SUPPORTS_MULTITOUCH)
      if (m_bTouchAreaDebug)
      {
        IVMultiTouchInput* pMultiTouchInput = NULL;
        pMultiTouchInput = static_cast<IVMultiTouchInput*>(&VInputManager::GetInputDevice(INPUT_DEVICE_TOUCHSCREEN));
        VPListT<VTouchArea> touchAreas = pMultiTouchInput->GetTouchAreas();

        const float fBorderWidth = 3.0f;
        VSimpleRenderState_t alphaState(VIS_TRANSP_ALPHA, RENDERSTATEFLAG_FRONTFACE|RENDERSTATEFLAG_NOWIREFRAME|RENDERSTATEFLAG_ALWAYSVISIBLE);

        IVRender2DInterface *pRI = Vision::RenderLoopHelper.BeginOverlayRendering();
        {
          for (int i=0; i<touchAreas.GetLength(); ++i)
          {
            const VRectanglef& rect = touchAreas.Get(i)->GetArea();
            const VColorRef color = touchAreas.Get(i)->GetTouchPointIndex() < 0 ? VColorRef(0, 255, 0, 64) : VColorRef(0, 255, 0, 96);
            pRI->DrawSolidQuad(rect.m_vMin, rect.m_vMax, color, alphaState);

            pRI->DrawSolidQuad(rect.m_vMin, hkvVec2(rect.m_vMax.x, rect.m_vMin.y + fBorderWidth), VColorRef(0, 255, 0, 255), alphaState);
            pRI->DrawSolidQuad(hkvVec2(rect.m_vMin.x, rect.m_vMax.y - fBorderWidth), rect.m_vMax, VColorRef(0, 255, 0, 255), alphaState);
            pRI->DrawSolidQuad(hkvVec2(rect.m_vMin.x, rect.m_vMin.y + fBorderWidth), hkvVec2(rect.m_vMin.x + fBorderWidth, rect.m_vMax.y - fBorderWidth), VColorRef(0, 255, 0, 255), alphaState);
            pRI->DrawSolidQuad(hkvVec2(rect.m_vMax.x - fBorderWidth, rect.m_vMin.y + fBorderWidth), hkvVec2(rect.m_vMax.x, rect.m_vMax.y - fBorderWidth), VColorRef(0, 255, 0, 255), alphaState);
          }
        }
        Vision::RenderLoopHelper.EndOverlayRendering();
      }
#endif
    }
  }

  int iIndex = GetCallbackIndex(pData);
  if (iIndex >= 0)
  {
    if (iIndex == OPTION_FPS)
    {
      m_bFpsVisible = !m_bFpsVisible;
    }
    else if (iIndex == OPTION_WIREFRAME)
    {
      if (Vision::Renderer.GetWireframeMode())
        Vision::Renderer.SetWireframeMode(false);
      else
        Vision::Renderer.SetWireframeMode(true);
    }
    else if (iIndex == OPTION_RELOAD_RESOURCES)
    {
      int iCount = Vision::ResourceSystem.ReloadModifiedResourceFiles(NULL, VURO_HOT_RELOAD);       

      // Clear effect caches so that material shaders will be re-created (not re-used).
      Vision::Shaders.GetShaderFXLibManager().ResetCompiledEffectCaches();

      // Reassign all material shaders.
      Vision::Shaders.ReloadAllShaderAssignmentFiles();

      Vision::Message.Add(1, "%i resources were outdated and have been reloaded.", iCount);
    }
    else if (iIndex == OPTION_TIME_STEP_GRAPH)
    {
      m_pTimeStepGraph->SetVisible(!m_pTimeStepGraph->IsVisible());
    }
#if defined(SUPPORTS_MULTITOUCH)
    else if (iIndex == OPTION_MULTITOUCH)
    {
      m_bTouchAreaDebug = !m_bTouchAreaDebug;
    }
#endif
    else if (iIndex == OPTION_SAVE_SCREENSHOT)
    {
      m_bSaveScreenshot = true;

      // We don't want the menu to be visible in the screenshot
      VAppMenu* pMainMenu = GetParent()->GetAppModule<VAppMenu>();
      if (pMainMenu != NULL)
        pMainMenu->SetVisible(false);
    }
  }

  iIndex = GetCallbackIndex(m_debugInfos, pData);
  if (iIndex >= 0)
    Vision::Profiling.ToggleDebugRenderFlags((unsigned int)iIndex);
}
bool VCablePathRenderer::RebuildModel()
{
  m_spChainMesh = NULL;

  IVPathRenderingData* pData = m_spPathRenderingData;
  if (pData == NULL || !pData->IsValid())
    return false;
  
  int iNumLinks = pData->GetNumLinks();
  m_iLastKnownNumLinks = iNumLinks;

  if (iNumLinks < 1)
  {
    hkvLog::Warning("VCablePathRenderer::RebuildModel: Can't create cable rendering - constraint chain has no links.");
    return false;
  }
  else if (iNumLinks > MAX_NUM_LINKS)
  {
    hkvLog::Warning("VCablePathRenderer::RebuildModel: Path chain contains too many links; clamping to %d.", MAX_NUM_LINKS);
    iNumLinks = MAX_NUM_LINKS;
  }

  int iVerticesPerRing = hkvMath::Max(6, VerticesPerRing);
  int iRingsPerLink = hkvMath::Max(1, RingsPerLink);

//#define ENDS_ONLY

  // Vertices for each ring (final vertex is at the position of the first
  // vertex), times the number of rings
#ifdef ENDS_ONLY
  int iNumVertices = 0;
#else
  int iNumVertices = ((iNumLinks * iRingsPerLink) + 1) * (iVerticesPerRing + 1);
#endif
  // Extra vertices for the end surfaces
  iNumVertices += (iVerticesPerRing + 1) * 2;
  if (iNumVertices > 65535)
  {
    hkvLog::Warning("VCablePathRenderer::RebuildModel: Can't create cable rendering - too many verticess.");
    return false;
  }

#ifdef ENDS_ONLY
  int iNumTriangles = 0;
#else
  int iNumTriangles = iRingsPerLink * iNumLinks * iVerticesPerRing * 2;
#endif
  // Extra triangles for the end surfaces
  iNumTriangles += iVerticesPerRing * 2;

  float fRadius = pData->GetDiameter() / 2.0f;
  float fCircumference = fRadius * 2.0f * hkvMath::pi();
  
  float fRingHeight = pData->GetLinkLength() / iRingsPerLink;
  float fTextureVPerRing = fRingHeight / fCircumference;

  // Load the model that provides the surface material of the cable
  VDynamicMeshPtr spTemplateMesh;
  if (!ModelFile.IsEmpty())
    spTemplateMesh = VDynamicMesh::LoadDynamicMesh(ModelFile);

  // Pre-calculate the coordinates, normals and texture offsets of the ring
  // and end cap vertices
  VScopedArray<hkvVec3> rgvVertexTemplates(new hkvVec3[iVerticesPerRing + 1]);
  VScopedArray<hkvVec3> rgvNormalTemplates(new hkvVec3[iVerticesPerRing + 1]);
  VScopedArray<float> rgfTextureU(new float[iVerticesPerRing + 1]);
  VScopedArray<hkvVec2> rgvEndTexCoords(new hkvVec2[iVerticesPerRing]);
  {
    float fMaxEndTexOffset = 1.0f / (2.0f * hkvMath::pi());
    for (int i = 0; i < iVerticesPerRing; ++i)
    {
      float fRatio = (float)i / (float)iVerticesPerRing;
      float fAngle = fRatio * 2.0f * hkvMath::pi();
      rgvNormalTemplates[i].set(0.0f, hkvMath::cosRad(fAngle), hkvMath::sinRad(fAngle));
      rgvVertexTemplates[i] = rgvNormalTemplates[i] * fRadius;
      rgfTextureU[i] = fRatio;
      rgvEndTexCoords[i].set(
        0.5f + (hkvMath::cosRad(fAngle) * fMaxEndTexOffset),
        0.5f + (hkvMath::sinRad(fAngle) * fMaxEndTexOffset));
    }
    rgvNormalTemplates[iVerticesPerRing] = rgvNormalTemplates[0];
    rgvVertexTemplates[iVerticesPerRing] = rgvVertexTemplates[0];
    rgfTextureU[iVerticesPerRing] = 1.0f;
  }

  VColorRef cableColor(V_RGBA_YELLOW);
  hkvVec3 vTangent(1.f, 0.f, 0.f);

  int usageFlags = VIS_MEMUSAGE_STREAM;
  int bindFlags = VIS_BIND_SHADER_RESOURCE;
  
#ifdef _VR_DX11
  // Only specify this flag if this is a true DX11 card, since the engine currently
  // just passes it along to the device. This fails if the feature is not supported.
  // It is needed for Compute Shader Skinning
  if (Vision::Video.GetDXFeatureLevel() >= D3D_FEATURE_LEVEL_11_0)
  {
    usageFlags |= VIS_MEMUSAGE_UAV_BYTEADDRESS;
    bindFlags |= VIS_BIND_UNORDERED_ACCESS;
  }
#endif

  VDynamicMeshBuilder meshBuilder(iNumVertices, iNumTriangles, iNumLinks + 2, 1, usageFlags, bindFlags);

  if (spTemplateMesh && (spTemplateMesh->GetSurfaceCount() > 0))
    meshBuilder.CopySurfaceFrom(0, *spTemplateMesh->GetSurface(0));

#ifndef ENDS_ONLY
  for (int iCurrentLink = 0; iCurrentLink < iNumLinks; ++iCurrentLink)
  {
    /// The vertices of a chain link are influenced by three bones.
    int iPrevBone = iCurrentLink;
    int iThisBone = iCurrentLink + 1;
    int iNextBone = iCurrentLink + 2;

    /// The last link has an additional ring of vertices at its end
    int iLocalNumRings = iCurrentLink == (iNumLinks - 1)
      ? iRingsPerLink + 1 : iRingsPerLink;

    /// Compute the vertices for each ring of the current chain link:
    for (int iCurrentRing = 0; iCurrentRing < iLocalNumRings; ++iCurrentRing)
    {
      /// Normalized offset of this ring from the start of the chain link (range 0..1)
      float fNormOffset = (float)iCurrentRing / (float)iRingsPerLink;

      /// Calculate the influence factors of the three bones that might affect
      /// the current ring
      float fPrevBoneWeight = hkvMath::Max(0.0f, 0.5f - fNormOffset);
      float fThisBoneWeight = 1.0f - hkvMath::Abs(fNormOffset - 0.5f);
      float fNextBoneWeight = hkvMath::Max(0.0f, fNormOffset - 0.5f);

      /// Compute the vertices of one ring. The start/end vertices are at the same
      /// position, since two different texture coordinates are needed here.
      int iStartVertex = meshBuilder.GetNextVertexIndex();
      for (int iLocalVertex = 0; iLocalVertex <= iVerticesPerRing; ++iLocalVertex)
      {
        hkvVec3 vPos(rgvVertexTemplates[iLocalVertex]);

        // Texture v coordinate increases throughout the chain
        float fTextureV = ((iCurrentLink * iRingsPerLink) + iCurrentRing) * fTextureVPerRing;
        hkvVec2 vTexCoords(rgfTextureU[iLocalVertex], fTextureV);

        // Add vertex data...
        int iCurrentVertex = meshBuilder.AddVertex(vPos, rgvNormalTemplates[iLocalVertex], vTangent, vTexCoords, cableColor);
        VASSERT(iCurrentVertex >= 0);

        // ...and bone weights.
        if (fPrevBoneWeight > 0.f)
          meshBuilder.AddBoneWeight(iPrevBone, fPrevBoneWeight);
        meshBuilder.AddBoneWeight(iThisBone, fThisBoneWeight);
        if (fNextBoneWeight > 0.f)
          meshBuilder.AddBoneWeight(iNextBone, fNextBoneWeight);

        // Unless we are at the last vertex in a ring or at the last ring of the
        // last link, compute the vertex indices that make up the triangles for 
        // the cable.
        if ((iCurrentRing < iRingsPerLink) && (iLocalVertex < iVerticesPerRing))
        {
          unsigned short i1, i2, i3;
          int iNextRing = iStartVertex + iVerticesPerRing + 1;

          i1 = iStartVertex + iLocalVertex;
          i2 = iStartVertex + iLocalVertex + 1;
          i3 = iNextRing + iLocalVertex;
          meshBuilder.AddTriangle(i1, i2, i3);

          i1 = iStartVertex + iLocalVertex + 1;
          i2 = iNextRing + iLocalVertex + 1;
          i3 = iNextRing + iLocalVertex;
          meshBuilder.AddTriangle(i1, i2, i3);
        }

        //iCurrentVertex++;
      } // End of vertex loop
    } // End of rings per chain link loop
  } // End of chain link loop
#endif

  // Add the end surfaces
  {
    hkvVec3 vEndNormal = hkvVec3(-1.0f, 0.0f, 0.0f);
    hkvVec3 vEndTangent = hkvVec3(0.0f, 1.0f, 0.0f);

    // Center vertex (Top)
    int iCenterVertexIndex = meshBuilder.GetNextVertexIndex();
    meshBuilder.AddVertex(hkvVec3::ZeroVector(), vEndNormal, vEndTangent, hkvVec2(0.5f, 0.5f), cableColor);
    meshBuilder.AddBoneWeight(0, 0.5f);
    meshBuilder.AddBoneWeight(1, 0.5f);

    // Outer vertices (Top)
    int iStartVertexIndex = meshBuilder.GetNextVertexIndex();
    for (int iLocalVertex = 0; iLocalVertex < iVerticesPerRing; ++iLocalVertex)
    {
      meshBuilder.AddVertex(rgvVertexTemplates[iLocalVertex], vEndNormal, vEndTangent, rgvEndTexCoords[iLocalVertex], cableColor);
      meshBuilder.AddBoneWeight(0, 0.5f);
      meshBuilder.AddBoneWeight(1, 0.5f);
      int iNextLocalVertex = iLocalVertex + 1;
      if (iNextLocalVertex == iVerticesPerRing)
        iNextLocalVertex = 0;

      meshBuilder.AddTriangle(iCenterVertexIndex, iStartVertexIndex + iLocalVertex, iStartVertexIndex + iNextLocalVertex);
    }

    // Bottom cap: normal points the other way (tangent remains)
    vEndNormal.set(1.0f, 0.0f, 0.0f);

    // Center vertex (Bottom)
    iCenterVertexIndex = meshBuilder.GetNextVertexIndex();
    meshBuilder.AddVertex(hkvVec3::ZeroVector(), vEndNormal, vEndTangent, hkvVec2(0.5f, 0.5f), cableColor);
    meshBuilder.AddBoneWeight(iNumLinks, 0.5f);
    meshBuilder.AddBoneWeight(iNumLinks + 1, 0.5f);

    // Outer vertices (Top)
    iStartVertexIndex = meshBuilder.GetNextVertexIndex();
    for (int iLocalVertex = 0; iLocalVertex < iVerticesPerRing; ++iLocalVertex)
    {
      meshBuilder.AddVertex(rgvVertexTemplates[iLocalVertex], vEndNormal, vEndTangent, rgvEndTexCoords[iLocalVertex], cableColor);
      meshBuilder.AddBoneWeight(iNumLinks, 0.5f);
      meshBuilder.AddBoneWeight(iNumLinks + 1, 0.5f);
      int iNextLocalVertex = iLocalVertex + 1;
      if (iNextLocalVertex == iVerticesPerRing)
        iNextLocalVertex = 0;

      meshBuilder.AddTriangle(iCenterVertexIndex, iStartVertexIndex + iLocalVertex, iStartVertexIndex + iNextLocalVertex);
    }
  }

  VASSERT(meshBuilder.GetNextVertexIndex() == iNumVertices);
  VASSERT(meshBuilder.GetNextIndexIndex() == (iNumTriangles * 3));

  m_spChainMesh = meshBuilder.Finalize();
  VASSERT(m_spChainMesh);
  m_spChainMesh->SetResourceFlag(VRESOURCEFLAG_AUTODELETE);

  // Create the entity and the animation state
  if (!m_spChainEntity)
  {
    m_spChainEntity = static_cast<VCableChainEntity*>(Vision::Game.CreateEntity("VCableChainEntity", hkvVec3::ZeroVector()));
  }
  m_spChainEntity->SetRenderingData(pData);
  m_spChainEntity->SetMesh(m_spChainMesh);
  m_spChainEntity->SetCastShadows(CastDynamicShadows);

  VisAnimFinalSkeletalResult_cl* pFinalSkeletalResult;
  VisAnimConfig_cl* pAnimConfig = VisAnimConfig_cl::CreateSkeletalConfig(m_spChainMesh, &pFinalSkeletalResult);
  m_spChainEntity->SetAnimConfig(pAnimConfig);

  return true;
}
void RPG_GuiManager_VisionGUI::AddHealthAndManaBarsToParentDialog()
{
  InitializeHealthAndManaBarDefinitions();

  // add tracks
  VASSERT(m_indicatorBarTrackTexture);
  {
    hkvVec2 const trackOffset = hkvVec2((m_indicatorBarTrackSize.x - m_indicatorBarSize.x) / 2, (m_indicatorBarTrackSize.y - m_indicatorBarSize.y) / 2);

    // add health bar track
    VASSERT(!m_healthBarTrack);
    m_healthBarTrack = new VImageControl();
    VASSERT(m_healthBarTrack);
    m_healthBarTrack->Image().SetTexture(m_indicatorBarTrackTexture);
    m_healthBarTrack->Image().SetTransparency(VIS_TRANSP_ALPHA);
    m_healthBarTrack->SetPosition(m_healthBarPosition.x - trackOffset.x, m_healthBarPosition.y - trackOffset.y);
    m_healthBarTrack->SetSize(m_indicatorBarTrackSize.x, m_indicatorBarTrackSize.y);
    m_healthBarTrack->SetVisible(true);

    m_parentDialog->AddControl(m_healthBarTrack);

    // add mana bar track
    VASSERT(!m_manaBarTrack);
    m_manaBarTrack = new VImageControl();
    VASSERT(m_manaBarTrack);
    m_manaBarTrack->Image().SetTexture(m_indicatorBarTrackTexture);
    m_manaBarTrack->Image().SetTransparency(VIS_TRANSP_ALPHA);
    m_manaBarTrack->SetPosition(m_manaBarPosition.x - trackOffset.x, m_manaBarPosition.y - trackOffset.y);
    m_manaBarTrack->SetSize(m_indicatorBarTrackSize.x, m_indicatorBarTrackSize.y);
    m_manaBarTrack->SetVisible(true);

    m_parentDialog->AddControl(m_manaBarTrack);
  }

  // add health meter
  VASSERT(!m_healthBar);
  m_healthBar = new VImageControl();
  VASSERT(m_healthBar);

  VASSERT_MSG(m_healthBarTexture, "Health bar texture failed to load.");
  m_healthBar->Image().SetTexture(m_healthBarTexture);
  m_healthBar->Image().SetTransparency(VIS_TRANSP_ALPHA);
  m_healthBar->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
  m_healthBar->SetPosition(m_healthBarPosition.x, m_healthBarPosition.y);
  m_healthBar->SetSize(m_indicatorBarSize.x, m_indicatorBarSize.y);
  m_healthBar->SetVisible(true);

  m_parentDialog->AddControl(m_healthBar);

  // add mana meter
  VASSERT(!m_manaBar);
  m_manaBar = new VImageControl();
  VASSERT(m_manaBar);

  VASSERT_MSG(m_manaBarTexture, "Mana bar texture failed to load.");
  m_manaBar->Image().SetTexture(m_manaBarTexture);
  m_manaBar->Image().SetTransparency(VIS_TRANSP_ALPHA);
  m_manaBar->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
  m_manaBar->SetPosition(m_manaBarPosition.x, m_manaBarPosition.y);
  m_manaBar->SetSize(m_indicatorBarSize.x, m_indicatorBarSize.y);
  m_manaBar->SetVisible(true);

  m_parentDialog->AddControl(m_manaBar);

  // add health meter glow
  hkvVec2 const glowOffset = hkvVec2((m_indicatorBarGlowSize.x - m_indicatorBarSize.x) / 2, (m_indicatorBarGlowSize.y - m_indicatorBarSize.y) / 2);

  VASSERT(!m_healthBarGlow);
  m_healthBarGlow = new VImageControl();
  VASSERT(m_healthBarGlow);

  VASSERT_MSG(m_healthBarGlowTexture, "Health bar glow texture failed to load.");
  m_healthBarGlow->Image().SetTexture(m_healthBarGlowTexture);
  m_healthBarGlow->Image().SetTransparency(VIS_TRANSP_ADDITIVE);
  m_healthBarGlow->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
  m_healthBarGlow->SetPosition(m_healthBarPosition.x - glowOffset.x, m_healthBarPosition.y - glowOffset.y);
  m_healthBarGlow->SetSize(m_indicatorBarGlowSize.x, m_indicatorBarGlowSize.y);
  m_healthBarGlow->SetVisible(false);

  m_parentDialog->AddControl(m_healthBarGlow);

  // add mana meter glow
  VASSERT(!m_manaBarGlow);
  m_manaBarGlow = new VImageControl();
  VASSERT(m_manaBarGlow);

  VASSERT_MSG(m_manaBarGlowTexture, "Mana bar glow texture failed to load.");
  m_manaBarGlow->Image().SetTexture(m_manaBarGlowTexture);
  m_manaBarGlow->Image().SetTransparency(VIS_TRANSP_ADDITIVE);
  m_manaBarGlow->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
  m_manaBarGlow->SetPosition(m_manaBarPosition.x - glowOffset.x, m_manaBarPosition.y - glowOffset.y);
  m_manaBarGlow->SetSize(m_indicatorBarGlowSize.x, m_indicatorBarGlowSize.y);
  m_manaBarGlow->SetVisible(false);

  m_parentDialog->AddControl(m_manaBarGlow);

  VASSERT(m_indicatorBarFlareTexture);
  {
    // add health bar flare
    VASSERT(!m_healthBarFlare);
    m_healthBarFlare = new VImageControl();
    VASSERT(m_healthBarFlare);

    m_healthBarFlare->Image().SetTexture(m_indicatorBarFlareTexture);
    m_healthBarFlare->Image().SetTransparency(VIS_TRANSP_ALPHA);
    m_healthBarFlare->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
    m_healthBarFlare->SetPosition(m_healthBarPosition.x - m_indicatorBarFlareOrigin.x, (m_healthBarPosition.y - m_indicatorBarFlareOrigin.y) + m_indicatorBarSize.y / 2);
    m_healthBarFlare->SetSize(m_indicatorBarFlareSize.x, m_indicatorBarFlareSize.y);
    m_healthBarFlare->SetVisible(true);

    m_parentDialog->AddControl(m_healthBarFlare);

    // add mana bar flare
    VASSERT(!m_manaBarFlare);
    m_manaBarFlare = new VImageControl();
    VASSERT(m_manaBarFlare);

    m_manaBarFlare->Image().SetTexture(m_indicatorBarFlareTexture);
    m_manaBarFlare->Image().SetTransparency(VIS_TRANSP_ALPHA);
    m_manaBarFlare->Image().SetStretchMode(VImageState::TEXTURE_SIZE);
    m_manaBarFlare->SetPosition(m_manaBarPosition.x - m_indicatorBarFlareOrigin.x, (m_manaBarPosition.y - m_indicatorBarFlareOrigin.y) + m_indicatorBarSize.y / 2);
    m_manaBarFlare->SetSize(m_indicatorBarFlareSize.x, m_indicatorBarFlareSize.y);
    m_manaBarFlare->SetVisible(true);

    m_parentDialog->AddControl(m_manaBarFlare);
  }
}