void VImageState::OnPaint(VGraphicsInfo &Graphics, const VItemRenderInfo &parentState)
{
  VTextureObject *pTex = GetCurrentTexture();
  if (!pTex)
    return;

  VASSERT(parentState.m_pWindow);
  VRectanglef rect = parentState.m_pWindow->GetBoundingBox();
  VSimpleRenderState_t state = VGUIManager::DefaultGUIRenderState(m_eTranspType);
  VColorRef iColor = parentState.iFadeColor*m_iColor;
  state.SetFlag(m_iAdditionalStateFlags); // apply filtering for instance

  if (m_eStretchMode==BORDER)
  {
    hkvVec2 v1 = rect.m_vMin;
    hkvVec2 v2 = rect.m_vMax;
    float bx = (float)pTex->GetTextureWidth()*0.5f;
    float by = (float)pTex->GetTextureHeight()*0.5f;
    float hx = 1.f / bx;
    float hy = 1.f / by;
    bx -= 1.f;
    by -= 1.f;
    Overlay2DVertex_t v[(4+4+1)*6]; // 9 quads
    int iVertexCount = 0;

    // corners
    IVRender2DInterface::CreateQuadVertices(v1.x,v1.y, v1.x+bx,v1.y+by, 0,0,0.5f-hx,0.5f-hy, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v2.x-bx,v1.y, v2.x,v1.y+by, 0.5f+hx,0,1,0.5f-hy, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v2.x-bx,v2.y-by, v2.x,v2.y, 0.5f+hx,0.5f+hy,1,1, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v1.x,v2.y-by, v1.x+bx,v2.y, 0,0.5f+hy,0.5f-hx,1, iColor, &v[iVertexCount]); iVertexCount+=6;
  
    // edges
    IVRender2DInterface::CreateQuadVertices(v1.x+bx,v1.y, v2.x-bx,v1.y+by, 0.5f-hx,0,0.5f+hx,0.5f-hy, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v1.x+bx,v2.y-by, v2.x-bx,v2.y, 0.5f-hx,0.5f+hy,0.5f+hx,1, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v1.x,v1.y+by, v1.x+bx,v2.y-by, 0,0.5f-hy,0.5f-hx,0.5f+hy, iColor, &v[iVertexCount]); iVertexCount+=6;
    IVRender2DInterface::CreateQuadVertices(v2.x-bx,v1.y+by, v2.x,v2.y-by, 0.5f+hx,0.5f-hy,1,0.5f+hy, iColor, &v[iVertexCount]); iVertexCount+=6;
    
    // inner rect
    IVRender2DInterface::CreateQuadVertices(v1.x+bx,v1.y+by, v2.x-bx,v2.y-by, 0.5f-hx,0.5f-hy,0.5f+hx,0.5f+hy, iColor, &v[iVertexCount]); iVertexCount+=6;

    RENDER_VERTICES(iVertexCount);
  } 
  else if (m_eStretchMode==STRETCHED)
  {
    Overlay2DVertex_t v[6];    
    IVRender2DInterface::CreateQuadVertices(rect.m_vMin.x,rect.m_vMin.y,rect.m_vMax.x,rect.m_vMax.y,texCoord.m_vMin.x,texCoord.m_vMin.y,texCoord.m_vMax.x,texCoord.m_vMax.y,iColor,v);
    RENDER_VERTICES(6);
  }
  else // actual texture size
  {
    Overlay2DVertex_t v[6];
    rect.m_vMax.x = rect.m_vMin.x + (float)pTex->GetTextureWidth();
    rect.m_vMax.y = rect.m_vMin.y + (float)pTex->GetTextureHeight();
    IVRender2DInterface::CreateQuadVertices(rect.m_vMin.x,rect.m_vMin.y,rect.m_vMax.x,rect.m_vMax.y,texCoord.m_vMin.x,texCoord.m_vMin.y,texCoord.m_vMax.x,texCoord.m_vMax.y,iColor,v);
    RENDER_VERTICES(6);
  }
}
void VTextState::Paint(VGraphicsInfo *pGraphics, VWindowBase *pParentWnd, VColorRef iColor)
{
  const char *szText = GetText();
  if (!m_spFont || !szText || !szText[0])
    return;

  VRectanglef vParentRect = pParentWnd->GetClientRect(); // clipping box of parent control

  if(!m_bCachedLinesValid)
  {
    m_lines.Reset();
    m_lineOffsets.Reset();

    float fLineHeight = m_spFont->GetFontHeight() * m_fRelativeFontHeight * m_fFontScaling;

    if(!m_bTextWrap)
    {
      const char* szCurrentLine = szText;
      for (const char* szPtr = szCurrentLine; *szPtr != '\0'; ++szPtr)
      {
        if (*szPtr == '\n')
        {
          VStaticString<512> line;
          line.Set(szCurrentLine, static_cast<int>(szPtr - szCurrentLine));

          m_lines.Add(line.AsChar());
          szCurrentLine = szPtr + 1;
        }
      }

      // Add the last line
      if(*szCurrentLine)
      {
        m_lines.Add(szCurrentLine);
      }
    }
    else
    {
      float fMaxLineWidth = vParentRect.GetSizeX() / m_fFontScaling;

      // Wrap text into individual lines
      {
        const char *szCurrentLine = szText;
        while (*szCurrentLine)
        {
          // byte offsets
          int iByteOffsetAtWrapPosition;
          int iByteOffsetAfterWrapPosition;

          // search for next newline
          const char *pNextNewLine = strchr(szCurrentLine, '\n');

          // compute automatic wrap character index
          int iCharCount = m_spFont->GetCharacterIndexAtPos(szCurrentLine, fMaxLineWidth, -1, false);
          int iWrapOffset = VString::GetUTF8CharacterOffset(szCurrentLine, iCharCount);

          if (pNextNewLine != NULL && (pNextNewLine - szCurrentLine) <= iWrapOffset)
          {
            // newline occurs before automatic text wrap
            iByteOffsetAtWrapPosition = static_cast<int>(pNextNewLine - szCurrentLine);
            iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition + 1;
          }
          else if(strlen(szCurrentLine) <= iWrapOffset)
          {
            // End of text occurs before automatic text wrap
            iByteOffsetAtWrapPosition = static_cast<int>(strlen(szCurrentLine));
            iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition;
          }
          else
          {
            // automatic text wrap
            iByteOffsetAtWrapPosition = iWrapOffset;
            if (iByteOffsetAtWrapPosition > 0)
            {
              // Go backwards and try to find white space
              while (iByteOffsetAtWrapPosition > 0 && !IsWhiteSpace(szCurrentLine[iByteOffsetAtWrapPosition]))
              {
                iByteOffsetAtWrapPosition--;
              }

              // no whitespace found? then wrap inside word
              if (iByteOffsetAtWrapPosition == 0)
              {
                iByteOffsetAtWrapPosition = iWrapOffset;
              }
              else
              {
                // Find end of next word
                int iEndOfWord = iByteOffsetAtWrapPosition + 1;
                while(szCurrentLine[iEndOfWord] && !IsWhiteSpace(szCurrentLine[iEndOfWord]))
                {
                  iEndOfWord++;
                }

                // If the word does not fit into a line by itself, it will be wrapped anyway, so wrap it early to avoid ragged looking line endings
                VRectanglef nextWordSize;
                m_spFont->GetTextDimension(szCurrentLine + iByteOffsetAtWrapPosition, nextWordSize, iEndOfWord - iByteOffsetAtWrapPosition);
                if(nextWordSize.GetSizeX() > fMaxLineWidth)
                {
                  iByteOffsetAtWrapPosition = iWrapOffset;
                }
              }
            }
            else
            {
              // First character is already wider than the line
              iByteOffsetAtWrapPosition = VString::GetUTF8CharacterOffset(szCurrentLine, 1);
            }
            iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition;
          }

          // put together line
          VStaticString<512> line;
          line.Set(szCurrentLine, iByteOffsetAtWrapPosition);

          m_lines.Add(line.AsChar());

          szCurrentLine = &szCurrentLine[iByteOffsetAfterWrapPosition];
          while(*szCurrentLine == ' ')
            szCurrentLine++;
        }
      }
    }

    // Compute offset for each line
    for(int iLineIdx = 0; iLineIdx < m_lines.GetLength(); iLineIdx++)
    {
      hkvVec2 offset = m_vOffset;

      offset.x += m_spFont->GetTextPositionOfs(m_lines[iLineIdx], vParentRect.GetSize(), m_hAlign, m_vAlign, m_fFontScaling).x;
      offset.y += iLineIdx * fLineHeight;

      if (m_vAlign == VisFont_cl::ALIGN_CENTER)
      {
        offset.y += (vParentRect.GetSizeY() - fLineHeight * m_lines.GetSize()) * 0.5f;
      }
      else if (m_vAlign == VisFont_cl::ALIGN_BOTTOM)
      {
        offset.y += (vParentRect.GetSizeY() - fLineHeight * m_lines.GetSize());
      }

      m_lineOffsets.Add(offset);
    }

    m_bCachedLinesValid = true;
  }

  // Render lines
  if (pGraphics)
  {
    VSimpleRenderState_t state = VGUIManager::DefaultGUIRenderState();
    if (m_fFontScaling!=1.0f)
      state.SetFlag(RENDERSTATEFLAG_FILTERING);

    for(int iLineIdx = 0; iLineIdx < m_lines.GetLength(); iLineIdx++)
    {
      m_spFont->PrintText(&pGraphics->Renderer, vParentRect.m_vMin + m_lineOffsets[iLineIdx], m_lines[iLineIdx], iColor, state, 
        m_fFontScaling, m_pCustomBBox ? m_pCustomBBox : &vParentRect);
    }
  }
}
void VTextState::Paint(VGraphicsInfo *pGraphics, VWindowBase *pParentWnd, VColorRef iColor)
{
  m_iNumTextLines = 0;
  const char *szText = GetText();
  if (!m_spFont || !szText || !szText[0])
    return;

  VSimpleRenderState_t state = VGUIManager::DefaultGUIRenderState();
  if (m_fFontScaling!=1.0f)
    state.SetFlag(RENDERSTATEFLAG_FILTERING);

  VRectanglef v = pParentWnd->GetBoundingBox(); // clipping box of parent control

  if (m_bTextWrap)
  {
    float fMaxWidth = v.GetSizeX()/m_fFontScaling;
    float fLineHeight = m_spFont->GetFontHeight() * m_fRelativeFontHeight * m_fFontScaling;
    hkvVec2 vPos = v.m_vMin;

    const char *szStart = szText;
    VMemoryTempBuffer<512> tmpBuffer;

    while (szStart[0])
    {
      // byte offsets
      int iOffset;
      int iNextOffset;

      // search for next newline
      const char *pCR = strchr(szStart, '\n');

      // compute automatic wrap character index
      int iCharCount = m_spFont->GetCharacterIndexAtPos(szStart, fMaxWidth, -1, false);
      int iWrapOffset = VString::GetUTF8CharacterOffset(szStart, iCharCount);

      if (pCR != NULL && (pCR - szStart) < iCharCount)
      {
        // newline occurs before automatic text wrap
        iOffset = static_cast<int>(pCR - szStart);
        iNextOffset = iOffset + 1;
      }
      else
      {
        // automatic text wrap
        iOffset = iWrapOffset;
        // try to find white space
        if (iOffset > 0)
        {
          while (iOffset > 0 && szStart[iOffset] != 0 && szStart[iOffset] != ' ')
            iOffset--;
          if (iOffset == 0) // no whitespace found? then wrap inside word
            iOffset = iWrapOffset;
        }
        else 
          iOffset = 1;
        iNextOffset = iOffset;
      }

      // put together line
      const int iLineBufferSize = (iOffset+1) * sizeof(char);
      tmpBuffer.EnsureCapacity(iLineBufferSize);
      char *szLineBuffer = static_cast<char*>(tmpBuffer.GetBuffer());

      memcpy(szLineBuffer, szStart, iLineBufferSize);
      szLineBuffer[iOffset] = 0;
      m_iNumTextLines++;

      // draw line
      if (pGraphics)
      {
        hkvVec2 vAlignedPos = m_spFont->GetTextPositionOfs(szLineBuffer, v.GetSize(), 
          m_hAlign, m_vAlign) * m_fFontScaling;
        vAlignedPos.set(vAlignedPos.x + vPos.x, vPos.y); // only consider the x-ofs
        m_spFont->PrintText(&pGraphics->Renderer, vAlignedPos, szLineBuffer, iColor, state, 
          m_fFontScaling, m_pCustomBBox ? m_pCustomBBox : &v);
      }
      vPos.y += fLineHeight;

      szStart = &szStart[iNextOffset];
      while (szStart[0] == ' ')
        szStart++;
    }
    return;
  }

  // recompute the alignment offset
  if (!m_bAlignmentValid)
  {
    m_vCurrentOfs = m_vOfs + m_spFont->GetTextPositionOfs(szText, v.GetSize(),
      m_hAlign,m_vAlign) * m_fFontScaling;
    m_bAlignmentValid = true;
  }

  m_iNumTextLines = 1;
  if (pGraphics)
  {
    m_spFont->PrintText(&pGraphics->Renderer, v.m_vMin+m_vCurrentOfs, szText, 
      iColor, state, m_fFontScaling, m_pCustomBBox ? m_pCustomBBox : &v);
  }
}
Ejemplo n.º 4
0
void VPostProcessFXAA::InitializePostProcessor()
{
  if (m_bIsInitialized || !m_bActive)
    return;

  SetupContext();

  // Load glow shader library
  BOOL bResult = Vision::Shaders.LoadShaderLibrary("\\Shaders\\FXAA.ShaderLib", SHADERLIBFLAG_HIDDEN) != NULL;
  VASSERT(bResult); // file not found?

  GetTargetContext()->GetSize(m_iWidth, m_iHeight);

  m_spMask = new VisScreenMask_cl();
  m_spMask->SetPos(0,0);
  m_spMask->SetTargetSize((float)m_iWidth,(float)m_iHeight);
  m_spMask->SetTextureRange(0.0f, 0.0f, (float)m_iWidth, (float)m_iHeight);
#ifdef _VR_DX9
  m_spMask->SetUseOpenGLTexelShift(TRUE);
#else
  m_spMask->SetUseOpenGLTexelShift(FALSE);
#endif
  //m_spMask->SetUseOpenGLTexelShift(FALSE);

  m_spMask->SetTransparency(VIS_TRANSP_NONE);
  m_spMask->SetVisible(FALSE);
  m_spMask->SetDepthWrite(FALSE);
  m_spMask->SetWrapping(FALSE, FALSE);
  m_spMask->SetVisibleBitmask(0); // this mask is rendered manually via a collection

  // no wireframe for this mask
  VSimpleRenderState_t s = m_spMask->GetRenderState();
  s.SetFlag(RENDERSTATEFLAG_NOWIREFRAME);
  m_spMask->SetRenderState(s);

  VTechniqueConfig vc;

  VString tags;
  tags.Format("FXAA_PRESET=%d", (int)Quality);
  vc.SetInclusionTags(tags);

  VCompiledTechnique *pTech = Vision::Shaders.CreateTechnique("FXAA", NULL, &vc, EFFECTFLAGS_FORCEUNIQUE);
  VASSERT(pTech!=NULL && "Could not create technique for FXAA postprocessor!");
  m_spMask->SetTechnique(pTech);
  m_spMask->SetTransparency(VIS_TRANSP_NONE);

  VShaderConstantBuffer *pPS = pTech->GetShader(0)->GetConstantBuffer(VSS_PixelShader);
  m_iRegScreenSize = pPS->GetRegisterByName("rcpFrame");
  
  // make frame copy only if this is not the last PP
  bool bFrameCopy = !IsLastComponent();
  if (bFrameCopy && GetTargetContext()->GetRenderTarget() == m_spSourceTextures[0])
  {
    m_spFrameCopyTexture = ScratchTexturePool_cl::GlobalManager().GetScratchTexture(m_iWidth, m_iHeight, m_spSourceTextures[0]->GetTextureFormat(), 0);
    m_spMask->SetTextureObject(m_spFrameCopyTexture);
  }
  else
  {
    m_spFrameCopyTexture = NULL;
    m_spMask->SetTextureObject(m_spSourceTextures[0]);
  }

  m_bIsInitialized = true;
}