Simples Render To Texture

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

Tritium

Betreff: Simples Render To Texture

BeitragMi, Okt 30, 2013 0:45
Antworten mit Zitat
Benutzer-Profile anzeigen
N'Abend zusammen,

da ich SetBuffer(ImageBuffer(...)) wie in BB doch sehr vermisse, habe ich mir eine simple Funktion als Ersatz geschrieben. Mit DrawToImage() ist es möglich, alle gängigen Zeichenbefehle auf ein Bild anzuwenden. Kurz zusammengefasst Vor- und Nachteile:

+ Benutzt nur die BlitzMax-Standardinstallation, benötigt also keine zusätzlichen Module und funktioniert mit DirectX wie auch OpenGL
+ Sollte unabhängig vom Betriebssystem funktionieren (hab hier nur Windows-Rechner zum Testen)

- Langsam, definitiv nicht echtzeittauglich
- Entstandenes Bild besitzt keine Transparenz mehr
- Zu bearbeitendes Bild darf max. so groß wie die aktuelle Auflösung sein

Für manche könnte es vielleicht interessant sein, um bspw. Bilder beim Laden eines Spiels aus Tilesets zu erzeugen o.ä.

Ich hab mal ein (sehr hässliches Laughing ) Beispiel dazu geschrieben:
BlitzMax: [AUSKLAPPEN]
Graphics 800,600
SeedRnd MilliSecs()
SetClsColor Rand(255),Rand(255),Rand(255)
SetMaskColor Rand(255),Rand(255),Rand(255)

'Testgrafik erstellen
img:TImage = CreateImage(200,200)

t = MilliSecs()
DrawToImage(img)
For i=0 To 255
SetColor Rand(255),Rand(255),Rand(255)
DrawOval Rand(200),Rand(200),Rand(5,30),Rand(5,30)
Next
SetColor 255,255,255
DrawText "Krawehl! Krawehl!",20,20
img = DrawToImage(Null)
DebugLog " " + (MilliSecs()-t) + "ms"


'Testgrafik zeichnen
Repeat
Cls

DrawImage img,MouseX(),MouseY()

Flip
Until KeyHit(KEY_ESCAPE)

End





'Sorgt dafür, dass ab sofort alles auf das angegebene Bild gezeichnet wird. Implementierung unschön per Backbuffer, Bilder dürfen nicht größer als aktuelle Auflösung sein, keine vollständige Unterstützung für Alphachannel.
'Entstandenes Bild wird mit aktuellem MaskColor maskiert.
'Es muss beim ersten Aufruf das zu beschreibende Bild übergeben werden, die Funktion gibt Null zurück. Wird Null übergeben, wird wieder normal auf den BackBuffer gezeichnet und das entstandene Bild zurückgegeben.
'Aufrufe wie "DrawToImage(img1) ... DrawToImage(img2) ... DrawToImage(null)" sind möglich
Function DrawToImage:TImage(image:TImage)
Global _backBuffer : TPixmap
Global _width : Int
Global _height : Int
Global _rMask:Int, _gMask:Int, _bMask:Int

If image Then
If _backBuffer Then
Local img:TImage = drawToImage(Null)
drawToImage(image)
Return img
EndIf

_width = ImageWidth(image)
_height = ImageHeight(image)
_backBuffer = GrabPixmap(0,0,_width,_height)

Local _r:Int,_g:Int,_b:Int,_a:Float
Local _blend:Int
Local _scaleX:Float,_scaleY:Float

GetColor(_r,_g,_b)
GetMaskColor(_rMask,_gMask,_bMask)
_a = GetAlpha()
_blend = GetBlend()
GetScale(_scaleX,_scaleY)

SetColor(_rMask,_gMask,_bMask)
SetAlpha(1.0)
SetBlend(ALPHABLEND)
SetScale(1.0,1.0)

DrawRect 0,0,_width,_height
DrawImage(image,0,0)

SetColor(_r,_g,_b)
SetAlpha(_a)
SetBlend(_blend)
SetScale(_scaleX,_scaleY)

Return Null
Else
If Not _backBuffer Then Return Null

image = LoadImage(MaskPixmap(GrabPixmap(0,0,_width,_height),_rMask,_gMask,_bMask))

DrawPixmap _backBuffer,0,0

_backBuffer = Null
_width = 0
_height = 0

Return image
EndIf
End Function


Kurz zum Funktionsprinzip: Das Bild wird in den Backbuffer gezeichnet, dann können Zeichenbefehle angewendet werden, am Schluss wird aus dem entsprechenden Abschnitt des Backbuffers das fertige Bild erzeugt und der vorherige Inhalt wiederhergestellt.

[EDIT]
Hab den Code etwas erweitert, sodass das entstandene Bild mit dem aktuellen MaskColor maskiert wird. Damit hat man zumindest eine transparente Farbe.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group