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

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

1

27.11.2010, 20:08

Dreieck in einer DLL erzeugen

Hi

Ich bin dabei eine Engine zu entwickeln. Nun will ich, dass man durch einen einfachen Aufruf, ein Dreieck erzeugen kann. Ich habe auch schon einen Code geschrieben.

Muss ich die Vertices speziell erzeugen, damit das Ausführungsprogramm der DLL diese auch kennt. Oder muss ich den VertexBuffer speziell erzeugen? Das Dreieck funktioniert ohne Probleme in einem normalen Programm, das direkt ohne DLL programmiert ist. Muss ich irgend etwas anders machen, damit man ein Dreieck in einer DLL programmieren kann, und danach verwenden kann. In meinem aktuellem Code funktioniert auch alles, ausser, dass das Dreieck nicht angezeigt wird.

Ich vermute, das Anwendungsprogramm kennt die Vertices nicht, und somit rendert es kein Dreieck, oder was muss ich machen, damit es funktioniert?

LG Patrick

denjo

Treue Seele

Beiträge: 163

Wohnort: BLB

  • Private Nachricht senden

2

27.11.2010, 20:41

Hmm, was du machen könntest, wäre zum Beispiel ein Code-Snippet zu posten und deine frage zu überarbeiten. Und was macht es für einen Sinn, wenn eine Funktion ein einziges Dreieck erzeugt? Solche Funktionen können auch gut und gerne in die Applikation rein.
"Irren ist menschlich, Vergeben göttlich."
- Alexander Pope -

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

3

27.11.2010, 23:32

Also hier ist der 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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
// veDirect3D.cpp
//
#include "VisualEngine.h"

veRenderObjects g_RenderObjects[10000];
int             g_NumRenderObjects;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_CREATE:
        break;

        case WM_CLOSE:
        DestroyWindow(hwnd);
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

veDirect3D& veDirect3D::D3DInstance()
{
    static veDirect3D TheD3D;
    return TheD3D;
}

veResult veDirect3D::Init(bool bWindowed, char * pcWindowTitle)
{
    // -----------------------------------------------------------------------------------
    // Direct3D initialisieren
    // -----------------------------------------------------------------------------------

    // Variablen deklarieren
    HRESULT                     hResult;            // Ist die Funktion erfolgreich oder nicht?
    D3DPRESENT_PARAMETERS       PresentParams;      // PresentParamters für Direct3D
    D3DDISPLAYMODE              VideoMode;          // Struktur ausfüllen
    WNDCLASSEX                  wc;                 // WNDCLASSEX-Struktur Variable um die Struktur zu füllen

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hInstance = ve_g_DLLHandle;
    wc.lpfnWndProc = WndProc;
    wc.cbWndExtra = 0;
    wc.cbClsExtra = 0;
    wc.lpszClassName = "VisualEngine";
    wc.lpszMenuName = NULL;
    wc.hbrBackground = HBRUSH(GetStockObject(BLACK_BRUSH));
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Fehler beim Registrieren des Fensters", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    // Fenster erzeugen
    m_hwnd = CreateWindow("VisualEngine",
                          pcWindowTitle,
                          WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                          GetSystemMetrics(SM_CXSCREEN) / 2,
                          GetSystemMetrics(SM_CYSCREEN) / 2,
                          800,
                          600,
                          NULL,
                          NULL,
                          ve_g_DLLHandle,
                          NULL);

    if(!m_hwnd)
    {
        MessageBox(NULL, "Fehler beim Erstellen des Fensters", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    // Direct3D Schnittstelle erzeugen
    m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

    m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &VideoMode);

    ZeroMemory(&PresentParams, sizeof(D3DPRESENT_PARAMETERS));

    // Presentations-Parameter setzen
    PresentParams.hDeviceWindow = m_hwnd;
    PresentParams.BackBufferCount = 1;
    PresentParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    PresentParams.BackBufferWidth = 800;
    PresentParams.BackBufferHeight = 600;
    PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    PresentParams.EnableAutoDepthStencil = TRUE;
    PresentParams.AutoDepthStencilFormat = D3DFMT_D16;
    PresentParams.Windowed = TRUE;
    PresentParams.MultiSampleQuality = 0;
    PresentParams.MultiSampleType = D3DMULTISAMPLE_NONE;
    PresentParams.Flags = 0;
    PresentParams.FullScreen_RefreshRateInHz = 0;
    PresentParams.PresentationInterval = 0;


    // IDirect3DDevice-Schnittstelle erzeugen
    if(FAILED(hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
                                             D3DDEVTYPE_REF,
                                             m_hwnd,
                                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                             &PresentParams,
                                             &m_pD3DDevice)))
    {
        MessageBox(NULL, "Fehler beim erstellen der IDirect3DDevice-Schnittstelle", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    // PresentParams der private Variable übergeben
    m_PresentParams = PresentParams;

    // Das Dreieck initialisieren
    veTriangleNormalInit();

    // Anzahl der RenderObjekte auf 0 setzen
    g_NumRenderObjects = 0;

    // Alle RenderObjekte auf false setzen
    for(int iRenderObject = 0; iRenderObject < 10000; iRenderObject++)
    {
        g_RenderObjects[iRenderObject].IsRenderObject = false;
        g_RenderObjects[iRenderObject].RenderObjectType = VE_NONE;
    }

    // Direct3D wurde initialisiert, also Variable auf True setzen.
    m_bInitialized = true;

    return VE_OK;
}

veResult veDirect3D::Exit()
{
    // -----------------------------------------------------------------------------------
    // Direct3D herunterfahren
    // -----------------------------------------------------------------------------------

    if(m_pD3D != NULL)
    {
        m_pD3D->Release();
    }

    if(m_pD3DDevice != NULL)
    {
        m_pD3DDevice->Release();
    }

    return VE_OK;
}

veResult veDirect3D::SetRenderState(D3DRENDERSTATETYPE RS, DWORD dwValue)
{
    m_pD3DDevice->SetRenderState(RS, dwValue);

    return VE_OK;
}

veResult veDirect3D::AddRenderObjectToScene(veRenderObjectList RenderObject, D3DXVECTOR3 ObjectPosition, D3DCOLOR Color)
{
    // -----------------------------------------------------------------------------------
    // Neues Objekt in die Szene einfügen
    // -----------------------------------------------------------------------------------

    g_RenderObjects[g_NumRenderObjects].RenderObjectType = RenderObject;
    g_RenderObjects[g_NumRenderObjects].Position = D3DXVECTOR3(ObjectPosition.x, ObjectPosition.y, ObjectPosition.z);
    g_RenderObjects[g_NumRenderObjects].Color = Color;
    g_RenderObjects[g_NumRenderObjects].NumberofObject = g_NumRenderObjects;
    g_RenderObjects[g_NumRenderObjects].IsRenderObject = true;

    // Anzahl der RenderObjekte um eins erhöhen
    g_NumRenderObjects++;

    return VE_OK;
}

veResult veDirect3D::RenderScene()
{
    // -----------------------------------------------------------------------------------
    // Die Render-Funktion von VisualEngine
    // -----------------------------------------------------------------------------------

    m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 100), 1.0f, 0);

    m_pD3DDevice->BeginScene();

    for(int iRenderObjects = 0; iRenderObjects < 10000; iRenderObjects++)
    {
        if(g_RenderObjects[iRenderObjects].IsRenderObject == true)
        {
            if(g_RenderObjects[iRenderObjects].RenderObjectType == VE_TRIANGLE)
            {
                // Ein Dreieck rendern
                veRenderTriangle();
            }
        }
    }

    m_pD3DDevice->EndScene();

    m_pD3DDevice->Present(NULL, NULL, NULL, NULL);

    return VE_OK;
}

// veVertexModels.h
//
#pragma once


// Triangle FVF and Vertex
struct veTriangleVertex
{
    float       x, y, z, rhw;
    DWORD       Color;
};

#define veTriangleFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

VE_API veResult veTriangleNormalInit();
VE_API veResult veRenderTriangle();
VE_API veResult veClearTriangle(veRenderObjects RenderObject);

// veVertexModels.cpp
//
#include "VisualEngine.h"

PDIRECT3D9                          g_pD3D;             // Globaler Zeiger von der IDirect3D-Schnittstelle
VE_API PDIRECT3DVERTEXBUFFER9       vTriangle = NULL;   // Vertex-Buffer für das Dreieck

VE_API veResult veTriangleNormalInit()
{
    // -----------------------------------------------------------------------------------
    // Das normale Dreieck von der VisualEngine initialisieren
    // -----------------------------------------------------------------------------------

    HRESULT hResult;

    veTriangleVertex TriangleVertices[] =
    {
        { 400.0f, 62.5f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
        { 650.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
        { 150.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
    };

    // Vertex-Buffer erzeugen für das Dreieck
    if(FAILED(hResult = veDirect3D::D3DInstance()->CreateVertexBuffer(3*sizeof(veTriangleVertex),
                                                                    0,
                                                                    veTriangleFVF,
                                                                    D3DPOOL_MANAGED,
                                                                    &vTriangle,
                                                                    NULL)))
    {
        MessageBox(NULL, "Fehler beim Erstellen des Dreieck-Vertex-Buffers", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    // Void-Zeiger
    VOID * pVoid;

    // Nun die Vertices auf den Buffer kopieren, deshalb zuerst den VertexBuffer schliessen.
    vTriangle->Lock(0, 0, (void**)&pVoid, 0); // Hier wird der VertexBuffer geschlossen.
    memcpy(pVoid, TriangleVertices, sizeof(TriangleVertices)); // Hier wird kopiert.
    vTriangle->Unlock(); // Nun wird der VertexBuffer wieder aufgemacht.

    MessageBox(NULL, "Der VertexBuffer für das Dreieck wurde erstellt", "Erfogreich",
               MB_OK | MB_ICONEXCLAMATION);

    return VE_OK;
}

VE_API veResult veRenderTriangle()
{
    // Das FVF setzen für das Dreieck
    veDirect3D::D3DInstance()->SetFVF(veTriangleFVF);

    // Den Vertexbuffer angeben
    veDirect3D::D3DInstance()->SetStreamSource(0, vTriangle, 0, sizeof(veTriangleVertex));

    // Das Dreieck rendern
    veDirect3D::D3DInstance()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); 

    MessageBox(NULL, "Das Dreieck wurde gerendert", "Erfogreich",
               MB_OK | MB_ICONEXCLAMATION);

    return VE_OK;
}


Wie gesagt, ich denke, dass das Ausführungsprogramm von der DLL die TriangleVertices nicht kennt. Oder ist sonst etwas falsch?

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

4

28.11.2010, 00:15

Hast du mal versucht, statt D3DPOOL_MANAGED etwas anderes zu nehmen? (D3DPOOL_DEFAULT) Könnte da Probleme mit den Pools geben, da die DLL ja nicht direkt ins Programm integriert wird, sonder "für sich" läuft.

Und das Design ist... nun ja.


mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

5

28.11.2010, 01:09

Leider funktioniert auch das nicht. Ich habe nun versucht eine Klasse daraus zu machen, diese nennt sich veTriangle

Hier der 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
// Klasse für ein Dreieck definieren
class VE_API veTriangle
{
private:

PDIRECT3DVERTEXBUFFER9vTriangle;// Vertex-Buffer für das Dreieck
veTriangleVertex m_TriangleVertices[3];// Die Vertices für das Dreieck

public:

veResult veNormalTriangleInit(veTriangleVertex (&TriangleVertices)[3]);
veResult veTriangleRender();

};

veResult veTriangle::veNormalTriangleInit(veTriangleVertex (&TriangleVertices)[3])
{
HRESULT hResult;

// Vertex-Buffer erzeugen für das Dreieck
if(FAILED(hResult = veDirect3D::D3DInstance()->CreateVertexBuffer(3*sizeof(veTriangleVertex),
                              0,
                              veTriangleFVF,
                              D3DPOOL_DEFAULT,
                              &vTriangle,
                              NULL)))
{
MessageBox(NULL, "Fehler beim Erstellen des Dreieck-Vertex-Buffers", "Fehler aufgetreten",
   MB_OK | MB_ICONEXCLAMATION);

return VE_ERROR;
}

VOID* pVoid;// a void pointer

// lock v_buffer and load the vertices into it
vTriangle->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, TriangleVertices, sizeof(TriangleVertices));
vTriangle->Unlock();

MessageBox(NULL, "Funktioniert", "Erfolgreich",
   MB_OK | MB_ICONEXCLAMATION);

m_TriangleVertices[3] = TriangleVertices[3];

return VE_OK;
}

veResult veTriangle::veTriangleRender()
{
// Das FVF setzen für das Dreieck
veDirect3D::D3DInstance()->SetFVF(veTriangleFVF);

// Den Vertexbuffer angeben
veDirect3D::D3DInstance()->SetStreamSource(0, vTriangle, 0, sizeof(veTriangleVertex));

// Das Dreieck rendern
veDirect3D::D3DInstance()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

return VE_OK;
}


Und den Aufruf habe ich diesmal direkt im Ausführungsprogramm:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
veTriangle * pTriangle;
    pTriangle = new veTriangle();

    veInit();

    D3D.Init(true, "VisualEngine");

    veTriangleVertex TriangleVertices[] =
    {
        { 400.0f, 62.5f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
        { 650.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
        { 150.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
    };

    pTriangle->veNormalTriangleInit(TriangleVertices);

    pTriangle->veTriangleRender();


Aber auch diese Variante funktioniert nicht, warum?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

28.11.2010, 09:04

Könnte da Probleme mit den Pools geben, da die DLL ja nicht direkt ins Programm integriert wird, sonder "für sich" läuft.

Was? Seit wann ist eine DLL nicht im Memory-Pool der Anwendung welche sie geladen hat? Und seit wann läuft eine DLL "für sich"? Die ist einfach nur dynamisch dazu geladener Code (und Daten), da läuft nix "für sich".
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige