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

Spy

Frischling

  • »Spy« ist der Autor dieses Themas
  • Private Nachricht senden

1

26.12.2007, 19:17

LNK2019 - Mal wieder die Symbole

Dieser Post hier hat nichts mit einem einfachen Fehler zu tun indem ich vergessen habe eine .lib einzubinden.

Wenn du nicht sehr viel Zeit hast musst du an dieser Stelle nicht weiterlesen... :)

Also ich liste hier erstmal meine Datei auf die gibts auch zum Download:
http://rapidshare.com/files/79222724/DirectX_Initalition.rar.html

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
//DirectX_Init.h

#ifndef _DIRECTX_INIT_
#define _DIRECTX_INIT_

class DirectX_Init
{
public:
    /********Funktinsdeklarationen***************/
    //Fenster:

    tbResult        InitWindow(int iWidth, int iHeight, char* pcName, HICON hIcon);
    tbResult        ExitWindow();
    tbResult        DoMessageLoop(tbResult (* pRenderProc)(float), tbResult (* pMoveProc)(float));
    LRESULT WINAPI  WindowProc(HWND hWindow, unsigned int uiMessage, WPARAM WParam, LPARAM LParam);
    //DirectX:

    tbResult        InitDirectX();
    tbResult        ExitDirectX();
    
    tbResult InitAll() 
    {
        tbInit();
        InitWindow(1024,768,"Beispiel",0);
        InitDirectX();

        return TB_OK;
    }

    tbResult ExitAll()
    {
        ExitWindow();
        ExitDirectX();
        tbExit();
        
        return TB_OK;
    }
};
#endif //Passt perfekt auf eine Seite


Hier die Implenmentierung(ihr könnt das auch überspringen...ist nur im nachhinein für die Fehlersuche gut...):

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//DirectX_Init.cpp


#include <TriBase.h>
#include <D3D9.h>
#include <windows.h>
#include "DirectX_Init.h"
#include "DirectX_Globals.h"


/*******Fenster Initalisieren*********/
tbResult InitWindow(int iWidth, int iHeight, char* pcName, HICON hIcon)
{
        // Fensterklassenstruktur ausfüllen

    WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0, 0,
                              GetModuleHandle(NULL), hIcon, LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)), NULL,
                              NULL, "Direct3D window", NULL};

    // Klasse registrieren

    if(!RegisterClassEx(&WindowClass))
    {
        TB_ERROR("Fensterklassenregistrierung fehlgeschlagen!", TB_ERROR);
    }

    TB_INFO("Fensterklasse wurde registriert!");

    RECT Rect;
    SetRect(&Rect, 0, 0, iWidth, iHeight);
    AdjustWindowRect(&Rect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE);
    iWidth = Rect.right - Rect.left;
    iHeight = Rect.bottom - Rect.top;

    // Fenster erstellen und prüfen

    g_hWindow = CreateWindow("Direct3D window",
                             pcName,
                             WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                             GetSystemMetrics(SM_CXSCREEN) / 2 - iWidth / 2,
                             GetSystemMetrics(SM_CYSCREEN) / 2 - iHeight / 2,
                             iWidth,
                             iHeight,
                             NULL,
                             NULL,
                             GetModuleHandle(NULL),
                             NULL);
    if(g_hWindow == NULL)
    {
        TB_ERROR("Erstellung des Fensters ist fehlgeschlagen!\n", TB_ERROR);
    }

    // Alles OK!

    TB_INFO("Fenster wurde erstellt!");

    return TB_OK;
}

/*************************************/

/*******Fenster herunterfahren********/
tbResult ExitWindow()
{
// Klasse löschen

    UnregisterClass("Direct3D window", GetModuleHandle(NULL));

    TB_INFO("Fensterkomponente wurde heruntergefahren!");

    return TB_OK;
}
/*************************************/

/*Die Nachrichtenfunktion des Fensters*/
LRESULT WINAPI WindowProc(HWND hWindow,
                          unsigned int uiMessage,
                          WPARAM WParam,
                          LPARAM LParam)
{
    PAINTSTRUCT Paint;

    switch(uiMessage)
    {
    case WM_CREATE:
        break;

    case WM_PAINT:
        // Das Fenster mit Schwarz füllen

        BeginPaint(hWindow, &Paint);
        FillRect(Paint.hdc, &Paint.rcPaint, (HBRUSH)(GetStockObject(BLACK_BRUSH)));
        EndPaint(hWindow, &Paint);
        break;

    case WM_CLOSE:
        DestroyWindow(hWindow);
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWindow, uiMessage, WParam, LParam);
    }

    return TRUE;
}

/*********************************/

/****DirectX initalisieren********/
tbResult InitDirectX()
{
    HRESULT                 hResult;
    D3DPRESENT_PARAMETERS   PresentParams;
    

    // Globale IDirect3D9-Schnittstelle erzeugen

    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_pD3D == NULL) TB_ERROR("IDirect3D9-Schnittstelle konnte nicht erstellt werden!", TB_ERROR);

    TB_INFO("IDirect3D9-Schnittstelle wurde erzeugt!");

    // Präsentationsstruktur ausfüllen

    ZeroMemory(&PresentParams, sizeof(D3DPRESENT_PARAMETERS));
    PresentParams.BackBufferWidth               = 800;
    PresentParams.BackBufferHeight              = 600;
    PresentParams.BackBufferFormat              = D3DFMT_R5G6B5;
    PresentParams.MultiSampleType               = D3DMULTISAMPLE_NONE;
    PresentParams.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
    PresentParams.hDeviceWindow                 = g_hWindow;
    PresentParams.Windowed                      = false;
    PresentParams.EnableAutoDepthStencil        = true;
    PresentParams.AutoDepthStencilFormat        = D3DFMT_D16;;
    
    

    UINT uiAdapter = g_pD3D->GetAdapterCount();

    // Und nun die Geräteschnittstelle generieren

    if(FAILED(hResult = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
                                             D3DDEVTYPE_HAL,
                                             g_hWindow,
                                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                             &PresentParams,
                                             &g_pD3DDevice)))
    {
        MessageBox(g_hWindow,"DirectX Fehler","DX",MB_OK);
        
        
        
        // Fehler beim Generieren der Schnittstelle!

        TB_SAFE_RELEASE(g_pD3D);
        TB_SAFE_RELEASE(g_pD3DDevice);
        TB_ERROR_DIRECTX("g_pD3D->CreateDevice", hResult, TB_ERROR);
        
        
        
    }

    // Es hat geklappt!

    TB_INFO("Geräteschnittstelle wurde generiert!");

    // Cursor ausblenden

    ShowCursor(FALSE);

    return TB_OK;
}
/*****DirectX herunterfahren*******/
tbResult ExitDirectX()
{
    TB_SAFE_RELEASE(g_pD3D);
    TB_SAFE_RELEASE(g_pD3DDevice);
    return TB_OK;
}
/**********************************/


So und für die globalen Variablen die ich hierfür brauche habe ich einen eignen Header gemacht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//DirectX_Globals.h

#ifdef _DIRECTX_GLOBALS_CPP
#undef VAR
#define VAR
#else
#undef VAR
#define VAR extern
#endif

 /******Globale Variablen******/
 static  HWND               g_hWindow(0);
 static PDIRECT3D9          g_pD3D(0);
 static PDIRECT3DDEVICE9    g_pD3DDevice(0);
/******************************/

Also wenn ich die Variablen als VAR(extern) deklariert habe dann habe ich den ersten Compilerfehler bekommen:

Zitat


1>DirectX_Init.obj : error LNK2005: "struct HWND__ * g_hWindow" (?g_hWindow@@3PAUHWND__@@A) ist bereits in DirectX_Globals.obj definiert.
1>DirectX_Init.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) ist bereits in DirectX_Globals.obj definiert.
1>DirectX_Init.obj : error LNK2005: "struct IDirect3DDevice9 * g_pD3DDevice" (?g_pD3DDevice@@3PAUIDirect3DDevice9@@A) ist bereits in DirectX_Globals.obj definiert.

