forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
3
Kha/Sources/kha/internal/AssetErrorCallback.hx
Normal file
3
Kha/Sources/kha/internal/AssetErrorCallback.hx
Normal file
@ -0,0 +1,3 @@
|
||||
package kha.internal;
|
||||
|
||||
typedef AssetErrorCallback = AssetError->Void;
|
216
Kha/Sources/kha/internal/AssetsBuilder.hx
Normal file
216
Kha/Sources/kha/internal/AssetsBuilder.hx
Normal file
@ -0,0 +1,216 @@
|
||||
package kha.internal;
|
||||
|
||||
import haxe.Json;
|
||||
import haxe.macro.Compiler;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr;
|
||||
#if macro
|
||||
import sys.io.File;
|
||||
#end
|
||||
|
||||
using StringTools;
|
||||
|
||||
class AssetsBuilder {
|
||||
#if macro
|
||||
public static var files: Array<Dynamic>;
|
||||
#end
|
||||
|
||||
public static function findResources(): String {
|
||||
#if macro
|
||||
var output = Compiler.getOutput();
|
||||
if (output == "Nothing__" || output == "") { // For Haxe background compilation
|
||||
#if kha_output
|
||||
output = Compiler.getDefine("kha_output");
|
||||
if (output.startsWith('"')) {
|
||||
output = output.substr(1, output.length - 2);
|
||||
}
|
||||
#end
|
||||
}
|
||||
output = output.replace("\\", "/");
|
||||
output = output.substring(0, output.lastIndexOf("/"));
|
||||
if (output.endsWith("/Assets")) { // For Unity
|
||||
output = output.substring(0, output.lastIndexOf("/"));
|
||||
}
|
||||
if (output.lastIndexOf("/") >= 0) {
|
||||
var system = output.substring(output.lastIndexOf("/") + 1);
|
||||
if (system.endsWith("-build"))
|
||||
system = system.substr(0, system.length - "-build".length);
|
||||
output = output.substring(0, output.lastIndexOf("/"));
|
||||
return output + "/" + system + "-resources/";
|
||||
}
|
||||
else {
|
||||
if (output.endsWith("-build"))
|
||||
output = output.substr(0, output.length - "-build".length);
|
||||
if (output == "")
|
||||
output = "empty";
|
||||
return output + "-resources/";
|
||||
}
|
||||
#else
|
||||
return "";
|
||||
#end
|
||||
}
|
||||
|
||||
macro static public function build(type: String): Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
if (files == null) {
|
||||
var content = Json.parse(File.getContent(findResources() + "files.json"));
|
||||
files = content.files;
|
||||
}
|
||||
|
||||
var names = new Array<Expr>();
|
||||
|
||||
for (file in files) {
|
||||
var name = file.name;
|
||||
final pos = Context.currentPos();
|
||||
var filesize: Int = file.file_sizes[0];
|
||||
|
||||
if (file.type == type) {
|
||||
names.push(macro $v{name});
|
||||
|
||||
switch (type) {
|
||||
case "image":
|
||||
fields.push({
|
||||
name: name,
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : kha.Image, macro null),
|
||||
pos: pos
|
||||
});
|
||||
case "sound":
|
||||
fields.push({
|
||||
name: name,
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : kha.Sound, macro null),
|
||||
pos: pos
|
||||
});
|
||||
case "blob":
|
||||
fields.push({
|
||||
name: name,
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : kha.Blob, macro null),
|
||||
pos: pos
|
||||
});
|
||||
case "font":
|
||||
fields.push({
|
||||
name: name,
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : kha.Font, macro null),
|
||||
pos: pos
|
||||
});
|
||||
case "video":
|
||||
fields.push({
|
||||
name: name,
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : kha.Video, macro null),
|
||||
pos: pos
|
||||
});
|
||||
}
|
||||
|
||||
fields.push({
|
||||
name: name + "Name",
|
||||
meta: [],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : String, macro $v{name}),
|
||||
pos: pos
|
||||
});
|
||||
|
||||
fields.push({
|
||||
name: name + "Description",
|
||||
meta: [{pos: pos, name: ":keep"}],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : Dynamic, macro $v{file}),
|
||||
pos: pos
|
||||
});
|
||||
|
||||
fields.push({
|
||||
name: name + "Size",
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : Dynamic, macro $v{filesize}),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
var loadExpressions = macro {};
|
||||
switch (type) {
|
||||
case "image":
|
||||
loadExpressions = macro {
|
||||
Assets.loadImage($v{name}, function(image: Image) done(), failure);
|
||||
};
|
||||
case "sound":
|
||||
loadExpressions = macro {
|
||||
Assets.loadSound($v{name}, function(sound: Sound) done(), failure);
|
||||
};
|
||||
case "blob":
|
||||
loadExpressions = macro {
|
||||
Assets.loadBlob($v{name}, function(blob: Blob) done(), failure);
|
||||
};
|
||||
case "font":
|
||||
loadExpressions = macro {
|
||||
Assets.loadFont($v{name}, function(font: Font) done(), failure);
|
||||
};
|
||||
case "video":
|
||||
loadExpressions = macro {
|
||||
Assets.loadVideo($v{name}, function(video: Video) done(), failure);
|
||||
};
|
||||
}
|
||||
|
||||
fields.push({
|
||||
name: name + "Load",
|
||||
meta: [],
|
||||
access: [APublic],
|
||||
kind: FFun({
|
||||
ret: null,
|
||||
params: null,
|
||||
expr: loadExpressions,
|
||||
args: [
|
||||
{
|
||||
value: null,
|
||||
type: Context.toComplexType(Context.getType("kha.internal.VoidCallback")),
|
||||
opt: null,
|
||||
name: "done"
|
||||
},
|
||||
{
|
||||
value: null,
|
||||
type: Context.toComplexType(Context.getType("kha.internal.AssetErrorCallback")),
|
||||
opt: true,
|
||||
name: "failure"
|
||||
}
|
||||
]
|
||||
}),
|
||||
pos: pos
|
||||
});
|
||||
|
||||
fields.push({
|
||||
name: name + "Unload",
|
||||
meta: [],
|
||||
access: [APublic],
|
||||
kind: FFun({
|
||||
ret: null,
|
||||
params: null,
|
||||
expr: macro {
|
||||
$i{name}.unload();
|
||||
$i{name} = null;
|
||||
},
|
||||
args: []
|
||||
}),
|
||||
pos: pos
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fields.push({
|
||||
name: "names",
|
||||
meta: [],
|
||||
access: [APublic],
|
||||
kind: FVar(macro : Array<String>, macro $a{names}),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
202
Kha/Sources/kha/internal/BytesBlob.hx
Normal file
202
Kha/Sources/kha/internal/BytesBlob.hx
Normal file
@ -0,0 +1,202 @@
|
||||
package kha.internal;
|
||||
|
||||
import haxe.ds.Vector;
|
||||
import haxe.io.Bytes;
|
||||
|
||||
class BytesBlob implements Resource {
|
||||
static inline var bufferSize: Int = 2000;
|
||||
|
||||
public var bytes: Bytes;
|
||||
|
||||
@:allow(kha.LoaderImpl)
|
||||
function new(bytes: Bytes) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public static function fromBytes(bytes: Bytes): Blob {
|
||||
return new Blob(bytes);
|
||||
}
|
||||
|
||||
public static function alloc(size: Int): Blob {
|
||||
return new Blob(Bytes.alloc(size));
|
||||
}
|
||||
|
||||
public function sub(start: Int, length: Int): Blob {
|
||||
return new Blob(bytes.sub(start, length));
|
||||
}
|
||||
|
||||
public var length(get, null): Int;
|
||||
|
||||
@:keep
|
||||
function get_length(): Int {
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
public function writeU8(position: Int, value: Int): Void {
|
||||
bytes.set(position, value);
|
||||
}
|
||||
|
||||
public function readU8(position: Int): Int {
|
||||
var byte = bytes.get(position);
|
||||
++position;
|
||||
return byte;
|
||||
}
|
||||
|
||||
public function readS8(position: Int): Int {
|
||||
var byte = bytes.get(position);
|
||||
++position;
|
||||
var sign = (byte & 0x80) == 0 ? 1 : -1;
|
||||
byte = byte & 0x7F;
|
||||
return sign * byte;
|
||||
}
|
||||
|
||||
public function readU16BE(position: Int): Int {
|
||||
var first = bytes.get(position + 0);
|
||||
var second = bytes.get(position + 1);
|
||||
position += 2;
|
||||
return first * 256 + second;
|
||||
}
|
||||
|
||||
public function readU16LE(position: Int): Int {
|
||||
var first = bytes.get(position + 0);
|
||||
var second = bytes.get(position + 1);
|
||||
position += 2;
|
||||
return second * 256 + first;
|
||||
}
|
||||
|
||||
public function readU32LE(position: Int): Int {
|
||||
var fourth = bytes.get(position + 0);
|
||||
var third = bytes.get(position + 1);
|
||||
var second = bytes.get(position + 2);
|
||||
var first = bytes.get(position + 3);
|
||||
position += 4;
|
||||
|
||||
return fourth + third * 256 + second * 256 * 256 + first * 256 * 256 * 256;
|
||||
}
|
||||
|
||||
public function readU32BE(position: Int): Int {
|
||||
var fourth = bytes.get(position + 0);
|
||||
var third = bytes.get(position + 1);
|
||||
var second = bytes.get(position + 2);
|
||||
var first = bytes.get(position + 3);
|
||||
position += 4;
|
||||
|
||||
return first + second * 256 + third * 256 * 256 + fourth * 256 * 256 * 256;
|
||||
}
|
||||
|
||||
public function readS16BE(position: Int): Int {
|
||||
var first = bytes.get(position + 0);
|
||||
var second = bytes.get(position + 1);
|
||||
position += 2;
|
||||
var sign = (first & 0x80) == 0 ? 1 : -1;
|
||||
first = first & 0x7F;
|
||||
if (sign == -1)
|
||||
return -0x7fff + first * 256 + second;
|
||||
else
|
||||
return first * 256 + second;
|
||||
}
|
||||
|
||||
public function readS16LE(position: Int): Int {
|
||||
var first = bytes.get(position + 0);
|
||||
var second = bytes.get(position + 1);
|
||||
var sign = (second & 0x80) == 0 ? 1 : -1;
|
||||
second = second & 0x7F;
|
||||
position += 2;
|
||||
if (sign == -1)
|
||||
return -0x7fff + second * 256 + first;
|
||||
else
|
||||
return second * 256 + first;
|
||||
}
|
||||
|
||||
public function readS32LE(position: Int): Int {
|
||||
var fourth = bytes.get(position + 0);
|
||||
var third = bytes.get(position + 1);
|
||||
var second = bytes.get(position + 2);
|
||||
var first = bytes.get(position + 3);
|
||||
var sign = (first & 0x80) == 0 ? 1 : -1;
|
||||
first = first & 0x7F;
|
||||
position += 4;
|
||||
if (sign == -1)
|
||||
return -0x7fffffff + fourth + third * 256 + second * 256 * 256 + first * 256 * 256 * 256;
|
||||
else
|
||||
return fourth + third * 256 + second * 256 * 256 + first * 256 * 256 * 256;
|
||||
}
|
||||
|
||||
public function readS32BE(position: Int): Int {
|
||||
var fourth = bytes.get(position + 0);
|
||||
var third = bytes.get(position + 1);
|
||||
var second = bytes.get(position + 2);
|
||||
var first = bytes.get(position + 3);
|
||||
var sign = (fourth & 0x80) == 0 ? 1 : -1;
|
||||
fourth = fourth & 0x7F;
|
||||
position += 4;
|
||||
if (sign == -1)
|
||||
return -0x7fffffff + first + second * 256 + third * 256 * 256 + fourth * 256 * 256 * 256;
|
||||
return first + second * 256 + third * 256 * 256 + fourth * 256 * 256 * 256;
|
||||
}
|
||||
|
||||
public function readF32LE(position: Int): Float {
|
||||
return readF32(readS32LE(position));
|
||||
}
|
||||
|
||||
public function readF32BE(position: Int): Float {
|
||||
return readF32(readS32BE(position));
|
||||
}
|
||||
|
||||
static function readF32(i: Int): Float {
|
||||
var sign: Float = ((i & 0x80000000) == 0) ? 1 : -1;
|
||||
var exp: Int = ((i >> 23) & 0xFF);
|
||||
var man: Int = (i & 0x7FFFFF);
|
||||
switch (exp) {
|
||||
case 0:
|
||||
// zero, do nothing, ignore negative zero and subnormals
|
||||
return 0.0;
|
||||
case 0xFF:
|
||||
if (man != 0)
|
||||
return Math.NaN;
|
||||
else if (sign > 0)
|
||||
return Math.POSITIVE_INFINITY;
|
||||
else
|
||||
return Math.NEGATIVE_INFINITY;
|
||||
default:
|
||||
return sign * ((man + 0x800000) / 8388608.0) * Math.pow(2, exp - 127);
|
||||
}
|
||||
}
|
||||
|
||||
public function toString(): String {
|
||||
return bytes.toString();
|
||||
}
|
||||
|
||||
static function bit(value: Int, position: Int): Bool {
|
||||
var b = (value >>> position) & 1 == 1;
|
||||
if (b) {
|
||||
var a = 3;
|
||||
++a;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
var c = 4;
|
||||
--c;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static function toText(chars: Vector<Int>, length: Int): String {
|
||||
var value = "";
|
||||
for (i in 0...length)
|
||||
value += String.fromCharCode(chars[i]);
|
||||
return value;
|
||||
}
|
||||
|
||||
public function readUtf8String(): String {
|
||||
return bytes.toString();
|
||||
}
|
||||
|
||||
public function toBytes(): Bytes {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public function unload(): Void {
|
||||
bytes = null;
|
||||
}
|
||||
}
|
209
Kha/Sources/kha/internal/HdrFormat.hx
Normal file
209
Kha/Sources/kha/internal/HdrFormat.hx
Normal file
@ -0,0 +1,209 @@
|
||||
package kha.internal;
|
||||
|
||||
import haxe.io.UInt8Array;
|
||||
import haxe.io.Float32Array;
|
||||
import haxe.io.Bytes;
|
||||
|
||||
// Based on https://github.com/vorg/pragmatic-pbr/blob/master/local_modules/parse-hdr/parse-hdr.js
|
||||
class HdrFormat {
|
||||
static var radiancePattern = new EReg("#\\?RADIANCE", "i");
|
||||
static var commentPattern = new EReg("#.*", "i");
|
||||
static var gammaPattern = new EReg("GAMMA=", "i");
|
||||
static var exposurePattern = new EReg("EXPOSURE=\\s*([0-9]*[.][0-9]*)", "i");
|
||||
static var formatPattern = new EReg("FORMAT=32-bit_rle_rgbe", "i");
|
||||
static var widthHeightPattern = new EReg("-Y ([0-9]+) \\+X ([0-9]+)", "i");
|
||||
static var buffer: UInt8Array;
|
||||
static var bufferLength: Int;
|
||||
static var fileOffset: Int;
|
||||
|
||||
static function readBuf(buf: UInt8Array): Int {
|
||||
var bytesRead = 0;
|
||||
do {
|
||||
buf[bytesRead++] = buffer[fileOffset];
|
||||
} while (++fileOffset < bufferLength && bytesRead < buf.length);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
static function readBufOffset(buf: UInt8Array, offset: Int, length: Int): Int {
|
||||
var bytesRead = 0;
|
||||
do {
|
||||
buf[offset + bytesRead++] = buffer[fileOffset];
|
||||
} while (++fileOffset < bufferLength && bytesRead < length);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
static function readPixelsRaw(buffer: UInt8Array, data: UInt8Array, offset: Int, numpixels: Int) {
|
||||
var numExpected = 4 * numpixels;
|
||||
var numRead = readBufOffset(data, offset, numExpected);
|
||||
if (numRead < numExpected) {
|
||||
trace("Error reading raw pixels: got " + numRead + " bytes, expected " + numExpected);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static function readPixelsRawRLE(buffer: UInt8Array, data: UInt8Array, offset: Int, scanline_width: Int, num_scanlines: Int) {
|
||||
var rgbe = new UInt8Array(4);
|
||||
var scanline_buffer: UInt8Array = null;
|
||||
var ptr: Int;
|
||||
var ptr_end: Int;
|
||||
var count: Int;
|
||||
var buf = new UInt8Array(2);
|
||||
// var bufferLength = buffer.length;
|
||||
|
||||
while (num_scanlines > 0) {
|
||||
if (readBuf(rgbe) < rgbe.length) {
|
||||
trace("Error reading bytes: expected " + rgbe.length);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rgbe[0] != 2) || (rgbe[1] != 2) || ((rgbe[2] & 0x80) != 0)) {
|
||||
// This file is not run length encoded
|
||||
data[offset++] = rgbe[0];
|
||||
data[offset++] = rgbe[1];
|
||||
data[offset++] = rgbe[2];
|
||||
data[offset++] = rgbe[3];
|
||||
readPixelsRaw(buffer, data, offset, scanline_width * num_scanlines - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((((rgbe[2] & 0xFF) << 8) | (rgbe[3] & 0xFF)) != scanline_width) {
|
||||
trace("Wrong scanline width " + (((rgbe[2] & 0xFF) << 8) | (rgbe[3] & 0xFF)) + ", expected " + scanline_width);
|
||||
return;
|
||||
}
|
||||
|
||||
if (scanline_buffer == null) {
|
||||
scanline_buffer = new UInt8Array(4 * scanline_width);
|
||||
}
|
||||
|
||||
ptr = 0;
|
||||
// Read each of the four channels for the scanline into the buffer
|
||||
for (i in 0...4) {
|
||||
ptr_end = (i + 1) * scanline_width;
|
||||
while (ptr < ptr_end) {
|
||||
if (readBuf(buf) < buf.length) {
|
||||
trace("Error reading 2-byte buffer");
|
||||
return;
|
||||
}
|
||||
if ((buf[0] & 0xFF) > 128) {
|
||||
// A run of the same value
|
||||
count = (buf[0] & 0xFF) - 128;
|
||||
if ((count == 0) || (count > ptr_end - ptr)) {
|
||||
trace("Bad scanline data");
|
||||
return;
|
||||
}
|
||||
while (count-- > 0) {
|
||||
scanline_buffer[ptr++] = buf[1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A non-run
|
||||
count = buf[0] & 0xFF;
|
||||
if ((count == 0) || (count > ptr_end - ptr)) {
|
||||
trace("Bad scanline data");
|
||||
return;
|
||||
}
|
||||
scanline_buffer[ptr++] = buf[1];
|
||||
if (--count > 0) {
|
||||
if (readBufOffset(scanline_buffer, ptr, count) < count) {
|
||||
trace("Error reading non-run data");
|
||||
return;
|
||||
}
|
||||
ptr += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy byte data to output
|
||||
for (i in 0...scanline_width) {
|
||||
data[offset + 0] = scanline_buffer[i];
|
||||
data[offset + 1] = scanline_buffer[i + scanline_width];
|
||||
data[offset + 2] = scanline_buffer[i + 2 * scanline_width];
|
||||
data[offset + 3] = scanline_buffer[i + 3 * scanline_width];
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
num_scanlines--;
|
||||
}
|
||||
}
|
||||
|
||||
static function readLine(): String {
|
||||
var buf = "";
|
||||
do {
|
||||
var b = buffer[fileOffset];
|
||||
if (b == 10) { // New line
|
||||
++fileOffset;
|
||||
break;
|
||||
}
|
||||
buf += String.fromCharCode(b);
|
||||
} while (++fileOffset < bufferLength);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static function parse(bytes: Bytes) {
|
||||
buffer = UInt8Array.fromBytes(bytes);
|
||||
bufferLength = buffer.length;
|
||||
fileOffset = 0;
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var exposure = 1.0;
|
||||
// var gamma = 1.0;
|
||||
var rle = false;
|
||||
|
||||
for (i in 0...20) {
|
||||
var line = readLine();
|
||||
if (formatPattern.match(line)) {
|
||||
rle = true;
|
||||
}
|
||||
else if (exposurePattern.match(line)) {
|
||||
exposure = Std.parseFloat(exposurePattern.matched(1));
|
||||
}
|
||||
else if (widthHeightPattern.match(line)) {
|
||||
height = Std.parseInt(widthHeightPattern.matched(1));
|
||||
width = Std.parseInt(widthHeightPattern.matched(2));
|
||||
break;
|
||||
}
|
||||
// else if (radiancePattern.match(line)) {}
|
||||
// else if (commentPattern.match(line)) {}
|
||||
}
|
||||
|
||||
if (!rle) {
|
||||
trace("File is not run length encoded!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var data = new UInt8Array(width * height * 4);
|
||||
var scanline_width = width;
|
||||
var num_scanlines = height;
|
||||
|
||||
readPixelsRawRLE(buffer, data, 0, scanline_width, num_scanlines);
|
||||
|
||||
// TODO: should be Float16
|
||||
var floatData = new Float32Array(width * height * 4);
|
||||
var offset = 0;
|
||||
while (offset < data.length) {
|
||||
var r = data[offset + 0] / 255;
|
||||
var g = data[offset + 1] / 255;
|
||||
var b = data[offset + 2] / 255;
|
||||
var e = data[offset + 3];
|
||||
var f = Math.pow(2.0, e - 128.0);
|
||||
r *= f;
|
||||
g *= f;
|
||||
b *= f;
|
||||
|
||||
floatData[offset + 0] = r;
|
||||
floatData[offset + 1] = g;
|
||||
floatData[offset + 2] = b;
|
||||
floatData[offset + 3] = 1.0;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
return {
|
||||
width: width,
|
||||
height: height,
|
||||
// exposure: exposure,
|
||||
// gamma: gamma,
|
||||
data: floatData
|
||||
}
|
||||
}
|
||||
}
|
9
Kha/Sources/kha/internal/IntBox.hx
Normal file
9
Kha/Sources/kha/internal/IntBox.hx
Normal file
@ -0,0 +1,9 @@
|
||||
package kha.internal;
|
||||
|
||||
class IntBox {
|
||||
public var value: Int;
|
||||
|
||||
public function new(value: Int) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
3
Kha/Sources/kha/internal/IntCallback.hx
Normal file
3
Kha/Sources/kha/internal/IntCallback.hx
Normal file
@ -0,0 +1,3 @@
|
||||
package kha.internal;
|
||||
|
||||
typedef IntCallback = Int->Void;
|
210
Kha/Sources/kha/internal/ShadersBuilder.hx
Normal file
210
Kha/Sources/kha/internal/ShadersBuilder.hx
Normal file
@ -0,0 +1,210 @@
|
||||
package kha.internal;
|
||||
|
||||
import haxe.Json;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr.Field;
|
||||
import haxe.Serializer;
|
||||
#if macro
|
||||
import sys.io.File;
|
||||
#end
|
||||
|
||||
using StringTools;
|
||||
|
||||
class ShadersBuilder {
|
||||
#if macro
|
||||
public static var files: Array<Dynamic>;
|
||||
#end
|
||||
|
||||
macro static public function build(): Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
|
||||
var manifestPath = AssetsBuilder.findResources() + "files.json";
|
||||
var content = Json.parse(File.getContent(manifestPath));
|
||||
|
||||
// rebuild Shaders module whenever manifest file is changed
|
||||
Context.registerModuleDependency(Context.getLocalModule(), manifestPath);
|
||||
|
||||
files = content.files;
|
||||
|
||||
var init = macro {};
|
||||
|
||||
for (file in files) {
|
||||
var name: String = file.name;
|
||||
var fixedName: String = name;
|
||||
var dataName = fixedName + "Data";
|
||||
var filenames: Array<String> = file.files;
|
||||
|
||||
if (file.type == "shader") {
|
||||
var serialized: Array<String> = [];
|
||||
for (filename in filenames) {
|
||||
serialized.push(Serializer.run(File.getBytes(AssetsBuilder.findResources() + filename)));
|
||||
}
|
||||
for (i in 0...filenames.length) {
|
||||
fields.push({
|
||||
name: dataName + i,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APrivate, AStatic],
|
||||
kind: FVar(macro : String, macro $v{serialized[i]}),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
}
|
||||
|
||||
if (name.endsWith("_comp")) {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.compute.Shader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.compute.Shader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (name.endsWith("_geom")) {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.graphics4.GeometryShader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.graphics4.GeometryShader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (name.endsWith("_tesc")) {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.graphics4.TessellationControlShader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.graphics4.TessellationControlShader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (name.endsWith("_tese")) {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.graphics4.TessellationEvaluationShader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.graphics4.TessellationEvaluationShader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (name.endsWith("_vert")) {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.graphics4.VertexShader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.graphics4.VertexShader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
fields.push({
|
||||
name: fixedName,
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FVar(macro : kha.graphics4.FragmentShader, macro null),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
init = macro {
|
||||
$init;
|
||||
{
|
||||
var blobs = new Array<Blob>();
|
||||
for (i in 0...$v{filenames.length}) {
|
||||
var data = Reflect.field(Shaders, $v{dataName} + i);
|
||||
var bytes: haxe.io.Bytes = haxe.Unserializer.run(data);
|
||||
blobs.push(kha.Blob.fromBytes(bytes));
|
||||
}
|
||||
$i{fixedName} = new kha.graphics4.FragmentShader(blobs, $v{filenames});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fields.push({
|
||||
name: "init",
|
||||
doc: null,
|
||||
meta: [],
|
||||
access: [APublic, AStatic],
|
||||
kind: FFun({
|
||||
ret: null,
|
||||
params: null,
|
||||
expr: init,
|
||||
args: []
|
||||
}),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
3
Kha/Sources/kha/internal/VoidCallback.hx
Normal file
3
Kha/Sources/kha/internal/VoidCallback.hx
Normal file
@ -0,0 +1,3 @@
|
||||
package kha.internal;
|
||||
|
||||
typedef VoidCallback = Void->Void;
|
Reference in New Issue
Block a user