修复修改高度导致渲染器不对齐 | 完成阶梯状的渲染
This commit is contained in:
parent
9a1642633f
commit
7ff8576bc9
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="">
|
<div class="">
|
||||||
<el-radio-group v-model="signalModal"
|
<el-radio-group v-model="signalModal"
|
||||||
@click="onRadioClick"
|
@change="onSignalModalUpdate"
|
||||||
>
|
>
|
||||||
<!-- 数字模式 -->
|
<!-- 数字模式 -->
|
||||||
<el-radio-button :label="0">
|
<el-radio-button :label="0">
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<span class="iconfont icon-common-digital"></span>
|
<span class="iconfont icon-common-digital"></span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
<!-- 折现模拟 -->
|
<!-- 阶梯模拟 -->
|
||||||
<el-radio-button :label="1">
|
<el-radio-button :label="1">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
effect="dark"
|
effect="dark"
|
||||||
@ -23,7 +23,7 @@
|
|||||||
raw-content
|
raw-content
|
||||||
><span class="iconfont icon-ladder-analog"></span></el-tooltip>
|
><span class="iconfont icon-ladder-analog"></span></el-tooltip>
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
<!-- 阶梯模拟 -->
|
<!-- 折线模拟 -->
|
||||||
<el-radio-button :label="2">
|
<el-radio-button :label="2">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
effect="dark"
|
effect="dark"
|
||||||
@ -49,6 +49,20 @@ const { t } = useI18n();
|
|||||||
|
|
||||||
const signalModal = ref(0);
|
const signalModal = ref(0);
|
||||||
|
|
||||||
|
function onSignalModalUpdate() {
|
||||||
|
const links = globalLookup.sidebarSelectedWireLinks;
|
||||||
|
if (links.size > 0) {
|
||||||
|
const modal = signalModal.value;
|
||||||
|
// 更新渲染选项
|
||||||
|
for (const link of links) {
|
||||||
|
globalLookup.setRenderOption(link, 'renderModal', modal);
|
||||||
|
globalLookup.waveRender.resetVertice(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新渲染
|
||||||
|
globalLookup.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getOneSelectLink() {
|
function getOneSelectLink() {
|
||||||
let selectedLink = undefined;
|
let selectedLink = undefined;
|
||||||
@ -60,7 +74,6 @@ function getOneSelectLink() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
watch(globalLookup.sidebarSelectedWireLinks, () => {
|
watch(globalLookup.sidebarSelectedWireLinks, () => {
|
||||||
const link = getOneSelectLink();
|
const link = getOneSelectLink();
|
||||||
if (link) {
|
if (link) {
|
||||||
|
@ -52,7 +52,7 @@ void main() {
|
|||||||
// 偏移包括三部分:用户滚动时发生的全局位移、为了设置线宽发生的位移、与 scale 无关的额外位移
|
// 偏移包括三部分:用户滚动时发生的全局位移、为了设置线宽发生的位移、与 scale 无关的额外位移
|
||||||
float offsetX = offset.x + float(ws.x) + float(shift.x);
|
float offsetX = offset.x + float(ws.x) + float(shift.x);
|
||||||
float offsetY = offset.y + float(ws.y) + float(shift.y);
|
float offsetY = offset.y + float(ws.y) + float(shift.y);
|
||||||
|
|
||||||
gl_Position = vec4(
|
gl_Position = vec4(
|
||||||
posX * scale.x + offsetX,
|
posX * scale.x + offsetX,
|
||||||
posY * scale.y + offsetY,
|
posY * scale.y + offsetY,
|
||||||
|
@ -8,7 +8,7 @@ import vline from './vline';
|
|||||||
import getX from './get-x';
|
import getX from './get-x';
|
||||||
import vlineStylo from './vline-stylo';
|
import vlineStylo from './vline-stylo';
|
||||||
import getLabel from './get-label';
|
import getLabel from './get-label';
|
||||||
import { globalLookup } from '../global.js';
|
import { globalLookup, globalSetting } from '../global.js';
|
||||||
|
|
||||||
const defs = ['defs',
|
const defs = ['defs',
|
||||||
['linearGradient', { id: 'valid' },
|
['linearGradient', { id: 'valid' },
|
||||||
@ -33,7 +33,49 @@ const defs = ['defs',
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} link
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function getVecRenderModal(link) {
|
||||||
|
const renderOptions = globalLookup.currentSignalRenderOptions;
|
||||||
|
if (renderOptions.has(link)) {
|
||||||
|
const option = renderOptions.get(link);
|
||||||
|
if (typeof option.renderModal === 'number') {
|
||||||
|
return option.renderModal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 根据 link 得到对应的 value 渲染模式
|
||||||
|
* @param {*} link
|
||||||
|
*/
|
||||||
|
function addVecRenderItem(link) {
|
||||||
|
const link2CurrentWires = globalLookup.link2CurrentWires;
|
||||||
|
const modal = getVecRenderModal(link);
|
||||||
|
if (modal === 0) {
|
||||||
|
const signal = link2CurrentWires.get(link);
|
||||||
|
return {
|
||||||
|
name: signal.name,
|
||||||
|
kind: signal.kind,
|
||||||
|
ref: signal.link
|
||||||
|
}
|
||||||
|
} else if (modal === 1) {
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
kind: '',
|
||||||
|
ref: ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
name: '',
|
||||||
|
kind: '',
|
||||||
|
ref: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,15 +94,10 @@ function* renderValues(desc, pstate) {
|
|||||||
|
|
||||||
const currentWires = desc.currentWires;
|
const currentWires = desc.currentWires;
|
||||||
const renderSignals = [];
|
const renderSignals = [];
|
||||||
const link2CurrentWires = globalLookup.link2CurrentWires;
|
|
||||||
for (const view of globalLookup.currentWiresRenderView) {
|
for (const view of globalLookup.currentWiresRenderView) {
|
||||||
if (view.renderType === 0) {
|
if (view.renderType === 0) {
|
||||||
const realSignal = link2CurrentWires.get(view.signalInfo.link);
|
const realSignal = addVecRenderItem(view.signalInfo.link);
|
||||||
renderSignals.push({
|
renderSignals.push(realSignal);
|
||||||
name: realSignal.name,
|
|
||||||
kind: realSignal.kind,
|
|
||||||
ref: realSignal.link
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// 如果是组,需要渲染空白的一行
|
// 如果是组,需要渲染空白的一行
|
||||||
renderSignals.push({
|
renderSignals.push({
|
||||||
@ -71,21 +108,17 @@ function* renderValues(desc, pstate) {
|
|||||||
// 如果没有关闭,把所有子节点加入其中
|
// 如果没有关闭,把所有子节点加入其中
|
||||||
if (view.groupInfo.collapse === false) {
|
if (view.groupInfo.collapse === false) {
|
||||||
for (const child of view.children) {
|
for (const child of view.children) {
|
||||||
const realSignal = link2CurrentWires.get(child.signalInfo.link);
|
const realSignal = addVecRenderItem(view.signalInfo.link);
|
||||||
renderSignals.push({
|
renderSignals.push(realSignal);
|
||||||
name: realSignal.name,
|
|
||||||
kind: realSignal.kind,
|
|
||||||
ref: realSignal.link
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const lineHeightExtra = (globalSetting.displaySignalHeight - 30) / 2;
|
||||||
const ilen = height / yStep;
|
const ilen = height / yStep;
|
||||||
const iskip = yOffset / yStep;
|
const iskip = (yOffset - lineHeightExtra) / yStep;
|
||||||
|
|
||||||
const ml = genSVG(width, height - topBarHeight - botBarHeight);
|
const ml = genSVG(width, height - topBarHeight - botBarHeight);
|
||||||
|
|
||||||
|
@ -2,7 +2,14 @@ import { globalSetting, globalStyle } from '../global';
|
|||||||
|
|
||||||
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_WidthShifts, barShift, getRatio, screenHeightPixel, maskColorIndexOffset, posYFactor, glslInputLength, prettyPrint } from './render-utils.js';
|
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_WidthShifts, barShift, getRatio, screenHeightPixel, maskColorIndexOffset, posYFactor, glslInputLength, prettyPrint } from './render-utils.js';
|
||||||
import { vertexShader, fragmentShader } from './render-shader.js';
|
import { vertexShader, fragmentShader } from './render-shader.js';
|
||||||
import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog } from './toolbar/renderModal';
|
import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog, renderAsLineAnalog } from './toolbar/renderModal';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* @typedef {Object} VecRenderNumberVertices
|
||||||
|
* @property {number[]} lineVertices
|
||||||
|
* @property {number[]} maskVertices
|
||||||
|
*/
|
||||||
|
|
||||||
// const { ChangoItem } = require('./types.d.ts');
|
// const { ChangoItem } = require('./types.d.ts');
|
||||||
|
|
||||||
@ -149,6 +156,42 @@ class WebGL2WaveRender {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GlobalLookup} lookup
|
||||||
|
* @param {string} link
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
getVecRenderModal(lookup, link) {
|
||||||
|
const renderOptions = lookup.currentSignalRenderOptions;
|
||||||
|
if (renderOptions.has(link)) {
|
||||||
|
const option = renderOptions.get(link);
|
||||||
|
if (typeof option.renderModal === 'number') {
|
||||||
|
return option.renderModal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GlobalLookup} lookup
|
||||||
|
* @param {string} link
|
||||||
|
* @param {Array<string | number>} wave
|
||||||
|
* @param { number } time
|
||||||
|
* @returns {(lookup: GlobalLookup, link: string, wave: number[], time: number) => VecRenderNumberVertices}
|
||||||
|
*/
|
||||||
|
selectVecRenderFn(lookup, link, wave, time) {
|
||||||
|
const modal = this.getVecRenderModal(lookup, link);
|
||||||
|
switch (modal) {
|
||||||
|
case 0:
|
||||||
|
return renderAsCommonDigital;
|
||||||
|
case 1:
|
||||||
|
return renderAsLadderAnalog;
|
||||||
|
case 2:
|
||||||
|
return renderAsLineAnalog;
|
||||||
|
default:
|
||||||
|
return renderAsCommonDigital;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} link
|
* @param {string} link
|
||||||
@ -161,8 +204,8 @@ class WebGL2WaveRender {
|
|||||||
*/
|
*/
|
||||||
makeVecVertex(link, wave, time, debug = false) {
|
makeVecVertex(link, wave, time, debug = false) {
|
||||||
const lookup = this.globalLookup;
|
const lookup = this.globalLookup;
|
||||||
|
const vecRenderFn = this.selectVecRenderFn(lookup, link, wave, time);
|
||||||
const { lineVertices, maskVertices } = renderAsCommonDigital(lookup, link, wave, time);
|
const { lineVertices, maskVertices } = vecRenderFn(lookup, link, wave, time);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log(lineVertices);
|
console.log(lineVertices);
|
||||||
@ -326,7 +369,7 @@ class WebGL2WaveRender {
|
|||||||
const plugins = this.plugins;
|
const plugins = this.plugins;
|
||||||
|
|
||||||
pstate.yStep = globalSetting.displaySignalHeight + globalStyle.sideBarItemMargin;
|
pstate.yStep = globalSetting.displaySignalHeight + globalStyle.sideBarItemMargin;
|
||||||
pstate.yDuty = (1 - 2 * globalStyle.sideBarItemMargin / this.pstate.yStep) * 0.95;
|
pstate.yDuty = (1 - 2 * globalStyle.sideBarItemMargin / pstate.yStep) * 0.95;
|
||||||
|
|
||||||
document.body.style.setProperty('--vcd-render-padding', pstate.topBarHeight + 'px');
|
document.body.style.setProperty('--vcd-render-padding', pstate.topBarHeight + 'px');
|
||||||
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
||||||
@ -411,8 +454,12 @@ class WebGL2WaveRender {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const offsetX = 2 * xOffset / canvasWidth - 1;
|
// 区间映射公式,将 [a, b] 内的数字映射到 [c, d] 中
|
||||||
const offsetY = 2 * (yOffset - yStep * index) / canvasHeight + 1;
|
// $f(x) = \frac{d - c}{b - a} (x - a) + c$
|
||||||
|
const offsetX = 2 / canvasWidth * xOffset - 1;
|
||||||
|
|
||||||
|
const lineHeightExtra = (globalSetting.displaySignalHeight - 30) / 2;
|
||||||
|
const offsetY = 2 / canvasHeight * (yOffset - yStep * index - lineHeightExtra) + 1;
|
||||||
gl.uniform2f(webglLocation.offset, offsetX, offsetY);
|
gl.uniform2f(webglLocation.offset, offsetX, offsetY);
|
||||||
|
|
||||||
// 根据 lineVao 进行绘制
|
// 根据 lineVao 进行绘制
|
||||||
@ -423,7 +470,7 @@ class WebGL2WaveRender {
|
|||||||
const maskVertices = maskVerticesMap.get(id);
|
const maskVertices = maskVerticesMap.get(id);
|
||||||
|
|
||||||
if (signal.size === 1) {
|
if (signal.size === 1) {
|
||||||
// 如果是 width 为 1 的
|
// 如果是 bit
|
||||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
||||||
gl.bindVertexArray(signalItem.lineVao);
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
|
||||||
@ -431,15 +478,34 @@ class WebGL2WaveRender {
|
|||||||
gl.bindVertexArray(signalItem.maskVao);
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
||||||
} else {
|
} else {
|
||||||
// 如果是 width 大于 1 的
|
// 如果是 vec,根据设定的渲染模式和进行设置
|
||||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
|
const vecRenderModal = _this.getVecRenderModal(globalLookup, signal.link);
|
||||||
gl.bindVertexArray(signalItem.lineVao);
|
if (vecRenderModal === 0) {
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength);
|
// 普通数字渲染模式
|
||||||
|
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
|
||||||
gl.bindVertexArray(signalItem.maskVao);
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength);
|
||||||
|
|
||||||
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
||||||
|
} else if (vecRenderModal === 1) {
|
||||||
|
// 梯形渲染模式
|
||||||
|
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
|
||||||
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
|
||||||
|
|
||||||
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
||||||
|
} else {
|
||||||
|
// 折线渲染模式
|
||||||
|
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
|
||||||
|
gl.bindVertexArray(signalItem.lineVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength);
|
||||||
|
|
||||||
|
gl.bindVertexArray(signalItem.maskVao);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins.map(fn => fn(globalLookup, pstate, elements));
|
plugins.map(fn => fn(globalLookup, pstate, elements));
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { globalLookup } from "@/hook/global";
|
import { globalLookup } from "@/hook/global";
|
||||||
import { maskColorIndexOffset, posYFactor } from "../render-utils";
|
import { maskColorIndexOffset, posYFactor, prettyPrint } from "../render-utils";
|
||||||
import { hexToSignedInt } from "./renderFormat";
|
import { hexToSignedInt } from "./renderFormat";
|
||||||
|
|
||||||
|
|
||||||
@ -130,15 +130,15 @@ function makeWidthShiftIndexByPoints(p0, p1, p2) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} link
|
* @param {string} link
|
||||||
* @param {Array<string | number>} wave
|
* @param {Array<string | number>} wave
|
||||||
* @param { number } time
|
* @param { number } time
|
||||||
* @param {(link: string, wave: number[], time: number) => BitRenderTempStruct} renderParamMaker
|
|
||||||
* @returns {VecRenderNumberVertices}
|
* @returns {VecRenderNumberVertices}
|
||||||
*/
|
*/
|
||||||
function renderBlockWave(link, wave, time, renderParamMaker) {
|
export function renderAsBit(link, wave, time) {
|
||||||
const length = wave.length;
|
const length = wave.length;
|
||||||
// 先将节点数据转化为裁剪空间的坐标
|
// 先将节点数据转化为裁剪空间的坐标
|
||||||
const perspectivePoints = [];
|
const perspectivePoints = [];
|
||||||
@ -153,8 +153,8 @@ function renderBlockWave(link, wave, time, renderParamMaker) {
|
|||||||
const value1 = currentWave[1];
|
const value1 = currentWave[1];
|
||||||
const value2 = nextWave[1];
|
const value2 = nextWave[1];
|
||||||
|
|
||||||
const renderParam1 = renderParamMaker(link, currentWave, time);
|
const renderParam1 = makeBitRenderParam(link, currentWave, time);
|
||||||
const renderParam2 = renderParamMaker(link, nextWave, time);
|
const renderParam2 = makeBitRenderParam(link, nextWave, time);
|
||||||
|
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||||
@ -250,17 +250,6 @@ function renderBlockWave(link, wave, time, renderParamMaker) {
|
|||||||
return { lineVertices, maskVertices };
|
return { lineVertices, maskVertices };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} link
|
|
||||||
* @param {Array<string | number>} wave
|
|
||||||
* @param { number } time
|
|
||||||
* @returns {VecRenderNumberVertices}
|
|
||||||
*/
|
|
||||||
export function renderAsBit(link, wave, time) {
|
|
||||||
return renderBlockWave(link, wave, time, makeBitRenderParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Digital
|
* @description Digital
|
||||||
* @param {GlobalLookup} lookup
|
* @param {GlobalLookup} lookup
|
||||||
@ -462,10 +451,6 @@ export function renderAsLadderAnalog(lookup, link, wave, time) {
|
|||||||
const { maxVal, minVal } = getMaxMinByFormat(link, wave, time, formatCode, width);
|
const { maxVal, minVal } = getMaxMinByFormat(link, wave, time, formatCode, width);
|
||||||
const coordinateTransform = getMappingFunc(formatCode, maxVal, minVal);
|
const coordinateTransform = getMappingFunc(formatCode, maxVal, minVal);
|
||||||
|
|
||||||
const length = wave.length;
|
|
||||||
const lineVertices = [];
|
|
||||||
const maskVertices = [];
|
|
||||||
|
|
||||||
function makeLadderAnalogRenderParam(link, wave, time) {
|
function makeLadderAnalogRenderParam(link, wave, time) {
|
||||||
const [t1, val, mask] = wave;
|
const [t1, val, mask] = wave;
|
||||||
|
|
||||||
@ -478,7 +463,6 @@ export function renderAsLadderAnalog(lookup, link, wave, time) {
|
|||||||
const numVal = explainAsJSNumber(formatCode, val, width);
|
const numVal = explainAsJSNumber(formatCode, val, width);
|
||||||
// 此时的 y 是一个 -1 到 1 的浮点数,因为 VAO 我设置了 Int
|
// 此时的 y 是一个 -1 到 1 的浮点数,因为 VAO 我设置了 Int
|
||||||
const y = coordinateTransform(numVal);
|
const y = coordinateTransform(numVal);
|
||||||
console.log(t1, y);
|
|
||||||
const colorParam = { y, color: 5 };
|
const colorParam = { y, color: 5 };
|
||||||
|
|
||||||
if (renderOptions.has(link)) {
|
if (renderOptions.has(link)) {
|
||||||
@ -490,8 +474,115 @@ export function renderAsLadderAnalog(lookup, link, wave, time) {
|
|||||||
|
|
||||||
return colorParam;
|
return colorParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const length = wave.length;
|
||||||
|
// 先将节点数据转化为裁剪空间的坐标
|
||||||
|
const perspectivePoints = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < length; ++ i) {
|
||||||
|
// const currentWave = wave[(i === 0) ? 0 : (i - 1)];
|
||||||
|
const currentWave = wave[i];
|
||||||
|
const nextWave = (i === (length - 1)) ? wave[i] : wave[i + 1];
|
||||||
|
|
||||||
|
const t1 = currentWave[0];
|
||||||
|
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
|
||||||
|
const value1 = currentWave[1];
|
||||||
|
const value2 = nextWave[1];
|
||||||
|
|
||||||
|
const renderParam1 = makeLadderAnalogRenderParam(link, currentWave, time);
|
||||||
|
const renderParam2 = makeLadderAnalogRenderParam(link, nextWave, time);
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||||
|
perspectivePoints.push({ x: t2, y: renderParam1.y, color: renderParam1.color });
|
||||||
|
} else {
|
||||||
|
const lastPoint = perspectivePoints[perspectivePoints.length - 1];
|
||||||
|
if ((lastPoint.y !== renderParam1.y) || (lastPoint.color !== renderParam1.color)) {
|
||||||
|
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||||
|
}
|
||||||
|
if ((renderParam1.y !== renderParam2.y) || (renderParam1.color !== renderParam2.color)) {
|
||||||
|
perspectivePoints.push({ x: t2, y: renderParam1.y, color: renderParam1.color });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保最后一个点延申到了 time
|
||||||
|
const lastPoint = perspectivePoints[perspectivePoints.length - 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 = [];
|
||||||
|
|
||||||
|
|
||||||
return renderBlockWave(link, wave, time, makeLadderAnalogRenderParam);
|
// 制作 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];
|
||||||
|
|
||||||
|
const wsIndex = makeWidthShiftIndexByPoints(p0, p1, p2);
|
||||||
|
|
||||||
|
if (wsIndex === undefined) {
|
||||||
|
console.log(p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineVertices.push(
|
||||||
|
// uvec2 pos; uvec3 control;
|
||||||
|
p1.x, p1.y * posYFactor, 0, wsIndex, p1.color,
|
||||||
|
p1.x, p1.y * posYFactor, 0, (wsIndex + 4) % 8, p1.color
|
||||||
|
);
|
||||||
|
|
||||||
|
// 防止颜色不同导致单个图元内出现两个颜色,这会引发shader的渐变
|
||||||
|
if (p2 !== undefined && p1.color !== p2.color) {
|
||||||
|
lineVertices.push(
|
||||||
|
// uvec2 pos; uvec3 control;
|
||||||
|
p1.x, p1.y * posYFactor, 0, wsIndex, p2.color,
|
||||||
|
p1.x, p1.y * posYFactor, 0, (wsIndex + 4) % 8, p2.color,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 制作 maskVertices
|
||||||
|
for (let i = 0; i < pointNum; ++ i) {
|
||||||
|
const p1 = perspectivePoints[i];
|
||||||
|
|
||||||
|
// 开头就有一条线
|
||||||
|
if (i === 0 && p1.y === 1) {
|
||||||
|
while (perspectivePoints[++ i] && perspectivePoints[i].y === 1);
|
||||||
|
// 回退
|
||||||
|
if (-- i > 0) {
|
||||||
|
// 四元组: (x, yshift_index, color_index, width_shift_index)
|
||||||
|
const rectangleVertices = makeRectangleVertices(p1.x, 1, perspectivePoints[i].x, -1, p1.color + maskColorIndexOffset, 4);
|
||||||
|
// 三角图元画矩形
|
||||||
|
maskVertices.push(...rectangleVertices);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上升沿才使用
|
||||||
|
const p2 = perspectivePoints[i + 1];
|
||||||
|
const p3 = perspectivePoints[i + 2];
|
||||||
|
|
||||||
|
if (p1 === undefined || p2 === undefined || p3 === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p2.y > -1) {
|
||||||
|
// 矩形的四个点
|
||||||
|
const rectangleVertices = makeRectangleVertices(p2.x, p2.y, p3.x, -1, p2.color + maskColorIndexOffset, 4);
|
||||||
|
// 三角图元画矩形
|
||||||
|
maskVertices.push(...rectangleVertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { lineVertices, maskVertices };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -507,9 +598,13 @@ export function renderAsLineAnalog(lookup, link, wave, time) {
|
|||||||
const formatCode = getValFormatCode(lookup, link);
|
const formatCode = getValFormatCode(lookup, link);
|
||||||
const signal = lookup.link2CurrentWires.get(link);
|
const signal = lookup.link2CurrentWires.get(link);
|
||||||
const width = signal.size;
|
const width = signal.size;
|
||||||
|
|
||||||
const { maxVal, minVal } = getMaxMinByFormat(link, wave, time, formatCode, width);
|
const { maxVal, minVal } = getMaxMinByFormat(link, wave, time, formatCode, width);
|
||||||
|
const coordinateTransform = getMappingFunc(formatCode, maxVal, minVal);
|
||||||
|
|
||||||
|
const length = wave.length;
|
||||||
|
const lineVertices = [];
|
||||||
|
const maskVertices = [];
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,21 +1,24 @@
|
|||||||
import { globalStyle, globalLookup } from '../global';
|
import { globalStyle, globalLookup, globalSetting } from '../global';
|
||||||
|
|
||||||
const yOffsetUpdate = (pstate, nextOffsetYFn) => {
|
const yOffsetUpdate = (pstate, nextOffsetYFn) => {
|
||||||
let nextOffsetY = nextOffsetYFn();
|
let nextOffsetY = nextOffsetYFn();
|
||||||
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
|
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
|
||||||
|
|
||||||
|
nextOffsetY = nextOffsetY;
|
||||||
|
|
||||||
const currentRenderHeight = globalLookup.currentWires.size * pstate.yStep;
|
const currentRenderHeight = globalLookup.currentWires.size * pstate.yStep;
|
||||||
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
||||||
// console.log(currentRenderHeight, canvasHeight);
|
// console.log(currentRenderHeight, canvasHeight);
|
||||||
const maxOffsetX = Math.max(-20, currentRenderHeight - canvasHeight); // maximum offset
|
const maxOffsetY = Math.max(-20,
|
||||||
nextOffsetY = Math.min(nextOffsetY, maxOffsetX);
|
currentRenderHeight - canvasHeight); // maximum offset
|
||||||
|
nextOffsetY = Math.min(nextOffsetY, maxOffsetY);
|
||||||
|
|
||||||
const minOffsetX = -20; // minimum offset
|
const minOffsetY = -20; // minimum offset
|
||||||
nextOffsetY = Math.max(nextOffsetY, minOffsetX);
|
nextOffsetY = Math.max(nextOffsetY, minOffsetY);
|
||||||
|
|
||||||
if (nextOffsetY === xOffset) {
|
// if (nextOffsetY === xOffset) {
|
||||||
return false; // exit without scroll
|
// return false; // exit without scroll
|
||||||
}
|
// }
|
||||||
|
|
||||||
pstate.oldYOffset = pstate.yOffset;
|
pstate.oldYOffset = pstate.yOffset;
|
||||||
pstate.yOffset = nextOffsetY;
|
pstate.yOffset = nextOffsetY;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user