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

Fred

Supermoderator

  • »Fred« ist der Autor dieses Themas

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

1

29.12.2006, 01:19

Fehler beim Rendern eines Models, in einer Klasse

Hi,
Alsoich weiß nicht wich lange ich schon nach dem Fehler such, aber ich komm einfach nicht drauf.

Ich habe eine renderfunktion geschrieben, die mit der TriBase, ein Model anzeigt:

C-/C++-Quelltext

1
2
g_pPlayerModel = new tbModel;
if(g_pPlayerModel->Init("Data\\Spieler.tbm"))   TB_ERROR("Fehler beim Laden des Spielermodells", TB_ERROR);

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
    // Variablen werden initialisiert

    tbMatrix        mProjection;
    tbMatrix        mCamera;
    tbMatrix        mWorld;
    D3DLIGHT9       PointLight;
    float           Fog             = 0.0001;
                    m_vPlayerPos    = tbVector3(1.0, 0.0, 0.0);

    // D3D Device

    tbDirect3D &D3D = tbDirect3D::Instance();
    // Z-Buffer leeren

    HRESULT hResult;
    hResult = D3D->Clear(0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 63),1.0f, 0);
    // Szene beginnen

    D3D->BeginScene();

    // Projektionsmatrix erstellen und einsetzen

    mProjection = tbMatrixProjection(TB_DEG_TO_RAD(90.0f), D3D.GetAspect(),0.1f, 1000.0f);
    D3D->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
    D3D.SetTransform(D3DTS_PROJECTION, mProjection);

    // Kameramatrix erstellen und einsetzen

    mCamera = tbMatrixCamera(tbVector3(-50.0, 300.0, 50.0), tbVector3(10.0, 70.0, 0.0));
    D3D.SetTransform(D3DTS_VIEW, mCamera);

    // Das Punktlicht wird nun erstellt.

    ZeroMemory(&PointLight, sizeof(D3DLIGHT9));
    PointLight.Type         = D3DLIGHT_POINT;                               // Punktlicht

    PointLight.Diffuse      = tbColor(1.0f, 1.0f, 1.0f);                    // Weiße Streufarbe

    PointLight.Ambient      = tbColor(0.0f, 0.0f, 0.0f);                    // Weiße Hintergrundfarbe

    PointLight.Specular     = tbColor(0.0f, 0.0f, 0.0f);                    // Weiße Glanzfarbe

    PointLight.Position     = tbVector3(1.0f, 70.0f, 5.0f);                         // Variierende Position

    PointLight.Range        = 10000.0f;                                     // 1000 Einheiten Reichweite

    PointLight.Attenuation0 = 1.0f;
    PointLight.Attenuation1 = 0.00001f;
    PointLight.Attenuation2 = 0.0f;
    // Und eingesetzt

    D3D->SetLight(0, &PointLight);
    D3D->LightEnable(0, TRUE);
    
    // Jetz noch den Spieler

    D3D.SetTransform(D3DTS_WORLD, tbMatrixTranslation(tbVector3(0.0,10.0,0.0)));
    g_pPlayerModel->Render();
    D3D->EndScene();


Das klappte auch recht gut. Da ich das ganze Projekt ausweiten will, wollte ich es so machen wie David in seinen Spielen aus dem buch. Also habe ich ne Klasse CGame erstellt und dementsprechend deklariert:

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
class CGame
{
public:
    // Modellvariablen

    tbModel*    m_pPlayerModel;                 // Modell der Spielfigur

    
    // Allgemeine Spielvariablen

    bool        m_bPaused;                      // Ist das Spiel pausiert?

    bool        m_bGameOver;                    // Ist der Spieler tot und das Spiel vorbei?

    int         m_iLevel;                       // In welchem Level spielt der Spieler?

    int         m_iLife;                        // Anzahl der verbleibenden Leben

    int         m_iScore;                       // Punkte

    tbVector3   m_vPlayerPos;                   // Position des Spielers

    tbVector3   m_vPlayerVel;                   // Bewegungsvektor des Spielers

    float       m_fLevelTime;                   // Zeit die für ein Level benötigt wird

    
    // Konstruktor

    inline CGame() {ZeroMemory(this, sizeof(CGame));}

    // Methoden

    tbResult    Init();                         // Initialisieren des Spieles

    tbResult    Exit();                         // Herunterfahren des Spielzustandes

    tbResult    Load();                         // Laden aller für das Spiel benötigter Dateien

    tbResult    Unload();                       // Entladen der Dateien

    tbResult    Move(float fTime);              // Bewegen der Szene

    tbResult    Render(float fTime);            // Rendern der Szene

    tbResult    InitLevel(int iLevel);          // Initialisieren eines Levels

};

Und in der Methode CGame::Load()
geladen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
tbResult    CGame::Load()
{
    // Laden des Spielermodells

    m_pPlayerModel = new tbModel;
    if(m_pPlayerModel->Init("Data\\Block2.tbm"))    TB_ERROR("Fehler beim Laden des Spielermodells", TB_ERROR);
    
    // Das war es dann auch schon wieder


    return TB_OK;
}


Und dann den rendervorgang in die funktion CGame::Render kopiert.

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
// Rendern der Szene

tbResult    CGame::Render(float fTime)
{
    // Variablen werden initialisiert

    tbMatrix        mProjection;
    tbMatrix        mCamera;
    tbMatrix        mWorld;
    D3DLIGHT9       PointLight;
    float           Fog             = 0.0001;
                    m_vPlayerPos    = tbVector3(1.0, 0.0, 0.0);

    // D3D Device

    tbDirect3D &D3D = tbDirect3D::Instance();
    // Z-Buffer leeren

    HRESULT hResult;
    hResult = D3D->Clear(0,NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 63),1.0f, 0);
    // Szene beginnen

    D3D->BeginScene();

    // Projektionsmatrix erstellen und einsetzen

    mProjection = tbMatrixProjection(TB_DEG_TO_RAD(90.0f), D3D.GetAspect(),0.1f, 1000.0f);
    D3D->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
    D3D.SetTransform(D3DTS_PROJECTION, mProjection);

    // Kameramatrix erstellen und einsetzen

    mCamera = tbMatrixCamera(tbVector3(-50.0, 300.0, 50.0), tbVector3(10.0, 70.0, 0.0));
    D3D.SetTransform(D3DTS_VIEW, mCamera);

    // Das Punktlicht wird nun erstellt.

    ZeroMemory(&PointLight, sizeof(D3DLIGHT9));
    PointLight.Type         = D3DLIGHT_POINT;                               // Punktlicht

    PointLight.Diffuse      = tbColor(1.0f, 1.0f, 1.0f);                    // Weiße Streufarbe

    PointLight.Ambient      = tbColor(0.0f, 0.0f, 0.0f);                    // Weiße Hintergrundfarbe

    PointLight.Specular     = tbColor(0.0f, 0.0f, 0.0f);                    // Weiße Glanzfarbe

    PointLight.Position     = tbVector3(1.0f, 70.0f, 5.0f);                         // Variierende Position

    PointLight.Range        = 10000.0f;                                     // 1000 Einheiten Reichweite

    PointLight.Attenuation0 = 1.0f;
    PointLight.Attenuation1 = 0.00001f;
    PointLight.Attenuation2 = 0.0f;
    // Und eingesetzt

    D3D->SetLight(0, &PointLight);
    D3D->LightEnable(0, TRUE);
    
    // Jetz noch den Spieler

    D3D.SetTransform(D3DTS_WORLD, tbMatrixTranslation(tbVector3(0.0,10.0,0.0)));
    m_pPlayerModel->Render();
    D3D->EndScene();
    return TB_OK;
}

Nbur jetzt bricht der Kompiler mir das Programm ab sobald ich die Zeile
m_pPlayerModel->Render()
im code hab und zeigt einen Windows-Senden/nicht senden-Dialog. Das andere läuft. Der Debugger sagt nichts der übergeht den fehler einfach.
Zur Verknüpfung. in der renderfunktion der Hauptklasse schreibe ich:

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
tbResult    COktagon::Render(float fTime)
{
    // Spielzustand minimiert?

    if(tbDirect3D::Instance().GetPresentResult())
    {
        // Spielzustand entladen

        m_pGame->Unload();

        // Spiel entladen und neu laden

        Unload();
        Load();

        // Spielzustand neu laden

        m_pGame->Load();
    }
    tbResult r = TB_OK;
    
    // Rendern des Spielzustands

    r = m_pGame->Render(fTime);
    // Fehler abfragen

    if(r) TB_ERROR("Fehler beim Bewegen des Spiels", TB_ERROR);

    return TB_OK;
}


Ich weiß es ist viel Code, aber derDebugger sagt nichts.

EDIT:
Hat sich erledigt.

Firefly

Alter Hase

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

2

29.12.2006, 13:51

hast du tbDirect3d eigentlich richtig initialisiert?
existiert das Modell überhaupt?

Chef-Koch

Treue Seele

Beiträge: 115

Wohnort: Ulm

  • Private Nachricht senden

3

29.12.2006, 15:10

an was lags?

Fred

Supermoderator

  • »Fred« ist der Autor dieses Themas

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

4

29.12.2006, 15:49

Ich habe das Modell vergessen zu initialisiern, bin heute früh dann drauf gekommen. Dass ich zwar die Renderfunktion aufrufe, aber eben nicht die Initfunktion

Aber etwas gefällt mir noch nicht:
Ich rendere ein Modell:

(Link)

