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

idontknow

unregistriert

1

06.05.2010, 22:49

[DirectX] Shape-Klasse

moin!

Ich will mir gerade fuer DX eine Shape Klasse erstellen (Klasse der ich min.3 Punkte gebe und die aus diesen dann ein 2-Dimensionales Sprite zeichnet!). Hab selber leider wenig Erfahrung mit 3D/DX.

Momentan schauts so aus, dass ich meiner Klasse 3 Punkte hinzufuegen konnte und sie mir dann ein Dreieck gezeichnet hat, das aber nicht dem Dreieck aus den 3 Punkten entsprochen hat. Witzig wurde es als ich die Punkte veraendert habe und immernoch das selbe Dreieck da war. Und noch besser wurde es als ich mehrere Punkte hinzugefuegt habe und das Dreieck immernoch das gleiche war ^^

Also nen sher komischer Bug! Vllt faellt jemand von den eingefleitschten 3D'lern bei meiner Klasse direkt ein offensichtlicher Fehler auf :).

Kurz zur Idee: 2 std::vector en die jeweils Indizes und Vertizes speichern, dann eine Methode die diese 2 vectoren in einen Index-/Vertexbuffer uebertraegt und anschließend eine Render Methode, nichts großes also :)

Header:

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
#pragma once

#include <d3dx9.h>
#include <list>
#include <vector>

class Shape
{
public:
    struct Vertex
    {
        D3DXVECTOR3 pos;
        DWORD       color;
        const static DWORD FVF;

        Vertex(D3DXVECTOR2 p, DWORD c);
    };

    Shape(void);
    ~Shape(void);

    void AddPoint(D3DXVECTOR2 pos, DWORD color);
    bool PushToBuffer(LPDIRECT3DDEVICE9 device);
    void Render(LPDIRECT3DDEVICE9 device);
private:
    std::vector<Vertex*> m_Vertizes;
    std::vector<short> m_Indizes;
    unsigned short m_CurrentIndexPos;

    LPDIRECT3DVERTEXBUFFER9 m_VertexBuffer;
    LPDIRECT3DINDEXBUFFER9 m_IndexBuffer;
};


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
#include "Shape.h"

const DWORD Shape::Vertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

Shape::Shape(void)
    : m_CurrentIndexPos(0)
{
}

Shape::~Shape(void)
{
    std::vector<Vertex*>::iterator it = m_Vertizes.begin();

    for( ; it != m_Vertizes.begin(); ++it)
    {
        delete (*it);
    }

    m_Vertizes.clear();
}

Shape::Vertex::Vertex(D3DXVECTOR2 p, DWORD c)
    : pos(p.x, p.y, 0), color(c)
{
}

void Shape::AddPoint(D3DXVECTOR2 pos, DWORD color)
{
    m_Vertizes.push_back(new Vertex(pos, color));

    if(m_CurrentIndexPos < 2)
    {
        // Nothing :)
    }
    else
    {
        unsigned short index = m_CurrentIndexPos;
        m_Indizes.push_back(index - 2); // Vorvorletzten Index
        m_Indizes.push_back(index - 1); // Vorletzter Index
        m_Indizes.push_back(index);     // letzter Index
    }

    m_CurrentIndexPos++;
}

bool Shape::PushToBuffer(LPDIRECT3DDEVICE9 device)
{
    if(FAILED(device->CreateVertexBuffer(m_Vertizes.size() * sizeof( Vertex ),
                                        D3DUSAGE_WRITEONLY, 
                                        Vertex::FVF,
                                        D3DPOOL_DEFAULT, 
                                        &m_VertexBuffer, 
                                        NULL)))
    {
        // Failed, error
        return false;
    }

    VOID* pVertices;
    if(FAILED(m_VertexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pVertices), 0)))
    {
        // Failed sth. goes wrong -> exit
        return false;
    }
    // Fine Copy vertices..
    memcpy(pVertices, static_cast<void*>(m_Vertizes[0]), m_Vertizes.size() * sizeof( Vertex ));
    // Unlock buffer :)
    m_VertexBuffer->Unlock();

    if(FAILED(device->CreateIndexBuffer(m_Indizes.size() * sizeof(short),
                                        D3DUSAGE_WRITEONLY,
                                        D3DFMT_INDEX16,
                                        D3DPOOL_DEFAULT,
                                        &m_IndexBuffer,
                                        NULL)))
    {
        return false;
    }
    
    // Try to fill the buffer
    VOID* pIndizes;
    if(FAILED(m_IndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIndizes), 0)))
    {
        // Failed sth. goes wrong -> exit
        return false;
    }
    memcpy(pIndizes, static_cast<void*>(&m_Indizes[0]), m_Indizes.size() * sizeof(short));
    m_IndexBuffer->Unlock();

    return true;
}

void Shape::Render(LPDIRECT3DDEVICE9 device)
{
    device->SetFVF(Vertex::FVF);
    device->SetStreamSource(0, m_VertexBuffer, 0, sizeof(Vertex));
    device->SetIndices(m_IndexBuffer);
    
    device->BeginScene();

    device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
                                0, 
                                0, 
                                m_Vertizes.size(), 
                                0, 
                                (m_Indizes.size() / 3));
                                
    device->EndScene();
}


Hoffe es faellt jemanden auf ich bin mit meine Latein am Ende :P^^

mfg

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

2

07.05.2010, 15:27

ganz klarer fall, du speicherst einen zeiger auf ein Vertex in dem vector. später kopierst du nur den ersten vertex.
speichere die vertices doch direkt im vektor. was du da mit den indices zusammenbaust, kannst du mit
einen D3DPT_TRIANGLESTRIP leicher haben.
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

idontknow

unregistriert

3

07.05.2010, 15:31

Wie meinst du das, die direkt im Vector zu speichern?
Wuesste nicht wie hatte frueher imemr ma l Probleme damit bekommen kann ja kaum vector.push_back(Vertex...)); machen oder?

@D3DPT_TRIANGLESTRIP werd ich mal kucken hab halt kaum Ahnung von DX :P

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

4

07.05.2010, 15:43

statt

C-/C++-Quelltext

1
std::vector<Vertex*> m_Vertizes;


C-/C++-Quelltext

1
std::vector<Vertex> m_Vertizes;


nehmen.

dann kannst du statt

C-/C++-Quelltext

1
m_Vertizes.push_back(new Vertex(pos, color));


C-/C++-Quelltext

1
m_Vertizes.push_back(Vertex(pos, color));


schreiben. das löschen ersparst du dir damit auch.

dann musst du nurnoch aus

C-/C++-Quelltext

1
 memcpy(pVertices, static_cast<void*>(m_Vertizes[0]), m_Vertizes.size() * sizeof( Vertex ));


C-/C++-Quelltext

1
 memcpy(pVertices, &m_Vertizes[0], m_Vertizes.size() * sizeof( Vertex ));


machen.

bei einem triangelstrip nimmt die graka immer den aktuellen vertex und die 2 davor. das klappt natürlich
nur bei zusammenhängenden objekten (dafür gibbet aber auch tricks).

dann brauchst du auch kein indexbuffer mehr, ein DrawPrimitive reicht dann aus.
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

Werbeanzeige