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

28.09.2010, 22:02

Problem beim Rendern auf Surface

Hallo zusammen,

nach längerem Mitlesen hier im Forum muss ich jetzt mal wieder selbst eine Frage stellen. Für einen Snake-Klon baue ich mir gerade ein Menü mit Mausunterstützung. Um zu überprüfen, ob sich die Maus über einem Menü-Objekt befindet, möchte ich ein Array int ObjMap[1024][600] erstellen, das für jeden Pixel der Menü-Fläche (Netbook-Auflösung) den Index des darauf befindlichen Menü-Objekts (oder -1 für leer) enthält.
Um dieses Array pixelgenau zu füllen, habe ich mir folgendes überlegt: Das Array wird mit -1 initialisiert. Wird jetzt z.B. ein Button mit dem Index 2 an der Position 20|40 mit der Breite 100 und der Höhe 50 eingefügt, werden die Array-Elemente "unter ihm" (also mit 20<=x<=120 und 40<=y<=90) auch auf 2 gesetzt.
Abgerundete Ecken z.B. werden dabei aber nicht berücksichtigt. Um so etwas jetzt zu überprüfen, dachte ich, ich erstelle mir ein Surface in Bildschirmgröße, fülle es mit einer in keinem Menü-Objekt vorkommenden Farbe, render dann die Menü-Objekte dort hinein und setze alle Pixel, die noch in der ursprünglichen Farbe sind, auf -1 (=leer). Damit habe ich dann nur noch die tatsächlich zum Menü-Objekt gehörenden Pixel-Koordinaten im Array mit dem Index des Objekts belegt.

Das Ganze funktioniert aber nicht so, wie ich es möchte. Ich erstelle mit CreateRenderTarget() ein Surface, registriere es als Render-Target, zeichen die Objekte und gehe anschließend das Surface durch und setze alle (in meinem Fall grünen) Pixel im Array zurück. Nur leider scheinen dabei alle Pixel grün zu bleiben - so als ob nichts gerendert werden würde.
Hier mal der relevante 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
//RenderTarget für den Objekt-Test 1erstellen und mit grün 0|255|0 füllen
    LPDIRECT3DSURFACE9 TestRenderTarget;
    F2D->GetDevicePtr()->CreateRenderTarget(    1024, 600,
                                                D3DFMT_A8R8G8B8,
                                                D3DMULTISAMPLE_NONE,
                                                0,
                                                true,
                                                &TestRenderTarget,
                                                NULL);
    F2D->GetDevicePtr()->ColorFill(TestRenderTarget, NULL, D3DCOLOR_ARGB(255, 0, 255, 0));
    //jetzt einmal alles reinzeichnen
    F2D->GetDevicePtr()->SetRenderTarget(0, TestRenderTarget);
    F2D->GetDevicePtr()->BeginScene();
    for (std::map<std::string, MenuBaseObject*>::iterator Itr=Objects.begin(); Itr!=Objects.end(); ++Itr) {
        Itr->second->Render();
    }
    F2D->GetDevicePtr()->EndScene();
    //testsurface erstellen und RenderTarget-Daten reinkopieren
    LPDIRECT3DSURFACE9 TestSurface;
    F2D->GetDevicePtr()->CreateOffscreenPlainSurface(1024, 600, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &TestSurface, NULL);
    F2D->GetDevicePtr()->GetRenderTargetData(TestRenderTarget, TestSurface);
    D3DLOCKED_RECT LockRect;
    TestSurface->LockRect( &LockRect, NULL, D3DLOCK_READONLY);
    D3DCOLOR *Pixel = reinterpret_cast<D3DCOLOR*>(LockRect.pBits);
    LockRect.Pitch /= 4;
    //alles durchgehen und dort, wo grün ist, das ObjRef-Array leeren
    for (int i=0; i<1024; ++i) {
        for (int j=0; j<600; ++j) {
            if (Pixel[j*LockRect.Pitch + i] == D3DCOLOR_ARGB(255, 0, 255, 0)) ObjMap[i][j]=-1;
        }
    }


ObjMap ist vor diesem Ausschnitt korrekt initialisiert, -1 an den leeren Stellen, den Index des Elementes an den belegten Stellen. Nach der letzten Schleife allerdings sind sämtliche Werte auf -1. Ich denke deshalb, dass beim Rendern irgendwas schief läuft und das gesamte Surface einfach grün bleibt.
Nur habe ich keine Ahnung, woran das liegen könnte... Wenn jemand einen Fehler findet oder sonst Hilfestellungen geben könnte, wäre ich dankbar!

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

2

29.09.2010, 15:32

Hmm ich kann den Fehler zwar nicht auf anhieb entdecken... allerdings rate ich dir, diese Methode zu unterlassen. Ich kenne das, dass man immer möglichst wenig Befehle nutzen möchte (also in der Gameloop) damit es schneller geht... allerdings ist das was du vor hast doch etwas Overkill... mach es lieber indem du alle
GUI-Elemente durchgehst und jeweils testest, ob der Mauszeiger darin ist... meinetwegen kannst du auch einen Baum mit Fenstern erstellen, was eventuell noch ein bisschen schneller ist... aber selbst wenn du 100 GUI-Elemente überprüfen musst, geht dass immer noch recht schnell und ist wesentlich einfacher außerdem ist es ja nicht in jedem Frame..
und von solchen runden Ecken würde ich mich nicht beeinducken lassen... da werden auch nur rechteckige Abfragen benutzt... (musst du mal testen, wenn du auf so nen windowsbutton in die abgerundete Ecke klickst, gehts auch ;) )

3

02.10.2010, 19:07

Zwar wegen Krankheit etwas verspätet, trotzdem aber noch danke! Wenn jemand anderem noch ein Grund auffällt, weshalb mein oben geposteter Code in dieser Form nicht funktioniert, wäre ich über ne Antwort froh.

Kurze nachfrage noch:

Zitat

außerdem ist es ja nicht in jedem Frame..
wieso? Zumindest solange die Maus bewegt wird (also Nachrichten gesendet werden) eigentlich schon, oder?

Werbeanzeige