Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Andreas

Frischling

  • »Andreas« ist der Autor dieses Themas

Beiträge: 77

Beruf: Schüler

  • Private Nachricht senden

1

24.01.2008, 17:18

Modell-Rendermethode verschnellern

Hallo, tut mir leid, ich weiß nicht sicher, ob ich hier richtig bin:

In meinem Spiel werden Gebäude gebaut, wobei ein Gebäudetyp dann auch mehrfach gerendert werden muss.
Da es sich dabei ja immer um die gleiche Modelldatei handelt, wollte ich fragen, ob man den Render-Prozess durch diese Kenntnis nicht etwas beschleunigen kann:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// ******************************************************************

// Diese Methode rendert das Modell.

tbResult tbModel::Render2(std::vector<tbMatrix*>* RenderListe,                        
                          BOOL bRenderOpaque,       // = TRUE

                         BOOL bRenderAlphaBlended,  // = TRUE               // = 0

                         BOOL loeschen)             // = true       

                                    
{
    HRESULT hResult;
    DWORD   dwOldFVF;
    int     iNumPasses;
    
    // Werte anpassen

    int iFrom = 0;
    int iTo = m_dwNumEffects-1;
    
    // Altes Vertexformat speichern

    tbDirect3D& D3D = tbDirect3D::Instance();
    dwOldFVF = D3D.GetFVF();

    // Vertexformat sowie Vertex- und Index-Buffer setzen

    D3D.SetFVF(m_dwFVF);
    D3D->SetStreamSource(0, m_pVertexBuffer->GetVB(), 0, m_pVertexBuffer->GetVertexSize());
    D3D->SetIndices(m_pIndexBuffer->GetIB());
    std::vector<tbMatrix*>::iterator dIter(RenderListe->begin());

    // Jeden Effekt durchgehen

    for(int iEffect = iFrom; iEffect <= iTo; iEffect++)
    {
        // Effekt aktivieren und alle Durchgänge rendern.

        // tbDirect3D::Capture wird später manuell aufgerufen.

        if(!m_pEffects[iEffect].Header.bAlphaBlended && bRenderOpaque ||
           m_pEffects[iEffect].Header.bAlphaBlended && bRenderAlphaBlended)
        {       
            for(dIter = RenderListe->begin(); dIter != RenderListe->end(); ++dIter)
            {
                D3D.SetTransform(D3DTS_WORLD, *(*dIter));
                iNumPasses = m_pEffects[iEffect].pEffect->Begin(TRUE, FALSE);
            
                
                for(int iPass = 0; iPass < iNumPasses; iPass++)
                {
                    // Durchgang aktivieren

                    m_pEffects[iEffect].pEffect->Pass(iPass);

                    // Rendern

                    hResult = D3D->DrawIndexedPrimitive(m_pEffects[iEffect].Header.PrimitiveType,
                                                    0,
                                                    m_pEffects[iEffect].Header.dwMinIndex,
                                                    m_pEffects[iEffect].Header.dwNumVertices,
                                                    m_pEffects[iEffect].Header.dwStartIndex,
                                                    m_pEffects[iEffect].Header.dwNumPrimitives);
                    if(FAILED(hResult))
                    {
                        // Fehler beim Rendern!

                        m_pEffects[iEffect].pEffect->End();
                        TB_ERROR_DIRECTX("D3D->DrawIndexedPrimitive", hResult, TB_ERROR);
                    }//end of if

                }//end of for

                // Effekt deaktivieren

                m_pEffects[iEffect].pEffect->End();
            }// end of for


            
        }//end of if

    }//end of for

Diese Render-Methode ist im Prinzip identisch mit der ursprünglichen Render-Methode der Tribase Engine, nur das dieser Methode die Transformationsmatrizen in einem Vector mitübergeben werden.
Jetzt werden die Transformationsmatrizen immer für jeden Effekt gesetzt, damit nicht zwischendurch erst immer ein anderer Effekt seine Einstellungen dazwischendrängt.
Ich hab mal gehört, das das Zeitintensivste beim Rendern sei, dass immer die Textur neu gesetzt werden müsste. Wird bei dieser Realisierung die Textur durch den Effekt auch jedes Mal wieder neu gesetzt, obwohl sie eigentlich schon gesetzt ist?
Da bei mehreren Gebäuden das Spiel trotzdem noch ins Stocken gerät, wollte ich fragen habt ihr vielleicht eine Idee, wie man diesen Renderprozess noch schneller gestalten könnte?
Eine Idee von mir wäre vielleicht noch, dass ein neuer dynamischer Index und Vertex-Buffer angelegt wird, in dem jedesmal die gesamten Dreiecke (vorher multipliziert mit der Transformationsmatrix) gesammelt werden und dann in einem Schlag gerendert werden. Würde das einen Geschwindigkeitsvorteil bringen, oder habt ihr noch bessere Ideen?

Vielen Dank auf jeden Fall schonmal, viele Grüße
Andreas

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

24.01.2008, 17:27

bei den dynamischen vertexbuffer wäre ich nicht sicher, ob das wirklich den geschwinigkeitsvorteil bringt, weil diese dynamsichen buffer wesentlich langsamer sind allgemein als die statischen, will aba nich drauf schwören, das müsste man testen bzw. vllt weiss es jemand besser als ich.

aba AFAIK ist eigentlich bei einem multi-pass gerendertes model kaum was zu optimieren (an den Shadern vielleicht noch), wobei der ansatz interessant klingt.

3

24.01.2008, 17:33

Aufräumen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// ******************************************************************

// Diese Methode rendert das Modell.

tbResult tbModel::Render2(std::vector<tbMatrix*> const& render_data, bool opaque, bool alpha_blended)                              
{
    tbDirect3D& d3d(tbDirect3D::Instance());

    const DWORD dwOldFVF(D3D.GetFVF());
    d3d.SetFVF(m_dwFVF);

    d3d->SetStreamSource(0, m_pVertexBuffer->GetVB(), 0, m_pVertexBuffer->GetVertexSize());
    d3d->SetIndices(m_pIndexBuffer->GetIB());
   
    for (unsigned int effect(0); effect < m_dwNumEffects; ++effect)
    {
        if (!m_pEffects[effect].Header.bAlphaBlended && bRenderOpaque || 
            m_pEffects[effect].Header.bAlphaBlended && bRenderAlphaBlended)
        {       
            for (std::vector<tbMatrix*>::const_iterator it(render_data.begin()); it != render_data.end(); ++it)
            {
                d3d.SetTransform(D3DTS_WORLD, *(*it));
                
                const unsigned int pass_count(m_pEffects[effect].pEffect->Begin(TRUE, FALSE));
                         
                for (unsigned int pass(0); pass < pass_count; ++pass)
                {
                    m_pEffects[effect].pEffect->Pass(pass);

                    const HRESULT hResult(d3d->DrawIndexedPrimitive(m_pEffects[effect].Header.PrimitiveType, 0, 
                                        m_pEffects[effect].Header.dwMinIndex, m_pEffects[effect].Header.dwNumVertices, 
                                        m_pEffects[effect].Header.dwStartIndex, m_pEffects[effect].Header.dwNumPrimitives));
                   
                    if (FAILED(hResult))
                    {
                        m_pEffects[effect].pEffect->End();
                        TB_ERROR_DIRECTX("D3D->DrawIndexedPrimitive", hResult, TB_ERROR);
                    }
                }
                m_pEffects[effect].pEffect->End();
            }
        }
    }
    return TB_OK;
}
:)
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Werbeanzeige