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(); }
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); } }
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 ); } }
// 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(); }
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."); }
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); }
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); } }
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)); } } }
// 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); }
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); } }