Einzelnen Beitrag anzeigen

Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#2

AW: [Andorra 2D] Taschenlampe

  Alt 26. Aug 2010, 09:20
Ich würde hierzu den Stencil-Buffer verwenden. Erklärungen hierzu finden sich u.a. hier: http://wiki.delphigl.com/index.php/Stencilbuffer und in der entsprechenden Demo.

Du zeichnest zuerst die komplette Umgebung etwas "dunkler" als normal Mittels "Ambient-Color". Dann aktivierst du den Stencil-Buffer und zeichnest eine "Schablone" unter der die Szene normal gezeichnet werden soll. Dann zeichnest du deine Szene nochmals. Der Code (nicht getestet) sollte ungefähr so aussehen:
Delphi-Quellcode:
AdDraw.Options := AdDraw.Options + [aoLights];
AdDraw.Scene.AmbientColor := Ad_ARGB(255, 64, 64, 128);
//Scene einmal zeichnen
AdDraw.Options := AdDraw.Options - [aoLights];

AdDraw.Options := AdDraw.Options + [aoStencil, aoAlphaMask];

//Dieser Aufruf bewirkt, dass jeder gezeichnete Pixel das unten aufgeführte Ereignis auslöst
AdDraw.AdAppl.SetStencilOptions(0, $FFFF, asfAlways);
//Der Wert des Stencil-Puffers wird um eins erhöht
AdDraw.AdAppl.SetStencilEvent(asePass, asoIncrement);

//Eine Maske mit weißer Farbe zeichnen, in der die Scene später mit normaler helligkeit Gezeichnet wird

AdDraw.Options := AdDraw.Options - [aoAlphaMask];

//Nur dort zeichnen, wo vorher die Maske war
//Nur wenn "Null" kleiner als der Stencilbuffer Wert ist (was für alle Pixel der Fall ist, bei denen die Maske gezeichnet wurde), darf ein neuer Pixel an diese Stelle gezeichnet werden.
AdDraw.AdAppl.SetStencilOptions(0, $FFFF, asfLessThan);
//Der Stencil-Buffer soll nicht mehr verändert werden, also beibehalten ("Keep")
AdDraw.AdAppl.SetStencilEvent(asePass, asoKeep);


//Szene zeichnen

//Um das ganze schöner Aussehen zu lassen, eine transparente Version der Maske zeichnen, die an den Ecken zu weniger Transparent ausblendet

AdDraw.Options := AdDraw.Options - [aoStencil];
Lies dich auf jeden Fall mal im oben genannten Link in das Thema ein, sodass du diese "SetStencil*" Aufrufe verstehst.

Andreas

Edit: Das mit "Nicht durch die Wand hindurch Leuchten" ist etwas komplizierter, du musst hier mit Raytraycing oder Shadowmapping - beides fortgeschrittene Techniken - arbeiten. Am einfachsten ist es wohl, wenn du dein Level in Zellen aufteilst und im Vorneherein mittels Raytracing (geht mit einfacher Vektorarithmetik) berechnest, welche Zellen von welcher Zelle aus angeleuchtet werden können, und du die nicht anleuchtbaren Zellen wieder aus dem Stencilbuffer entfernst indem du über diese z.B. ein Weißes Quadrat zeichnest und mit "asoZero" den Stencilbuffer für diese zurücksetzt.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein

Geändert von igel457 (26. Aug 2010 um 10:50 Uhr)
  Mit Zitat antworten Zitat