Du bist nicht angemeldet.

Werbeanzeige

alexm

Frischling

  • »alexm« ist der Autor dieses Themas

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

1

20.06.2006, 00:27

Klassendesign für Renderer?

hi!
ich hätte da mal eine frage:
ich habe meine DirectX Initialisierungen in eine Singleton-Klasse verpackt.
mir taugts ja nicht unbedingt, da singleton mehr probleme bringt, als vorteile, aber bitte ...

hier mal meine .h

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
class cDX_Interface
{

private:

    static  cDX_Interface* pDX_Interface;
            HWND * m_hWnd;
            LPDIRECT3D9         m_D3DObject; 
            LPDIRECT3DDEVICE9   m_D3DDevice;                

    cDX_Interface();
    cDX_Interface( const cDX_Interface& );  // kopierkonstruktor private, KEIN kopieren mehr möglich


public:

    ~cDX_Interface(){ Destroy(); }

    static  cDX_Interface*      Create();
            BOOL                InitDirectX(HWND * phWnd);
            LPDIRECT3DDEVICE9 & GetD3DDevice(){return m_D3DDevice; }

            HRESULT             Destroy();
            HRESULT             CleanUpDirectX();
}


noch der 'wichtige' teil aus der .cpp:

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
cDX_Interface* cDX_Interface::pDX_Interface = NULL;

cDX_Interface::cDX_Interface(): m_D3DObject(NULL),
                                m_D3DDevice(NULL)

{
    //

}

cDX_Interface* cDX_Interface::Create()
{
    if (pDX_Interface==NULL)
    {
        pDX_Interface = new cDX_Interface;
        return pDX_Interface;
    }
    return pDX_Interface;
}

HRESULT cDX_Interface::Destroy()
{
    // Speicherbereich mit 0 auffüllen

    // Pointer löschen

    // Point-to Adresse löschen

    if (pDX_Interface)
    {
        SecureZeroMemory(&pDX_Interface,sizeof(pDX_Interface));
        delete pDX_Interface;
        pDX_Interface = NULL;
        return S_OK;
    }
    // Keine Objektinstanz zum löschen vorhanden

    // RETURN: Invalid_Pointer

    return E_POINTER;
}


wenn ich nun zb. in meiner WinMain folgenden aufruf mache:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
    cDX_Interface* DX_DEVICE = cDX_Interface::Create();

    BOOL initOk = DX_DEVICE->InitDirectX(&hWnd);

    if (!initOk)
    {
        DX_DEVICE->Destroy();
        LOGFILE->ShowMsg(ERR_MSG_INIT_D3DDEVICE);
        // APP-beenden

        PostQuitMessage(WM_QUIT);
    }

    LPDIRECT3DDEVICE9 refDX_DEVICE = DX_DEVICE->GetD3DDevice();


... haut danach auch alles super hin - sprich wenn ich in meiner WinMain dann zb. meine Sprites rendern lasse.

nun sollte aber der renderer auch in eine eigene klasse.
wie oder wo platziert mann sowas am geschicktesten?
könnt ihr mir da einen rat geben?

von der cDX_Interface trau ich mich nicht wirklich ableiten.

sollte ich den renderer auch als eigenständige singleton machen und dann das DX_DEVICE übergeben?

wah mir kommt das alles a bisserl unsauber und gefährlich im bezug auf mem-leaks vor ...

Black-Panther

Alter Hase

Beiträge: 1 444

Wohnort: Innsbruck

  • Private Nachricht senden

2

20.06.2006, 11:15

Also ich habs so gelöst, dass ich mir den ->- Operator (wie auch bei Davids Tribase) überlade, und damit direkt auf D3DDevice zugreife (bei mir heißt die Klasse ogDirect3D):

Achtung: Pseudocode ;)

C-/C++-Quelltext

1
2
3
4
5
//Singletoninstanz holen

ogDirect3D& D3D = ogDirect3D::Instance();

D3D.MethodeAusDerKlasseSelbst();
D3D->MethodeVonD3DDevice();

alexm

Frischling

  • »alexm« ist der Autor dieses Themas

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

3

20.06.2006, 11:30

aha, also doch eine ganz seperate klasse für den renderer und nix mit ableitung oder nested-class (?)

momentan mach ich mir gerade eben so eine eigenständige renderer-klasse - auch als singleton. die bekommt bei der erzeugung das D3D_DEVICE-Handle mit und somit kann der renderer dann damit machen was er will.

hab ich mir halt so gedacht - ob das so als sauber gilt, weiss ich halt nicht
:roll:

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

4

20.06.2006, 12:23

Du brauchst deinem Renderer gar kein D3D_DEVICE zu übergeben, weil du ja auf den entsprechenden Singleton zugreifen kannst. Andernfalls hättest du dir den Singleton cDX_Interface auch sparen können.

Du hast blos den Zugriff auf den cDX_Interface Singleton unglücklich benannt; deine "Create ()" Methode hiesse besser "GetInstance ()"

Das könnte dann so aussehen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void Renderer::render ()
{
  cDX_Interface* d3d = cDX_Interface::Create (); // schöner wäre GetInstance


  LPDIRECT3DDEVICE9 device = d3d->getD3DDevice ();

  // Rendern

}


Wenn du so auf die cDX_Interface Instanz zugreifst, kannst du sie (sozusagen hinter dem Rücken des Renderer) einfach austauschen ohne dass du auch den Renderer neu erzeugen musst.

Zum Thema Speicherlecks mit Singletons gibt es hier im Forum schon einige Threads, z.B. diesen hier: https://www.spieleprogrammierer.de/phpBB…light=singleton

MfG
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

alexm

Frischling

  • »alexm« ist der Autor dieses Themas

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

5

20.06.2006, 13:08

:idea: ah super denkanstoss!

hab das mal so umgeschrieben - momentan hauts das ganze aber noch voll auf(->absturz). irgendwo hab ich einen fehler drinn ... mal suchen.

wegen dem thread: ah super, den hatte ich schon mal gesehen, da steht ja inzwischen um einiges mehr drinn. mal schmökern. hilft mir vielleicht bei meinem absturz ...


DANKESCHÖN !!!
8)

Werbeanzeige