forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
199
Kha/Backends/HTML5/kha/graphics4/CubeMap.hx
Normal file
199
Kha/Backends/HTML5/kha/graphics4/CubeMap.hx
Normal 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;
|
||||
}
|
||||
}
|
32
Kha/Backends/HTML5/kha/graphics4/FragmentShader.hx
Normal file
32
Kha/Backends/HTML5/kha/graphics4/FragmentShader.hx
Normal 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;
|
||||
}
|
||||
}
|
50
Kha/Backends/HTML5/kha/graphics4/IndexBuffer.hx
Normal file
50
Kha/Backends/HTML5/kha/graphics4/IndexBuffer.hx
Normal 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;
|
||||
}
|
||||
}
|
133
Kha/Backends/HTML5/kha/graphics4/PipelineState.hx
Normal file
133
Kha/Backends/HTML5/kha/graphics4/PipelineState.hx
Normal 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;
|
||||
}
|
||||
}
|
206
Kha/Backends/HTML5/kha/graphics4/VertexBuffer.hx
Normal file
206
Kha/Backends/HTML5/kha/graphics4/VertexBuffer.hx
Normal 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;
|
||||
}
|
||||
}
|
32
Kha/Backends/HTML5/kha/graphics4/VertexShader.hx
Normal file
32
Kha/Backends/HTML5/kha/graphics4/VertexShader.hx
Normal 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user