Ich glaube alles hängt damit zusammen...wenn ich sie als "static" deklarier kommen diese 3 Zeilen nicht.

Das ist aber nicht mein Hauptproblem:
So wenn ich jetzt die Klasse verwenden möchte und ich schön brav so eine main.cpp aufsetze:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <TriBase.h>
#include <D3D9.h>
#include <windows.h>
#include "C:\Dokumente und Einstellungen\GliderBugFix\Desktop\MyClasses\Second Release\DirectX_Init.h"
tbResult Render(float fNumSecsPassed)
{
    return TB_OK;
}
tbResult Move(float fNumSecsPassed)
{
    return TB_OK;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    DirectX_Init Init;
    Init.DoMessageLoop(Render,Move);

    return FALSE;
}

Dann erzeugt Init.DoMessageLoop(Render,Move) einen Fehler names LNK2019 und der sieht folgendermassen aus:

Zitat


1>main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: enum tbResult __thiscall DirectX_Init::DoMessageLoop(enum tbResult (__cdecl*)(float),enum tbResult (__cdecl*)(float))" (?DoMessageLoop@DirectX_Init@@QAE?AW4tbResult@@P6A?AW42@M@Z0@Z)" in Funktion "_WinMain@16".

Was soll ich nur tun und diese Funktion hat nichts mit der "static" Deklaration zu tun da hier keine Globale "benützt" wird.

Weis jemand was ich machen muss? Ich vermute das es etwas mit Aufrufkonvention zu tun hat...hier der Link in der MSDN:
:arrow: ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.de/dv_vccomp/html/4392be92-195c-4eb2-bd4d-49cfac3ca291.htm
Achtung den Link müsst hier mit eurem VC++ aufrufen(mit diesem Hilfsbrowser).

Weis jemand wie ich meinen Code verändern muss/soll.

Vielleicht gehört das ganze hier doch lieber in das C++ Forum :?

Danke Leute!
____________________________________________
MfG Spy(bescheuerter Name) 8)

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

2

26.12.2007, 19:37

Also was mir als erste auffällt ist, dass du deine sämtlichen Implementierungen von DirectX_Init Memberfunktionen nicht mit dem Klassenname qualifizierst... also statt

C-/C++-Quelltext

1
2
3
4
tbResult InitWindow(...)
{
 ...
}

lieber

C-/C++-Quelltext

1
2
3
4
tbResult DirectX_Init::InitWindow(...)
{
 ...
}


Könnte sein, dass das dein Problem löst, ansonsten ma weiter schaun.

Bugger

Frischling

Beiträge: 66

Wohnort: Bezirk Freistadt

Beruf: EDVO HTL Schüler

  • Private Nachricht senden

3

26.12.2007, 19:40

Wundert dich das wirklich?

Du rufst eine Funktion auf die du nie definiert hast (DoMessageLoop) :roll:

Außerdem sollte man #includes wenn möglich schon im header machen - dein ganzes #ifdef, #define könntest du dir nebenbei mit einem #pragma once sparen, wenn du erreichen willst dass dein Header nur einmal kompiliert wird und was du am Anfang von DirectX_Globals.h erreichen willst ist mir ein Rätsel(so nebenbei - du solltest besser _DIRECTX_GLOBALS_H definieren)
Hältst du nicht den Bug in Ehren, wird er dich noch manches Lehren.

Ein Gespräch setzt voraus, dass der andere Recht haben könnte.

NicoWe

Treue Seele

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

4

26.12.2007, 23:40

#pragma once ist aber microsoft spezifisch(so weit ich weiß) und es ist vllt besser etwas standartkonformeres zu benutzen ;)

Das mit dem ist bereits in xy definiert ließe sich vllt mit einer pragma once ÄHNLICHEN Konstruktion umgehen, da wenn der Kompiler 2 cpp Dateien kompiliert die diesen Header includieren werden so weit ich weiß auch die dort definierten/deklarierten Funktionen/Variablen/Klasse/etc. 2 mal definiert/deklariert (bei jeder .cpp einmal).

@Bugger: ja, das wäre die pragma once sache, nur er hat iwo anders _DIRECTX_GLOBALS definiert/nicht definiert und so ist die Aufgabe des Headers entweder dieses VAR als extern zu definieren oder eben nicht :) Wenn er das benutzt hätte was du benutzt hättest wären dort keine Fehler gewesen(pragma once ähnliches)

So, das sind meine Vermutungen, vllt ist sogar was dran richtig ;)
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

Spy

Frischling

  • »Spy« ist der Autor dieses Themas
  • Private Nachricht senden

5

27.12.2007, 07:42

Zitat von »"grek40"«

Also was mir als erste auffällt ist, dass du deine sämtlichen Implementierungen von DirectX_Init Memberfunktionen nicht mit dem Klassenname qualifizierst... also statt

C-/C++-Quelltext

1
2
3
4
tbResult InitWindow(...)
{
 ...
}

lieber

C-/C++-Quelltext

1
2
3
4
tbResult DirectX_Init::InitWindow(...)
{
 ...
}


Könnte sein, dass das dein Problem löst, ansonsten ma weiter schaun.


Oh Sorry. Grosser Anfängerfehler. Mann bin ich dumm das hätte ich auch selber schnallen können.

Spy

Frischling

  • »Spy« ist der Autor dieses Themas
  • Private Nachricht senden

6

27.12.2007, 07:54

Jetzt hätte ich da noch ein Problem:
WindowProc ist eine "overloaded-function" sprich überladen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
//......

tbResult DirectX_Init::InitWindow(int iWidth, int iHeight, char* pcName, HICON hIcon)
{
    // Fensterklassenstruktur ausfüllen

    WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0, 0,
                              GetModuleHandle(NULL), hIcon, LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)), NULL,
                              NULL, "Direct3D window", NULL};
//....

Was soll ich in diesem ganz speziellen Fall machen um zu bestimmen welches WindowProc gemeint ist...
Hier der Compilerfehler:

Zitat


1>..\..\..\..\MyClasses\Second Release\DirectX_Init.cpp(12) : error C2440: 'Initialisierung': 'overloaded-function' kann nicht in 'WNDPROC' konvertiert werden
1> Keine Funktion mit diesem Namen im Gültigkeitsbereich stimmt mit dem Zieltyp überein


Nochmal danke an alle für ihre freundliche Hilfe ;)
__________________________________
MfG Spy :D

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

27.12.2007, 09:50

Mach aus:

C-/C++-Quelltext

1
...CS_CLASSDC, WindowProc, ...


ein

C-/C++-Quelltext

1
...CS_CLASSDC, (WNDPROC)WindowProc, ...


Und schau nach ob die Signatur deiner Windows Procedure korrekt ist:

C-/C++-Quelltext

1
LRESULT CALLBACK WindowProc(HWND hWindow, UINT uiMessage, WPARAM WParam, LPARAM LParam)


Und nur so am Rande: Hör auf die Macros der WinAPI aufzulösen!
@D13_Dreinig

8

27.12.2007, 12:56

Hmm wenn die WindowProc teil der Klasse sein soll, musst du diese als static setzen ...
(wie man dann wieder auf eine non-static-Funktion kommt, sag ich dir, falls du es brauchst ;) In dem Fall sollte es aber ohne gehen, da du keine Variablen deiner Klasse zu brauchen scheinst ...)
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

Spy

Frischling

  • »Spy« ist der Autor dieses Themas
  • Private Nachricht senden

9

27.12.2007, 13:20

Zitat von »"Deviloper"«

