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

26.11.2008, 13:13

Schnelles zeichnen von Pixeln mit WinAPI

Hi,

Ich habe vor etwas längerer Zeit eine kleine, auf WinAPI basierende
3D-Engine programmiert. Da sie alle Pixel durchgeht und sie dann mit SetPixel zeichnet, ist die maximale Auflösung, in der sie läuft ohne zu ruckeln, 100x100 Pixel. Ich habe versucht, das ganze mit einem Thread
hinzukriegen, doch es ist nur etwas Schneller.

Door = Eine Klasse zur Verwaltung von Backbuffern, Matrizen
Backbuffer = Ein Backbuffer

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
BOOL g_bRendering = FALSE; // Darf der Thread nicht gestartet werden ?


// Struktutur als Parameter für den Render-Thread.

struct Rnd
{
    Backbuffer *pBuffer;
    Door*       pDoor;

    Point3D     vCamPos, vCamLookAt;
};

// Thread zum sichtbarmachen des Backbuffers.

DWORD WINAPI PresentBackbuffer (LPVOID pParameter)
{
    // Wenn es schon gerendert wurde, muss nicht gezeichnet werden.

    if(g_bRendering) return 0;

    // Jetzt wird gezeichnet!

    g_bRendering = TRUE;

    // Parameter abfragen

    Rnd *pRnd = (Rnd*)(pParameter);

    // Zeiger auf die einzelnen Elemente der Struktur holen

    Backbuffer *pBuffer = pRnd->pBuffer;
    Door       *pDoor = pRnd->pDoor;

    // Wenn der Backbuffer nicht gesperrt ist,

    // also der nötige Speicher nicht reserviert worden

    // ist, muss auch nicht gerendert werden.

    if(!pBuffer->m_bLocked) return 1;

    // Alle Pixel durchgehen und zeichnen

    for (int x = 0; x < pBuffer->m_dwW; x++)
    {
        for (int y = 0; y < pBuffer->m_dwH; y++)
        {   
            // Farbe des Pixels speichern

            Color c1 = pBuffer->m_aColor[x][y];

            // Pixel zeichnen, Farb-Renderstates beachten

            ::SetPixel(pBuffer->m_hDC, x, y,
                RGB(pBuffer->m_aRS [RS_COLOR] & RS_COLOR_RED ? c1.r * 255 : 0,  // Rot

                    pBuffer->m_aRS [RS_COLOR] & RS_COLOR_GREEN ? c1.g * 255 : 0,     // Grün

                    pBuffer->m_aRS [RS_COLOR] & RS_COLOR_BLUE ? c1.b * 255 : 0));   // Blau


            // Wenn nach dem Zeichnen der Backbuffer wieder

            // geleert werden soll, ist das Renderstate RS_CLEAR

            // auf TRUE gesetzt.

            if(pBuffer->m_aRS [RS_CLEAR] == TRUE) 
            {
                // Die Farbe des Pixels auf schwarz

                // und die Distanz zur Kamera auf der Clipping-Ebene + 2

                // setzten.

                pBuffer->m_aColor [x][y] = GetColor (0, 0, 0, 1.0f);
                pBuffer->m_afDistance [x][y] = pBuffer->m_fFarPlane + 2;

                // Den Pixel des Backbuffers so setzten

                pBuffer->SetPixel (x, y, GetColor (0, 0, 0, 1.0f), pBuffer->m_fFarPlane + 1);
            }
        }
    }

    // Transformationen, Kameraposition und Kamerablickrichtung übertragen

    pBuffer->m_mTransform = pDoor->m_mWorld * pDoor->m_mView * pDoor->m_mProjection;
    pBuffer->m_vCameraPos = pRnd->vCamPos;
    pBuffer->m_vCameraLookAt = pRnd->vCamLookAt;
    pBuffer->m_mWorld = pDoor->m_mWorld;

    // Die Clipping-Ebenen berechnen

    ComputeClipPlanes (pDoor->m_mView, pDoor->m_mProjection, pBuffer->m_aView);

    // Jetzt darf wieder gezeichnet werden,

    // da der Thread jetzt zuende ist.

    g_bRendering = FALSE;
    return 0;
}


Wer hat eine Idee, wie man das sichtbar machen des Backbuffers beschleunigen könnte?
Ich freue mich schon auf eure Beiträge!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

26.11.2008, 13:18

Direkt in den Backbuffer zu schreiben dürfte schneller sein. Um Zugriff auf den Puffer zu bekommen kannst du z.B. die alten CreateDIBSection APIs verwenden, oder für Vollbild DirectDraw.
@D13_Dreinig

3

26.11.2008, 13:23

Ne, ich will ja nicht mit DirectX oder der SDL oder sonst was arbeiten,
sondern nur mit SetPixel. Die Transformtationen, das Zeichnen von Dreiecken usw. habe ich alles selber gemacht, als Übung für DirectX.
Und desshalb ist es ja auch so lahm. Aber vielleicht könnte man den Backbuffer in eine Surface der SDL schreiben und sie dann auch mit der SDL zeichnen? :idea:

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

26.11.2008, 13:27

Zitat von »"David_pb"«

Direkt in den Backbuffer zu schreiben dürfte schneller sein. Um Zugriff auf den Puffer zu bekommen kannst du z.B. die alten CreateDIBSection APIs verwenden, oder für Vollbild DirectDraw.


Les doch wenigstens was man dir schreibt...
@D13_Dreinig

5

26.11.2008, 13:30

Hab ich doch :cry: ! Nur das mit dem DirectDraw hat mich gestört.
Außerdem verstehe ich das, was du da schreibst, nicht ganz.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

26.11.2008, 13:37

So wie ich das verstanden habe willst du deinen Rasterisierer beschleunigen, oder? Da SetPixel notorisch langsam ist wäre es besser die Farben direkt in den Farbpuffer (Backbuffer oder sonstiges) zu schreiben, also direkt den Speicherbereich zu manipulieren der den Backbuffer repräsentiert. Dafür hab ich dir zwei mögliche Wege vorgeschlagen. Zum einen kannst du zum erzeugen des Puffers CreateDIBSection[size=7]1[/size] verwenden zum anderen kannst du per DirectDraw ein Surface erzeugen und dieses als Puffer verwenden. Letzteres ist vorallem dann vorzuziehen wenn dein Applikation im Vollbild laufen soll.


[size=7]1[/size]:http://msdn.microsoft.com/en-us/library/ms532292(VS.85).aspx
@D13_Dreinig

7

26.11.2008, 13:49

Danke :D :D :D

Werbeanzeige