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

23.04.2009, 16:51

DrawPrimitive Problem

Hi,

ich arbeite gerade dieses Tutorial durch:

http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B4.aspx

Das klappt auch so wie es dort steht.
Jetzt wollte ich etwas mit den Werten rumprobieren und schon passiert der erste Fehler.

Ich habe zuerst ein Dreieck erstellt mit:

Quellcode

1
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
Jetzt wollte ich stattdessen aber nur die Linien verbinden:

Quellcode

1
d3ddev->DrawPrimitive(D3DPT_LINELIST, 0, 1);
Wenn ich das Programm starte funktioniert das auch zuerst. Aber nach etwa 3 Sekunden flackern die Linien und danach sieht es so aus:



Muss ich noch irgendetwas umstellen? Oder wieso ändert sich das nach ein paar Sekunden?

Hier ist vorsichtshalber noch mein Code:

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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// include the basic windows header files and the Direct3D header file

#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>

// define the screen resolution and keyboard macros

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// include the Direct3D Library file

#pragma comment (lib, "d3d9.lib")

// global declarations

LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface

LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class

LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;    // the pointer to the vertex buffer


// function prototypes

void initD3D(HWND hWnd);    // sets up and initializes Direct3D

void render_frame(void);    // renders a single frame

void cleanD3D(void);    // closes Direct3D and releases memory

void init_graphics(void);    // 3D declarations


struct CUSTOMVERTEX {FLOAT X, Y, Z, RHW; DWORD COLOR;};
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

// the WindowProc function prototype

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


// the entry point for any Windows program

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "WindowClass";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
                          "WindowClass",
                          "Our Direct3D Program",
                          WS_OVERLAPPEDWINDOW,
                          0, 0,
                          SCREEN_WIDTH, SCREEN_HEIGHT,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    ShowWindow(hWnd, nCmdShow);

    // set up and initialize Direct3D

    initD3D(hWnd);

    // enter the main loop:


    MSG msg;

    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if(msg.message == WM_QUIT)
            break;

        render_frame();

        // check the 'escape' key

        if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);
    }

    // clean up DirectX and COM

    cleanD3D();

    return msg.wParam;
}


// this is the main message handler for the program

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}


// this function initializes and prepares Direct3D for use

void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = SCREEN_WIDTH;
    d3dpp.BackBufferHeight = SCREEN_HEIGHT;

    // create a device class using this information and the info from the d3dpp stuct

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);

    init_graphics();    // call the function to initialize the triangle

}


// this is the function used to render a single frame

void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);

    d3ddev->BeginScene();

        // select which vertex format we are using

        d3ddev->SetFVF(CUSTOMFVF);

        // select the vertex buffer to display

        d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

        // copy the vertex buffer to the back buffer

        d3ddev->DrawPrimitive(D3DPT_LINELIST, 0, 3);

    d3ddev->EndScene();

    d3ddev->Present(NULL, NULL, NULL, NULL);
}


// this is the function that cleans up Direct3D and COM

void cleanD3D(void)
{
    v_buffer->Release();    // close and release the vertex buffer

    d3ddev->Release();    // close and release the 3D device

    d3d->Release();    // close and release Direct3D

}


// this is the function that puts the 3D models into video RAM

void init_graphics(void)
{
    // create the vertices using the CUSTOMVERTEX struct

    CUSTOMVERTEX vertices[] =
    {
        { 400.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
        { 650.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
        { 150.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
    };

    // create a vertex buffer interface called v_buffer

    d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
                               0,
                               CUSTOMFVF,
                               D3DPOOL_MANAGED,
                               &v_buffer,
                               NULL);

    VOID* pVoid;    // a void pointer


    // lock v_buffer and load the vertices into it

    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, vertices, sizeof(vertices));
    v_buffer->Unlock();
}
Danke schonmal!

ph4nt0m

Frischling

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

2

23.04.2009, 17:08

Der letzte Parameter von DrawPrimitive erwartet immer die Anzahl der jeweiligen Primitiven und nicht die Anzahl der Vertizes. Du hast drei Vertizes erstellt, also hast du verschiedene Möglichkeiten: Du kannst daraus mit D3DPT_TRIANGLELIST ein Dreieck zeichnen, dann wäre der letzte Parameter 1 (für ein Dreieck, welches natürlich drei Vertizes braucht).

Wenn du jedoch den Typ zu D3DPT_LINELIST änderst, erwartet Direct3D pro Linie zwei Vertizes (jeweils Start- und Endpunkt). Da du nur drei Vertizes hast, kannst du also auch nur eine Linie zeichnen und musst somit deinen Aufruf wie folgt abändern:

C-/C++-Quelltext

1
d3ddev->DrawPrimitive(D3DPT_LINELIST, 0, 1);


Dass sich zeitlich etwas an der Szene ändert, liegt übrigens daran, dass du durch deinen ursprünglichen Aufruf natürlich aus fremden Speicherbereichen Daten für deine Vertizes zugewiesen hast, denn für drei Linien braucht Direct3D ja sechs Vertizes (zumindest bei D3DPT_LINELIST) und hat somit einfach das genommen, was sich gerade hinter deinen drei Vertizes im Speicher befand.
;)

3

23.04.2009, 17:33

Interessant. Das ist mal ne echt gute Antwort :)

Vielen Dank!!

Werbeanzeige