update 0.8.0
This commit is contained in:
parent
6c1dd199b1
commit
eda41a625b
20 changed files with 9833 additions and 4280 deletions
283
sae/video.js
283
sae/video.js
|
|
@ -34,130 +34,168 @@ function Vide0() {
|
|||
antialias: false
|
||||
};
|
||||
|
||||
this.available = 0;
|
||||
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var size = 0;
|
||||
var scale = false;
|
||||
var pixels = null;
|
||||
|
||||
var div = null;
|
||||
var canvas = null;
|
||||
var gl = null;
|
||||
var ctx = null;
|
||||
var imagedata = null;
|
||||
var video = null;
|
||||
var open = false;
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
function getShader(gl, id) {
|
||||
//this.init = function()
|
||||
{
|
||||
var test = document.createElement('canvas');
|
||||
if (test && test.getContext) {
|
||||
var test2 = test.getContext('2d');
|
||||
if (test2) {
|
||||
this.available |= SAEI_Video_Canvas2D;
|
||||
test2 = null;
|
||||
}
|
||||
test = null;
|
||||
}
|
||||
test = document.createElement('canvas');
|
||||
if (test && test.getContext) {
|
||||
test2 = test.getContext('experimental-webgl', glParams) || test.getContext('webgl', glParams);
|
||||
if (test2) {
|
||||
this.available |= SAEI_Video_WebGL;
|
||||
test2 = null;
|
||||
}
|
||||
test = null;
|
||||
}
|
||||
//console.log(this.available);
|
||||
}
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
function getShader(ctx, id) {
|
||||
var shader, source;
|
||||
|
||||
if (id == 'vertex') {
|
||||
shader = gl.createShader(gl.VERTEX_SHADER);
|
||||
shader = ctx.createShader(ctx.VERTEX_SHADER);
|
||||
source = vertexShader;
|
||||
} else if (id == 'fragment') {
|
||||
shader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
shader = ctx.createShader(ctx.FRAGMENT_SHADER);
|
||||
source = fragmentShader;
|
||||
}
|
||||
gl.shaderSource(shader, source);
|
||||
gl.compileShader(shader);
|
||||
ctx.shaderSource(shader, source);
|
||||
ctx.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
|
||||
Fatal(SAEE_Video_Shader_Error, gl.getShaderInfoLog(shader));
|
||||
if (!ctx.getShaderParameter(shader, ctx.COMPILE_STATUS))
|
||||
Fatal(SAEE_Video_Shader_Error, ctx.getShaderInfoLog(shader));
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
function initGL() {
|
||||
var vertexShader = getShader(gl, 'vertex');
|
||||
var fragmentShader = getShader(gl, 'fragment');
|
||||
var program = gl.createProgram();
|
||||
gl.attachShader(program, vertexShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
gl.linkProgram(program);
|
||||
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
|
||||
var vertexShader = getShader(ctx, 'vertex');
|
||||
var fragmentShader = getShader(ctx, 'fragment');
|
||||
var program = ctx.createProgram();
|
||||
ctx.attachShader(program, vertexShader);
|
||||
ctx.attachShader(program, fragmentShader);
|
||||
ctx.linkProgram(program);
|
||||
if (!ctx.getProgramParameter(program, ctx.LINK_STATUS))
|
||||
Fatal(SAEE_Video_Shader_Error, 'Can\'t initialise the shaders for WebGL.');
|
||||
|
||||
gl.useProgram(program);
|
||||
ctx.useProgram(program);
|
||||
|
||||
var positionLocation = gl.getAttribLocation(program, "a_position");
|
||||
var texCoordLocation = gl.getAttribLocation(program, "a_texCoord");
|
||||
var positionLocation = ctx.getAttribLocation(program, "a_position");
|
||||
var texCoordLocation = ctx.getAttribLocation(program, "a_texCoord");
|
||||
|
||||
var texCoordBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
var texCoordBuffer = ctx.createBuffer();
|
||||
ctx.bindBuffer(ctx.ARRAY_BUFFER, texCoordBuffer);
|
||||
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
0.0, 1.0,
|
||||
1.0, 0.0,
|
||||
1.0, 1.0]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(texCoordLocation);
|
||||
gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);
|
||||
1.0, 1.0]), ctx.STATIC_DRAW);
|
||||
ctx.enableVertexAttribArray(texCoordLocation);
|
||||
ctx.vertexAttribPointer(texCoordLocation, 2, ctx.FLOAT, false, 0, 0);
|
||||
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
var texture = ctx.createTexture();
|
||||
ctx.bindTexture(ctx.TEXTURE_2D, texture);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
|
||||
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
|
||||
|
||||
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
|
||||
gl.uniform2f(resolutionLocation, width, height);
|
||||
var resolutionLocation = ctx.getUniformLocation(program, "u_resolution");
|
||||
ctx.uniform2f(resolutionLocation, width, height);
|
||||
|
||||
var buffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
gl.enableVertexAttribArray(positionLocation);
|
||||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
||||
var buffer = ctx.createBuffer();
|
||||
ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer);
|
||||
ctx.enableVertexAttribArray(positionLocation);
|
||||
ctx.vertexAttribPointer(positionLocation, 2, ctx.FLOAT, false, 0, 0);
|
||||
|
||||
gl.viewport(0, 0, width, height);
|
||||
gl.clearColor(0, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.colorMask(true, true, true, false);
|
||||
ctx.viewport(0, 0, width, height);
|
||||
ctx.clearColor(0, 0, 0, 1);
|
||||
ctx.clear(ctx.COLOR_BUFFER_BIT);
|
||||
ctx.colorMask(true, true, true, false);
|
||||
}
|
||||
|
||||
this.setup = function() {
|
||||
if (!AMIGA.config.video.enabled) return;
|
||||
if (open) this.cleanup();
|
||||
|
||||
width = AMIGA.config.video.scale ? VIDEO_WIDTH << 1 : VIDEO_WIDTH;
|
||||
height = AMIGA.config.video.scale ? VIDEO_HEIGHT << 1 : VIDEO_WIDTH;
|
||||
size = width * height;
|
||||
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
|
||||
|
||||
div = document.getElementById(AMIGA.config.video.id);
|
||||
if (!div)
|
||||
Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: '+AMIGA.config.video.id+')');
|
||||
|
||||
if ((canvas = document.createElement('canvas'))) {
|
||||
canvas.width = width;
|
||||
scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false;
|
||||
width = VIDEO_WIDTH << (scale ? 1 : 0);
|
||||
height = VIDEO_HEIGHT << (scale ? 1 : 0);
|
||||
size = width * height;
|
||||
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
|
||||
|
||||
if (this.available & SAEI_Video_Canvas2D) {
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
} else {
|
||||
if (confirm('Can\'t create a CANVAS-element. Continue without video-playback?'))
|
||||
AMIGA.config.video.enabled = false;
|
||||
else
|
||||
Fatal(SAEE_Video_Canvas_Not_Supported, 'Can\'t create a CANVAS-element. Please update the browser.');
|
||||
}
|
||||
if (AMIGA.config.video.enabled) {
|
||||
if ((gl = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams)))
|
||||
canvas.oncontextmenu = function() { return false; }
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); }
|
||||
canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); }
|
||||
canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); }
|
||||
canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); }
|
||||
canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); }
|
||||
}
|
||||
if (this.available & SAEI_Video_WebGL) {
|
||||
ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams);
|
||||
initGL();
|
||||
pixels = new Uint16Array(size);
|
||||
for (var i = 0; i < size; i++) pixels[i] = 0;
|
||||
|
||||
this.drawpixel = drawpixel_gl;
|
||||
this.drawline = drawline_gl;
|
||||
this.render = render_gl;
|
||||
this.show = show_gl;
|
||||
} else {
|
||||
ctx = canvas.getContext('2d');
|
||||
imagedata = ctx.createImageData(width, height);
|
||||
pixels = imagedata.data;
|
||||
|
||||
this.drawpixel = drawpixel_2d;
|
||||
this.drawline = drawline_2d;
|
||||
this.render = render_2d;
|
||||
this.show = show_2d;
|
||||
}
|
||||
} else {
|
||||
if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?'))
|
||||
Fatal(SAEE_Video_Canvas_Not_Supported, null);
|
||||
else
|
||||
if (confirm('Can\'t initialise WebGL. Continue without video-playback?'))
|
||||
AMIGA.config.video.enabled = false;
|
||||
else
|
||||
Fatal(SAEE_Video_WebGL_Not_Avail, 'Can\'t initialise WebGL. Is WebGL enabled in the browser-config?');
|
||||
AMIGA.config.video.enabled = false;
|
||||
}
|
||||
if (AMIGA.config.video.enabled) {
|
||||
pixels = new Uint16Array(size);
|
||||
for (var i = 0; i < size; i++) pixels[i] = 0;
|
||||
}
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); }
|
||||
canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); }
|
||||
canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); }
|
||||
canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); }
|
||||
canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); }
|
||||
}
|
||||
canvas.oncontextmenu = function() { return false; }
|
||||
|
||||
|
||||
video = document.createElement('div');
|
||||
video.style.width = width + 'px';
|
||||
video.style.height = height + 'px';
|
||||
|
|
@ -168,15 +206,18 @@ function Vide0() {
|
|||
video.style.mozUserSelect = 'none';
|
||||
video.style.msUserSelect = 'none';
|
||||
video.style.userSelect = 'none';
|
||||
video.appendChild(canvas);
|
||||
if (AMIGA.config.video.enabled)
|
||||
video.appendChild(canvas);
|
||||
|
||||
div.appendChild(video);
|
||||
open = true;
|
||||
open = true;
|
||||
}
|
||||
|
||||
this.cleanup = function() {
|
||||
if (open) {
|
||||
div.removeChild(video);
|
||||
canvas = null;
|
||||
imagedata = null;
|
||||
pixels = null;
|
||||
video = null;
|
||||
open = false;
|
||||
|
|
@ -189,57 +230,59 @@ function Vide0() {
|
|||
canvas.style.cursor = hide ? 'none' : 'auto';
|
||||
}
|
||||
|
||||
this.clear_pixels = function () {
|
||||
/*this.clear_pixels = function () {
|
||||
for (var i = 0; i < size; i++)
|
||||
pixels[i] = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
this.drawpixel = function (x, y, rgb) {
|
||||
/*---------------------------------*/
|
||||
/* Canvas 2D */
|
||||
|
||||
function drawpixel_2d(x, y, rgb) {
|
||||
pixels[y * width + x] = rgb;
|
||||
}
|
||||
this.draw2pixel = function (x, y, rgb) {
|
||||
var ptr = y * width + x;
|
||||
pixels[ptr] = pixels[ptr + 1] = rgb;
|
||||
}
|
||||
|
||||
this.drawline = function (y, rgb) {
|
||||
var ptr = y * width;
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
pixels[ptr++] = rgb;
|
||||
}
|
||||
this.drawline_from_to = function (x1, x2, y, rgb) {
|
||||
var ptr = y * width + x1;
|
||||
|
||||
for (var i = 0; i < x2 - x1; i++)
|
||||
pixels[ptr++] = rgb;
|
||||
}
|
||||
|
||||
this.draw = function (rgb, scalex, scaley, colorOnly) {
|
||||
var r = 0.0625 * (((rgb >> 11) & 31) >> 1);
|
||||
var g = 0.0625 * (((rgb >> 5) & 63) >> 2);
|
||||
var b = 0.0625 * ((rgb & 31) >> 1);
|
||||
|
||||
gl.viewport(0, 0, width, height);
|
||||
gl.clearColor(r, g, b, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
if (!colorOnly) {
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, pixels);
|
||||
|
||||
var s = AMIGA.config.video.scale ? 1 : 0;
|
||||
var x1 = 0;
|
||||
//var x2 = 0 + (width << (scalex ? (s+1) : s));
|
||||
var x2 = 0 + (width << s);
|
||||
var y1 = 0;
|
||||
var y2 = 0 + (height << (scaley ? (s+1) : s));
|
||||
//var y2 = 0 + (height << s);
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
x1, y1, x2, y1, x1, y2,
|
||||
x1, y2, x2, y1, x2, y2]), gl.STATIC_DRAW);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
function drawline_2d(y, data, offs) {
|
||||
var yoffs = (y * width) << 2;
|
||||
for (var x = 0, d = 0; x < width << 2; x += 4, d++) {
|
||||
pixels[yoffs + x ] = ((data[offs + d] >> 8) & 0xf) << 4;
|
||||
pixels[yoffs + x + 1] = ((data[offs + d] >> 4) & 0xf) << 4;
|
||||
pixels[yoffs + x + 2] = ((data[offs + d] >> 0) & 0xf) << 4;
|
||||
pixels[yoffs + x + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
function render_2d() {
|
||||
ctx.putImageData(imagedata, 0, 0);
|
||||
}
|
||||
|
||||
function show_2d() {}
|
||||
|
||||
/*---------------------------------*/
|
||||
/* WebGL */
|
||||
|
||||
function drawpixel_gl(x, y, rgb) {
|
||||
pixels[y * width + x] = rgb;
|
||||
}
|
||||
|
||||
function drawline_gl(y, data, offs) {
|
||||
var yoffs = y * width;
|
||||
for (var x = 0; x < width; x++)
|
||||
pixels[yoffs + x] = data[offs + x] & 0xffff;
|
||||
}
|
||||
|
||||
function render_gl() {
|
||||
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGB, width, height, 0, ctx.RGB, ctx.UNSIGNED_SHORT_5_6_5, pixels);
|
||||
|
||||
var x1 = 0;
|
||||
var x2 = width << (scale ? 1 : 0);
|
||||
var y1 = 0;
|
||||
var y2 = height << (scale ? 1 : 0);
|
||||
|
||||
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]), ctx.STATIC_DRAW);
|
||||
}
|
||||
|
||||
function show_gl() {
|
||||
ctx.drawArrays(ctx.TRIANGLES, 0, 6);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue