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

1

10.09.2013, 13:08

(3. Auflage) Anzeigeproblem einer eigener Milkshape-Leuchtturmtextur in Übungsaufgabe 2.9.5

Hallo zusammen,

in Übungsaufgabe 2.9.5. geht es darum einen Leuchtturm mittels SpotLight zum Leuchten zu bringen. Ich habe daraufhin mit Hilfe von MilkShape und einer Textur ein 3D-Modell eines Leuchtturms erstellt und diese Datei in ein ".x"-file nach DirectX 9.0 zu konvertiert (Modell-Dateien sind im Anhang (lighthouse.zip)).

Die Konvertierung in Milkshape erfolgte bei mir mittels "DirectX JT" (vgl. Screenshot DirectX (JT).bmp).

Nun habe ich versucht diesen Leuchtturm in einem Programm anzeigen zu lassen. Dafür habe ich zunächst die folgende Dateien des beiliegenden Datenträgers zum Buch in mein Projekt eingebunden:
  • Allgemeines.h
  • Direct3DEnum.h (+cpp)
  • InitDirect3D.h (+cpp)
  • InitWindow.h (+cpp)
  • Allgemeines.rc
  • Sphere.x (entspricht der Sphere-Textur aus den Beispielprogramm Nr. 7: Beleuchtung)

Ferner habe ich eine eigene Datei Buffer.cpp erstellt, die die Init-Funktion, die Render-Funktion und die Move-Funktion enthält (die noch enthaltenen Funktionen WinMain, InitApplication, ExitApplication entsprechen denen aus Beispielprogramm Nr 7: Beleuchtung)

