Здравствуйте Андрей
Код приведенный ниже должен вернуть в скрипт изображение содержащее красную линию на сером фоне.
Однако получается красная линия на чёрном фоне. Если закоментировать img.paint(&painter) то получается изображение с серым фоном (без красной линии естественно). Когда начинает работать painter фон закрашивается чёрным
Вопрос — как залить всё изображение нужным цветом не прибегая к gfx.rectangle(0, 0, width, height)?
img.clear(sciter::gcolor(127, 127, 127)) у меня не заработал (смотри предыдущее сообщение)
Здравствуйте Андрей
Где взять HGFX gfx, который передаётся конструктору?
sciter::graphics gfx(HGFX gfx);
А ещё на страничке Скайтера есть красивые скриншоты: http://sciter.com/htmlcss-ui-in-medicine/
Вы не в курсе, эти графики рисовались tiscript'ом или из нативного кода?
Вообще здорово графики выглядят
Здравствуйте, goldfish, Вы писали:
G>Вы не в курсе, эти графики рисовались tiscript'ом или из нативного кода? G>Вообще здорово графики выглядят
Вот ответ автора:
Приветствую.
1) Все представленные графики можно отрисовать на движке sciter в его фронт части, т.е на tis. "Красота" графиков это прежде всего красота данных, в данном случае красота природы работы человеческого сердца. У вас должны быть "красивые" данные, мы их получали, естественно, из бекенд части, т.е. из С++.
2) Со скоростью отрисовки готовых данных проблем у tis нет, но в некоторых случаях (не во всех) нужно было создавать различные буферы. В частности я делал буфер для уже готовых участков gfx.path, чтобы не перерисовывать картинку для каждого чиха. В некоторых случаях в качастве буфера использовали Image, и просто смотрели, нужно его перерисовывать или нет. (Изменились размеры или нет, изменились данные или нет, изменилось смещение или нет.. )
3) Нюансы.
Если данные имеют дискретную природу, рисуйте дискретно. Т.е. если график это набор вертикальных линий шириной в int пикселов, то и рисуйте их в точках x, где x — int, а не float. В tis я перед отрисовкой вообще всегда смещал общую сетку на 0.5, чтобы линии рисовались четко в интовых положениях ( там есть особенность по умолчанию рисовать между двумя физическими пикселами, т.е в итоге линии получаются размытыми) Если стоит
При отрисовке "мелкого" экг было больше всего проблем как с "красотой" так и с производительностью. Там большие массивы данных. В итоге на сях сделали алгоритм поиска экстремумов, и рисовали линии не сглаженные) именно между ними. И рисовали полностью уже на сях, но это правда после алгоритма поиска экстремумов думаю не принципиально, сама по себе отрисовка относительно быстрая, проблема в обработке данных.
Re[3]: Как использовать graphics из нативного кода
G>Как рационально передавать данные из нативного кода в tiscript, как минимизировать накладные расходы при передаче? G>Если для каждой вершины вызывается функция из нативного кода, это правильно?
*
Понятно, что N вызовов tis -> с++ по 1 кусочку данных хуже, чем 1 вызов массива или объекта из N кусков данных.
Накладные расходы на вызовы методов и внутренние проверки корректности данных (если, конечно, они есть).
Т.е. имеет смысл 1 раз забирать массив данных, и в tis бегать уже по этому массиву.
Как можно ускорить передачу?
*
Кроме варианта с массивами, можно устранить сам факт передачи данных, т.е. максимальное кол-во
работы с данными и саму отрисовку — все поместить в нативный код, а в tis оставить все "врапперы", обработки событий
и всякое наследуемое общее для других модулей и бехавиоров.
Т.е я для особенно требующих производительности модулей писал связку:
sciter behavior на с++ (есть в примерах кода) + behavior (наследующий несколько общих для проекта методов, чтобы не повторять код) на tis.
G>А ещё на страничке Скайтера есть красивые скриншоты: http://sciter.com/htmlcss-ui-in-medicine/ G>Вы не в курсе, эти графики рисовались tiscript'ом или из нативного кода? G>Вообще здорово графики выглядят
Здравствуйте, goldfish, Вы писали:
G>а есть ограничение на количество элементов в патче?
*
Патч ? Кол-во элементов в Graphics.Path() наверное. Я с такими ограничениями не сталкивался, полагаю,
path.moveTo() перед gfx.drawPath можно вызывать ну очень много раз. Вопрос в том, зачем это делать
слишком много раз: рисовать нужно не менее, чем необходимо, но и не более того. В смысле, не видимые пользователю
участки больших графиков в path загонять, конечно, не стоит.
G>сетку смещали на 0,5 с помощью translate?
*
да.
У вас должны быть "красивые" данные, мы их получали, естественно, из бекенд части, т.е. из С++.
Здравствуйте
Как рационально передавать данные из нативного кода в tiscript, как минимизировать накладные расходы при передаче?
Если для каждой вершины вызывается функция из нативного кода, это правильно?
Как можно ускорить передачу?
Кроме того, в нашем случае больше всего времени уходило на пробежки по массивам.
Представьте себе — ~ 100000 раз пройтись раза три: сначала получить данные, потом подгововить конкретно для текущего модуля (100 000 тут становится меньшим числом, но тем не менее),
потом еще раз бегать и рисовать.
В c++ бехавиоре я сократил эту пробежку до 2-х. Т.е. подготавливаю в цикле участок и сразу внутри этого цикла вызываю отрисовку линии.
Какие-то случаи можно сокращать и до 1-го цикла.
G>У вас должны быть "красивые" данные, мы их получали, естественно, из бекенд части, т.е. из С++.
G>Здравствуйте G>Как рационально передавать данные из нативного кода в tiscript, как минимизировать накладные расходы при передаче? G>Если для каждой вершины вызывается функция из нативного кода, это правильно? G>Как можно ускорить передачу?
Ну рисовать polygons или polylines путем вызовов gfx.line это неправильно по любому.
От native надо запрашивать массив точек.
function createChartPath()
var positions = get_data_vector(0);
var path = new Graphics.Path();
path.moveTo(positions[0],positions[1]);
var count = positions.length;
for(var n = 2; n < count; n += 2)
path.lineTo( positions[n],positions[n+1] );
return path;
}
Этот path есть cacheable object т.е. его надо создавать только если данные изменились.
При отрисовке использовать уже готовый raphics.Path объект.
Надо помнить что WM_PAINT могу приходить чаще чем данные меняются. Например при анимациях где-то в стороне.
Совсем не обязательно в этом случае по новой path строить.
Дело в том что GPU фактически рисует только треугольники.
Для вывести на экран линию, её нужно сначала tesselate.
Вот Graphics.Path внутри хранит этот triangle mesh.
А в paint этот mesh просто закидывается в GPU. А тот уже быстро рисует треугольники.
Re[3]: Как использовать graphics из нативного кода
Спасибо всем за ответы
Если графики рисовать в текстуру только когда нужно, после чего выводить текстуру в окне скайтера и уже поверх неё рисовать всё остальное (оси координат, легенду , rect tracker и т.д).
tiscript:
function paint(gfx)
{
// если графики изменились то рисуем их в imageChart
if(invalidChart)
{
if(imageChart) imageChart.destroy();
imageChart = new Image(width, height, drawChart);
invalidChart = false;
}
gfx.drawImage(imageChart, 0.0, 0.0);
// рисуем всё остальное
...
}
function drawChart(gfx)
{
...
}
Как поместить drawChart в нативный код?
drawChart вызывается из tiscript при необходимости, заполняет текстуру, а уже она выводится в tiscript
Re[4]: Как использовать graphics из нативного кода
r4521 — [api, graphics] sciter::image::paint() preserves original image allowing incremental updates.
G>и ещё один вопрос: есть в нативном коде аналог скриптового image.destroy()?
Он там не нужен.
sciter::image это smart pointer, если ты его нигде не сохрагишь или не передашь в script то он уничтожится.
Re[3]: Как использовать graphics из нативного кода
Здравствуйте, c-smile, Вы писали: CS>sciter::image это smart pointer, если ты его нигде не сохрагишь или не передашь в script то он уничтожится.
в скрипте при изменении размеров окна я делал так:
var image = null;
function paint(gfx)
{
...
if(imageNeedResize) // если изменились размеры окна
{
if(image) image.destroy(); // удаляем старую картинку
image = new Image(width, height, drawChart); // рисуем новую картинку
}
gfx.drawImage(image, 0.0, 0.0);
Здравствуйте
Возможно изменить размеры элемента (ширина,высота) программно, из скрипта или нативного кода?
стили элементов заданы так
div.axis {width:100px;}
div.chart {size: *;}
Слева вертикальная шкала, справа график
На шкале выводятся числа разной ширины, может быть 1, 2, 3 а может -0.00126, числа или не влазят по ширине или остаётся много пустого места
Нужно менять ширину шкалы.
пробовал через стиль this.style#width но это очень тормозит
Есть ещё варианты?
Re[2]: Как использовать graphics из нативного кода
Здравствуйте, goldfish, Вы писали:
G>пробовал через стиль this.style#width но это очень тормозит
Логично.
G>Есть ещё варианты?
Не менять ширину элемента в реалтайме
Тем более, я так понимаю, график справа от шкалы и его положение зависит от ширины шкалы? И пользователю это удобно?
Re[2]: Как использовать graphics из нативного кода
Здравствуйте, goldfish, Вы писали:
G>div.axis {width:100px;} G>div.chart {size: *;} G>Нужно менять ширину шкалы. G>пробовал через стиль this.style#width но это очень тормозит G>Есть ещё варианты?
А почему не
div.axis {width:max-content;}
?
И вообще приведи markup чтобы ясно было что там у тебя.