mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-15 11:22:55 +00:00
add wip bizz
This commit is contained in:
parent
677357ba37
commit
a61f40571d
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit 74bd0131b705e87f9704c54a44d64579153ab4af
|
||||
Subproject commit f73c8f4798bfcd23c98db03bcde2e0afcbce4cfd
|
407
source/funkin/graphics/FlxFilteredSprite.hx
Normal file
407
source/funkin/graphics/FlxFilteredSprite.hx
Normal file
|
@ -0,0 +1,407 @@
|
|||
package funkin.graphics;
|
||||
|
||||
import flixel.FlxBasic;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.math.FlxMatrix;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.util.FlxColor;
|
||||
import lime.graphics.cairo.Cairo;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.display.BlendMode;
|
||||
import openfl.display.DisplayObjectRenderer;
|
||||
import openfl.display.Graphics;
|
||||
import openfl.display.OpenGLRenderer;
|
||||
import openfl.display._internal.Context3DGraphics;
|
||||
import openfl.display3D.Context3D;
|
||||
import openfl.display3D.Context3DClearMask;
|
||||
import openfl.filters.BitmapFilter;
|
||||
import openfl.filters.BlurFilter;
|
||||
import openfl.geom.ColorTransform;
|
||||
import openfl.geom.Matrix;
|
||||
import openfl.geom.Point;
|
||||
import openfl.geom.Rectangle;
|
||||
#if (js && html5)
|
||||
import lime._internal.graphics.ImageCanvasUtil;
|
||||
import openfl.display.CanvasRenderer;
|
||||
import openfl.display._internal.CanvasGraphics as GfxRenderer;
|
||||
#else
|
||||
import openfl.display.CairoRenderer;
|
||||
import openfl.display._internal.CairoGraphics as GfxRenderer;
|
||||
#end
|
||||
|
||||
/**
|
||||
* A modified `FlxSprite` that supports filters.
|
||||
* The name's pretty much self-explanatory.
|
||||
* @author CheemsAndFriends
|
||||
*/
|
||||
@:access(openfl.geom.Rectangle)
|
||||
@:access(openfl.filters.BitmapFilter)
|
||||
@:access(flixel.graphics.frames.FlxFrame)
|
||||
class FlxFilteredSprite extends FlxSprite
|
||||
{
|
||||
@:noCompletion var _renderer:FlxAnimateFilterRenderer = new FlxAnimateFilterRenderer();
|
||||
|
||||
@:noCompletion var _filterMatrix:FlxMatrix;
|
||||
|
||||
/**
|
||||
* An `Array` of shader filters (aka `BitmapFilter`).
|
||||
*/
|
||||
public var filters(default, set):Array<BitmapFilter>;
|
||||
|
||||
/**
|
||||
* a flag to update the image with the filters.
|
||||
* Useful when trying to render a shader at all times.
|
||||
*/
|
||||
public var filterDirty:Bool = false;
|
||||
|
||||
@:noCompletion var filtered:Bool;
|
||||
|
||||
@:noCompletion var _blankFrame:FlxFrame;
|
||||
|
||||
var _filterBmp1:BitmapData;
|
||||
var _filterBmp2:BitmapData;
|
||||
|
||||
override public function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
if (!filterDirty && filters != null)
|
||||
{
|
||||
for (filter in filters)
|
||||
{
|
||||
if (filter.__renderDirty)
|
||||
{
|
||||
filterDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
override function initVars():Void
|
||||
{
|
||||
super.initVars();
|
||||
_filterMatrix = new FlxMatrix();
|
||||
filters = null;
|
||||
filtered = false;
|
||||
}
|
||||
|
||||
override public function draw():Void
|
||||
{
|
||||
checkEmptyFrame();
|
||||
|
||||
if (alpha == 0 || _frame.type == FlxFrameType.EMPTY) return;
|
||||
|
||||
if (dirty) // rarely
|
||||
calcFrame(useFramePixels);
|
||||
|
||||
if (filterDirty) filterFrame();
|
||||
|
||||
for (camera in cameras)
|
||||
{
|
||||
if (!camera.visible || !camera.exists || !isOnScreen(camera)) continue;
|
||||
|
||||
getScreenPosition(_point, camera).subtractPoint(offset);
|
||||
|
||||
if (isSimpleRender(camera)) drawSimple(camera);
|
||||
else
|
||||
drawComplex(camera);
|
||||
|
||||
#if FLX_DEBUG
|
||||
FlxBasic.visibleCount++;
|
||||
#end
|
||||
}
|
||||
|
||||
#if FLX_DEBUG
|
||||
if (FlxG.debugger.drawDebug) drawDebug();
|
||||
#end
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
override function drawComplex(camera:FlxCamera):Void
|
||||
{
|
||||
_frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY());
|
||||
_matrix.concat(_filterMatrix);
|
||||
_matrix.translate(-origin.x, -origin.y);
|
||||
_matrix.scale(scale.x, scale.y);
|
||||
|
||||
if (bakedRotationAngle <= 0)
|
||||
{
|
||||
updateTrig();
|
||||
|
||||
if (angle != 0) _matrix.rotateWithTrig(_cosAngle, _sinAngle);
|
||||
}
|
||||
|
||||
_point.add(origin.x, origin.y);
|
||||
_matrix.translate(_point.x, _point.y);
|
||||
|
||||
if (isPixelPerfectRender(camera))
|
||||
{
|
||||
_matrix.tx = Math.floor(_matrix.tx);
|
||||
_matrix.ty = Math.floor(_matrix.ty);
|
||||
}
|
||||
|
||||
camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader);
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
function filterFrame()
|
||||
{
|
||||
filterDirty = false;
|
||||
_filterMatrix.identity();
|
||||
var filteredFrame = (filtered) ? _frame : null;
|
||||
|
||||
if (filters != null && filters.length > 0)
|
||||
{
|
||||
_flashRect.setEmpty();
|
||||
|
||||
for (filter in filters)
|
||||
{
|
||||
_flashRect.__expand(-filter.__leftExtension,
|
||||
-filter.__topExtension, filter.__leftExtension
|
||||
+ filter.__rightExtension,
|
||||
filter.__topExtension
|
||||
+ filter.__bottomExtension);
|
||||
}
|
||||
_flashRect.width += frameWidth;
|
||||
_flashRect.height += frameHeight;
|
||||
if (_blankFrame == null) _blankFrame = new FlxFrame(null);
|
||||
|
||||
if (_blankFrame.parent == null || _flashRect.width > _blankFrame.parent.width || _flashRect.height > _blankFrame.parent.height)
|
||||
{
|
||||
if (_blankFrame.parent != null)
|
||||
{
|
||||
_blankFrame.parent.destroy();
|
||||
_filterBmp1.dispose();
|
||||
_filterBmp2.dispose();
|
||||
}
|
||||
|
||||
_blankFrame.parent = FlxGraphic.fromRectangle(Math.ceil(_flashRect.width * 1.25), Math.ceil(_flashRect.height * 1.25), 0, true);
|
||||
_filterBmp1 = new BitmapData(_blankFrame.parent.width, _blankFrame.parent.height, 0);
|
||||
_filterBmp2 = new BitmapData(_blankFrame.parent.width, _blankFrame.parent.height, 0);
|
||||
}
|
||||
_blankFrame.offset.copyFrom(_frame.offset);
|
||||
_blankFrame.parent.bitmap = _renderer.applyFilter(_blankFrame.parent.bitmap, _filterBmp1, _filterBmp2, frame.parent.bitmap, filters, _flashRect,
|
||||
frame.frame.copyToFlash());
|
||||
_blankFrame.frame = FlxRect.get(0, 0, _blankFrame.parent.bitmap.width, _blankFrame.parent.bitmap.height);
|
||||
_filterMatrix.translate(_flashRect.x, _flashRect.y);
|
||||
_frame = _blankFrame.copyTo();
|
||||
filtered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetFrame();
|
||||
filtered = false;
|
||||
}
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
function set_filters(value:Array<BitmapFilter>)
|
||||
{
|
||||
if (filters != value) filterDirty = true;
|
||||
|
||||
return filters = value;
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
override function set_frame(value:FlxFrame)
|
||||
{
|
||||
if (value != frame) filterDirty = true;
|
||||
|
||||
return super.set_frame(value);
|
||||
}
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
@:access(openfl.display.OpenGLRenderer)
|
||||
@:access(openfl.filters.BitmapFilter)
|
||||
@:access(openfl.geom.Rectangle)
|
||||
@:access(openfl.display.Stage)
|
||||
@:access(openfl.display.Graphics)
|
||||
@:access(openfl.display.Shader)
|
||||
@:access(openfl.display.BitmapData)
|
||||
@:access(openfl.geom.ColorTransform)
|
||||
@:access(openfl.display.DisplayObject)
|
||||
@:access(openfl.display3D.Context3D)
|
||||
@:access(openfl.display.CanvasRenderer)
|
||||
@:access(openfl.display.CairoRenderer)
|
||||
@:access(openfl.display3D.Context3D)
|
||||
class FlxAnimateFilterRenderer
|
||||
{
|
||||
var renderer:OpenGLRenderer;
|
||||
var context:Context3D;
|
||||
|
||||
public function new()
|
||||
{
|
||||
// context = new openfl.display3D.Context3D(null);
|
||||
renderer = new OpenGLRenderer(FlxG.game.stage.context3D);
|
||||
renderer.__worldTransform = new Matrix();
|
||||
renderer.__worldColorTransform = new ColorTransform();
|
||||
}
|
||||
|
||||
@:noCompletion function setRenderer(renderer:DisplayObjectRenderer, rect:Rectangle)
|
||||
{
|
||||
@:privateAccess
|
||||
if (true)
|
||||
{
|
||||
var displayObject = FlxG.game;
|
||||
var pixelRatio = FlxG.game.stage.__renderer.__pixelRatio;
|
||||
|
||||
var offsetX = rect.x > 0 ? Math.ceil(rect.x) : Math.floor(rect.x);
|
||||
var offsetY = rect.y > 0 ? Math.ceil(rect.y) : Math.floor(rect.y);
|
||||
if (renderer.__worldTransform == null)
|
||||
{
|
||||
renderer.__worldTransform = new Matrix();
|
||||
renderer.__worldColorTransform = new ColorTransform();
|
||||
}
|
||||
if (displayObject.__cacheBitmapColorTransform == null) displayObject.__cacheBitmapColorTransform = new ColorTransform();
|
||||
|
||||
renderer.__stage = displayObject.stage;
|
||||
|
||||
renderer.__allowSmoothing = true;
|
||||
renderer.__setBlendMode(NORMAL);
|
||||
renderer.__worldAlpha = 1 / displayObject.__worldAlpha;
|
||||
|
||||
renderer.__worldTransform.identity();
|
||||
renderer.__worldTransform.invert();
|
||||
renderer.__worldTransform.concat(new Matrix());
|
||||
renderer.__worldTransform.tx -= offsetX;
|
||||
renderer.__worldTransform.ty -= offsetY;
|
||||
renderer.__worldTransform.scale(pixelRatio, pixelRatio);
|
||||
|
||||
renderer.__pixelRatio = pixelRatio;
|
||||
}
|
||||
}
|
||||
|
||||
public function applyFilter(target:BitmapData = null, target1:BitmapData = null, target2:BitmapData = null, bmp:BitmapData, filters:Array<BitmapFilter>,
|
||||
rect:Rectangle, bmpRect:Rectangle)
|
||||
{
|
||||
if (filters == null || filters.length == 0) return bmp;
|
||||
|
||||
renderer.__setBlendMode(NORMAL);
|
||||
renderer.__worldAlpha = 1;
|
||||
|
||||
if (renderer.__worldTransform == null)
|
||||
{
|
||||
renderer.__worldTransform = new Matrix();
|
||||
renderer.__worldColorTransform = new ColorTransform();
|
||||
}
|
||||
renderer.__worldTransform.identity();
|
||||
renderer.__worldColorTransform.__identity();
|
||||
|
||||
var bitmap:BitmapData = (target == null) ? new BitmapData(Math.ceil(rect.width * 1.25), Math.ceil(rect.height * 1.25), true, 0) : target;
|
||||
|
||||
var bitmap2 = (target1 == null) ? new BitmapData(Math.ceil(rect.width * 1.25), Math.ceil(rect.height * 1.25), true, 0) : target1,
|
||||
bitmap3 = (target2 == null) ? bitmap2.clone() : target2;
|
||||
renderer.__setRenderTarget(bitmap);
|
||||
|
||||
bmp.__renderTransform.translate(Math.abs(rect.x) - bmpRect.x, Math.abs(rect.y) - bmpRect.y);
|
||||
bmpRect.x = Math.abs(rect.x);
|
||||
bmpRect.y = Math.abs(rect.y);
|
||||
|
||||
var bestResolution = renderer.__context3D.__backBufferWantsBestResolution;
|
||||
renderer.__context3D.__backBufferWantsBestResolution = false;
|
||||
renderer.__scissorRect(bmpRect);
|
||||
renderer.__renderFilterPass(bmp, renderer.__defaultDisplayShader, true);
|
||||
renderer.__scissorRect();
|
||||
|
||||
renderer.__context3D.__backBufferWantsBestResolution = bestResolution;
|
||||
|
||||
bmp.__renderTransform.identity();
|
||||
|
||||
var shader, cacheBitmap = null;
|
||||
for (filter in filters)
|
||||
{
|
||||
if (filter.__preserveObject)
|
||||
{
|
||||
renderer.__setRenderTarget(bitmap3);
|
||||
renderer.__renderFilterPass(bitmap, renderer.__defaultDisplayShader, filter.__smooth);
|
||||
}
|
||||
|
||||
for (i in 0...filter.__numShaderPasses)
|
||||
{
|
||||
shader = filter.__initShader(renderer, i, (filter.__preserveObject) ? bitmap3 : null);
|
||||
renderer.__setBlendMode(filter.__shaderBlendMode);
|
||||
renderer.__setRenderTarget(bitmap2);
|
||||
renderer.__renderFilterPass(bitmap, shader, filter.__smooth);
|
||||
|
||||
cacheBitmap = bitmap;
|
||||
bitmap = bitmap2;
|
||||
bitmap2 = cacheBitmap;
|
||||
}
|
||||
filter.__renderDirty = false;
|
||||
}
|
||||
if (target1 == null) bitmap2.dispose();
|
||||
if (target2 == null) bitmap3.dispose();
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public function applyBlend(blend:BlendMode, bitmap:BitmapData)
|
||||
{
|
||||
bitmap.__update(false, true);
|
||||
var bmp = new BitmapData(bitmap.width, bitmap.height, 0);
|
||||
|
||||
#if (js && html5)
|
||||
ImageCanvasUtil.convertToCanvas(bmp.image);
|
||||
@:privateAccess
|
||||
var renderer = new CanvasRenderer(bmp.image.buffer.__srcContext);
|
||||
#else
|
||||
var renderer = new CairoRenderer(new Cairo(bmp.getSurface()));
|
||||
#end
|
||||
|
||||
// setRenderer(renderer, bmp.rect);
|
||||
|
||||
var m = new Matrix();
|
||||
var c = new ColorTransform();
|
||||
renderer.__allowSmoothing = true;
|
||||
renderer.__overrideBlendMode = blend;
|
||||
renderer.__worldTransform = m;
|
||||
renderer.__worldAlpha = 1;
|
||||
renderer.__worldColorTransform = c;
|
||||
|
||||
renderer.__setBlendMode(blend);
|
||||
#if (js && html5)
|
||||
bmp.__drawCanvas(bitmap, renderer);
|
||||
#else
|
||||
bmp.__drawCairo(bitmap, renderer);
|
||||
#end
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public function graphicstoBitmapData(gfx:Graphics)
|
||||
{
|
||||
if (gfx.__bounds == null) return null;
|
||||
// var cacheRTT = renderer.__context3D.__state.renderToTexture;
|
||||
// var cacheRTTDepthStencil = renderer.__context3D.__state.renderToTextureDepthStencil;
|
||||
// var cacheRTTAntiAlias = renderer.__context3D.__state.renderToTextureAntiAlias;
|
||||
// var cacheRTTSurfaceSelector = renderer.__context3D.__state.renderToTextureSurfaceSelector;
|
||||
|
||||
// var bmp = new BitmapData(Math.ceil(gfx.__width), Math.ceil(gfx.__height), 0);
|
||||
// renderer.__context3D.setRenderToTexture(bmp.getTexture(renderer.__context3D));
|
||||
// gfx.__owner.__renderTransform.identity();
|
||||
// gfx.__renderTransform.identity();
|
||||
// Context3DGraphics.render(gfx, renderer);
|
||||
GfxRenderer.render(gfx, cast renderer.__softwareRenderer);
|
||||
var bmp = gfx.__bitmap;
|
||||
|
||||
gfx.__bitmap = null;
|
||||
|
||||
// if (cacheRTT != null)
|
||||
// {
|
||||
// renderer.__context3D.setRenderToTexture(cacheRTT, cacheRTTDepthStencil, cacheRTTAntiAlias, cacheRTTSurfaceSelector);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// renderer.__context3D.setRenderToBackBuffer();
|
||||
// }
|
||||
|
||||
return bmp;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
package funkin.ui;
|
||||
|
||||
import flixel.FlxSprite;
|
||||
import funkin.graphics.FlxFilteredSprite;
|
||||
|
||||
/**
|
||||
* The icon that gets used for Freeplay capsules and char select
|
||||
* NOT to be confused with the CharIcon class, which is for the in-game icons
|
||||
*/
|
||||
class PixelatedIcon extends FlxSprite
|
||||
class PixelatedIcon extends FlxFilteredSprite
|
||||
{
|
||||
public function new(x:Float, y:Float)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ import funkin.audio.FunkinSound;
|
|||
import funkin.data.freeplay.player.PlayerData;
|
||||
import funkin.data.freeplay.player.PlayerRegistry;
|
||||
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||
import openfl.filters.DropShadowFilter;
|
||||
import funkin.graphics.FunkinCamera;
|
||||
import funkin.modding.events.ScriptEvent;
|
||||
import funkin.modding.events.ScriptEventDispatcher;
|
||||
|
@ -672,6 +673,7 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
if (index == getCurrentSelected())
|
||||
{
|
||||
// memb.pixels = memb.withDropShadow.clone();
|
||||
if (memb.scale.x != 2.6) memb.filters = [new DropShadowFilter()];
|
||||
memb.scale.set(2.6, 2.6);
|
||||
|
||||
if (controls.ACCEPT) memb.animation.play("confirm");
|
||||
|
@ -687,6 +689,7 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
else
|
||||
{
|
||||
// memb.pixels = memb.noDropShadow.clone();
|
||||
if (memb.scale.x == 2) memb.filters = [];
|
||||
memb.scale.set(2, 2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue