Skip to content

Commit ee2015c

Browse files
committed
Work in Progress GPU Textures
Signed-off-by: TechnikTil <techniktil@tilnotdrip.org>
1 parent 8a15e00 commit ee2015c

5 files changed

Lines changed: 131 additions & 20 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package funkin.graphics;
2+
3+
import lime.graphics.Image;
4+
import openfl.Lib;
5+
import openfl.display.BitmapData;
6+
import openfl.display.DisplayObject;
7+
import openfl.display.DisplayObjectContainer;
8+
import openfl.display.IBitmapDrawable;
9+
import openfl.display.OpenGLRenderer;
10+
import openfl.display3D.Context3D;
11+
import openfl.display3D.textures.TextureBase;
12+
#if (js && html5)
13+
import lime._internal.graphics.ImageCanvasUtil;
14+
#end
15+
16+
/**
17+
* A fixed version of `BitmapData` that includes proper rendering to the GPU.
18+
*/
19+
@:access(openfl.display3D.textures.TextureBase)
20+
@:access(openfl.display.OpenGLRenderer)
21+
@:access(openfl.display3D.Context3D)
22+
class FunkinBitmapData extends BitmapData
23+
{
24+
/**
25+
* Creates a new `FunkinBitmapData` using an existing Lime Image instance.
26+
* @param image A Lime Image object.
27+
* @return A new `FunkinBitmapData` if the Image (and associated ImageBuffer) are not `null`, otherwise `null` will be returned/
28+
*/
29+
public static function fromImage(image:Image):FunkinBitmapData
30+
{
31+
if (image == null || image.buffer == null)
32+
return null;
33+
34+
var bitmapData:FunkinBitmapData = new FunkinBitmapData(0, 0, true, 0);
35+
bitmapData.__fromImage(image);
36+
bitmapData.image.transparent = true;
37+
38+
return bitmapData.image != null ? bitmapData : null;
39+
}
40+
41+
override function __drawGL(source:IBitmapDrawable, renderer:OpenGLRenderer):Void
42+
{
43+
if (Std.isOfType(source, DisplayObject))
44+
{
45+
final object:DisplayObjectContainer = cast source;
46+
renderer.__stage = object.stage;
47+
}
48+
49+
super.__drawGL(source, renderer);
50+
}
51+
52+
/**
53+
* Uploads this `FunkinBitmapData` image to the GPU.
54+
*/
55+
public function uploadToGPU():Void
56+
{
57+
var context3D:Context3D = Lib.current.stage.context3D;
58+
59+
if (context3D == null || this.image == null)
60+
return;
61+
62+
#if openfl_power_of_two this.image.powerOfTwo = true; #end
63+
this.image.premultiplied = true;
64+
this.image.format = BGRA32;
65+
66+
if (this.__texture == null)
67+
{
68+
this.__texture = context3D.createTexture(this.image.width, this.image.height, BGRA, true);
69+
this.__textureContext = context3D.__context;
70+
}
71+
72+
this.getTexture(context3D);
73+
74+
this.readable = false;
75+
this.__surface = null;
76+
this.image = null;
77+
}
78+
}
Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
package funkin.util.path;
1+
package funkin.graphics;
22

33
import flixel.graphics.FlxGraphic;
44
import haxe.Http;
55
import haxe.io.Bytes;
6+
import lime.app.Future;
7+
import lime.graphics.Image;
68
import lime.media.AudioBuffer;
9+
import lime.utils.Assets as LimeAssets;
710
import openfl.display.BitmapData;
811
import openfl.media.Sound;
912
import openfl.system.System;
1013

1114
/**
12-
* A caching system for PathsContent.
13-
*
14-
* This caches content like audios and images for faster returning rather than taking a long time each time.
15+
* The main caching system.
1516
*/
16-
class PathsCache
17+
@:access(flixel.system.frontEnds.AssetFrontEnd)
18+
class FunkinCache
1719
{
1820
/**
1921
* The content that doesn't get wiped from a cache clean.
@@ -86,7 +88,33 @@ class PathsCache
8688
return cachedAudio.get(key);
8789
}
8890

89-
// TODO: Maybe add gpu caching to images when we get options?
91+
/**
92+
* Returns an `Image` instance.
93+
* @param key Image key to return.
94+
* @return `Image` Instance.
95+
*/
96+
function getImage(key:String):Image
97+
{
98+
var useOpenFL:Bool = {
99+
#if FLX_CUSTOM_ASSETS_DIRECTORY
100+
FlxG.assets.useOpenflAssets(key);
101+
#else
102+
true;
103+
#end
104+
};
105+
106+
var isURL:Bool = StringUtil.isURL(key);
107+
108+
if (!useOpenFL)
109+
{
110+
var path:String = isURL ? key : FlxG.assets.getPath(key);
111+
return Image.fromFile(path);
112+
}
113+
else
114+
{
115+
return LimeAssets.getImage(key, false);
116+
}
117+
}
90118

91119
/**
92120
* Caches and returns an BitmapData instance.
@@ -101,16 +129,11 @@ class PathsCache
101129

102130
try
103131
{
104-
if (StringUtil.isURL(key))
105-
{
106-
var imageRequest:Http = new Http(key);
107-
imageRequest.request();
108-
bitmapData = BitmapData.fromBytes(imageRequest.responseBytes);
109-
}
110-
else
111-
{
112-
bitmapData = FlxG.assets.getBitmapDataUnsafe(key, false);
113-
}
132+
var image:Image = getImage(key);
133+
bitmapData = FunkinBitmapData.fromImage(image);
134+
135+
// TODO: Put this behind an option.
136+
cast(bitmapData, FunkinBitmapData)?.uploadToGPU();
114137
}
115138
catch (e:Exception)
116139
{

src/funkin/ui/FunkinTransition.hx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class FunkinTransition extends FunkinSubState
5353

5454
initCamera();
5555

56+
// TODO: put the gradient into cache.
5657
transGradient = FlxGradient.createGradientFlxSprite(transitionCamera.width, transitionCamera.height, [0xFF000000, 0x0]);
5758

5859
black = new FunkinSprite(0, 0);

src/funkin/ui/freeplay/backingcards/BoyfriendBackingCard.hx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package funkin.ui.freeplay.backingcards;
22

3+
import animate.internal.filters.MaskShader;
4+
import flixel.graphics.FlxGraphic;
35
import flixel.util.FlxSpriteUtil;
46
import funkin.ui.freeplay.BGScrollingText;
57
import funkin.ui.freeplay.FreeplayState;
8+
import openfl.geom.Rectangle;
69

710
class BoyfriendBackingCard extends BackingCard
811
{
@@ -25,8 +28,13 @@ class BoyfriendBackingCard extends BackingCard
2528
{
2629
super(instance);
2730

28-
orangeBack = new FunkinSprite(84, 440).loadTexture('#FEDA00', Std.int(pinkBack.width), 75);
29-
FlxSpriteUtil.alphaMaskFlxSprite(orangeBack, pinkBack, orangeBack);
31+
var rectangle:Rectangle = new Rectangle(84, 440);
32+
33+
var orangeBackGraphic:FlxGraphic = FlxG.bitmap.create(Std.int(pinkBack.width), 75, 0xFFFEDA00);
34+
MaskShader.maskAlpha(orangeBackGraphic.bitmap, pinkBack.graphic.bitmap, rectangle);
35+
36+
orangeBack = new FunkinSprite(rectangle.x, rectangle.y);
37+
orangeBack.loadGraphic(orangeBackGraphic);
3038
add(orangeBack);
3139

3240
orangeBackTwo = new FunkinSprite(0, 440).loadTexture('#FFD400', 100, Std.int(orangeBack.height));

src/funkin/util/path/PathsContent.hx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import animate.FlxAnimateFrames;
44
import flixel.graphics.FlxGraphic;
55
import flixel.graphics.frames.FlxAtlasFrames;
66
import flixel.graphics.frames.FlxFramesCollection;
7+
import funkin.graphics.FunkinCache;
78
import haxe.io.Path;
89
import openfl.display.BitmapData;
910
import openfl.media.Sound;
@@ -19,14 +20,14 @@ class PathsContent
1920
*
2021
* Contains BitmapData, FlxGraphic, and Sound objects.
2122
*/
22-
public var cache:PathsCache = null;
23+
public var cache:FunkinCache = null;
2324

2425
/**
2526
* Initializes all variables for use with this class.
2627
*/
2728
public function new()
2829
{
29-
cache = new PathsCache();
30+
cache = new FunkinCache();
3031
}
3132

3233
/**

0 commit comments

Comments
 (0)