LPD3DXFONT DrawText Scrolling



  • Na du setzt eben dein Scissor Rect und zeichnest den Text!?



  • ich dachte, das wäre verständlich, was ich oben geschrieben habe:

    angenommen wir haben folgendes

    RECT pRect = { 0, 0, ScreenSize.x, ScreenSize.y };
    device->SetScissorRect(&pRect);
    Font->DrawText("blahblubb",......);
    RECT pRect = { 0, 0, ScreenSize.x, ScreenSize.y };
    device->SetScissorRect(&pRect);
    

    jetzt wird der text an sich nicht wirklich geclipped, da ich danach das rect ja wieder groß setzen muss, damit mein restlicher screen nicht darunter leidet.

    wenn das der richtige weg ist, was mach ich falsch?



  • anti-freak schrieb:

    wenn das der richtige weg ist, was mach ich falsch?

    Du vergisst den Scissor Test auch einzuschalten (SetRenderState)...



  • muss ich das nach jedem mal machen, wenn ich ein neues RECT setze?
    am anfang des Projekts hatte ich das aktiviert.

    aber es funktioniert trotzdem nicht...

    Habe auch damit noch ein wenig herum probiert, funktionieren tut es ja, wenn ich das rect danach nicht wieder zurück setze.



  • anti-freak schrieb:

    muss ich das nach jedem mal machen, wenn ich ein neues RECT setze?

    Nun, vielleicht schaltet dein Font Objekt es wieder ab?



  • Wie gesagt, es liegt nicht am SetRenderState(). Das Clippen funktioniert, wenn ich das Rect nach meinem Draw Font nicht wieder zurück setze, aber das ist nicht Sinn der Sache, weil dann der restliche Teil des Bildschirms auch nicht mehr gedrawt wird.

    ist das so schwer zu verstehen, was ich meine?^^

    im moment besitzt eigentlich jede größere draw routine ein eigenes LPD3DXSPRITE (also, die map, die layer der Objecte, die Textbox), wird aber schlussendlich alles zusammen auf den Backbuffer gedrawt.
    Muss ich hier irgendwo ansetzen, und was verändern?



  • Nein, es ist absolut klar was du meinst. Das Problem ist, dass du einfach zu wenig Information darüber gibst, wie du die von dir beschriebenen Abläufe jetzt genau implementiert hast. Nur weil du denkst dass du was machst, heißt das noch lange nicht, dass dein Code auch wirklich tut was du denkst...

    Verwendest du ein ID3DXFont? Wenn ja: Gibt dem mal beim Draw ein eigenes ID3DXSprite mit und ruf bei dem explizit Begin und End() auf.



  • hat so leider auch nicht funktioniert.

    letztendlich sieht der draw so aus:

    void TextBox::DrawTextboxMsg()
    {
        if (m_sTextMsg.empty())
            return;
    
        CDirect3D *pDirect3D = CDirect3D::Get();
        if (!pDirect3D)
            return;
    
        // set scissor rect to msgbox area
        RECT pRect = { 50, 400, 300, 450};
        if (LPDIRECT3DDEVICE9 pDevice = pDirect3D->GetDevice())
            pDevice->SetScissorRect(&pRect);
    
        LPD3DXSPRITE pSprite = pDirect3D->GetSpriteForDraw();
    
        UINT uiBorderSize = 0;
        if (m_pTexture)
        {
            if (m_pTexture->m_TextureInfo.m_uiSpriteType == (UINT)SPRITE_TYPE_TEXTBOX)
                uiBorderSize = m_pTexture->m_TextureInfo.Type.Textbox.m_uiBorderSize;
        }
    
        std::string sMsg = m_sTextMsg.substr(0, m_uiShownLetters);
    
        RECT pos = {m_Position.x + uiBorderSize, m_Position.y + uiBorderSize, m_Position.x + m_uiSize.x - uiBorderSize, m_Position.y + m_uiSize.y - uiBorderSize };
        DirectFont::DrawFont(sMsg, pos, D3DXCOLOR(0.5f, 0.4f, 0.6f, 1), m_uiFontSize, 1000, m_sFontName, DT_LEFT, false, pSprite);
    
        pDirect3D->EndSpriteDraw();
        // set scissor rect to window size
        if (CGame *pGame = CGame::Get())
        {
            if (CGameInfo *pInfo = pGame->GetGameInfo())
            {
                Point<UINT> ScreenSize;
                pInfo->GetWindowSize(ScreenSize.x, ScreenSize.y);
                pRect.left = 0;
                pRect.top = 0;
                pRect.right = ScreenSize.x;
                pRect.bottom = ScreenSize.y;
                if (LPDIRECT3DDEVICE9 pDevice = pDirect3D->GetDevice())
                    pDevice->SetScissorRect(&pRect);
            }
        }
    }
    

    GetSpriteForDraw() fordert einfach nur ein Sprite an und startet ruft gleichzeitig ->Begin() auf.
    EndSpriteDraw() ruft ->End() für das letzte so übergebene Sprite auf.
    Die DrawFont Methode sieht so aus:

    void DirectFont::DrawFont(std::string sText, RECT pos, D3DXCOLOR color, UINT uiTextSize, UINT uiBoldness, std::string font, DWORD format, bool bItalic, LPD3DXSPRITE pSprite)
    {
        LPD3DXFONT m_pFontObj = NULL;
        CDirect3D *pDirect3D = CDirect3D::Get();
        if (!pDirect3D)
            return;
    
        D3DXFONT_DESC FontDesc = {uiTextSize, 0, uiBoldness, 1, bItalic, DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_PITCH, ""};
        strcpy_s(FontDesc.FaceName, font.c_str());
        HRESULT hr = D3DXCreateFontIndirect(pDirect3D->GetDevice(),&FontDesc,&m_pFontObj);
        if (hr != S_OK)
            return;
    
        m_pFontObj->DrawText(pSprite, sText.c_str(), -1, &pos, format, color);
    
        // release
        if(m_pFontObj != NULL)
        {
            m_pFontObj->Release();
            m_pFontObj = NULL;
        }
    }
    

    (ich weiß, nicht sonderlich performan, aber zum Testen reicht es erst einmal so, wenn ich jedes mal das Font obj neu erstelle).

    Ist eigentlich alles wichtige.

    mfg

    EDIT: das oben eingestellte ScissorRect sollte nur einen kleinen Teil des Textes sichtbar werden lassen, die Punkte stimmen soweit.



  • Also prinzipiell sollte RenderState aktivieren und Scissor Rect setzen passen.
    Aber ich hab keinen Einblick in dein State-Management und daher ist es eben leider schwer zu sagen was du da genau falsch machst, das müsste man einfach mal selber debuggen um da draufzukommen.
    Vor allem die D3DX Objekte verwenden intern State Blöcke, gut möglich dass dir das Sprite selbst also am Ende alles zusammenhaut.
    Ich kann dir nur empfehlen, dir mal PIX anzuschauen (kommt mit dem DirectX SDK) 😉



  • ok, danke für den tipp mit PIX, es lag tatsächlich am nicht gesetzten scissor test, obwohl ich ihn am anfang gesetzt habe o.O
    naja, ist erledigt 🙂


Anmelden zum Antworten