:this:
Render:

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
// ******************************************************************
// Render-Funktion
tbResult Render(float fNumSecsPassed)
{
    HRESULT         hResult;
    float           fAspect;
    tbMatrix        mCamera;
    tbMatrix        mProjection;
    tbMatrix        mScaling;       // Skalierungsmatrix
    tbMatrix        mRotationX;     // Rotationsmatrix für die x-Achse
    tbMatrix        mRotationY;     // Rotationsmatrix für die y-Achse
    tbMatrix        mRotationZ;     // Rotationsmatrix für die z-Achse
    tbMatrix        mTranslation;   // Translationsmatrix
    tbMatrix        mWorld;         // Vereinende Weltmatrix
    D3DMATERIAL9    pMaterial;      // aktuelles Material
    D3DXMATERIAL*   pMaterials = NULL;



    // Den Bildpuffer und den Z-Buffer leeren
    if(FAILED(hResult = g_pD3DDevice->Clear(0,
                                            NULL,
                                            D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                                            g_dwFogColor,
                                            1.0f,
                                            0)))
    {
        // Fehler beim Leeren!
        TB_ERROR_DIRECTX("g_pD3DDevice->Clear", hResult, TB_STOP);
    }

    // Szene beginnen
    g_pD3DDevice->BeginScene();

    // ------------------------------------------------------------------

    // Die Kameramatrix erzeugen und einsetzen.
    // Dafür benötigen wir die Kameraposition, den Blickpunkt der Kamera und
    // die lokale y-Achse der Kamera, die normalerweise (0, 1, 0) ist (es sei denn,
    // die Kamera "rollt").
    mCamera = tbMatrixCamera(g_vCameraPosition,
                             g_vCameraPosition + tbVector3(sinf(g_fCameraAngle),
                                                           0.0f,
                                                           cosf(g_fCameraAngle)),
                             tbVector3(0.0f, 1.0f, 0.0f));
    g_pD3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)(&mCamera));

    // Das Bildseitenverhältnis berechnen
    fAspect =   (float)(g_Direct3DParameters.VideoMode.Width)
              / (float)(g_Direct3DParameters.VideoMode.Height);

    // Die Projektionsmatrix erzeugen und einsetzen.
    // Das geschieht hier einmal pro Bild, weil das Sichtfeld variabel ist.
    mProjection = tbMatrixProjection(g_fFOV,    // Sichtfeld
                                     fAspect,   // Bildseitenverhältnis
                                     0.1f,      // Nahe Clipping-Ebene
                                     250.0f);   // Ferne Clipping-Ebene
    g_pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)(&mProjection));

    // ------------------------------------------------------------------



    // Leuchtturm zeichnen

    mTranslation = tbMatrixTranslation(tbVector3(10.0f, 0.0f, 10.0f));
    mWorld = mTranslation;

    g_pD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&mWorld));
    pMaterials = (D3DXMATERIAL*)g_pLighthouseMaterial->GetBufferPointer();
    g_pLighthouseTextures = new PDIRECT3DTEXTURE9[g_dwLighthouseMaterialCount];

    for (DWORD i = 0; i < g_dwLighthouseMaterialCount; i++){
        pMaterial = pMaterials[i].MatD3D;
        if(i==1) {
            pMaterial.Ambient = tbColor(1.0f, 1.0f, -1.0f);
        } 
    //  tbWriteToLog("%s\n",(char*)pMaterials[i].pTextureFilename);
        if(FAILED(D3DXCreateTextureFromFileEx(g_pD3DDevice,
                                            pMaterials[i].pTextureFilename,
                                            D3DX_DEFAULT,
                                            D3DX_DEFAULT,
                                            D3DX_DEFAULT,
                                            0,
                                            D3DFMT_UNKNOWN,
                                            D3DPOOL_MANAGED,
                                            D3DX_FILTER_NONE,
                                            D3DX_DEFAULT,
                                            0,
                                            NULL,
                                            NULL,
                                            &g_pLighthouseTextures[i])))
        {
            g_pLighthouseTextures[i] = NULL;
        }
        g_pD3DDevice->SetMaterial(&pMaterial);
        g_pD3DDevice->SetTexture(0, g_pLighthouseTextures[i]);
        if(FAILED(g_pLighthouse->DrawSubset(i))){
        // Fehler beim Zeichnen!
        TB_ERROR_DIRECTX("g_pLighthouse->DrawSubset", hResult, TB_STOP);
        }
    }

    // Punktlicht Zeichnen
    mTranslation = tbMatrixTranslation(tbVector3(5.0f, 5.0f, 5.0f));
    mWorld = mTranslation;
    
    g_pD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&mWorld));
    pMaterial.Diffuse = tbColor(0.75f, 0.75f, 0.75f);
    pMaterial.Ambient = tbColor(0.25f, 0.25f, 0.25f);
    pMaterial.Specular = tbColor(1.0f, 1.0f, 1.0f);
    pMaterial.Emissive = tbColor(0.1f, 0.1f, 0.1f);
    pMaterial.Power = 1.0f;
    g_pD3DDevice->SetMaterial(&pMaterial);
    g_pD3DDevice->SetTexture(0, NULL);
    g_pSphere->DrawSubset(0);
    

    // Licht aktivieren
    g_pD3DDevice->SetLight(0, &g_SpotLight);
    g_pD3DDevice->LightEnable(0, TRUE);


    // Zeichnen!

    // Szene beenden
    g_pD3DDevice->EndScene();

    // Der große Moment: den Bildpuffer sichtbar machen
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

    return TB_OK;
}


Init:

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
tbResult InitScene()
{
    HRESULT         hResult;

    // Beleuchtung und Culling ausschalten, Dithering aktivieren
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);

    // Beleuchtung
    g_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

    // Hintergrundlicht
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, tbColor(0.25f, 0.25f, 0.25f));

    // Nebel aktivieren
    g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
    g_pD3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP);
    g_pD3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);

    // Bilineare Texturfilter mit linearem MIP-Mapping
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);


    // Leuchtturm laden
    if(FAILED(hResult = D3DXLoadMeshFromX(  "Lighthouse.x",
                                            D3DXMESH_SYSTEMMEM,
                                            g_pD3DDevice,
                                            NULL,
                                            &g_pLighthouseMaterial,
                                            NULL,
                                            &g_dwLighthouseMaterialCount,
                                            &g_pLighthouse)))
    {
        // Fehler
        TB_ERROR_DIRECTX("D3DXLoadMeshFromX", hResult, TB_ERROR);
    }
    // Leuchtturm laden
    if(FAILED(hResult = D3DXLoadMeshFromX(  "Sphere.x",
                                            D3DXMESH_SYSTEMMEM,
                                            g_pD3DDevice,
                                            NULL,
                                            NULL,
                                            NULL,
                                            NULL,
                                            &g_pSphere)))
    {
        // Fehler
        TB_ERROR_DIRECTX("D3DXLoadMeshFromX", hResult, TB_ERROR);
    }

    // SpotLight definieren
    ZeroMemory(&g_SpotLight, sizeof(D3DLIGHT9));
    g_SpotLight.Type          = D3DLIGHT_SPOT;                               
    g_SpotLight.Diffuse       = tbColor(1.0f, 1.0f, 1.0f);                    
    g_SpotLight.Ambient       = tbColor(1.0f, 1.0f, 1.0f);                    
    g_SpotLight.Specular      = tbColor(1.0f, 1.0f, 1.0f);                    
    g_SpotLight.Position      = tbVector3(10.0f, 10.0f , 10.0f);

    g_SpotLight.Range         = 10000.0f;                                     
    g_SpotLight.Attenuation0  = 0.0f;                                         
    g_SpotLight.Attenuation1  = 0.05f;                                       
    g_SpotLight.Attenuation2  = 0.0f; 
    g_SpotLight.Falloff       = 1.0f;
    g_SpotLight.Theta         = TB_DEG_TO_RAD(45.0f);
    g_SpotLight.Phi           = TB_DEG_TO_RAD(90.0f);

    return TB_OK;
}


ExitScene:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tbResult ExitScene()
{
    // Textur deaktivieren und löschen
    g_pD3DDevice->SetTexture(0, NULL);

    // Vertex- und Index-Buffer deaktivieren und löschen
    g_pD3DDevice->SetStreamSource(0, NULL, 0, 0);
    g_pD3DDevice->SetIndices(NULL);

    // Texturen löschen
    for(DWORD i = 0; i < g_dwLighthouseMaterialCount; i++){
        TB_SAFE_RELEASE(g_pLighthouseTextures[i]);
    }
    // Modelle löschen
    TB_SAFE_RELEASE(g_pLighthouse);
    TB_SAFE_RELEASE(g_pSphere);

    return TB_OK;
}


Globale Variablen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ******************************************************************
// ******************************************************************
// Globale Variablen
float                   g_fTime = 0.0f;                 // Zeitzähler
SDirect3DParameters     g_Direct3DParameters;           // Direct3D-Parameter
tbVector3               g_vCameraPosition;              // Die Kameraposition
float                   g_fCameraAngle = 0.0f;          // Drehwinkel der Kamera
float                   g_fFOV = TB_DEG_TO_RAD(90.0f);  // Sichtfeld
DWORD                   g_dwFogColor;                   // Nebelfarbe
// Leuchtturn
LPD3DXMESH              g_pLighthouse = NULL;           // Leuchtturn
LPD3DXBUFFER            g_pLighthouseMaterial;          // Material für Leuchtturm
DWORD                   g_dwLighthouseMaterialCount;    // Anzahl der Materialien
PDIRECT3DTEXTURE9*      g_pLighthouseTextures = NULL;   // Texturen für den Leuchtturm
// Punktlicht
LPD3DXMESH              g_pSphere = NULL;               // 3D-Objekt des Punktlichts
// Licht
D3DLIGHT9               g_SpotLight;


Nun zu meinem Problem:

Wenn ich den Code Debugge, so wird der Leuchtturm ohne die Textur gezeichnet. Als Dateiname der Textur wird irgendwas kryptisches ausgegeben, sofern ich den in den Log-File schreibe (Zeile 78 auskommentieren). Wenn ich nun in der Renderfunktion in Zeile 80 statt "pMaterials.pTextureFilename" den Dateinamen der Textur angebe, so funktioniert das Einbinden der Textur. Ich möchte das aber so nicht lösen, da meiner Meinung nach die Texturnamen ja bereits in pMaterials[i].pTextureFilename stehen der Code so elleganter (allgemeiner) ist. Auch habe ich diese Vorlage zum Laden der texturen so im Internet gefunden.

In den Projekteigenschaften verwende ich den Multibyte-Zeichensatz. Vll. liegt es ja daran, glaube ich aber eher weniger. Vrmlt. könnte es auch an der Konvertierung der Milkshape-Datei liegen.

Ich wäre euch sehr verbunden, wenn Ihr mir bei meinem Problem helfen könntet. Denn ich rätzle/suche schon knapp einen Tag, wie ich das lösen könnte, finde aber weder im Internet, noch im Forum existierende Lösungen/Anhalspunkte. ?(

Danke und Gruß :)
Martin
»Losbarthos« hat folgendes Bild angehängt:
  • DirectX (JT).gif
»Losbarthos« hat folgende Datei angehängt:
  • lighthouse.zip (11,35 kB - 55 mal heruntergeladen - zuletzt: 21.04.2024, 06:46)