Hmm wenn die WindowProc teil der Klasse sein soll, musst du diese als static setzen ...
(wie man dann wieder auf eine non-static-Funktion kommt, sag ich dir, falls du es brauchst ;) In dem Fall sollte es aber ohne gehen, da du keine Variablen deiner Klasse zu brauchen scheinst ...)


Ich brauche mein Buch über OOP wieder. Ich habe keine Ahnung mehr von "static" und Co. Entschuldigung ,dass ich hier das Forum mit diesen Anfängerfragen verseuche. :( Naja das probiere ich gleich mal aus.

Vorerst Danke an Alle


EDIT: Gut das da ein "vorerst" drinne war.
Also hier sind die Änderungen meiner Klassen:
DirectX_Init.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
25
26
27
28
29
30
31
32
33
34
35
#ifndef _DIRECTX_INIT_H_
#define _DIRECTX_INIT_H_

class DirectX_Init
{
public:
    /********Funktionsdeklarationen***************/
    //Fenster:

    tbResult                         InitWindow(int iWidth, int iHeight, char* pcName, HICON hIcon);
    tbResult                         ExitWindow();
    tbResult                         DoMessageLoop(tbResult (* pRenderProc)(float), tbResult (* pMoveProc)(float));
    static LRESULT  CALLBACK WINAPI  WindowProc(HWND hWindow, unsigned int uiMessage, WPARAM WParam, LPARAM LParam);
    //DirectX:

    tbResult        InitDirectX();
    tbResult        ExitDirectX();
    
    tbResult InitAll() 
    {
        tbInit();
        InitWindow(1024,768,"Beispiel",0);
        InitDirectX();

        return TB_OK;
    }

    tbResult ExitAll()
    {
        ExitWindow();
        ExitDirectX();
        tbExit();
        
        return TB_OK;
    }
};
#endif //Passt perfekt auf eine Seite

Wie ihr sieht habe ich die Präprozzesoranweisungen umgeschrieben und WindowProc als "static" deklariert.
DirectX_Init.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
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <TriBase.h>
#include <D3D9.h>
#include <windows.h>
#include "DirectX_Globals.h"
#include "DirectX_Init.h"






/*******Fenster Initalisieren*********/
tbResult DirectX_Init::InitWindow(int iWidth, int iHeight, char* pcName, HICON hIcon)
{
    // Fensterklassenstruktur ausfüllen

    WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0, 0,
                              GetModuleHandle(NULL), hIcon, LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)), NULL,
                              NULL, "Direct3D window", NULL};

    // Klasse registrieren

    if(!RegisterClassEx(&WindowClass))
    {
        TB_ERROR("Fensterklassenregistrierung fehlgeschlagen!", TB_ERROR);
    }

    TB_INFO("Fensterklasse wurde registriert!");

    RECT Rect;
    SetRect(&Rect, 0, 0, iWidth, iHeight);
    AdjustWindowRect(&Rect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE);
    iWidth = Rect.right - Rect.left;
    iHeight = Rect.bottom - Rect.top;

    // Fenster erstellen und prüfen

    g_hWindow = CreateWindow("Direct3D window",
                             pcName,
                             WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                             GetSystemMetrics(SM_CXSCREEN) / 2 - iWidth / 2,
                             GetSystemMetrics(SM_CYSCREEN) / 2 - iHeight / 2,
                             iWidth,
                             iHeight,
                             NULL,
                             NULL,
                             GetModuleHandle(NULL),
                             NULL);
    if(g_hWindow == NULL)
    {
        TB_ERROR("Erstellung des Fensters ist fehlgeschlagen!\n", TB_ERROR);
    }

    // Alles OK!

    TB_INFO("Fenster wurde erstellt!");

    return TB_OK;
}

/*************************************/

/*******Fenster herunterfahren********/
tbResult DirectX_Init::ExitWindow()
{
// Klasse löschen

    UnregisterClass("Direct3D window", GetModuleHandle(NULL));

    TB_INFO("Fensterkomponente wurde heruntergefahren!");

    return TB_OK;
}
/*************************************/

/*Die Nachrichtenfunktion des Fensters*/
LRESULT CALLBACK WINAPI DirectX_Init::WindowProc(HWND hWindow,
                                                 unsigned int uiMessage,
                                                 WPARAM WParam,
                                                 LPARAM LParam)
{
    PAINTSTRUCT Paint;

    switch(uiMessage)
    {
    case WM_CREATE:
        break;

    case WM_PAINT:
        // Das Fenster mit Schwarz füllen

        BeginPaint(hWindow, &Paint);
        FillRect(Paint.hdc, &Paint.rcPaint, (HBRUSH)(GetStockObject(BLACK_BRUSH)));
        EndPaint(hWindow, &Paint);
        break;

    case WM_CLOSE:
        DestroyWindow(hWindow);
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWindow, uiMessage, WParam, LParam);
    }

    return TRUE;
}

/*********************************/

/****DirectX initalisieren********/
tbResult DirectX_Init::InitDirectX()
{
    HRESULT                 hResult;
    D3DPRESENT_PARAMETERS   PresentParams;
    

    // Globale IDirect3D9-Schnittstelle erzeugen

    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_pD3D == NULL) TB_ERROR("IDirect3D9-Schnittstelle konnte nicht erstellt werden!", TB_ERROR);

    TB_INFO("IDirect3D9-Schnittstelle wurde erzeugt!");

    // Präsentationsstruktur ausfüllen

    ZeroMemory(&PresentParams, sizeof(D3DPRESENT_PARAMETERS));
    PresentParams.BackBufferWidth               = 800;
    PresentParams.BackBufferHeight              = 600;
    PresentParams.BackBufferFormat              = D3DFMT_R5G6B5;
    PresentParams.MultiSampleType               = D3DMULTISAMPLE_NONE;
    PresentParams.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
    PresentParams.hDeviceWindow                 = g_hWindow;
    PresentParams.Windowed                      = false;
    PresentParams.EnableAutoDepthStencil        = true;
    PresentParams.AutoDepthStencilFormat        = D3DFMT_D16;;
    
    

    UINT uiAdapter = g_pD3D->GetAdapterCount();

    // Und nun die Geräteschnittstelle generieren

    if(FAILED(hResult = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
                                             D3DDEVTYPE_HAL,
                                             g_hWindow,
                                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                             &PresentParams,
                                             &g_pD3DDevice)))
    {
        MessageBox(g_hWindow,"DirectX Fehler","DX",MB_OK);
        
        
        
        // Fehler beim Generieren der Schnittstelle!

        TB_SAFE_RELEASE(g_pD3D);
        TB_SAFE_RELEASE(g_pD3DDevice);
        TB_ERROR_DIRECTX("g_pD3D->CreateDevice", hResult, TB_ERROR);
        
        
        
    }

    // Es hat geklappt!

    TB_INFO("Geräteschnittstelle wurde generiert!");

    // Cursor ausblenden

    ShowCursor(FALSE);

    return TB_OK;
}
/*****DirectX herunterfahren*******/
tbResult DirectX_Init::ExitDirectX()
{
    TB_SAFE_RELEASE(g_pD3D);
    TB_SAFE_RELEASE(g_pD3DDevice);
    return TB_OK;
}
/**********************************/

Hier habe ich allen Funktionsdefinitionen mitttels "::"-Operator den Klassennamen vorangestellt.
DirectX_Globals.h:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
#pragma once
#ifndef _DIRECTX_GLOBALS_H
#define _DIRECTX_GLOBALS_H

 /******Globale Variablen******/
 static  HWND               g_hWindow(0);
 static  PDIRECT3D9         g_pD3D(0);
 static  PDIRECT3DDEVICE9   g_pD3DDevice(0);
/******************************/

#endif

Hier wurden auch die Präprozessoranweisung verändert. Alles wird allerdings als "static" deklriert "extern" erzeugt Compilerfehler.
DirectX_Globals.cpp:

C-/C++-Quelltext

1
2
3
4
5
#include <TriBase.h>
#include <D3D9.h>
#include <windows.h>

#include "DirectX_Globals.h"

Das hier wurde nicht verändert. Ich weis nicht was es für einen Nutzen hat die includes schon im Header zu tätigen.
main.cpp(Ausführung):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <TriBase.h>
#include <D3D9.h>
#include <windows.h>
#include "C:\Dokumente und Einstellungen\GliderBugFix\Desktop\MyClasses\Second Release\DirectX_Init.h"
tbResult Render(float fNumSecsPassed)
{
    return TB_OK;
}
tbResult Move(float fNumSecsPassed)
{
    return TB_OK;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    DirectX_Init Init;
    Init.InitWindow(1024,768,"Beispiel",0);
            tbDoMessageLoop(Move,Render);
            Init.ExitWindow();
    return FALSE;
}

Jetzt macht der Code auch endlich mal einen Sinn.

Leider erzeugt hier InitWindow und ExitWindow den folgenden Linkererror:

Zitat


LNK-Error 2 unaufgelöst externe Verweise...

Wurde einfach nur erstellt weil die Objekt-Files im falschen Verzeichnis war.

Also funzt super und wird meine Arbeit total erleichtern.

Jetzt endgültig: Danke an alle.
MfG Spy
Mein GE-Projekt

10

27.12.2007, 14:49

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
#if !defined(DIRECTXWINDOW_HPP_INCLUDED)
#define DIRECTXWINDOW_HPP_INCLUDED

#if (_MSC_VER >= 1300)
#pragma once
#endif // (_MSC_VER >= 1300)


#include <windows.h>
#include <TriBase.h>
#include <D3D9.h>

class DirectXWindow
{
    ::HWND  m_hWnd;
    ::IDirect3D9* m_ptrD3D;
    ::IDirect3DDevice9* m_ptrDevice;

public:
    DirectXWindow(unsigned int cx = 1024, unsigned int cy = 768, const char* caption = "DirectX", ::HICON const& icon)
        : m_ptrD3D(::Direct3DCreate9(D3D_SDK_VERSION))
    {
        tbInit();
        init_window(cx, cy, caption, icon);
        if (m_ptrD3D == NULL) throw std::runtime_error("directx not installed");
        init_directx();
    }
    ~DirectXWindow()
    {
        exit_window();
        exit_directx();
        tbExit();
    }

public:
    operator ::HWND() const     {   return m_hWnd;  }
#pragma warning(disable: 4312)
    static DirectXWindow* FromHandle(::HWND const & hWnd) { return reinterpret_cast<DirectXWindow*>(GetWindowLongPtr(hWnd, GWL_USERDATA)); };
#pragma warning(default: 4312)


protected:
    bool                            init_window(unsigned int, unsigned int, const char*, ::HICON const&);
    void                            exit_window();
    virtual LRESULT                 window_proc(HWND, UINT, WPARAM, LPARAM);

private:
    static LRESULT CALLBACK WINAPI  __window_proc(HWND, UINT, WPARAM, LPARAM);

protected:
    void                            init_directx();
    void                            exit_directx();
    tbResult                        message_loop(tbResult (* pRenderProc)(float), tbResult (* pMoveProc)(float));
};

#endif // DIRECTXWINDOW_HPP_INCLUDED


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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "DirectXWindow.hpp"

bool DirectXWindow::init_window(unsigned int width, unsigned int height, const char* caption, ::HICON const& icon)
{
    ::WNDCLASSEXA wc = {};
    wc.cbSize = sizeof(::WNDCLASSEXA);
    wc.style            = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc      = &DirectXWindow::__window_proc;
    wc.hInstance        = ::GetModuleHandleA(NULL);
    wc.hIcon            = wc.hIconSm = icon;
    wc.hCursor          = ::LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));     
    wc.hbrBackground    = reinterpret_cast<::HBRUSH>(::GetStockObject(LTGRAY_BRUSH));
    wc.lpszClassName    = "DirectXWindow";

    if (::RegisterClassExA(&WindowClass) == 0) return false;

    m_hWnd = ::CreateWindowExA(NULL, "DirectXWindow", caption, WS_VISIBLE | WS_OVERLAPPEDWINDOW, ::GetSystemMetrics(SM_CXSCREEN) / 2.0 - width / 2.0, 
        ::GetSystemMetrics(SM_CYSCREEN) / 2.0 - height / 2.0, NULL, NULL, wc.hInstance, reinterpret_cast<LPVOID>(this));
    
    return m_hWnd != NULL
}

void DirectX_Init::exit_window()
{
    ::UnregisterClassA("DirectXWindow", ::GetModuleHandleA(NULL));
}

LRESULT DirectXWindow::window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_PAINT:
        {
            ::RECT rect;
            ::GetClientRect(hWnd, &rect);
            ::PAINTSTRUCT ps;
            ::HDC hDC(::BeginPaint(hWnd, &ps));
            ::FillRect(hDC, &rect, static_cast<::HBRUSH>(::GetStockObject(BLACK_BRUSH)));
            ::EndPaint(hWnd, &ps);
        } break;
        case WM_CLOSE:
        {
            ::PostQuitMessage(0);
        } break;
        default:
            return ::DefWindowProcA(hWnd, msg, wParam, lParam);
    }
    return 0L;
}

LRESULT CALLBACK DirectXWindow::__window_proc(::HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    DirectXWindow* ptr_window(DirectXWindow::FromHandle(hWnd));
#pragma warning(disable: 4311)
    if (message == WM_NCCREATE)
    {
        ptr_window = reinterpret_cast<DirectXWindow*>(reinterpret_cast<::LPCREATESTRUCT>(lParam)->lpCreateParams);
        ::SetWindowLongPtr(hWnd, GWL_USERDATA, reinterpret_cast<LONG>(ptr_window));
    }
#pragma warning(default: 4311)
    return (ptr_window != NULL ? ptr_window->window_proc(hWnd, message, wParam, lParam) : ::DefWindowProcA(hWnd, message, wParam, lParam));
}


void DirectXWindow::init_directx()
{
    D3DPRESENT_PARAMETERS ppm = {0};
    ppm.BackBufferWidth = 800;
    ppm.BackBufferHeight = 600;
    ppm.BackBufferFormat = D3DFMT_R5G6B5;
    ppm.MultiSampleType = D3DMULTISAMPLE_NONE;
    ppm.SwapEffect = D3DSWAPEFFECT_DISCARD;
    ppm.hDeviceWindow = m_hWnd;
    ppm.Windowed = true;
    ppm.EnableAutoDepthStencil = true;
    ppm.AutoDepthStencilFormat = D3DFMT_D16;;

    if (FAILED(m_ptrD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &ppm, &m_ptrDevice)))
    {
        TB_SAFE_RELEASE(m_ptrD3D);
        TB_SAFE_RELEASE(m_ptrDevice);
        throw std::runtime_error("could not create device");
    }
}

void DirectXWindow::exit_directx()
{
    TB_SAFE_RELEASE(m_pD3D);
    TB_SAFE_RELEASE(m_pD3DDevice);
}


Was mit tbDoMessageLoop ist, weiß ich nicht ...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
#include <TriBase.h>
#include "DirectXWindow.hpp"

tbResult Render(float) { return TB_OK; }
tbResult Move(float) { return TB_OK; }

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    DirectXWindow window(1024, 768, "Beispiel", NULL);
    tbDoMessageLoop(Move, Render);
    return 0;
}


So der Code ist nicht compiliert / getestet und kann d.h. noch Syntaxfehler enthalten ... die wirst du dann aber wohl selbst finden ... das meiste ist ja weg.
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