Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,199 @@
package kha.graphics4;
import js.html.webgl.GL;
import haxe.io.Bytes;
import kha.js.graphics4.Graphics;
class CubeMap implements Canvas implements Resource {
var myWidth: Int;
var myHeight: Int;
var format: TextureFormat;
var renderTarget: Bool;
var depthStencilFormat: DepthStencilFormat;
var graphics4: kha.graphics4.Graphics;
public var frameBuffer: Dynamic = null;
public var texture: Dynamic = null;
public var depthTexture: Dynamic = null;
public var isDepthAttachment: Bool = false;
// WebGL2 constants
static inline var GL_RGBA16F = 0x881A;
static inline var GL_RGBA32F = 0x8814;
static inline var GL_R16F = 0x822D;
static inline var GL_R32F = 0x822E;
static inline var GL_DEPTH_COMPONENT24 = 0x81A6;
static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
function new(size: Int, format: TextureFormat, renderTarget: Bool, depthStencilFormat: DepthStencilFormat) {
myWidth = size;
myHeight = size;
this.format = format;
this.renderTarget = renderTarget;
this.depthStencilFormat = depthStencilFormat;
if (renderTarget)
createTexture();
}
public static function createRenderTarget(size: Int, format: TextureFormat = null, depthStencil: DepthStencilFormat = null): CubeMap {
if (format == null)
format = TextureFormat.RGBA32;
if (depthStencil == null)
depthStencil = NoDepthAndStencil;
return new CubeMap(size, format, true, depthStencil);
}
function createTexture() {
if (SystemImpl.gl == null)
return;
texture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
if (renderTarget) {
frameBuffer = SystemImpl.gl.createFramebuffer();
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
switch (format) {
case DEPTH16:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth,
myHeight, 0, GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
case RGBA128:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
GL.FLOAT, null);
case RGBA64:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
case RGBA32:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
case A32:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
GL.FLOAT, null);
case A16:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
default:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
}
if (format == DEPTH16) {
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
isDepthAttachment = true;
// Some WebGL implementations throw incomplete framebuffer error, create color attachment
if (!SystemImpl.gl2) {
var colortex = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, colortex);
for (i in 0...6) {
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, colortex, 0);
}
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
}
}
initDepthStencilBuffer(depthStencilFormat);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, null);
}
function initDepthStencilBuffer(depthStencilFormat: DepthStencilFormat) {
switch (depthStencilFormat) {
case NoDepthAndStencil:
case DepthOnly, Depth16:
{
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
if (depthStencilFormat == DepthOnly)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_INT, null);
else
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
}
case DepthAutoStencilAuto, Depth24Stencil8, Depth32Stencil8:
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH24_STENCIL8 : GL.DEPTH_STENCIL, myWidth, myHeight, 0,
GL.DEPTH_STENCIL, SystemImpl.depthTexture.UNSIGNED_INT_24_8_WEBGL, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
}
}
public function set(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
}
public function setDepth(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
public var width(get, never): Int;
function get_width(): Int {
return myWidth;
}
public var height(get, never): Int;
function get_height(): Int {
return myHeight;
}
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
return null;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
if (graphics4 == null) {
graphics4 = new Graphics(this);
}
return graphics4;
}
}

View File

@ -0,0 +1,32 @@
package kha.graphics4;
import js.html.webgl.GL;
class FragmentShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.type = GL.FRAGMENT_SHADER;
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): FragmentShader {
var shader = new FragmentShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
SystemImpl.gl.deleteShader(shader);
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,50 @@
package kha.graphics4;
import js.html.webgl.GL;
import kha.arrays.Uint32Array;
import kha.graphics4.Usage;
class IndexBuffer {
public var _data: Uint32Array;
var buffer: Dynamic;
var mySize: Int;
var usage: Usage;
var lockStart: Int = 0;
var lockEnd: Int = 0;
public function new(indexCount: Int, usage: Usage, canRead: Bool = false) {
this.usage = usage;
mySize = indexCount;
buffer = SystemImpl.gl.createBuffer();
_data = new Uint32Array(indexCount);
}
public function delete(): Void {
_data = null;
SystemImpl.gl.deleteBuffer(buffer);
}
public function lock(?start: Int, ?count: Int): Uint32Array {
lockStart = start != null ? start : 0;
lockEnd = count != null ? start + count : mySize;
return _data.subarray(lockStart, lockEnd);
}
public function unlock(?count: Int): Void {
if (count != null)
lockEnd = lockStart + count;
SystemImpl.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, buffer);
var data = _data.subarray(lockStart, lockEnd);
var glData: Dynamic = SystemImpl.elementIndexUint == null ? new js.lib.Uint16Array(data.buffer) : data;
SystemImpl.gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, glData, usage == Usage.DynamicUsage ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
}
public function set(): Void {
SystemImpl.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, buffer);
}
public function count(): Int {
return mySize;
}
}

View File

@ -0,0 +1,133 @@
package kha.graphics4;
import js.html.webgl.GL;
import kha.graphics4.VertexData;
class PipelineState extends PipelineStateBase {
var program: Dynamic = null;
var textures: Array<String>;
var textureValues: Array<Dynamic>;
public function new() {
super();
textures = new Array<String>();
textureValues = new Array<Dynamic>();
}
public function delete(): Void {
if (program != null) {
SystemImpl.gl.deleteProgram(program);
}
}
public function compile(): Void {
if (program != null) {
SystemImpl.gl.deleteProgram(program);
}
program = SystemImpl.gl.createProgram();
compileShader(vertexShader);
compileShader(fragmentShader);
SystemImpl.gl.attachShader(program, vertexShader.shader);
SystemImpl.gl.attachShader(program, fragmentShader.shader);
var index = 0;
for (structure in inputLayout) {
for (element in structure.elements) {
SystemImpl.gl.bindAttribLocation(program, index, element.name);
if (element.data == VertexData.Float32_4X4) {
index += 4;
}
else {
++index;
}
}
}
SystemImpl.gl.linkProgram(program);
if (!SystemImpl.gl.getProgramParameter(program, GL.LINK_STATUS)) {
var message = "Could not link the shader program:\n" + SystemImpl.gl.getProgramInfoLog(program);
trace("Error: " + message);
throw message;
}
}
public function set(): Void {
SystemImpl.gl.useProgram(program);
for (index in 0...textureValues.length)
SystemImpl.gl.uniform1i(textureValues[index], index);
SystemImpl.gl.colorMask(colorWriteMaskRed, colorWriteMaskGreen, colorWriteMaskBlue, colorWriteMaskAlpha);
}
function compileShader(shader: Dynamic): Void {
if (shader.shader != null)
return;
var s = SystemImpl.gl.createShader(shader.type);
var highp = SystemImpl.gl.getShaderPrecisionFormat(GL.FRAGMENT_SHADER, GL.HIGH_FLOAT);
var highpSupported = highp.precision != 0;
var files: Array<String> = shader.files;
for (i in 0...files.length) {
if (SystemImpl.gl2) {
if (files[i].indexOf("-webgl2") >= 0 || files[i].indexOf("runtime-string") >= 0) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
}
else {
if (!highpSupported && (files[i].indexOf("-relaxed") >= 0 || files[i].indexOf("runtime-string") >= 0)) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
if (highpSupported && (files[i].indexOf("-relaxed") < 0 || files[i].indexOf("runtime-string") >= 0)) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
}
}
SystemImpl.gl.compileShader(s);
if (!SystemImpl.gl.getShaderParameter(s, GL.COMPILE_STATUS)) {
var message = "Could not compile shader:\n" + SystemImpl.gl.getShaderInfoLog(s);
trace("Error: " + message);
throw message;
}
shader.shader = s;
}
public function getConstantLocation(name: String): kha.graphics4.ConstantLocation {
var location = SystemImpl.gl.getUniformLocation(program, name);
if (location == null) {
trace("Warning: Uniform " + name + " not found.");
}
var type = GL.FLOAT;
var count: Int = SystemImpl.gl.getProgramParameter(program, GL.ACTIVE_UNIFORMS);
for (i in 0...count) {
var info = SystemImpl.gl.getActiveUniform(program, i);
if (info.name == name || info.name == name + "[0]") {
type = info.type;
break;
}
}
return new kha.js.graphics4.ConstantLocation(location, type);
}
public function getTextureUnit(name: String): kha.graphics4.TextureUnit {
var index = findTexture(name);
if (index < 0) {
var location = SystemImpl.gl.getUniformLocation(program, name);
if (location == null) {
trace("Warning: Sampler " + name + " not found.");
}
index = textures.length;
textureValues.push(location);
textures.push(name);
}
return new kha.js.graphics4.TextureUnit(index);
}
function findTexture(name: String): Int {
for (index in 0...textures.length) {
if (textures[index] == name)
return index;
}
return -1;
}
}

View File

@ -0,0 +1,206 @@
package kha.graphics4;
import kha.arrays.Float32Array;
import js.html.webgl.GL;
import kha.arrays.ByteArray;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
class VertexBuffer {
public var _data: ByteArray;
var buffer: Dynamic;
var mySize: Int;
var myStride: Int;
var sizes: Array<Int>;
var offsets: Array<Int>;
var types: Array<Int>;
var instanceDataStepRate: Int;
var lockStart: Int = 0;
var lockEnd: Int = 0;
public function new(vertexCount: Int, structure: VertexStructure, usage: Usage, instanceDataStepRate: Int = 0, canRead: Bool = false) {
this.instanceDataStepRate = instanceDataStepRate;
mySize = vertexCount;
myStride = 0;
for (element in structure.elements) {
myStride += VertexStructure.dataByteSize(element.data);
}
buffer = SystemImpl.gl.createBuffer();
_data = ByteArray.make(vertexCount * myStride);
sizes = new Array<Int>();
offsets = new Array<Int>();
types = new Array<Int>();
sizes[structure.elements.length - 1] = 0;
offsets[structure.elements.length - 1] = 0;
types[structure.elements.length - 1] = 0;
var offset = 0;
var index = 0;
for (element in structure.elements) {
var size;
var type;
switch (element.data) {
case Float32_1X:
size = 1;
type = GL.FLOAT;
case Float32_2X:
size = 2;
type = GL.FLOAT;
case Float32_3X:
size = 3;
type = GL.FLOAT;
case Float32_4X:
size = 4;
type = GL.FLOAT;
case Float32_4X4:
size = 4 * 4;
type = GL.FLOAT;
case Int8_1X, Int8_1X_Normalized:
size = 1;
type = GL.BYTE;
case Int8_2X, Int8_2X_Normalized:
size = 2;
type = GL.BYTE;
case Int8_4X, Int8_4X_Normalized:
size = 4;
type = GL.BYTE;
case UInt8_1X, UInt8_1X_Normalized:
size = 1;
type = GL.UNSIGNED_BYTE;
case UInt8_2X, UInt8_2X_Normalized:
size = 2;
type = GL.UNSIGNED_BYTE;
case UInt8_4X, UInt8_4X_Normalized:
size = 4;
type = GL.UNSIGNED_BYTE;
case Int16_1X, Int16_1X_Normalized:
size = 1;
type = GL.SHORT;
case Int16_2X, Int16_2X_Normalized:
size = 2;
type = GL.SHORT;
case Int16_4X, Int16_4X_Normalized:
size = 4;
type = GL.SHORT;
case UInt16_1X, UInt16_1X_Normalized:
size = 1;
type = GL.UNSIGNED_SHORT;
case UInt16_2X, UInt16_2X_Normalized:
size = 2;
type = GL.UNSIGNED_SHORT;
case UInt16_4X, UInt16_4X_Normalized:
size = 4;
type = GL.UNSIGNED_SHORT;
case Int32_1X:
size = 1;
type = GL.INT;
case Int32_2X:
size = 2;
type = GL.INT;
case Int32_3X:
size = 3;
type = GL.INT;
case Int32_4X:
size = 4;
type = GL.INT;
case UInt32_1X:
size = 1;
type = GL.UNSIGNED_INT;
case UInt32_2X:
size = 2;
type = GL.UNSIGNED_INT;
case UInt32_3X:
size = 3;
type = GL.UNSIGNED_INT;
case UInt32_4X:
size = 4;
type = GL.UNSIGNED_INT;
}
sizes[index] = size;
offsets[index] = offset;
types[index] = type;
offset += VertexStructure.dataByteSize(element.data);
++index;
}
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), mySize * stride()),
usage == Usage.DynamicUsage ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
}
public function delete(): Void {
_data = null;
SystemImpl.gl.deleteBuffer(buffer);
}
public function lock(?start: Int, ?count: Int): Float32Array {
lockStart = start != null ? start : 0;
lockEnd = count != null ? start + count : mySize;
return _data.subarray(lockStart * stride(), lockEnd * stride());
}
public function unlock(?count: Int): Void {
if (count != null)
lockEnd = lockStart + count;
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
if (SystemImpl.safari) {
SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), lockEnd * stride()), GL.DYNAMIC_DRAW);
}
else {
SystemImpl.gl.bufferSubData(GL.ARRAY_BUFFER, lockStart * stride(), _data.subarray(lockStart * stride(), lockEnd * stride()));
}
}
public function stride(): Int {
return myStride;
}
public function count(): Int {
return mySize;
}
public function set(offset: Int): Int {
var ext: Dynamic = SystemImpl.gl2 ? true : SystemImpl.gl.getExtension("ANGLE_instanced_arrays");
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
var attributesOffset = 0;
for (i in 0...sizes.length) {
if (sizes[i] > 4) {
var size = sizes[i];
var addonOffset = 0;
while (size > 0) {
SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, 4, GL.FLOAT, false, myStride, offsets[i] + addonOffset);
if (ext) {
if (SystemImpl.gl2) {
untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
}
else {
ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
}
}
size -= 4;
addonOffset += 4 * 4;
++attributesOffset;
}
}
else {
var normalized = types[i] == GL.FLOAT ? false : true;
SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, sizes[i], types[i], normalized, myStride, offsets[i]);
if (ext) {
if (SystemImpl.gl2) {
untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
}
else {
ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
}
}
++attributesOffset;
}
}
return attributesOffset;
}
}

View File

@ -0,0 +1,32 @@
package kha.graphics4;
import js.html.webgl.GL;
class VertexShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.type = GL.VERTEX_SHADER;
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): VertexShader {
var shader = new VertexShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
SystemImpl.gl.deleteShader(shader);
shader = null;
sources = null;
}
}