[1 bit]完成 line 类型的轮廓和遮罩层的绘制
This commit is contained in:
parent
0a36a28a57
commit
5481921722
93
backup/drawline.js
Normal file
93
backup/drawline.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
const bar = [
|
||||||
|
(f, t, a, b, c0, c1) => [].concat( // 0
|
||||||
|
(f === 1) ? [a, 2, c1] : [],
|
||||||
|
[a, 5, c0],
|
||||||
|
[b, 5, c0],
|
||||||
|
(t > 1) ? [b, 0, c0] : []
|
||||||
|
),
|
||||||
|
|
||||||
|
(f, t, a, b, c0, c1) => [].concat( // 1
|
||||||
|
(f === 0) ? [a, 5, c0] :
|
||||||
|
(f > 1) ? [a, 0, c0] : [],
|
||||||
|
[a, 2, c1],
|
||||||
|
[b, 2, c1],
|
||||||
|
(t > 1) ? [b, 0, c0] : []
|
||||||
|
),
|
||||||
|
|
||||||
|
(f, t, a, b, c0, c1) => [a, 0, c0, b, 0, c1] // 2 = Z
|
||||||
|
];
|
||||||
|
|
||||||
|
const brick = [
|
||||||
|
(f, t, a, b, c0, c1) => [].concat( // 0
|
||||||
|
(f === 0) ? [a, 5, c0] :
|
||||||
|
(f === 1) ? [a, 1, c1] : [],
|
||||||
|
[a, 6, c0],
|
||||||
|
(t === 0) ? [b, 5, c0] :
|
||||||
|
[b, 4, c0],
|
||||||
|
(t === 3) ? [b, 0, c0] : []
|
||||||
|
),
|
||||||
|
(f, t, a, b, c0, c1) => [].concat( // 1
|
||||||
|
(f === 0) ? [a, 4, c0, a, 3, c1] :
|
||||||
|
(f === 1) ? [a, 2, c1] :
|
||||||
|
(f === 2) ? [a, 3, c1] :
|
||||||
|
[a, 0, c0, a, 3, c1],
|
||||||
|
(t === 1) ? [b, 3, c1] :
|
||||||
|
[b, 1, c1],
|
||||||
|
(t === 3) ? [b, 0, c0] : []
|
||||||
|
),
|
||||||
|
(f, t, a, b, c0, c1) => [].concat( // 2
|
||||||
|
(f === 0) ? [a, 4, 0] :
|
||||||
|
(f === 1) ? [a, 1, 0] :
|
||||||
|
[a, 0, 0],
|
||||||
|
|
||||||
|
(t === 0) ? [b, 6, 0, b, 6, c0] :
|
||||||
|
(t === 1) ? [b, 3, 0, b, 3, c1, b, 4, c0] :
|
||||||
|
[b, 0, 0, b, 0, c0, b, 4, c0],
|
||||||
|
|
||||||
|
(f === 0) ? [a, 4, c0, a, 3, c1] :
|
||||||
|
(f === 1) ? [a, 6, c0, a, 1, c1] :
|
||||||
|
[a, 6, c0, a, 0, c0, a, 3, c1],
|
||||||
|
|
||||||
|
(t === 0) ? [b, 1, c1, b, 6, c0] :
|
||||||
|
(t === 1) ? [b, 3, c1] :
|
||||||
|
[b, 1, c1, b, 0, c0]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
// switch (val) {
|
||||||
|
// case 0:
|
||||||
|
// if (i === 0) {
|
||||||
|
// if (y1 === y2) {
|
||||||
|
// vertices.push(
|
||||||
|
// t1, y1ShiftIndex, renderParam1.color, 0,
|
||||||
|
// t1, y1ShiftIndex, renderParam1.color, 4
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// break;
|
||||||
|
// case 1: // 0 1
|
||||||
|
// vertices.push(...bar[val](f[1], t[1], t1, t2, 2, 3));
|
||||||
|
// break;
|
||||||
|
// case 2: case 3: // x X
|
||||||
|
// vertices.push(...bar[2](f[1], t[1], t1, t2, 4, 4));
|
||||||
|
// break;
|
||||||
|
// case 4: case 5: // z Z
|
||||||
|
// vertices.push(...bar[2](f[1], t[1], t1, t2, 1, 1));
|
||||||
|
// break;
|
||||||
|
// case 6: case 7: // u U uninitialized
|
||||||
|
// vertices.push(...bar[2](f[1], t[1], t1, t2, 6, 6));
|
||||||
|
// break;
|
||||||
|
// case 8: case 9: // w W weak unknown
|
||||||
|
// vertices.push(...bar[2](f[1], t[1], t1, t2, 10, 10));
|
||||||
|
// break;
|
||||||
|
// case 10: case 11: // l L
|
||||||
|
// vertices.push(...bar[0](f[1], t[1], t1, t2, 8, 9));
|
||||||
|
// break;
|
||||||
|
// case 12: case 13: // h H
|
||||||
|
// vertices.push(...bar[1](f[1], t[1], t1, t2, 8, 9));
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// vertices.push(...bar[2](f[1], t[1], t1, t2, 7, 7));
|
||||||
|
// }
|
@ -7,6 +7,9 @@
|
|||||||
--sidebar-width: 280px;
|
--sidebar-width: 280px;
|
||||||
--right-nav-width: 60px;
|
--right-nav-width: 60px;
|
||||||
--time-scale-height: 50px;
|
--time-scale-height: 50px;
|
||||||
|
--sidebar-padding: 10px;
|
||||||
|
--vcd-render-padding: 24px;
|
||||||
|
/* 需要满足如下公式 --time-scale-height + --sidebar-padding = --vcd-render-padding + canvas预留 高度 */
|
||||||
--render-scale-x: 1;
|
--render-scale-x: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,10 @@ export default {
|
|||||||
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
|
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
|
||||||
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
||||||
|
|
||||||
|
// 设置全局宏
|
||||||
|
document.body.style.setProperty('--time-scale-height', '50px');
|
||||||
|
document.body.style.setProperty('--sidebar-padding', '10px');
|
||||||
|
document.body.style.setProperty('--vcd-render-padding', '24px');
|
||||||
|
|
||||||
// signal height
|
// signal height
|
||||||
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
||||||
|
@ -59,7 +59,7 @@ export default {
|
|||||||
* @param { PointerEvent } event
|
* @param { PointerEvent } event
|
||||||
*/
|
*/
|
||||||
function makeCursor(event) {
|
function makeCursor(event) {
|
||||||
console.log(event.x);
|
// console.log(event.x);
|
||||||
showFixedOne.value = true;
|
showFixedOne.value = true;
|
||||||
fixedLeft.value = event.x - boxShift;
|
fixedLeft.value = event.x - boxShift;
|
||||||
globalLookup.view.currentX = event.x - boxShift;
|
globalLookup.view.currentX = event.x - boxShift;
|
||||||
|
@ -60,20 +60,20 @@ export default {
|
|||||||
|
|
||||||
.vcd-view {
|
.vcd-view {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 24px;
|
top: var(--vcd-render-padding);
|
||||||
bottom: 24px;
|
bottom: var(--vcd-render-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-values {
|
.vcd-values {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 24px;
|
top: var(--vcd-render-padding);
|
||||||
bottom: 24px;
|
bottom: var(--vcd-render-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.wd-waveql {
|
.wd-waveql {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 24px;
|
top: var(--vcd-render-padding);
|
||||||
bottom: 24px;
|
bottom: var(--vcd-render-padding);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
transition: width .3s ease-out;
|
transition: width .3s ease-out;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<div class="vcd-control-panel-wrapper"
|
<div class="vcd-control-panel-wrapper"
|
||||||
v-for="(section, index) of controlPanel.sections" :key="index"
|
v-for="(section, index) of controlPanel.sections" :key="index"
|
||||||
@click="controlPanel.click(index)"
|
@click="controlPanel.click(index)"
|
||||||
>
|
>
|
||||||
<div :class="controlPanel.currentIndex === index ? 'vcd-control-panel-active': ''"><span
|
<div :class="controlPanel.currentIndex === index ? 'vcd-control-panel-active': ''"><span
|
||||||
class="vcd-control-panel-icon"
|
class="vcd-control-panel-icon"
|
||||||
:class="section.iconClass"
|
:class="section.iconClass"
|
||||||
@ -69,7 +69,7 @@ export default {
|
|||||||
this.currentIndex = index;
|
this.currentIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(this.currentIndex);
|
// console.log(this.currentIndex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.display-signal-wrapper {
|
.display-signal-wrapper {
|
||||||
padding: 10px;
|
padding: var(--sidebar-padding);
|
||||||
background-color: var(--sidebar);
|
background-color: var(--sidebar);
|
||||||
border: solid 1px var(--sidebar-border);
|
border: solid 1px var(--sidebar-border);
|
||||||
min-width: var(--sidebar-width);
|
min-width: var(--sidebar-width);
|
||||||
@ -173,6 +173,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signal-info-name {
|
.signal-info-name {
|
||||||
|
@ -76,9 +76,9 @@ function toggleRender(signal) {
|
|||||||
} else {
|
} else {
|
||||||
globalLookup.currentWires.add(signal);
|
globalLookup.currentWires.add(signal);
|
||||||
const signalItem = globalLookup.chango[signal.link];
|
const signalItem = globalLookup.chango[signal.link];
|
||||||
const { wave } = signalItem;
|
const { wave, kind } = signalItem;
|
||||||
const time = globalLookup.currentTime;
|
const time = globalLookup.currentTime;
|
||||||
globalLookup.currentSignalValues[signal.link] = findCurrentSignalValue(wave, time);
|
globalLookup.currentSignalValues[signal.link] = findCurrentSignalValue(kind, wave, time);
|
||||||
globalLookup.render();
|
globalLookup.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,20 +135,29 @@ function makeSearchResultItem(searchString, module, searchScope, caseSensitivity
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param {'bit' | 'vec'} kind
|
||||||
* @param {BigInt} value
|
* @param {BigInt} value
|
||||||
* @param {BigInt} mask
|
* @param {BigInt} mask
|
||||||
* @returns {number | string}
|
* @returns {number | string}
|
||||||
*/
|
*/
|
||||||
function getWireValueCaption(value, mask) {
|
function getWireValueCaption(kind, value, mask) {
|
||||||
if (!mask) {
|
if (kind === 'bit') {
|
||||||
|
if (value === 2) {
|
||||||
|
return 'x';
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
|
} else if (kind === 'vec') {
|
||||||
|
if (!mask) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
// mask 不为空,代表存在问题
|
||||||
|
if (value) {
|
||||||
|
return '?';
|
||||||
|
} else {
|
||||||
|
return 'x';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// mask 不为空,代表存在问题
|
|
||||||
if (value) {
|
|
||||||
return '?';
|
|
||||||
} else {
|
|
||||||
return 'x';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateWireCurrentValue() {
|
async function updateWireCurrentValue() {
|
||||||
@ -158,13 +167,14 @@ async function updateWireCurrentValue() {
|
|||||||
|
|
||||||
for (const signal of globalLookup.currentWires) {
|
for (const signal of globalLookup.currentWires) {
|
||||||
const signalItem = chango[signal.link];
|
const signalItem = chango[signal.link];
|
||||||
const { wave } = signalItem;
|
const { wave, kind } = signalItem;
|
||||||
|
// console.log(signalItem);
|
||||||
if (wave === undefined || wave.length === 0) {
|
if (wave === undefined || wave.length === 0) {
|
||||||
currentSignalValues[signal.link] = 'x';
|
currentSignalValues[signal.link] = 'x';
|
||||||
} else if (wave.length === 1) {
|
} else if (wave.length === 1) {
|
||||||
currentSignalValues[signal.link] = getWireValueCaption(wave[0][1], wave[0][2]);
|
currentSignalValues[signal.link] = getWireValueCaption(kind, wave[0][1], wave[0][2]);
|
||||||
} else {
|
} else {
|
||||||
currentSignalValues[signal.link] = findCurrentSignalValue(wave, time);
|
currentSignalValues[signal.link] = findCurrentSignalValue(kind, wave, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(signal.name, currentSignalValues[signal.link]);
|
// console.log(signal.name, currentSignalValues[signal.link]);
|
||||||
@ -172,11 +182,11 @@ async function updateWireCurrentValue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param {'bit' | 'vec'} kind
|
||||||
* @param {Array<Array<string | number>>} wave
|
* @param {Array<Array<string | number>>} wave
|
||||||
* @param {number} time
|
* @param {number} time
|
||||||
*/
|
*/
|
||||||
function findCurrentSignalValue(wave, time) {
|
function findCurrentSignalValue(kind, wave, time) {
|
||||||
const times = wave.map(p => p[0]);
|
const times = wave.map(p => p[0]);
|
||||||
|
|
||||||
// 二分查找,并将结果存入 i
|
// 二分查找,并将结果存入 i
|
||||||
@ -185,7 +195,7 @@ function findCurrentSignalValue(wave, time) {
|
|||||||
if (times[i] === time) {
|
if (times[i] === time) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (times[j] === time) {
|
if (times[j] <= time) {
|
||||||
i = j;
|
i = j;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -200,8 +210,7 @@ function findCurrentSignalValue(wave, time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = getWireValueCaption(wave[i][1], wave[i][2]);
|
const value = getWireValueCaption(kind, wave[i][1], wave[i][2]);
|
||||||
console.log(wave[i][1], wave[i][2]);
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const mouseMoveHandler = (cursor, content, pstate /* , render */) => {
|
|||||||
|
|
||||||
|
|
||||||
const getFullView = desc => {
|
const getFullView = desc => {
|
||||||
console.log(desc);
|
// console.log(desc);
|
||||||
if (desc.waveql) {
|
if (desc.waveql) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,38 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
||||||
event => {
|
event => {
|
||||||
const {deltaY} = event;
|
const { deltaX, deltaY } = event;
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const key = (deltaY < 0)
|
const key = (deltaY < 0)
|
||||||
? 'Ctrl+icon:scrollUp'
|
? 'Ctrl+icon:scrollUp'
|
||||||
: ((deltaY > 0) ? 'Ctrl+icon:scrollDown' : 'nop');
|
: ((deltaY > 0) ? 'Ctrl+icon:scrollDown' : 'nop');
|
||||||
if (keyBindo[key].fn(pstate)) {
|
if (keyBindo[key].fn(pstate)) {
|
||||||
if (plugins != undefined) {
|
if (plugins != undefined) {
|
||||||
plugins.map(fn => fn(key, event));
|
plugins.map(fn => fn(key, event));
|
||||||
|
}
|
||||||
|
deso.render();
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
} else if (event.shiftKey) {
|
||||||
|
const key = (deltaY < 0) ? 'Shift+icon:scrollUp' : ((deltaY > 0) ? 'Shift+icon:scrollDown' : 'nop');
|
||||||
|
if (keyBindo[key].fn(pstate)) {
|
||||||
|
if (plugins != undefined) {
|
||||||
|
plugins.map(fn => fn(key, event));
|
||||||
|
}
|
||||||
|
deso.render();
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
} else if (deltaX !== 0 && deltaY === 0) {
|
||||||
|
const key = (deltaX < 0) ? 'icon:scrollLeft': 'icon:scrollRight';
|
||||||
|
if (keyBindo[key].fn(pstate)) {
|
||||||
|
if (plugins != undefined) {
|
||||||
|
plugins.map(fn => fn(key, event));
|
||||||
|
}
|
||||||
|
deso.render();
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
deso.render();
|
};
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
} else
|
|
||||||
if (event.shiftKey) {
|
|
||||||
const key = (deltaY < 0) ? 'Shift+icon:scrollUp' : ((deltaY > 0) ? 'Shift+icon:scrollDown' : 'nop');
|
|
||||||
if (keyBindo[key].fn(pstate)) {
|
|
||||||
if (plugins != undefined) {
|
|
||||||
plugins.map(fn => fn(key, event));
|
|
||||||
}
|
|
||||||
deso.render();
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = genOnWheel;
|
module.exports = genOnWheel;
|
||||||
|
@ -1,29 +1,32 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const cColors = new Float32Array([
|
// 控制颜色
|
||||||
0, 0, 0, 0, // 0:
|
const gl_Colors = new Float32Array([
|
||||||
0, 0, 1, 1, // 1: (Z) high impedance
|
0, 0, 0, 0, // 0: 空
|
||||||
|
|
||||||
0.2, 0.847, 0.1, 1, // 2: strong 0
|
0, 0, 1, 1, // 1: 高阻态 Z
|
||||||
0.2, 0.847, 0.1, 1, // 3: strong 1
|
0.2, 0.847, 0.1, 1, // 2: value = 0 用于 width = 1 的信号
|
||||||
0.9, 0.2, 0.2, 1, // 4: (x X) strong unknown
|
0.2, 0.847, 0.1, 1, // 3: value = 1 用于 width = 1 的信号
|
||||||
|
0.9, 0.2, 0.2, 1, // 4: 未知态 X
|
||||||
|
.5, 1, 1, 1, // 5: vec 用于 width > 1 的信号
|
||||||
|
|
||||||
.5, 1, 1, 1, // 5: vec
|
1, 1, 0, 1, // 6: yellow
|
||||||
1, 1, 0, 1, // 6: yellow
|
1, 0, 1, 1, // 7: strange purple
|
||||||
1, 0, 1, 1, // 7: strange purple
|
|
||||||
|
|
||||||
0, 1, 0, .5, // 8: (l L) weak 0
|
0, 1, 0, .5, // 8: (l L) weak 0
|
||||||
0, 1, 1, .5, // 9: (h H) weak 1
|
0, 1, 1, .5, // 9: (h H) weak 1
|
||||||
1, 0, 0, .5, // 10: (w W) weak unknown
|
1, 0, 0, .5, // 10: (w W) weak unknown
|
||||||
|
|
||||||
0, 0, 0, 0, // 11:
|
0, 0, 1, 0.1, // 11: 高阻态 Z 遮罩
|
||||||
0, 0, 0, 0, // 12:
|
0.2, 0.847, 0.1, 0.1, // 12: value = 0 遮罩
|
||||||
0, 0, 0, 0, // 13:
|
0.2, 0.847, 0.1, 0.1, // 13: value = 1 遮罩
|
||||||
0, 0, 0, 0, // 14:
|
0.9, 0.2, 0.2, 0.1, // 14: 未知态 X 遮罩
|
||||||
0, 0, 0, 0 // 15:
|
.5, 1, 1, 0.1 // 15: vec 遮罩
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const cTilts = new Float32Array([ // 14
|
|
||||||
|
// 控制方向
|
||||||
|
const gl_Shifts = new Float32Array([ // 14
|
||||||
0, 0, // 0
|
0, 0, // 0
|
||||||
1, -1, // 1
|
1, -1, // 1
|
||||||
1, 0, // 2
|
1, 0, // 2
|
||||||
@ -33,92 +36,79 @@ const cTilts = new Float32Array([ // 14
|
|||||||
-1, 1 // 6
|
-1, 1 // 6
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const shaderer = (kind, src) => webgl2 => {
|
const gl_Shifts_map = new Map();
|
||||||
const vShader = webgl2.createShader(webgl2[kind]);
|
gl_Shifts_map.set(-1, 4);
|
||||||
webgl2.shaderSource(vShader, src);
|
gl_Shifts_map.set(0, 0);
|
||||||
webgl2.compileShader(vShader);
|
gl_Shifts_map.set(1, 1);
|
||||||
return vShader;
|
|
||||||
};
|
|
||||||
|
|
||||||
const vertexShaderScalar = shaderer('VERTEX_SHADER', `#version 300 es
|
const lineWidth = 0.004; // 不能写为 0.0045 这样会因为插值造成不同线段的宽度不一致的问题
|
||||||
in uvec3 pos;
|
const widthShift = lineWidth / 2;
|
||||||
|
const gl_WidthShifts = new Float32Array([
|
||||||
|
0, widthShift, // 0
|
||||||
|
- widthShift, widthShift, // 1
|
||||||
|
- widthShift, 0, // 2
|
||||||
|
- widthShift, - widthShift, // 3
|
||||||
|
0, - widthShift, // 4
|
||||||
|
widthShift, - widthShift, // 5
|
||||||
|
widthShift, 0, // 6
|
||||||
|
widthShift, widthShift // 7
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
class ShaderMaker {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {'VERTEX_SHADER' | 'FRAGMENT_SHADER'} type
|
||||||
|
* @param {string} source
|
||||||
|
*/
|
||||||
|
constructor(type, source) {
|
||||||
|
this.type = type;
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @return {WebGLShader}
|
||||||
|
*/
|
||||||
|
make(gl) {
|
||||||
|
const shader = gl.createShader(gl[this.type]);
|
||||||
|
gl.shaderSource(shader, this.source);
|
||||||
|
gl.compileShader(shader);
|
||||||
|
const ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
||||||
|
if (!ok) {
|
||||||
|
console.log('创建类型为 ' + type + ' 的着色器失败!');
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const vertexShaderScalar = new ShaderMaker('VERTEX_SHADER', `#version 300 es
|
||||||
|
in uvec4 pos;
|
||||||
out vec4 v_color;
|
out vec4 v_color;
|
||||||
uniform vec2 scale;
|
uniform vec2 scale;
|
||||||
uniform vec2 offset;
|
uniform vec2 offset;
|
||||||
uniform vec4 colors[16];
|
uniform vec4 colors[16];
|
||||||
uniform vec2 tilts[7];
|
uniform vec2 shifts[7]; // 基础八位图偏移量,为了性能,pos 只传入整数,需要的坐标负数由该值提供
|
||||||
uniform float tilt;
|
uniform vec2 widthShifts[8]; // 用于构造线宽的偏移
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
v_color = colors[pos.z];
|
v_color = colors[pos.z];
|
||||||
vec2 node = tilts[pos.y];
|
vec2 shift = shifts[pos.y];
|
||||||
|
vec2 widthShift = widthShifts[pos.w];
|
||||||
gl_Position = vec4(
|
gl_Position = vec4(
|
||||||
float(pos.x) * scale.x + offset.x + node[1] * tilt,
|
float(pos.x) * scale.x + offset.x + float(widthShift.x),
|
||||||
float(node[0]) * scale.y + offset.y,
|
float(shift.x) * scale.y + offset.y + float(widthShift.y),
|
||||||
1, 1
|
1, 1
|
||||||
);
|
);
|
||||||
}
|
}`);
|
||||||
`);
|
|
||||||
|
|
||||||
const fragmentShader = shaderer('FRAGMENT_SHADER', `#version 300 es
|
const fragmentShader = new ShaderMaker('FRAGMENT_SHADER', `#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
in vec4 v_color;
|
in vec4 v_color;
|
||||||
out vec4 myOutputColor;
|
out vec4 outColor;
|
||||||
void main() {
|
void main() {
|
||||||
myOutputColor = v_color;
|
outColor = v_color;
|
||||||
}
|
}`);
|
||||||
`);
|
|
||||||
|
|
||||||
|
|
||||||
const bar = [
|
|
||||||
(f, t, a, b, c0, c1) => [].concat( // 0
|
|
||||||
(f === 1) ? [a, 2, c1] : [],
|
|
||||||
[a, 5, c0],
|
|
||||||
[b, 5, c0],
|
|
||||||
(t > 1) ? [b, 0, c0] : []
|
|
||||||
),
|
|
||||||
(f, t, a, b, c0, c1) => [].concat( // 1
|
|
||||||
(f === 0) ? [a, 5, c0] :
|
|
||||||
(f > 1) ? [a, 0, c0] : [],
|
|
||||||
[a, 2, c1],
|
|
||||||
[b, 2, c1],
|
|
||||||
(t > 1) ? [b, 0, c0] : []
|
|
||||||
),
|
|
||||||
(f, t, a, b, c0, c1) => [a, 0, c0, b, 0, c1] // 2 = Z
|
|
||||||
];
|
|
||||||
|
|
||||||
const brick = [
|
|
||||||
(f, t, a, b, c0, c1) => [].concat( // 0
|
|
||||||
(f === 0) ? [a, 5, c0] :
|
|
||||||
(f === 1) ? [a, 1, c1] : [],
|
|
||||||
[a, 6, c0],
|
|
||||||
(t === 0) ? [b, 5, c0] :
|
|
||||||
[b, 4, c0],
|
|
||||||
(t === 3) ? [b, 0, c0] : []
|
|
||||||
),
|
|
||||||
(f, t, a, b, c0, c1) => [].concat( // 1
|
|
||||||
(f === 0) ? [a, 4, c0, a, 3, c1] :
|
|
||||||
(f === 1) ? [a, 2, c1] :
|
|
||||||
(f === 2) ? [a, 3, c1] :
|
|
||||||
[a, 0, c0, a, 3, c1],
|
|
||||||
(t === 1) ? [b, 3, c1] :
|
|
||||||
[b, 1, c1],
|
|
||||||
(t === 3) ? [b, 0, c0] : []
|
|
||||||
),
|
|
||||||
(f, t, a, b, c0, c1) => [].concat( // 2
|
|
||||||
(f === 0) ? [a, 4, 0] :
|
|
||||||
(f === 1) ? [a, 1, 0] :
|
|
||||||
[a, 0, 0],
|
|
||||||
(t === 0) ? [b, 6, 0, b, 6, c0] :
|
|
||||||
(t === 1) ? [b, 3, 0, b, 3, c1, b, 4, c0] :
|
|
||||||
[b, 0, 0, b, 0, c0, b, 4, c0],
|
|
||||||
(f === 0) ? [a, 4, c0, a, 3, c1] :
|
|
||||||
(f === 1) ? [a, 6, c0, a, 1, c1] :
|
|
||||||
[a, 6, c0, a, 0, c0, a, 3, c1],
|
|
||||||
(t === 0) ? [b, 1, c1, b, 6, c0] :
|
|
||||||
(t === 1) ? [b, 3, c1] :
|
|
||||||
[b, 1, c1, b, 0, c0]
|
|
||||||
)
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
class WebGL2WaveRender {
|
class WebGL2WaveRender {
|
||||||
@ -133,7 +123,8 @@ class WebGL2WaveRender {
|
|||||||
* chango: Record<string, {
|
* chango: Record<string, {
|
||||||
* kind: string,
|
* kind: string,
|
||||||
* wave: Array<number | string>,
|
* wave: Array<number | string>,
|
||||||
* vao: WebGLVertexArrayObject
|
* lineVao: WebGLVertexArrayObject
|
||||||
|
* maskVao: WebGLVertexArrayObject
|
||||||
* }>
|
* }>
|
||||||
* view: Array<{ ref: string }>,
|
* view: Array<{ ref: string }>,
|
||||||
* currentWires: Set<{
|
* currentWires: Set<{
|
||||||
@ -167,47 +158,49 @@ class WebGL2WaveRender {
|
|||||||
this.pstate = pstate;
|
this.pstate = pstate;
|
||||||
this.plugins = plugins;
|
this.plugins = plugins;
|
||||||
|
|
||||||
const webgl2 = canvas.getContext('webgl2', {
|
const gl = canvas.getContext('webgl2', {
|
||||||
premultipliedAlpha: false,
|
premultipliedAlpha: false,
|
||||||
alpha: true,
|
alpha: true,
|
||||||
antialias: false,
|
antialias: false,
|
||||||
depth: false
|
depth: false
|
||||||
});
|
});
|
||||||
this.webglLocation = this.initProgram(webgl2);
|
this.webglLocation = this.initProgram(gl);
|
||||||
this.verticesMap = this.makeVertex();
|
const { lineVerticesMap, maskVerticesMap } = this.makeVertex();
|
||||||
this.initData();
|
this.lineVerticesMap = lineVerticesMap;
|
||||||
|
this.maskVerticesMap = maskVerticesMap;
|
||||||
|
|
||||||
|
this.initData();
|
||||||
this.animationHandler = undefined;
|
this.animationHandler = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {WebGL2RenderingContext} webgl2
|
* @param {WebGL2RenderingContext} gl
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* colors: WebGLUniformLocation,
|
* colors: WebGLUniformLocation,
|
||||||
* tilts: WebGLUniformLocation,
|
* shifts: WebGLUniformLocation,
|
||||||
* scale: WebGLUniformLocation,
|
* scale: WebGLUniformLocation,
|
||||||
* offset: WebGLUniformLocation,
|
* offset: WebGLUniformLocation,
|
||||||
* tilt: WebGLUniformLocation,
|
|
||||||
* pos: number,
|
* pos: number,
|
||||||
* webgl2: WebGL2RenderingContext
|
* widthShifts: WebGLUniformLocation,
|
||||||
|
* gl: WebGL2RenderingContext
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
initProgram(webgl2) {
|
initProgram(gl) {
|
||||||
const program = webgl2.createProgram();
|
const program = gl.createProgram();
|
||||||
webgl2.attachShader(program, vertexShaderScalar(webgl2));
|
gl.attachShader(program, vertexShaderScalar.make(gl));
|
||||||
webgl2.attachShader(program, fragmentShader(webgl2));
|
gl.attachShader(program, fragmentShader.make(gl));
|
||||||
webgl2.linkProgram(program);
|
gl.linkProgram(program);
|
||||||
webgl2.useProgram(program);
|
gl.useProgram(program);
|
||||||
|
|
||||||
const webglLocation = {
|
const webglLocation = {
|
||||||
colors: webgl2.getUniformLocation(program, 'colors'),
|
colors: gl.getUniformLocation(program, 'colors'),
|
||||||
tilts: webgl2.getUniformLocation(program, 'tilts'),
|
shifts: gl.getUniformLocation(program, 'shifts'),
|
||||||
scale: webgl2.getUniformLocation(program, 'scale'),
|
scale: gl.getUniformLocation(program, 'scale'),
|
||||||
offset: webgl2.getUniformLocation(program, 'offset'),
|
offset: gl.getUniformLocation(program, 'offset'),
|
||||||
tilt: webgl2.getUniformLocation(program, 'tilt'),
|
pos: gl.getAttribLocation(program, 'pos'),
|
||||||
pos: webgl2.getAttribLocation(program, 'pos'),
|
widthShifts: gl.getUniformLocation(program, 'widthShifts'),
|
||||||
webgl2
|
gl
|
||||||
};
|
};
|
||||||
|
|
||||||
return webglLocation;
|
return webglLocation;
|
||||||
@ -215,68 +208,215 @@ class WebGL2WaveRender {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns {Map<string, Uint32Array>}
|
* @returns {{
|
||||||
|
* lineVerticesMap: Map<string, Uint32Array>,
|
||||||
|
* maskVerticesMap: Map<string, Uint32Array>
|
||||||
|
* }}
|
||||||
*/
|
*/
|
||||||
makeVertex() {
|
makeVertex() {
|
||||||
const globalLookup = this.globalLookup;
|
const globalLookup = this.globalLookup;
|
||||||
const time = globalLookup.time;
|
const time = globalLookup.time;
|
||||||
const verticesMap = new Map();
|
const lineVerticesMap = new Map();
|
||||||
|
const maskVerticesMap = new Map();
|
||||||
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
||||||
const signalItem = globalLookup.chango[id];
|
const signalItem = globalLookup.chango[id];
|
||||||
const { kind, wave } = signalItem;
|
const { kind, wave } = signalItem;
|
||||||
if (kind === 'bit') {
|
if (kind === 'bit') {
|
||||||
const vertices = this.makeBitVertex(wave, time);
|
const { lineVertices, maskVertices } = this.makeBitVertex(wave, time);
|
||||||
verticesMap.set(id, vertices);
|
lineVerticesMap.set(id, lineVertices);
|
||||||
|
maskVerticesMap.set(id, maskVertices);
|
||||||
} else if (kind === 'vec') {
|
} else if (kind === 'vec') {
|
||||||
const vertices = this.makeVecVertex(wave, time);
|
// const vertices = this.makeVecVertex(wave, time);
|
||||||
verticesMap.set(id, vertices);
|
// lineVerticesMap.set(id, vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { lineVerticesMap, maskVerticesMap };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 将wave 的值转化为渲染需要用到的值
|
||||||
|
* @param {*} value
|
||||||
|
* @return {{
|
||||||
|
* y: number // 裁剪空间的纵坐标
|
||||||
|
* color: number // 颜色的索引 颜色rgb = gl_Colors[color]
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
translateValue2RenderParameter(value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0: return { y: -1, color: 2 }; // 0 value
|
||||||
|
case 1: return { y: 1, color: 3 }; // 1 value
|
||||||
|
case 2: case 3: return { y: -1, color: 4 }; // 不定态 x
|
||||||
|
case 4: case 5: return { y: 0, color: 2 }; // 高阻态 z
|
||||||
|
default: return { y: -1, color: 7 }; // 其他,我也不知道还有啥
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {{x: number, y: number, color: number} | undefined} p0 前一个点
|
||||||
|
* @param {{x: number, y: number, color: number} | undefined} p1 当前的点
|
||||||
|
* @param {{x: number, y: number, color: number} | undefined} p2 后一个点
|
||||||
|
* @returns {number} 这是 widthshift 的索引,只需要 + 4 再 % 8 就能得到另一个
|
||||||
|
*/
|
||||||
|
makeWidthShiftIndexByPoints(p0, p1, p2) {
|
||||||
|
if (p0 === undefined) {
|
||||||
|
if (p1.y === p2.y) {
|
||||||
|
return 0;
|
||||||
|
} else if (p1.x === p2.x) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
} else if (p2 === undefined) {
|
||||||
|
if (p1.y === p0.y) {
|
||||||
|
return 0;
|
||||||
|
} else if (p1.x === p0.x) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p0.x !== p1.x && p0.y === p1.y && p1.x === p2.x && p1.y !== p2.y) {
|
||||||
|
if (p2.y > p1.y) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
} else if (p0.x === p1.x && p0.y !== p1.y && p1.x !== p2.x && p1.y === p2.y) {
|
||||||
|
if (p1.y > p0.y) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return verticesMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Array<string | number>} wave
|
* @param {Array<string | number>} wave
|
||||||
* @param { number } time
|
* @param { number } time
|
||||||
* @returns {Uint32Array}
|
* @returns {{
|
||||||
|
* lineVertices: Uint32Array
|
||||||
|
* maskVertices: Uint32Array
|
||||||
|
* }}
|
||||||
*/
|
*/
|
||||||
makeBitVertex(wave, time) {
|
makeBitVertex(wave, time, debug = false) {
|
||||||
const vertices = [];
|
const length = wave.length;
|
||||||
const ilen = wave.length;
|
// 先将节点数据转化为裁剪空间的坐标
|
||||||
for (let i = 0; i < ilen; i++) {
|
const perspectivePoints = [];
|
||||||
const f = wave[(i === 0) ? 0 : (i - 1)];
|
|
||||||
const [tim, val] = wave[i];
|
for (let i = 0; i < length; ++ i) {
|
||||||
const t = wave[(i === (ilen - 1)) ? i : (i + 1)];
|
// const currentWave = wave[(i === 0) ? 0 : (i - 1)];
|
||||||
const tt = (i === (ilen - 1)) ? time : wave[i + 1][0];
|
const currentWave = wave[i];
|
||||||
switch (val) {
|
const nextWave = (i === (length - 1)) ? wave[i] : wave[i + 1];
|
||||||
case 0: case 1: // 0 1
|
|
||||||
vertices.push(...bar[val](f[1], t[1], tim, tt, 2, 3));
|
const t1 = currentWave[0];
|
||||||
break;
|
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
|
||||||
case 2: case 3: // x X
|
const value1 = currentWave[1];
|
||||||
vertices.push(...bar[2](f[1], t[1], tim, tt, 4, 4));
|
const value2 = nextWave[1];
|
||||||
break;
|
|
||||||
case 4: case 5: // z Z
|
const renderParam1 = this.translateValue2RenderParameter(value1);
|
||||||
vertices.push(...bar[2](f[1], t[1], tim, tt, 1, 1));
|
const renderParam2 = this.translateValue2RenderParameter(value2);
|
||||||
break;
|
|
||||||
case 6: case 7: // u U uninitialized
|
if (i === 0) {
|
||||||
vertices.push(...bar[2](f[1], t[1], tim, tt, 6, 6));
|
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||||
break;
|
perspectivePoints.push({ x: t2, y: renderParam1.y, color: renderParam1.color });
|
||||||
case 8: case 9: // w W weak unknown
|
} else {
|
||||||
vertices.push(...bar[2](f[1], t[1], tim, tt, 10, 10));
|
const lastPoint = perspectivePoints.at(-1);
|
||||||
break;
|
if ((lastPoint.y !== renderParam1.y) || (lastPoint.color !== renderParam1.color)) {
|
||||||
case 10: case 11: // l L
|
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||||
vertices.push(...bar[0](f[1], t[1], tim, tt, 8, 9));
|
}
|
||||||
break;
|
if ((renderParam1.y !== renderParam2.y) || (renderParam1.color !== renderParam2.color)) {
|
||||||
case 12: case 13: // h H
|
perspectivePoints.push({ x: t2, y: renderParam1.y, color: renderParam1.color });
|
||||||
vertices.push(...bar[1](f[1], t[1], tim, tt, 8, 9));
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vertices.push(...bar[2](f[1], t[1], tim, tt, 7, 7));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Uint32Array(vertices);
|
// 确保最后一个点延申到了 time
|
||||||
|
const lastPoint = perspectivePoints.at(-1);
|
||||||
|
if (lastPoint.x < time) {
|
||||||
|
perspectivePoints.push({ x: time, y: lastPoint.y, color: lastPoint.color });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算出传入 shader 四元组数组
|
||||||
|
// 四元组: (x, yshift_index, color_index, width_shift_index)
|
||||||
|
const pointNum = perspectivePoints.length;
|
||||||
|
const lineVertices = [];
|
||||||
|
const maskVertices = [];
|
||||||
|
|
||||||
|
// const lineVertices = [
|
||||||
|
// 0, 0, 2, 0,
|
||||||
|
// 10, 0, 2, 0,
|
||||||
|
// 10, 4, 2, 0,
|
||||||
|
// 20, 4, 2, 0,
|
||||||
|
// 20, 0, 2, 0,
|
||||||
|
// 30, 0, 2, 0,
|
||||||
|
// 30, 4, 2, 0
|
||||||
|
// ];
|
||||||
|
// return new Uint32Array(lineVertices);
|
||||||
|
|
||||||
|
|
||||||
|
// 制作 lineVertices
|
||||||
|
for (let i = 0; i < pointNum; ++ i) {
|
||||||
|
// p0: 上一个点
|
||||||
|
// p1: 当前的点
|
||||||
|
// p2: 下一个点
|
||||||
|
const p0 = perspectivePoints[i - 1];
|
||||||
|
const p1 = perspectivePoints[i];
|
||||||
|
const p2 = perspectivePoints[i + 1];
|
||||||
|
// p1.x, y1Index, p1.color, 0,
|
||||||
|
const y1Index = gl_Shifts_map.get(p1.y);
|
||||||
|
|
||||||
|
const wsIndex = this.makeWidthShiftIndexByPoints(p0, p1, p2);
|
||||||
|
lineVertices.push(
|
||||||
|
p1.x, y1Index, p1.color, wsIndex,
|
||||||
|
p1.x, y1Index, p1.color, (wsIndex + 4) % 8
|
||||||
|
);
|
||||||
|
|
||||||
|
// 防止颜色不同导致单个图元内出现两个颜色,这会引发shader的渐变
|
||||||
|
if (p2 !== undefined && p1.color !== p2.color) {
|
||||||
|
lineVertices.push(
|
||||||
|
p1.x, y1Index, p2.color, wsIndex,
|
||||||
|
p1.x, y1Index, p2.color, (wsIndex + 4) % 8
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 制作 maskVertices
|
||||||
|
for (let i = 0; i < pointNum; ++ i) {
|
||||||
|
const p1 = perspectivePoints[i];
|
||||||
|
const p2 = perspectivePoints[i + 1];
|
||||||
|
const p3 = perspectivePoints[i + 2];
|
||||||
|
if (p1 === undefined || p2 === undefined || p3 === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p2.y > p1.y) {
|
||||||
|
// 矩形的四个点
|
||||||
|
// 四元组: (x, yshift_index, color_index, width_shift_index)
|
||||||
|
const r1 = [p1.x, gl_Shifts_map.get(p1.y), p2.color + 10, 4];
|
||||||
|
const r2 = [p2.x, gl_Shifts_map.get(p2.y), p2.color + 10, 4];
|
||||||
|
const r3 = [p3.x, gl_Shifts_map.get(p3.y), p2.color + 10, 4];
|
||||||
|
const r4 = [p3.x, gl_Shifts_map.get(p1.y), p2.color + 10, 4];
|
||||||
|
// 三角图元画矩形
|
||||||
|
maskVertices.push(
|
||||||
|
...r1, ...r2, ...r3,
|
||||||
|
...r1, ...r3, ...r4,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
console.log(perspectivePoints);
|
||||||
|
console.log(pointNum);
|
||||||
|
console.log(lineVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Uint32lineVertices = new Uint32Array(lineVertices);
|
||||||
|
const Uint32maskVertices = new Uint32Array(maskVertices);
|
||||||
|
|
||||||
|
return {
|
||||||
|
lineVertices : Uint32lineVertices,
|
||||||
|
maskVertices : Uint32maskVertices
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,13 +427,24 @@ class WebGL2WaveRender {
|
|||||||
*/
|
*/
|
||||||
makeVecVertex(wave, time) {
|
makeVecVertex(wave, time) {
|
||||||
const vertices = [];
|
const vertices = [];
|
||||||
const ilen = wave.length;
|
const length = wave.length;
|
||||||
for (let i = 0; i < ilen; i++) {
|
for (let i = 0; i < length; ++ i) {
|
||||||
const [t1, val, msk] = wave[i];
|
const [t1, val, msk] = wave[i];
|
||||||
const t2 = (i === (ilen - 1)) ? time : wave[i + 1][0];
|
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
|
||||||
|
// t1(val) --- t2(val)
|
||||||
|
|
||||||
if (msk) {
|
if (msk) {
|
||||||
vertices.push(...brick[2](2, 2, t1, t2, 4, 4)); // x,z?
|
vertices.push(
|
||||||
|
t1, 0, 0,
|
||||||
|
t2, 0, 0,
|
||||||
|
t2, 0, 4,
|
||||||
|
t2, 4, 4,
|
||||||
|
t1, 6, 4,
|
||||||
|
t1, 0, 4,
|
||||||
|
t1, 3, 4,
|
||||||
|
t2, 1, 4,
|
||||||
|
t2, 0, 4
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
vertices.push(
|
vertices.push(
|
||||||
t1, 0, 0,
|
t1, 0, 0,
|
||||||
@ -315,26 +466,48 @@ class WebGL2WaveRender {
|
|||||||
|
|
||||||
initData() {
|
initData() {
|
||||||
const webglLocation = this.webglLocation;
|
const webglLocation = this.webglLocation;
|
||||||
const webgl2 = webglLocation.webgl2;
|
const gl = webglLocation.gl;
|
||||||
const globalLookup = this.globalLookup;
|
const globalLookup = this.globalLookup;
|
||||||
const verticesMap = this.verticesMap;
|
const lineVerticesMap = this.lineVerticesMap;
|
||||||
|
const maskVerticesMap = this.maskVerticesMap;
|
||||||
|
|
||||||
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
||||||
const signalItem = globalLookup.chango[id];
|
const signalItem = globalLookup.chango[id];
|
||||||
const vertices = verticesMap.get(id);
|
|
||||||
|
|
||||||
const vertexBuffer = webgl2.createBuffer();
|
const lineVertices = lineVerticesMap.get(id);
|
||||||
webgl2.bindBuffer(webgl2.ARRAY_BUFFER, vertexBuffer);
|
if (lineVertices === undefined) {
|
||||||
// 将初始化的顶点数据复制到 buffer 区域
|
// console.warn(`无法找到 link 为 ${id} 的顶点数据`);
|
||||||
webgl2.bufferData(webgl2.ARRAY_BUFFER, vertices, webgl2.STATIC_DRAW);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
signalItem.vao = webgl2.createVertexArray();
|
// 创建并设置 绘制wave轮廓 主体轮廓的 缓冲区、vao、顶点设置
|
||||||
webgl2.bindVertexArray(signalItem.vao);
|
const lineVertexBuffer = gl.createBuffer();
|
||||||
webgl2.vertexAttribIPointer(webglLocation.pos, 3, webgl2.UNSIGNED_INT, 0, 0);
|
gl.bindBuffer(gl.ARRAY_BUFFER, lineVertexBuffer);
|
||||||
webgl2.enableVertexAttribArray(webglLocation.pos);
|
gl.bufferData(gl.ARRAY_BUFFER, lineVertices, gl.STATIC_DRAW);
|
||||||
webgl2.uniform4fv(webglLocation.colors, cColors);
|
signalItem.lineVao = gl.createVertexArray();
|
||||||
webgl2.uniform2fv(webglLocation.tilts, cTilts);
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
|
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||||
|
gl.enableVertexAttribArray(webglLocation.pos);
|
||||||
|
|
||||||
|
|
||||||
|
const maskVertices = maskVerticesMap.get(id);
|
||||||
|
if (maskVertices === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建并设置 绘制wave半透明遮罩层 主体轮廓的 缓冲区、vao、顶点设置
|
||||||
|
const maskVertexBuffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, maskVertexBuffer);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, maskVertices, gl.STATIC_DRAW);
|
||||||
|
signalItem.maskVao = gl.createVertexArray();
|
||||||
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
|
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||||
|
gl.enableVertexAttribArray(webglLocation.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.uniform4fv(webglLocation.colors, gl_Colors);
|
||||||
|
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
|
||||||
|
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -344,42 +517,74 @@ class WebGL2WaveRender {
|
|||||||
|
|
||||||
const canvas = this.canvas;
|
const canvas = this.canvas;
|
||||||
const webglLocation = this.webglLocation;
|
const webglLocation = this.webglLocation;
|
||||||
const webgl2 = webglLocation.webgl2;
|
const gl = webglLocation.gl;
|
||||||
const globalLookup = this.globalLookup;
|
const globalLookup = this.globalLookup;
|
||||||
const verticesMap = this.verticesMap;
|
const lineVerticesMap = this.lineVerticesMap;
|
||||||
|
const maskVerticesMap = this.maskVerticesMap;
|
||||||
const elements = this.elements;
|
const elements = this.elements;
|
||||||
|
|
||||||
|
const timeScaleHeight = parseInt(document.body.style.getPropertyValue('--time-scale-height').match(/\d+/)[0]);
|
||||||
|
const sidebarPadding = parseInt(document.body.style.getPropertyValue('--sidebar-padding').match(/\d+/)[0]);
|
||||||
|
const vcdRenderPadding = parseInt(document.body.style.getPropertyValue('--vcd-render-padding').match(/\d+/)[0]);
|
||||||
|
const canvasPaddingTop = timeScaleHeight + sidebarPadding - vcdRenderPadding;
|
||||||
|
|
||||||
this.animationHandler = window.requestAnimationFrame(() => {
|
this.animationHandler = window.requestAnimationFrame(() => {
|
||||||
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate;
|
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate;
|
||||||
const canvasHeight = height - 40;
|
const canvasHeight = height - canvasPaddingTop;
|
||||||
canvas.width = width;
|
const canvasWidth = width;
|
||||||
|
|
||||||
|
// 默认 1594
|
||||||
|
canvas.width = canvasWidth;
|
||||||
|
|
||||||
|
// 默认 1260
|
||||||
canvas.height = canvasHeight;
|
canvas.height = canvasHeight;
|
||||||
|
|
||||||
// 设置 glsl 变量
|
// 设置 glsl 变量
|
||||||
webgl2.uniform1f(webglLocation.tilt, 3 / width);
|
gl.uniform2f(webglLocation.scale,
|
||||||
webgl2.uniform2f(webglLocation.scale, 2 * xScale / width, yStep * yDuty / canvasHeight);
|
2 * xScale / canvasWidth,
|
||||||
|
yStep * yDuty / canvasHeight
|
||||||
|
);
|
||||||
|
console.log(yStep, yDuty, canvasHeight);
|
||||||
// 设置 webgl 和 canvas 大小位置一致
|
// 设置 webgl 和 canvas 大小位置一致
|
||||||
webgl2.viewport(0, 0, width, canvasHeight);
|
gl.viewport(0, 0, canvasWidth, canvasHeight);
|
||||||
// 清楚颜色缓冲区,也就是删除上一次的渲染结果
|
// 清楚颜色缓冲区,也就是删除上一次的渲染结果
|
||||||
webgl2.clear(webgl2.COLOR_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
// 根据 globalLookup 当前激活的需要渲染的信号进行渲染
|
// 根据 globalLookup 当前激活的需要渲染的信号进行渲染
|
||||||
let index = 0;
|
let index = 0;
|
||||||
for (const signal of globalLookup.currentWires) {
|
for (const signal of globalLookup.currentWires) {
|
||||||
|
const wave = globalLookup.chango[signal.link].wave;
|
||||||
|
// this.makeBitVertex(wave, globalLookup.time, true);
|
||||||
const signalItem = globalLookup.chango[signal.link];
|
const signalItem = globalLookup.chango[signal.link];
|
||||||
if (!signalItem) {
|
if (!signalItem) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
webgl2.bindVertexArray(signalItem.vao);
|
// TODO: 将此处的 offset 计算中的参数和 globalSetting 的数字形成关联
|
||||||
webgl2.uniform2f(webglLocation.offset,
|
gl.uniform2f(webglLocation.offset,
|
||||||
(2 * xOffset / width) - 1,
|
(2 * xOffset / width) - 1,
|
||||||
(2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1
|
(2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1
|
||||||
);
|
);
|
||||||
// 根据 vao 进行绘制
|
|
||||||
const vertices = verticesMap.get(signal.link);
|
|
||||||
// console.log(vertices);
|
console.log('offset y', (2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1);
|
||||||
webgl2.drawArrays(webgl2.LINE_STRIP, 0, vertices.length / 3);
|
|
||||||
|
// 根据 lineVao 进行绘制
|
||||||
|
const lineVertices = lineVerticesMap.get(signal.link);
|
||||||
|
const maskVertices = maskVerticesMap.get(signal.link);
|
||||||
|
|
||||||
|
if (signal.size === 1) {
|
||||||
|
// 如果是 width 为 1 的
|
||||||
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / 4);
|
||||||
|
``
|
||||||
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / 4);
|
||||||
|
} else {
|
||||||
|
// 如果是 width 大于 1 的
|
||||||
|
gl.drawArrays(gl.LINE_STRIP, 0, lineVertices.length / 4);
|
||||||
|
}
|
||||||
|
|
||||||
index ++;
|
index ++;
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,8 @@ const genResizeHandler = pstate =>
|
|||||||
yOffset = yOffsetMax;
|
yOffset = yOffsetMax;
|
||||||
}
|
}
|
||||||
pstate.yOffset = yOffset;
|
pstate.yOffset = yOffset;
|
||||||
// console.log('resize handler', pstate);
|
|
||||||
// X
|
|
||||||
// const xScaleMin = pstate.xScaleMin = (width - sidebarWidth) / time;
|
|
||||||
const xScaleMin = pstate.xScaleMin = 0.001;
|
const xScaleMin = pstate.xScaleMin = 0.001;
|
||||||
console.log(width, sidebarWidth);
|
|
||||||
console.log('xScaleMin', xScaleMin);
|
|
||||||
pstate.xScale = (xScale < xScaleMin) ? xScaleMin : xScale;
|
pstate.xScale = (xScale < xScaleMin) ? xScaleMin : xScale;
|
||||||
xOffsetUpdate(pstate, xOffset);
|
xOffsetUpdate(pstate, xOffset);
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,6 @@ const getLabel = (lane) => {
|
|||||||
const formatter = format(fmt, width);
|
const formatter = format(fmt, width);
|
||||||
|
|
||||||
return (value, mask, x, w) => {
|
return (value, mask, x, w) => {
|
||||||
console.log(value, mask, x, w);
|
|
||||||
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
@ -52,9 +52,8 @@ const editable = {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Alt + <, >. left / right
|
// Alt + <, >. left / right
|
||||||
'Alt+,': scroll.left, 'Shift+icon:scrollUp': scroll.left,
|
'Alt+,': scroll.left,
|
||||||
|
'Alt+.': scroll.right,
|
||||||
'Alt+.': scroll.right, 'Shift+icon:scrollDown': scroll.right,
|
|
||||||
|
|
||||||
// Alt + [ ] home / end
|
// Alt + [ ] home / end
|
||||||
'Alt+[': { desc: 'Jump to beginning of time', fn: pstate => xOffsetUpdate(pstate, pstate.sidebarWidth) }, // Home
|
'Alt+[': { desc: 'Jump to beginning of time', fn: pstate => xOffsetUpdate(pstate, pstate.sidebarWidth) }, // Home
|
||||||
@ -63,15 +62,18 @@ module.exports = {
|
|||||||
|
|
||||||
// ALT + - +
|
// ALT + - +
|
||||||
'Alt+=': pluso, // '+': pluso, '=': pluso,
|
'Alt+=': pluso, // '+': pluso, '=': pluso,
|
||||||
'Ctrl+icon:scrollUp': pluso,
|
|
||||||
|
|
||||||
'Alt+-': minuso, // '-': minuso, '_': minuso,
|
'Alt+-': minuso, // '-': minuso, '_': minuso,
|
||||||
'Ctrl+icon:scrollDown': minuso,
|
|
||||||
|
|
||||||
'Alt+0': fullo, // 'Shift+f': fullo, F: fullo, 'Shift+F': fullo,
|
'Alt+0': fullo, // 'Shift+f': fullo, F: fullo, 'Shift+F': fullo,
|
||||||
|
|
||||||
'Alt+/': editable,
|
'Alt+/': editable,
|
||||||
|
|
||||||
|
// wheel
|
||||||
|
'icon:scrollLeft': scroll.left,
|
||||||
|
'icon:scrollRight': scroll.right,
|
||||||
|
'Shift+icon:scrollUp': scroll.left,
|
||||||
|
'Shift+icon:scrollDown': scroll.right,
|
||||||
|
'Ctrl+icon:scrollUp': pluso,
|
||||||
|
'Ctrl+icon:scrollDown': minuso,
|
||||||
|
|
||||||
// CAN'T DO: Alt + e, d, f, l
|
// CAN'T DO: Alt + e, d, f, l
|
||||||
|
|
||||||
// ArrowUp: scroll.up, 'Shift+ArrowUp': scroll.up,
|
// ArrowUp: scroll.up, 'Shift+ArrowUp': scroll.up,
|
||||||
|
@ -91,7 +91,7 @@ function* renderValues(desc, pstate) {
|
|||||||
|
|
||||||
const [tCur, vCur, mCur] = (mark || [desc.time, 0, 0]);
|
const [tCur, vCur, mCur] = (mark || [desc.time, 0, 0]);
|
||||||
const xCur = getX(pstate, tCur);
|
const xCur = getX(pstate, tCur);
|
||||||
console.log(mark, vPre, mPre, vCur, mCur);
|
// console.log(mark, vPre, mPre, vCur, mCur);
|
||||||
|
|
||||||
if (vPre !== undefined || mPre !== undefined) {
|
if (vPre !== undefined || mPre !== undefined) {
|
||||||
if (xPre > width && xCur > width) { // both time stamps to the right
|
if (xPre > width && xCur > width) { // both time stamps to the right
|
||||||
@ -111,9 +111,7 @@ function* renderValues(desc, pstate) {
|
|||||||
}
|
}
|
||||||
xPre = xCur;
|
xPre = xCur;
|
||||||
vPre = vCur;
|
vPre = vCur;
|
||||||
console.log(mPre, mCur);
|
|
||||||
mPre = mCur;
|
mPre = mCur;
|
||||||
console.log(mPre, mCur);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ml.push(mLane);
|
ml.push(mLane);
|
||||||
|
@ -33,7 +33,7 @@ const progress = (lane, desc, pstate) => {
|
|||||||
|
|
||||||
|
|
||||||
if (desc.chango[clock.ref] === undefined) {
|
if (desc.chango[clock.ref] === undefined) {
|
||||||
console.log(desc.chango, clock, clock.ref);
|
// console.log(desc.chango, clock, clock.ref);
|
||||||
return pco;
|
return pco;
|
||||||
}
|
}
|
||||||
const clockWave = desc.chango[clock.ref].wave;
|
const clockWave = desc.chango[clock.ref].wave;
|
||||||
|
@ -6,6 +6,7 @@ import zh from './zh.json';
|
|||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
legacy: false,
|
legacy: false,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
|
warnHtmlMessage: false,
|
||||||
messages: { en, zh }
|
messages: { en, zh }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
1
test/render-line/delaunator.min.js
vendored
Normal file
1
test/render-line/delaunator.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
test/render-line/fragment.shader.glsl
Normal file
9
test/render-line/fragment.shader.glsl
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
uniform vec4 a_color;
|
||||||
|
out vec4 outColor;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
outColor = a_color;
|
||||||
|
}
|
24
test/render-line/index.html
Normal file
24
test/render-line/index.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" height="500", width="500"></canvas>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<script src="./main.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
#canvas {
|
||||||
|
top: 20px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
278
test/render-line/main.js
Normal file
278
test/render-line/main.js
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/**
|
||||||
|
* @description 创建着色器对象
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @param {'VERTEX_SHADER' | 'FRAGMENT_SHADER'} type
|
||||||
|
* @param {string} source
|
||||||
|
* @return { WebGLShader | undefined }
|
||||||
|
*/
|
||||||
|
function makeShader(gl, type, source) {
|
||||||
|
// 创建 shader
|
||||||
|
const shader = gl.createShader(gl[type]);
|
||||||
|
// 给 shader 提供 glsl 代码
|
||||||
|
gl.shaderSource(shader, source);
|
||||||
|
// 编译 glsl 生成 shader
|
||||||
|
gl.compileShader(shader);
|
||||||
|
const ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
|
||||||
|
// 如果成功,则返回 shader,否则返回 undefined
|
||||||
|
return ok ? shader : gl.deleteShader(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} path
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
async function getSource(path) {
|
||||||
|
const response = await fetch(path);
|
||||||
|
const source = await response.text();
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.onload = async () => {
|
||||||
|
const canvas = document.getElementById('canvas');
|
||||||
|
const gl = canvas.getContext('webgl2');
|
||||||
|
|
||||||
|
if (!(gl instanceof WebGL2RenderingContext)) {
|
||||||
|
console.log('浏览器不支持 webgl2');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vertexSource = await getSource('./vertex.shader.glsl');
|
||||||
|
const fragementSource = await getSource('./fragment.shader.glsl');
|
||||||
|
const vertexShader = makeShader(gl, 'VERTEX_SHADER', vertexSource);
|
||||||
|
const fragmentShader = makeShader(gl, 'FRAGMENT_SHADER', fragementSource);
|
||||||
|
if (!vertexShader || !fragmentShader) {
|
||||||
|
console.log('着色器创建失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const program = createProgram(gl, vertexShader, fragmentShader);
|
||||||
|
if (!program) {
|
||||||
|
console.log('着色程序创建失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
|
||||||
|
gl.clearColor(0, 0, 0, 0);
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
const points = [
|
||||||
|
0, -0.5,
|
||||||
|
0.5, -0.5,
|
||||||
|
];
|
||||||
|
|
||||||
|
drawMask(gl, program, points, { width: 0.06 });
|
||||||
|
drawLine2D(gl, program, points, { width: 0.06 });
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTheSameLine(x0, y0, x1, y1, x2, y2) {
|
||||||
|
const slope1 = (x1 - x0) !== 0 ? (y1 - y0) / (x1 - x0) : Infinity;
|
||||||
|
const slope2 = (x2 - x0) !== 0 ? (y2 - y0) / (x2 - x0) : Infinity;
|
||||||
|
|
||||||
|
return slope1 === slope2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sgn(value) {
|
||||||
|
if (value === 0) return 0;
|
||||||
|
return value > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @param {WebGLProgram} program
|
||||||
|
* @param {number[]} points
|
||||||
|
* @param {{
|
||||||
|
* width: number
|
||||||
|
* color: string
|
||||||
|
* }} config
|
||||||
|
*/
|
||||||
|
function drawLine2D(gl, program, points, config) {
|
||||||
|
const pointNum = points.length >> 1;
|
||||||
|
const w = config.width;
|
||||||
|
const shift = w / 2;
|
||||||
|
const positions = [];
|
||||||
|
for (let i = 0; i < pointNum; ++ i) {
|
||||||
|
const x1 = points[(i << 1)];
|
||||||
|
const y1 = points[(i << 1) + 1];
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
const x2 = points[((i + 1) << 1)];
|
||||||
|
const y2 = points[((i + 1) << 1) + 1];
|
||||||
|
if (y1 === y2) {
|
||||||
|
// console.log('enter i = 0');
|
||||||
|
positions.push(
|
||||||
|
x1, y1 + shift, // v0
|
||||||
|
x1, y1 - shift // v1
|
||||||
|
);
|
||||||
|
} else if (x1 === x2) {
|
||||||
|
positions.push(
|
||||||
|
x1 + shift, y1, // v1
|
||||||
|
x1 - shift, y1, // v0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (i === pointNum - 1) {
|
||||||
|
const x0 = points[((i - 1) << 1)];
|
||||||
|
const y0 = points[((i - 1) << 1) + 1];
|
||||||
|
if (y1 === y0) {
|
||||||
|
// console.log('enter i = pointNum - 1');
|
||||||
|
positions.push(
|
||||||
|
x1, y1 + shift, // v0
|
||||||
|
x1, y1 - shift // v1
|
||||||
|
);
|
||||||
|
} else if (x1 === x0) {
|
||||||
|
positions.push(
|
||||||
|
x1 + shift, y1, // v1
|
||||||
|
x1 - shift, y1, // v0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const x0 = points[((i - 1) << 1)];
|
||||||
|
const y0 = points[((i - 1) << 1) + 1];
|
||||||
|
const x2 = points[((i + 1) << 1)];
|
||||||
|
const y2 = points[((i + 1) << 1) + 1];
|
||||||
|
|
||||||
|
if (x0 !== x1 && y0 === y1 && x1 === x2 && y1 !== y2) {
|
||||||
|
const d = sgn(y2 - y1);
|
||||||
|
if (y2 > y1) {
|
||||||
|
positions.push(
|
||||||
|
x1 - shift, y1 + shift,
|
||||||
|
x1 + shift, y1 - shift
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
positions.push(
|
||||||
|
x1 + shift, y1 + shift,
|
||||||
|
x1 - shift, y1 - shift,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (x0 === x1 && y0 !== y1 && x1 !== x2 && y1 === y2) {
|
||||||
|
const d = sgn(y1 - y0);
|
||||||
|
if (y1 > y0) {
|
||||||
|
positions.push(
|
||||||
|
x1 - shift, y1 + shift,
|
||||||
|
x1 + shift, y1 - shift,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
positions.push(
|
||||||
|
x1 + shift, y1 + shift,
|
||||||
|
x1 - shift, y1 - shift,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const positionFloat32 = new Float32Array(positions);
|
||||||
|
const buffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, positionFloat32, gl.STATIC_DRAW);
|
||||||
|
gl.useProgram(program);
|
||||||
|
const positionLocation = gl.getAttribLocation(program, 'a_position');
|
||||||
|
const colorLocation = gl.getUniformLocation(program, 'a_color');
|
||||||
|
gl.uniform4f(colorLocation, 0.4, 0.0, 1.0, 1.0);
|
||||||
|
gl.enableVertexAttribArray(positionLocation);
|
||||||
|
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
||||||
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, positionFloat32.length >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @param {WebGLProgram} program
|
||||||
|
* @param {number[]} times
|
||||||
|
* @param {{
|
||||||
|
* width: number
|
||||||
|
* color: string
|
||||||
|
* }} config
|
||||||
|
* @param {number} yshift
|
||||||
|
*/
|
||||||
|
function drawBlock(gl, program, times, config, yshift) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @param {WebGLProgram} program
|
||||||
|
* @param {number[]} points
|
||||||
|
* @param {{
|
||||||
|
* width: number
|
||||||
|
* color: string
|
||||||
|
* }} config
|
||||||
|
*/
|
||||||
|
function drawMask(gl, program, points, config) {
|
||||||
|
const positions = [];
|
||||||
|
const pointNum = points.length >> 1;
|
||||||
|
const w = config.width;
|
||||||
|
const shift = w / 2;
|
||||||
|
for (let i = 0; i < pointNum; ++ i) {
|
||||||
|
const x1 = points[(i << 1)];
|
||||||
|
const y1 = points[(i << 1) + 1];
|
||||||
|
if (i + 1 < pointNum) {
|
||||||
|
const x2 = points[((i + 1) << 1)];
|
||||||
|
const y2 = points[((i + 1) << 1) + 1];
|
||||||
|
if (y2 > y1 && i + 2 < pointNum) {
|
||||||
|
const x3 = points[((i + 2) << 1)];
|
||||||
|
const y3 = points[((i + 2) << 1) + 1];
|
||||||
|
const p1 = [x1, y1 - shift];
|
||||||
|
const p2 = [x2, y2 - shift];
|
||||||
|
const p3 = [x3, y3 - shift];
|
||||||
|
const p4 = [x3, y1 - shift];
|
||||||
|
|
||||||
|
positions.push(
|
||||||
|
...p1,
|
||||||
|
...p2,
|
||||||
|
...p3,
|
||||||
|
...p1,
|
||||||
|
...p3,
|
||||||
|
...p4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const positionFloat32 = new Float32Array(positions);
|
||||||
|
const buffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, positionFloat32, gl.STATIC_DRAW);
|
||||||
|
gl.useProgram(program);
|
||||||
|
|
||||||
|
const aPostionLocation = gl.getAttribLocation(program, 'a_position');
|
||||||
|
const colorLocation = gl.getUniformLocation(program, 'a_color');
|
||||||
|
gl.uniform4f(colorLocation, 0.4, 0.0, 1.0, 0.2);
|
||||||
|
|
||||||
|
gl.enable(gl.BLEND);
|
||||||
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(aPostionLocation);
|
||||||
|
gl.vertexAttribPointer(aPostionLocation, 2, gl.FLOAT, false, 0, 0);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, positionFloat32.length >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 创建着色器
|
||||||
|
* @param {WebGL2RenderingContext} gl
|
||||||
|
* @param {WebGLShader} vertexShader
|
||||||
|
* @param {WebGLShader} fragmentShader
|
||||||
|
* @return { WebGLProgram | undefined }
|
||||||
|
*/
|
||||||
|
function createProgram(gl, vertexShader, fragmentShader) {
|
||||||
|
// 创建着色程序
|
||||||
|
const program = gl.createProgram();
|
||||||
|
// 加载着色器到着色程序
|
||||||
|
gl.attachShader(program, vertexShader);
|
||||||
|
gl.attachShader(program, fragmentShader);
|
||||||
|
// 连接着色程序
|
||||||
|
gl.linkProgram(program);
|
||||||
|
const ok = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||||
|
|
||||||
|
return ok ? program : gl.deleteProgram(program);
|
||||||
|
}
|
7
test/render-line/vertex.shader.glsl
Normal file
7
test/render-line/vertex.shader.glsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
in vec4 a_position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = a_position;
|
||||||
|
}
|
655
test/render-line/webgl.drawio
Normal file
655
test/render-line/webgl.drawio
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram id="fareUikBvdjO0hJmng89" name="第 1 页">
|
||||||
|
<mxGraphModel dx="1683" dy="929" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="101" value="\[p_1\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1340" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="94" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f0a30a;fontColor=#000000;strokeColor=#BD7000;opacity=30;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1090" y="802.5" width="150" height="267.5" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="345" y="545" as="sourcePoint"/>
|
||||||
|
<mxPoint x="345" y="385" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="\[p_2=(x_2,y_2)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="290" y="350" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" value="\[p_0=(x_0,y_0)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="50" y="540" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="105" y="545" as="sourcePoint"/>
|
||||||
|
<mxPoint x="345" y="545" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="6" value="\[p_1=(x_1,y_1)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="290" y="540" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="7" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="95" y="600" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="390" y="600" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="9" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="95" y="480" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="270" y="480" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="11" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="270" y="380" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="14" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="390" y="380" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="16" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="584" y="360" as="sourcePoint"/>
|
||||||
|
<mxPoint x="914" y="360" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" value="\[p_2=(x_2,y_2)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="890" y="350" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" value="\[p_0=(x_0,y_0)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="530" y="545" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="19" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="585" y="550" as="sourcePoint"/>
|
||||||
|
<mxPoint x="585" y="360" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="20" value="\[p_1=(x_1,y_1)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="480" y="340" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="21" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="620" y="545" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="22" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="900" y="310" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="525" y="545" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="24" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="620" y="390" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="25" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="525" y="310" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="26" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="900" y="390" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="28" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="360.0000000000001" y="875.0000000000001" as="sourcePoint"/>
|
||||||
|
<mxPoint x="360" y="1050" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="29" value="\[p_2=(x_2,y_2)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="320" y="1060" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="30" value="\[p_0=(x_0,y_0)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="50" y="870" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="31" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="105" y="875.0000000000001" as="sourcePoint"/>
|
||||||
|
<mxPoint x="360" y="875" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" value="\[p_1=(x_1,y_1)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="290" y="830" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="33" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="95" y="930" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="34" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="290" y="1030" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="35" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="95" y="810" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="36" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="400" y="810" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="37" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="290" y="930" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="38" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="400" y="1030" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="W18mgVVtD26MayaxvlpH-38" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint y="490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="80" y="490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="W18mgVVtD26MayaxvlpH-39" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint y="609.58" as="sourcePoint"/>
|
||||||
|
<mxPoint x="80" y="609.58" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="W18mgVVtD26MayaxvlpH-40" value="" style="endArrow=classic;startArrow=classic;html=1;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="40" y="610" as="sourcePoint"/>
|
||||||
|
<mxPoint x="40" y="490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="W18mgVVtD26MayaxvlpH-41" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="-10" y="520" width="50" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="40" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1" source="126">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="825" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1090" y="1070" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="44" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1" target="42">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="824.9999999999998" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1094.9999999999998" y="1070" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="47" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="42" target="46">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="49" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="42" target="48">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="51" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="42" target="50">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="54" style="edgeStyle=none;html=1;exitX=0;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="56">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="764.9999999999998" y="1010" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="55" style="edgeStyle=none;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="57">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="764.9999999999998" y="1130" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="90" style="edgeStyle=none;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="89">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="42" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="815" y="1060" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="46" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="815" y="960" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="48" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="715" y="1060" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="50" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="815" y="1160" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="56" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="715" y="960" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="57" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="715" y="1160" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="58" value="\[(0, \frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="770" y="925" width="110" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="59" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="870" y="1450" as="sourcePoint"/>
|
||||||
|
<mxPoint x="670" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="60" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="670" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="670" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="61" value="\[p_0\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="62" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="670" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="63" value="\[p_1\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="880" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="64" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="910" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1330" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="65" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1070" y="1330" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1330" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="66" value="\[p_2\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="880" y="1300" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="67" value="\[p_3\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1040" y="1300" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="68" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="870" y="1450" as="sourcePoint"/>
|
||||||
|
<mxPoint x="670" y="1530" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="69" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="910" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="670" y="1530" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="70" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="910" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="870" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="71" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="910" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="950" y="1490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="72" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="870" y="1450" as="sourcePoint"/>
|
||||||
|
<mxPoint x="870" y="1330" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="73" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="870" y="1330" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1290" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="74" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="950" y="1370" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="75" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1070" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="950" y="1370" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="76" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1070" y="1290" as="sourcePoint"/>
|
||||||
|
<mxPoint x="904" y="1290" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="77" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1070" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1070" y="1290" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="78" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="870" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="79" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="870" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="80" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="870" y="1330" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="81" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1290" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="82" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="950" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1070" y="1290" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="83" value="\[p_0\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="84" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="670" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="910" y="1490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="85" value="\[(-\frac{w}{2}<br>, \frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="635" y="920" width="100" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="86" value="\[(-\frac{w}{2}, 0<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="620" y="1050" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="87" value="\[(-\frac{w}{2}<br>, -\frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="630" y="1175" width="100" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="88" value="\[(0, -\frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="765" y="1190" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="89" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="905" y="1160" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="91" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1089.999999999967" y="1069.6599999999999" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1090" y="800" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="92" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1240" y="800" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1090" y="800" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="93" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1240" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1240" y="800" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="95" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1370" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1240" y="1070" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="96" value="\[(\frac{w}{2}<br>, -\frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="930" y="1175" width="100" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="97" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1329.9999999999998" y="1449.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1129.9999999999998" y="1449.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="98" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1129.9999999999998" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1129.9999999999998" y="1449.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="99" value="\[p_0\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1100" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="100" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1129.9999999999998" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1369.9999999999998" y="1490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="102" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1369.9999999999998" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1369.9999999999998" y="1329.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="103" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1530" y="1329.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1369.9999999999998" y="1329.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="104" value="\[p_2\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1340" y="1300" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="105" value="\[p_3\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1500" y="1300" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="106" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1329.9999999999998" y="1449.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1129.9999999999998" y="1530" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="107" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1410" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1129.9999999999998" y="1530" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="110" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1329.9999999999998" y="1449.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1330" y="1270" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="111" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1410" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1409.9999999999998" y="1369.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="112" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1530" y="1369.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1409.9999999999998" y="1369.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="115" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1410" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1329.9999999999998" y="1449.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="117" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1129.9999999999998" y="1490" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1369.9999999999998" y="1490" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="118" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1530" y="1280" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1330" y="1279.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="119" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1530" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1530" y="1279.5799999999997" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="120" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1410" y="1370" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1330" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="121" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1410" y="1369.9999999999998" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1330" y="1280" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="122" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="1530" y="1280" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1410" y="1369.9999999999998" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="116" value="\[p_0\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1100" y="1490" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="123" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="905" y="960" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="124" value="" style="edgeStyle=none;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="123">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="970" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="970" y="990" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="125" value="\[(\frac{w}{2}<br>, \frac{w}{2})\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="920" y="915" width="100" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="127" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1" source="42" target="126">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="835" y="1070" as="sourcePoint"/>
|
||||||
|
<mxPoint x="1090" y="1070" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="126" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#000000;fillColor=#f0a30a;strokeColor=#BD7000;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="905" y="1060" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="128" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="925" y="1035" width="110" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="129" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="540" y="969.42" as="sourcePoint"/>
|
||||||
|
<mxPoint x="620" y="969.42" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="130" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="540" y="1174" as="sourcePoint"/>
|
||||||
|
<mxPoint x="620" y="1174" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="131" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="580" y="1170" as="sourcePoint"/>
|
||||||
|
<mxPoint x="580" y="969.42" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="132" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="520" y="1040" width="50" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="133" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="570" y="1450" as="sourcePoint"/>
|
||||||
|
<mxPoint x="650" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="134" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="570" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="650" y="1530" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="135" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="610" y="1530" as="sourcePoint"/>
|
||||||
|
<mxPoint x="610" y="1450" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="136" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="550" y="1460" width="50" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
<diagram id="ldzhMOmdS79g5s7hsVNb" name="第 2 页">
|
||||||
|
<mxGraphModel dx="1345" dy="451" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-1" value="\[p_0=(x_0,y_0)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="120" y="500" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="120" y="520" as="sourcePoint"/>
|
||||||
|
<mxPoint x="160" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-3" value="\[p_1=(x_1,y_1)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="440" y="500" width="110" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-4" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="810" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-5" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="485" y="810" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-6" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="690" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-7" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="485" y="690" width="20" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-8" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="120" y="520" as="sourcePoint"/>
|
||||||
|
<mxPoint x="160" y="640" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-9" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="160" y="400" as="sourcePoint"/>
|
||||||
|
<mxPoint x="400" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-10" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="160" y="640" as="sourcePoint"/>
|
||||||
|
<mxPoint x="400" y="640" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="0KlvA6460LBpeT4quUVe-11" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="400" y="400" as="sourcePoint"/>
|
||||||
|
<mxPoint x="440" y="520" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="YzxP9u1fmLVgk9Jru_4W-1" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="-40" y="400" as="sourcePoint"/>
|
||||||
|
<mxPoint x="140" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="YzxP9u1fmLVgk9Jru_4W-2" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="-40" y="640" as="sourcePoint"/>
|
||||||
|
<mxPoint x="120" y="639.9999999999999" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="YzxP9u1fmLVgk9Jru_4W-3" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="80" y="640" as="sourcePoint"/>
|
||||||
|
<mxPoint x="80" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="YzxP9u1fmLVgk9Jru_4W-4" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="20" y="480" width="50" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="YzxP9u1fmLVgk9Jru_4W-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="400" y="640.0000000000001" as="sourcePoint"/>
|
||||||
|
<mxPoint x="440" y="520" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
7
test/shader/fragment.glsl
Normal file
7
test/shader/fragment.glsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
in vec4 v_color;
|
||||||
|
out vec4 outColor;
|
||||||
|
void main() {
|
||||||
|
outColor = v_color;
|
||||||
|
}
|
@ -7,11 +7,11 @@ uniform vec4 colors[16];
|
|||||||
uniform vec2 tilts[7];
|
uniform vec2 tilts[7];
|
||||||
uniform float tilt;
|
uniform float tilt;
|
||||||
void main() {
|
void main() {
|
||||||
v_color = colors[pos.z];
|
v_color = colors[pos.z];
|
||||||
vec2 node = tilts[pos.y];
|
vec2 node = tilts[pos.y];
|
||||||
gl_Position = vec4(
|
gl_Position = vec4(
|
||||||
float(pos.x) * scale.x + offset.x + node[1] * tilt,
|
float(pos.x) * scale.x + offset.x + node[1] * tilt,
|
||||||
float(node[0]) * scale.y + offset.y,
|
float(node[0]) * scale.y + offset.y,
|
||||||
1, 1
|
1, 1
|
||||||
);
|
);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user