Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 118 additions & 12 deletions src/openfl/display/Shader.hx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import openfl.display3D._internal.GLShader;
import openfl.utils.ByteArray;
import openfl.utils._internal.Float32Array;
import openfl.utils._internal.Log;
import openfl.Lib;

/**
// TODO: Document GLSL Shaders
Expand Down Expand Up @@ -119,6 +120,8 @@ import openfl.utils._internal.Log;
@:access(openfl.display3D.Program3D)
@:access(openfl.display.ShaderInput)
@:access(openfl.display.ShaderParameter)
@:access(openfl.display.Stage)
@:access(openfl.events.UncaughtErrorEvents)
// #if (!display && !macro)
#if !macro
@:autoBuild(openfl.utils._internal.ShaderMacro.build())
Expand Down Expand Up @@ -417,21 +420,72 @@ class Shader
gl.compileShader(shader);
var shaderInfoLog = gl.getShaderInfoLog(shader);
var hasInfoLog = shaderInfoLog != null && StringTools.trim(shaderInfoLog) != "";
var compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
var isError = gl.getShaderParameter(shader, gl.COMPILE_STATUS) == 0;

if (hasInfoLog || compileStatus == 0)
if (hasInfoLog || isError)
{
var message = (compileStatus == 0) ? "Error" : "Info";
message += (type == gl.VERTEX_SHADER) ? " compiling vertex shader" : " compiling fragment shader";
message += "\n" + shaderInfoLog;
message += "\n" + source;
if (compileStatus == 0) Log.error(message);
else if (hasInfoLog) Log.debug(message);
__logGLShaderInfo(isError, type, shaderInfoLog, source);
}

return shader;
}

/**
* Retrieves the line number from a shader log line.
*/
@:noCompletion private var __lineExtractor = ~/^\w+?: \d+:(\d+):(.+$)/;
/**
* Searches for strings that have only whitespace.
*
* **Note:** Searching for all whitespace via `~/^\s*$/` caused false-negatives,
* notably: `String.fromCharCode(0)` is `false` but `\W` is `true`.
*/
@:noCompletion private var __isEmptyLine = ~/^\W*$/;
@:noCompletion private function __logGLShaderInfo(isError:Bool, type:Int, infoLog:String, source:String):Void
{
var message = "";
var lines = source.split("\n");
var failingLine:String = null;
for (log in infoLog.split("\n"))
{
// ignore empty lines
if (__isEmptyLine.match(log))
continue;

// look for a line number
if (!__lineExtractor.match(log))
{
// Could not find expected info, abort pretty formatting
failingLine = log;
break;
}

var lineNumberStr = __lineExtractor.matched(1);
var lineNumber = Std.parseInt(lineNumberStr);
var info = __lineExtractor.matched(2);
if (lineNumber >= lines.length)
{
// EOF errors will not have a valid line
message += '\n\n $lineNumber | $info';
}
else
{
// Add the relevant line to each log
var line = lines[lineNumber - 1];
var indent = StringTools.lpad("|", " ", lineNumberStr.length + 3);
message += '\n\n $lineNumber | $line\n$indent ${info}';
}
}

// If we couldn't parse the logs, output the old, verbose format
if (failingLine != null)
message = '\nFailed to simplify log:"$failingLine"\n$infoLog\n$source';

var typeName = (type == __context.gl.VERTEX_SHADER) ? "vertex" : "fragment";
if (isError) Log.error('Error compiling $typeName shader $message');
else Log.debug('Info compiling $typeName shader $message');
}

@:noCompletion private function __createGLProgram(vertexSource:String, fragmentSource:String):GLProgram
{
var gl = __context.gl;
Expand Down Expand Up @@ -622,7 +676,22 @@ class Shader

// TODO
// program.uploadSources (vertex, fragment);
program.__glProgram = __createGLProgram(vertex, fragment);

if (Lib.current.stage.__uncaughtErrorEvents.__enabled)
{
try
{
program.__glProgram = __createGLProgram(vertex, fragment);
}
catch (e:Dynamic)
{
Lib.current.stage.__handleError(e);

program.__glProgram = null;
}
}
else
program.__glProgram = __createGLProgram(vertex, fragment);

__context.__programs.set(id, program);
}
Expand Down Expand Up @@ -730,7 +799,16 @@ class Shader
}

Reflect.setField(__data, name, input);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input);

try
{
if (__isGenerated) Reflect.setField(this, name, input);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, input);
}
catch (e:Dynamic)
{
Log.debug('Failed to set field $name: $e');
}
}
else if (!Reflect.hasField(__data, name) || Reflect.field(__data, name) == null)
{
Expand Down Expand Up @@ -796,7 +874,16 @@ class Shader
}

Reflect.setField(__data, name, parameter);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter);

try
{
if (__isGenerated) Reflect.setField(this, name, parameter);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter);
}
catch (e:Dynamic)
{
Log.debug('Failed to set field $name: $e');
}

case INT, INT2, INT3, INT4:
var parameter = new ShaderParameter<Int>();
Expand All @@ -807,9 +894,19 @@ class Shader
parameter.__isUniform = isUniform;
parameter.__length = length;
__paramInt.push(parameter);

Reflect.setField(__data, name, parameter);

if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter);

try
{
if (__isGenerated) Reflect.setField(this, name, parameter);
}
catch (e:Dynamic)
{
Log.debug('Failed to set field $name: $e');
}
default:
var parameter = new ShaderParameter<Float>();
parameter.name = name;
Expand Down Expand Up @@ -839,7 +936,16 @@ class Shader
}

Reflect.setField(__data, name, parameter);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter);

try
{
if (__isGenerated) Reflect.setField(this, name, parameter);
if (__isGenerated && thisHasField(name)) Reflect.setProperty(this, name, parameter);
}
catch (e:Dynamic)
{
Log.debug('Failed to set field $name: $e');
}
}
}

Expand Down
Loading