@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
166 lines (133 loc) • 5.61 kB
JavaScript
/**
* Copy a patch from another sampler with a margin.
* This is useful for texture rendering where filtering can cause bleeding along the edges of the patch.
* @param {Sampler2D} destination
* @param {Sampler2D} source where to copy from
* @param {Number} sourceX where to start reading from, X coordinate
* @param {Number} sourceY where to start reading from, X coordinate
* @param {Number} destinationX where to start writing to, X coordinate
* @param {Number} destinationY where to start writing to, X coordinate
* @param {Number} width size of the patch that is to be copied
* @param {Number} height size of the patch that is to be copied
* @param {Number} marginLeft
* @param {Number} marginRight
* @param {Number} marginTop
* @param {Number} marginBottom
*/
export function sampler2d_copy_with_margins(
destination,
source,
sourceX, sourceY,
destinationX, destinationY,
width, height,
marginLeft,
marginRight,
marginTop,
marginBottom
) {
const dItemSize = destination.itemSize;
const sItemSize = source.itemSize;
const _itemSize = Math.min(dItemSize, sItemSize);
const dRowSize = dItemSize * destination.width;
const sRowSize = sItemSize * source.width;
const sData = source.data;
const dData = destination.data;
let x, y, i;
let xMax, yMax;
let dA, sA, dOffset, sOffset;
//Write top-left corner
sOffset = sourceY * sRowSize + sourceX * dItemSize;
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
dA = y * dRowSize;
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write top margin
sA = sourceY * sRowSize;
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
dA = y * dRowSize;
for (x = 0; x < width; x++) {
dOffset = dA + (x + destinationX) * dItemSize;
sOffset = sA + (x + sourceX) * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write top-right corner
sOffset = sourceY * sRowSize + (sourceX + width - 1) * dItemSize;
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
dA = y * dRowSize;
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write left margin
for (y = 0; y < height; y++) {
dA = (y + destinationY) * dRowSize;
sA = (y + sourceY) * sRowSize;
sOffset = sA + (sourceX) * dItemSize;
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//write actual patch
destination.copy(source, sourceX, sourceY, destinationX, destinationY, width, height);
//Write right margin
for (y = 0; y < height; y++) {
dA = (y + destinationY) * dRowSize;
sA = (y + sourceY) * sRowSize;
sOffset = sA + (sourceX + width - 1) * dItemSize;
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write Bottom-left margin
sOffset = (sourceY + height - 1) * sRowSize + sourceX * dItemSize;
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
dA = y * dRowSize;
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write Bottom margin
sA = (sourceY + height - 1) * sRowSize;
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
dA = y * dRowSize;
for (x = 0; x < width; x++) {
dOffset = dA + (x + destinationX) * dItemSize;
sOffset = sA + (x + sourceX) * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
//Write Bottom-right margin
sOffset = (sourceY + height - 1) * sRowSize + (sourceX + width - 1) * dItemSize;
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
dA = y * dRowSize;
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
dOffset = dA + x * dItemSize;
for (i = 0; i < _itemSize; i++) {
dData[dOffset + i] = sData[sOffset + i];
}
}
}
destination.version++;
}