mirror of
https://github.com/zellyn/apple2shader.git
synced 2025-02-05 13:34:19 +00:00
webgl: renderImage now correct except for final copy; untabify all
This commit is contained in:
parent
dba6c94236
commit
1881b62f3a
22
index.html
22
index.html
@ -153,7 +153,7 @@ void main() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="screen">
|
<div class="screen">
|
||||||
<canvas id="c"></canvas>
|
<canvas id="c"></canvas>
|
||||||
<canvas id="d"></canvas>
|
<canvas id="d" width="755" height="240"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- class="wrapper" -->
|
</div><!-- class="wrapper" -->
|
||||||
<script>
|
<script>
|
||||||
@ -218,16 +218,32 @@ void main() {
|
|||||||
gl.drawArrays(primitiveType, offset, count);
|
gl.drawArrays(primitiveType, offset, count);
|
||||||
|
|
||||||
// screenEmu.loadImage("images/airheart-560x192.png").then(image => {
|
// screenEmu.loadImage("images/airheart-560x192.png").then(image => {
|
||||||
// let c = screenEmu.screenData(image, screenEmu.C.NTSC_DETAILS);
|
// let [c, data] = screenEmu.screenData(image, screenEmu.C.NTSC_DETAILS);
|
||||||
// document.body.appendChild(c);
|
// document.body.appendChild(c);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
async function tryScreenView() {
|
async function tryScreenView() {
|
||||||
|
const image = await screenEmu.loadImage("images/airheart-560x192.png");
|
||||||
|
const [imageCanvas, imageData] = screenEmu.screenData(image, screenEmu.C.NTSC_DETAILS);
|
||||||
|
|
||||||
let canvas = document.getElementById("d");
|
let canvas = document.getElementById("d");
|
||||||
let sv = new screenEmu.ScreenView(canvas);
|
let sv = new screenEmu.ScreenView(canvas);
|
||||||
await sv.initOpenGL();
|
await sv.initOpenGL();
|
||||||
|
|
||||||
let imageInfo = new screenEmu.ImageInfo(0, 0, 0, 0, 0, 0, new ImageData(10, 10));
|
const sampleRate = 4 * screenEmu.C.NTSC_DETAILS.fsc;
|
||||||
|
const blackLevel = 0;
|
||||||
|
const whiteLevel = 1;
|
||||||
|
const subCarrier = screenEmu.C.NTSC_DETAILS.fsc;
|
||||||
|
const colorBurst = screenEmu.C.NTSC_DETAILS.colorBurst;
|
||||||
|
const phaseAlternation = [false];
|
||||||
|
let imageInfo = new screenEmu.ImageInfo(
|
||||||
|
sampleRate,
|
||||||
|
blackLevel,
|
||||||
|
whiteLevel,
|
||||||
|
subCarrier,
|
||||||
|
colorBurst,
|
||||||
|
phaseAlternation,
|
||||||
|
imageData);
|
||||||
let displayConfig = new screenEmu.DisplayConfiguration();
|
let displayConfig = new screenEmu.DisplayConfiguration();
|
||||||
sv.image = imageInfo;
|
sv.image = imageInfo;
|
||||||
sv.displayConfiguration = displayConfig;
|
sv.displayConfiguration = displayConfig;
|
||||||
|
52
screenEmu.js
52
screenEmu.js
@ -208,7 +208,7 @@ void main(void)
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function buildTiming(clockFrequency, displayRect, visibleRect, vertTotal) {
|
function buildTiming(clockFrequency, displayRect, visibleRect, vertTotal, fsc) {
|
||||||
const vertStart = displayRect[0][1];
|
const vertStart = displayRect[0][1];
|
||||||
// Total number of CPU cycles per frame: 17030 for NTSC.
|
// Total number of CPU cycles per frame: 17030 for NTSC.
|
||||||
const frameCycleNum = HORIZ_TOTAL * vertTotal;
|
const frameCycleNum = HORIZ_TOTAL * vertTotal;
|
||||||
@ -228,6 +228,7 @@ void main(void)
|
|||||||
const topLeft80Col = [imageLeft - CELL_WIDTH/2, vertStart - visibleRect[0][1]];
|
const topLeft80Col = [imageLeft - CELL_WIDTH/2, vertStart - visibleRect[0][1]];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
fsc: fsc,
|
||||||
clockFrequency: clockFrequency,
|
clockFrequency: clockFrequency,
|
||||||
displayRect: displayRect,
|
displayRect: displayRect,
|
||||||
visibleRect: visibleRect,
|
visibleRect: visibleRect,
|
||||||
@ -430,7 +431,7 @@ void main(void)
|
|||||||
mul(val) {
|
mul(val) {
|
||||||
const m = new Matrix3(0,0,0,0,0,0,0,0,0);
|
const m = new Matrix3(0,0,0,0,0,0,0,0,0);
|
||||||
if (typeof val == "number") {
|
if (typeof val == "number") {
|
||||||
m.data = m.data.map(x => x * val);
|
m.data = this.data.map(x => x * val);
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
for (let j = 0; j < 3; j++) {
|
for (let j = 0; j < 3; j++) {
|
||||||
@ -472,8 +473,22 @@ void main(void)
|
|||||||
context.fillStyle = 'rgba(0,0,0,1)';
|
context.fillStyle = 'rgba(0,0,0,1)';
|
||||||
context.fillRect(0, 0, width, height);
|
context.fillRect(0, 0, width, height);
|
||||||
context.drawImage(image, details.topLeft80Col[0], details.topLeft80Col[1]);
|
context.drawImage(image, details.topLeft80Col[0], details.topLeft80Col[1]);
|
||||||
// const myData = context.getImageData(0, 0, image.naturalWidth, image.naturalHeight);
|
const imageData = context.getImageData(0, 0, width, height);
|
||||||
return canvas;
|
return [canvas, imageData];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Given an ImageData (RGBA), convert to luminance by taking the max
|
||||||
|
// of (R,G,B) for each pixel. Return a Uint8Array.
|
||||||
|
const luminanceData = (imageData) => {
|
||||||
|
const width = imageData.width;
|
||||||
|
const height = imageData.height;
|
||||||
|
const data = imageData.data;
|
||||||
|
const size = width * height;
|
||||||
|
const ary = new Uint8Array(size);
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
ary[i] = Math.max(data[i*4], data[i*4+1], data[i*4+2]);
|
||||||
|
}
|
||||||
|
return ary;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEXTURE_NAMES = [
|
const TEXTURE_NAMES = [
|
||||||
@ -566,17 +581,17 @@ void main(void)
|
|||||||
this.videoHue = 0;
|
this.videoHue = 0;
|
||||||
this.videoCenter = [0,0];
|
this.videoCenter = [0,0];
|
||||||
this.videoSize = [1,1];
|
this.videoSize = [1,1];
|
||||||
this.videoBandwidth = 14318180;
|
this.videoBandwidth = 6000000; // 14318180;
|
||||||
this.videoLumaBandwidth = 600000;
|
this.videoLumaBandwidth = 2000000; // 600000;
|
||||||
this.videoChromaBandwidth = 2000000;
|
this.videoChromaBandwidth = 600000; // 2000000;
|
||||||
this.videoWhiteOnly = false;
|
this.videoWhiteOnly = false;
|
||||||
|
|
||||||
this.displayResolution = [640, 480];
|
this.displayResolution = [640, 480];
|
||||||
this.displayPixelDensity = 72;
|
this.displayPixelDensity = 72;
|
||||||
this.displayBarrel = 0;
|
this.displayBarrel = 0.05; // 0;
|
||||||
this.displayScanlineLevel = 0;
|
this.displayScanlineLevel = 0.05; // 0;
|
||||||
this.displayShadowMaskLevel = 0;
|
this.displayShadowMaskLevel = 0.05; // 0;
|
||||||
this.displayShadowMaskDotPitch = 1;
|
this.displayShadowMaskDotPitch = 0.5; // 1;
|
||||||
this.displayShadowMask = "SHADOWMASK_TRIAD";
|
this.displayShadowMask = "SHADOWMASK_TRIAD";
|
||||||
this.displayPersistence = 0;
|
this.displayPersistence = 0;
|
||||||
this.displayCenterLighting = 1;
|
this.displayCenterLighting = 1;
|
||||||
@ -786,20 +801,23 @@ void main(void)
|
|||||||
gl.bindTexture(gl.TEXTURE_2D, texInfoImage.glTexture);
|
gl.bindTexture(gl.TEXTURE_2D, texInfoImage.glTexture);
|
||||||
const format = gl.LUMINANCE;
|
const format = gl.LUMINANCE;
|
||||||
const type = gl.UNSIGNED_BYTE;
|
const type = gl.UNSIGNED_BYTE;
|
||||||
|
const luminance = luminanceData(image.data);
|
||||||
gl.texSubImage2D(gl.TEXTURE_2D, 0,
|
gl.texSubImage2D(gl.TEXTURE_2D, 0,
|
||||||
0, 0, // xoffset, yoffset
|
0, 0, // xoffset, yoffset
|
||||||
format, type, image.data);
|
image.data.width,
|
||||||
|
image.data.height,
|
||||||
|
format, type, luminance);
|
||||||
|
|
||||||
// Update configuration
|
// Update configuration
|
||||||
if ((image.sampleRate != this.imageSampleRate) ||
|
if ((image.sampleRate != this.imageSampleRate) ||
|
||||||
(image.blackLevel != this.imageBlackLevel) ||
|
(image.blackLevel != this.imageBlackLevel) ||
|
||||||
(image.whiteLevel != this.imageWhiteLevel) ||
|
(image.whiteLevel != this.imageWhiteLevel) ||
|
||||||
(image.subcarrier != this.imageSubcarrier))
|
(image.subCarrier != this.imageSubcarrier))
|
||||||
{
|
{
|
||||||
this.imageSampleRate = image.sampleRate;
|
this.imageSampleRate = image.sampleRate;
|
||||||
this.imageBlackLevel = image.blackLevel;
|
this.imageBlackLevel = image.blackLevel;
|
||||||
this.imageWhiteLevel = image.whiteLevel;
|
this.imageWhiteLevel = image.whiteLevel;
|
||||||
this.imageSubcarrier = image.subcarrier;
|
this.imageSubcarrier = image.subCarrier;
|
||||||
|
|
||||||
this.configurationChanged = true;
|
this.configurationChanged = true;
|
||||||
}
|
}
|
||||||
@ -1204,7 +1222,7 @@ void main(void)
|
|||||||
texInfo.height = height;
|
texInfo.height = height;
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texInfo.glTexture);
|
gl.bindTexture(gl.TEXTURE_2D, texInfo.glTexture);
|
||||||
const dummy = new Uint8Array(width * height);
|
const dummy = new Uint8Array(width * height);
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0,
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0,
|
||||||
gl.LUMINANCE, gl.UNSIGNED_BYTE, dummy);
|
gl.LUMINANCE, gl.UNSIGNED_BYTE, dummy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1227,9 +1245,9 @@ void main(void)
|
|||||||
NTSC_Q_CUTOFF: NTSC_Q_CUTOFF,
|
NTSC_Q_CUTOFF: NTSC_Q_CUTOFF,
|
||||||
NTSC_IQ_DELTA: NTSC_IQ_DELTA,
|
NTSC_IQ_DELTA: NTSC_IQ_DELTA,
|
||||||
NTSC_DETAILS: buildTiming(ntscClockFrequency, ntscDisplayRect,
|
NTSC_DETAILS: buildTiming(ntscClockFrequency, ntscDisplayRect,
|
||||||
ntscVisibleRect, ntscVertTotal),
|
ntscVisibleRect, ntscVertTotal, NTSC_FSC),
|
||||||
PAL_DETAILS: buildTiming(palClockFrequency, palDisplayRect,
|
PAL_DETAILS: buildTiming(palClockFrequency, palDisplayRect,
|
||||||
palVisibleRect, palVertTotal),
|
palVisibleRect, palVertTotal, PAL_FSC),
|
||||||
},
|
},
|
||||||
loadImage: loadImage,
|
loadImage: loadImage,
|
||||||
screenData: screenData,
|
screenData: screenData,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user