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

Anonymous

unregistriert

1

30.04.2006, 21:15

[selfmade]: DrawPrimitiveUP

Hi,

wie gewünscht diesmal eine DrawPrimitiveUP-Funktion als selfmade. Sie ist für Direct3D9 konzipiert (kann aber auch auf Direct3D8 ohne weiteres portiert werden) und sollte die selbe Funktionalität bieten wie die Orginale.

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
long DrawPrimitiveUP (::D3DPRIMITIVETYPE type, unsigned long count, const void *data, unsigned long stride, ::IDirect3DDevice9* device)
{
        // Rückgabewert

    long result = D3D_OK;

        // Device muß vorhanden sein!

    if (!device) return (E_FAIL);

        // Vertexbuffer

    ::IDirect3DVertexBuffer9 *vertexbuffer = NULL;

        // Vertexbuffer erstellen

    if ((result = device->CreateVertexBuffer (stride*count, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &vertexbuffer, NULL)) != D3D_OK)
        return (result);

        // Pointer auf Datenbereich

    void *vertices = NULL;

        // Verriegeln ist angesagt!

    if ((result = vertexbuffer->Lock (0, 0, &vertices, 0)) != D3D_OK)
        return (result);

        // Vertices kopieren (Secure Rocks!)

    if (::memcpy_s (vertices, stride*count, data, stride*count) != 0)
        return (E_FAIL);

        // Entriegeln

    if ((result = vertexbuffer->Unlock ()) != D3D_OK)
        return (result);

        // Verbindung zwischen Vertexbuffer und Renderingstream herstellen

    if ((result = device->SetStreamSource (0, vertexbuffer, 0, stride)) != D3D_OK)
        return (result);

        // Rendern

    if ((result = device->DrawPrimitive (type, 0, count)) != D3D_OK)
        return (result);

        // VertexBuffer freigeben NIEMALS vergessen!

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

        // Alles roger!

    return (result);
}
Schnell, schön und easy. Parameter sind bis auf den Letzten äquivalent zu der Orginalen. Ein DrawIndexedPrimitiveUP ist fast genau so aufgebaut ;)

Feedback und Wünsche wie immer gerne gesehen.

- Patrick

Weiterführende Links
Microsoft Developer Network - memcpy_s
Microsoft Developer Network - D3DPRIMITIVETYPE
Microsoft Developer Network - IDirect3DDevice9
Microsoft Developer Network - IDirect3DVertexBuffer9

Sheddex

unregistriert

2

30.04.2006, 21:19

1. 11,5 Stunden schneller als erwartet

2. Sogar für mich einigermaßen verständlich ;)

3. ThanX für die Mühe :)

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

3

01.05.2006, 00:41

THX....! ^^ Vor allem für die Mühe...

Was mich aber eigentlich interessiert hätte, wäre wie das RENDERN selbst von statten geht, oder geht das zu tief!?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

4

01.05.2006, 00:43

Black-Panther
Du meinst wie man ein Dreieck auf ein 1D-Farbarray rendert?

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

5

01.05.2006, 00:47

Noch tiefer....
Einen Rasterizer sozusagen mit Z-Test usw...
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

6

01.05.2006, 00:54

Black-Panther
Ein Rasterizer ist nicht für die Tiefensortierung direkt zuständig. Hier einen kompletten Softwarerenderer schreiben, ist mir persönlich etwas zuviel - damit könnte ich im Endeffekt mir sogar meine Brötchen verdienen.

Aber wenn Du wissen willst wie man ein Dreieck rendert (was die primäre Aufgabe eines Rasterizer ist), das ist eine Sache von maximal 20 Minuten.

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

7

01.05.2006, 01:07

Danke für die Infos... und ja, bitte, würd mich interessieren (20min-Job mein ich ;))
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

8

01.05.2006, 01:15

Black-Panther

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
void triangle (const vertex &v1, const vertex &v2, const vertex &v3)
{
        // Y-Positionen der Dreiecke merken

    const float x1 = v1.x;
    const float x2 = v2.x;
    const float x3 = v3.x;

        // X-Positionen der Dreiecke merken

    const float y1 = v1.y;
    const float y2 = v2.y;
    const float y3 = v3.y;

        // Bounding Rechteck Dimensionen bestimmen

    const long minx = static_cast<long>(min(x1, x2, x3));
    const long maxx = static_cast<long>(max(x1, x2, x3));
    const long miny = static_cast<long>(min(y1, y2, y3));
    const long maxy = static_cast<long>(max(y1, y2, y3));

        // Startpunkt setzen

    reinterpret_cast<char*>(&backbuffer) += miny * pitch;

        // Das Bounding Rechteck durchlaufen

    for (long y=miny; y<maxy; ++y)
    {
        for (long x=minx; x<maxx; ++x)
        {
                // Prüfen ob Pixel _im_ Dreieck liegt

            if ((x1 - x2) * (y - y1) - (y1 - y2) * (x - x1) > 0 &&
             << (x2 - x3) * (y - y2) - (y2 - y3) * (x - x2) > 0 &&
             << (x3 - x1) * (y - y3) - (y3 - y1) * (x - x3) > 0)
            {
                    // Weißen Pixel malen

                backbuffer[x] = 0xFFFFFFFF;
            }
        }

            // Startpunkt neu setzen

        reinterpret_cast<char*>(&backbuffer) += pitch;
    }
}

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

01.05.2006, 10:01

Natürlich sollte man von Patricks Dreiecks-Renderer keine Wunder erwarten. Für gewöhnlich verwendet man einen Scanline-Algorithmus, bei dem nur diejenigen Pixel durchlaufen werden, die auch tatsächlich zum Dreieck gehören.
Wie Ihr wisst, habe ich ja das Framework für die DUSMania letztes Jahr geschrieben. Zuerst wollte ich dort einen Software-Rasterizer einsetzen. Der war auch schon soweit fertig implementiert und unterstützte auch schon Texturen (alles mit DirectDraw). Screen-Clipping ist ebenfalls integriert.
Aus Geschwindigkeitsgründen habe ich dort mit Fixed-Point-Arithmetik gearbeitet (also nicht float bzw. double).
Die Performance konnte sich sehen lassen... ;)

Wer möchte, kann sich den Software-Rasterizer hier anschauen:
http://www.scherfgen-software.net/misc/swrast.zip

Die interessanten Methoden befinden sich in surface.cpp (beispielsweise Surface::drawTexturedTriangle).
In utils.h befinden sich die Fixed-Point-Funktionen.

Anonymous

unregistriert

10

01.05.2006, 10:50

David Scherfgen
Natürlich ist diese Funktion nicht die Krönung, sondern ein einfaches Beispiel ;) Bevor ich hier mit advanced Rasterization auspacke, die einige hier total überfordern, nee ;) War ja nur die Frage und als Beantwortung hat diese recht simple Funktion gereicht ;)

Das Framework sieht gut aus, aber nur mit Fixed Point, naja schnell aber nicht schön :D Dazu wundert mich das Du nicht direkt mit einem kleinen Level angekommen bist? :D

- Patrick

Werbeanzeige