Das funktionier auch. Jetzt habe ich eine Movefunktion eingebaut:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    // Bewegen des Spielers

    if(g_pbButtons[TB_KEY_LEFT])
    {
        m_fPlayerZ += 300.0f * fTime;
    }
    if(g_pbButtons[TB_KEY_RIGHT])
    {
        m_fPlayerZ -= 300.0f * fTime;
    }
    if(g_pbButtons[TB_KEY_UP])
    {
        m_fPlayerY += 300.0f * fTime;
    }
    if(g_pbButtons[TB_KEY_DOWN])
    {
        m_fPlayerY -= 300.0f * fTime;
    }
    m_vPlayerPos = tbVector3(0.0, m_fPlayerY, m_fPlayerZ);

Mit den Pfeiltasten kann ich nun auch das Modell steurenn, aber steuere ich es aus der Mitte an den Rand, sieht das so aus:

(Link)

Hier ist jetzt das Model ganz unten im Eck und es sieht ja völllig verformt aus, aber das will ich nicht kann man das ändern. Das Problem, die Kamera sollte sich nicht bewegen.

C-/C++-Quelltext

1
2
3
// Kameramatrix erstellen und einsetzen

    mCamera = tbMatrixCamera(tbVector3(-250.0, 50.0, 0.0), tbVector3(0.0, 70.0, 0.0));
    D3D.SetTransform(D3DTS_VIEW, mCamera);


Und das Modell rendere ich so:

C-/C++-Quelltext

1
2
mPlayer = tbMatrixTranslation(m_vPlayerPos);
    D3D.SetTransform(D3DTS_WORLD, mPlayer);

Wieso verformt erdas Modell so?[/cpp]

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

5

29.12.2006, 17:40

Zitat von »"Fred"«


Wieso verformt erdas Modell so?

Weil deine Kamera einen zu grossen Sichtwinkel hat. Experimentier mal mit dem Gesichtsfeld-Winkel, dem Abstand und der Groesse des Objekts
"Have you tried turning it off and on again?"

Fred

Supermoderator

  • »Fred« ist der Autor dieses Themas

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

6

29.12.2006, 18:41

Das heißt wiederum, dass ich einen dementsprechend Große Clipping Ebenen Entfernung brauche, was wiederum mehr rechenleistung benötigt, aber das kriefge ich schon in den Griff.

VIELEN DANK

Fred

Supermoderator

  • »Fred« ist der Autor dieses Themas

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

7

01.01.2007, 23:31

Ich weiß nicht woran es liegt, aber meine Textur wird nicht richtig dargestellt, also vollig verzerrt.
Sieht ungefähr so aus:

(Link)

Ich arbeite mit der TB und das Effekt-Script des Model-Converters sieht so aus

Quellcode

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
DWORD   NumTextures         = 1;
STRING  Texture1Filename    = "Tex.jpg";
DWORD   Texture1Type        = 1; // 1: 2D-Textur; 2: Würfel; 3: Volumen
DWORD   Texture1ColorKey    = 0x00000000;
TEXTURE Texture1;

TECHNIQUE T1
{
    PASS P1
    {
        Texture[0]          = <Texture1>;

        // Es scheint keine Opazitätstextur zu geben!
        // Wenn Sie doch eine benutzen, ändern Sie "SelectArg2" in "Modulate" um!
        AlphaOp[0]          = SelectArg2;
        AlphaArg1[0]        = Texture;
        AlphaArg2[0]        = Current;

        // Materialeinstellungen
        MaterialDiffuse     = {0.549f, 0.487f, 0.469f, 0.000f};
        MaterialAmbient     = {0.000f, 0.000f, 0.000f, 0.000f};
        MaterialEmissive    = {0.000f, 0.000f, 0.000f, 0.000f};
        MaterialSpecular    = {0.000f, 0.000f, 0.000f, 0.000f};
        MaterialPower       = 0.000f;

    }


Eingebunden wird es dann so:

C-/C++-Quelltext

1
2
m_pModel = new tbModel;
    if(m_pModel->Init("Data\\Wand.tbm", "Data\\"))  TB_ERROR("Fehler beim Laden des Spielermodells", TB_ERROR);
Textur übernimmt er ja aber warum ist das so verzerrt und wie kannn man das beheben?
Aber nur die vordere Seite wird so verzerrt hier ist der Quader gedreht um ein besseres Blid zu machen,aber dieunterenbeiden Seiten bilden die Texur normal.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

8

02.01.2007, 01:21

Sieht für mich nach einen Fehler in den Textcoords aus. Wie sind die Werte von den Vertices?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Fred

Supermoderator

  • »Fred« ist der Autor dieses Themas

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

9

02.01.2007, 01:24

Nein das war ein Fehler im Modellierprogramm. Habe da vorhin die Einstellungen noch ein Mal geändert und dann hat es geklappt

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

10

02.01.2007, 03:20

Das eine schließt das andere nicht aus, aber nvm
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige