Форум

Показывает несколько "старых" кадров после "снятия с ПАУЗЫ" как обновить рендер до отображения?

31 июля 2016 15:24
Движок в браузере показывает несколько "старых" кадров
после "снятия с ПАУЗЫ" как обновить рендер до отображения?
( или при возврате фокуса на окно, возвращения с энергосберегающего режима итд… )

получается не красиво.. т.е. рендер прыгает на новое состояние картинки рывком
задержка на несколько кадров.

(мой рендер 1к в сек ограничен(так надо))

обычно подобные дела с прямым доступом к рендеру делал так:
    document.addEventListener("visibilitychange", function() {
        if (!document.hidden) {
        		//обновить пересчитаный кадр или   
                       //как вариант в 2Д - window.requestAnimationFrame(РЕФРЕШЪ);
        }
    }); 


как в данном "движке" это пофиксить подскажите плиз.
СПАСИБО
Денис
01 августа 2016 23:05
В общем я заметил, что при установки паузы, метод, повешенный с помощью append_loop_cb() продолжает выполняться, что наверное не очень логично, и меня удивило
Хотя конечно можно чекать is_paused()
После выполнения команды resume() обновление картинки происходит не моментально, а только после наступления по таймингу обновления следующего кадра. Наверное из за этого вы и видите предыдущий кадр.
Пример render_test.zip (вверху слева кнопки управления)

как в данном "движке" это пофиксить подскажите плиз.
Поборол это немного костыльно так:
Перед методом resume() установил fps в 60, а колбеке рендера поставил fps обратно 1.

Код из примера выше преобразился в это:
"use strict"

// register the application module
b4w.register("render_test", function(exports, require) {

// import modules used by the app
var m_app       = require("app");
var m_data      = require("data");
var m_main      = require("main");
var m_config    = require("config");
var m_scs       = require("scenes");
var m_trans     = require("transform");

var _count_frame = 0;

/**
 * export the method to initialize the app (called at the bottom of this file)
 */
exports.init = function() {
    m_app.init({
        canvas_container_id: "main_canvas_container",
        callback: init_cb,
        show_fps: true,
        console_verbose: true,
        autoresize: true
    });
}

/**
 * callback executed when the app is initialized 
 */
function init_cb(canvas_elem, success) {

    if (!success) {
        console.log("b4w init failure");
        return;
    }

    load();
}

/**
 * load the scene data
 */
function load() {
    m_data.load("render_test.json", load_cb);
}

/**
 * callback executed when the scene is loaded
 */
function load_cb(data_id) {
    m_app.enable_camera_controls();

    // place your code here
    m_main.append_loop_cb(frame_cb);
    
    btn_pause.onclick = function(){
        m_main.pause();
    }
    btn_play.onclick = function(){
        m_config.set("max_fps", 60);
        m_main.resume();
    }
    btn_transalte.onclick = function(){
        var cube = m_scs.get_object_by_name('Cube');
        m_trans.rotate_z_local(cube, 30);
    }
}

function frame_cb(){
    
    _count_frame+=1;
    led_render.innerText = _count_frame;

    led_render.style.backgroundColor = 'green';
    setTimeout(function(){
        led_render.style.backgroundColor = 'red';
    },100);

    m_config.set("max_fps", 1);
    
}

});

// import the app module and start the app by calling the init method
b4w.require("render_test").init();


Теперь при нажатии кнопки play изменения на сцене отображаются моментально.

P.S. Ещё можно изменить исходники и "экспортнуть" метод loop из модуля main и вызвать его из api в нужное время.
Но пока не хочу ковырять исходники, так как после обновы всё слетит, лучше написать свой аддон/модуль со своими изменениями.
Не стой, где попало… Попадет еще раз.
http://naviris.ru/
01 августа 2016 23:48
Проблема в том что мой тестовый девайс выдает макс 2-4 к в сек. на моей сцене и я его собственно поставил на 1к в сек вполне логично. и боюсь что в моем случае этот метод не сработает так как на ПК.

к стати пример в ФФ как то не работает кубик не крутится на кнопки реакции почти нет, кроме транслейт.

Спасибо за инфу.. попробуем дождаться ответа от программистов движка.. , как будто это буфер показывается сразу готовый.. , а надо по идее сразу запускать рендер в очищенный предварительно буфер и не ждать наступление сл. кадра. вроде как все асинхронно происходит же? верно?

ну и про "метод, повешенный с помощью append_loop_cb() продолжает выполняться," хотелось бы уточнений
Денис
02 августа 2016 07:16
Проблема в том что мой тестовый девайс выдает макс 2-4 к в сек. на моей сцене и я его собственно поставил на 1к в сек вполне логично. и боюсь что в моем случае этот метод не сработает так как на ПК.
Устройству всёравно нужно время что бы отрендерить первый кадр. Можно модифицировать код так, что бы изначально был чёрный экран или какая нить картинка, а после того как отрисуется сцена, после метода resume(), отобразилась картинка рендера.

Я бы на вашем месте поставил вместо чёрного фона картинку циферблата без стрелок

к стати пример в ФФ как то не работает кубик не крутится на кнопки реакции почти нет, кроме транслейт.
Изначально, сцену можно крутить мышкой и, нажимая транслейт, крутить объект на 30 градусов вокруг оси z (с тормозами fps =1), после нажатия паузы сцена не рендерится, мышь игнорируется, изменения при нажатии транслейта не отображаются.
После нажатия play можно увидеть, что кадр рендерится не мгновенно, а после наступления очередного тайминга.
И я приложил код, что бы это поправить.

ну и про "метод, повешенный с помощью append_loop_cb() продолжает выполняться," хотелось бы уточнений
После нажатия паузы счётчик кадров продолжает тикать, что означает, что дёргается метод, назначенный append_loop_cb(). Однако сцена не рендерится.

Однако ещё заметил, что если вкладка не активна, то append_loop_cb() останавливается… Чувствую, где то в коде есть ещё одна пауза, которая отключает и append_loop_cb()
Не стой, где попало… Попадет еще раз.
http://naviris.ru/
02 августа 2016 10:36
Ответ на сообщение пользователя Кирилл
Устройству всёравно нужно время что бы отрендерить первый кадр. Можно модифицировать код так, что бы изначально был чёрный экран или какая нить картинка, а после того как отрисуется сцена, после метода resume(), отобразилась картинка рендера.

Я бы на вашем месте поставил вместо чёрного фона картинку циферблата без стрелок
…………….

про отобразить картинку. проблема в том что свет динамический и любое небольшое изменение в картинке видно как дергаье изобраажения


Хотелось бы без костыликофф ((( обойтись тем более что разработчики тут где то есть, надеюсь услышат и ответят.
Денис
02 августа 2016 10:47
В общем я заметил, что при установки паузы, метод, повешенный с помощью append_loop_cb() продолжает выполняться, что наверное не очень логично, и меня удивило
а вот не надо удивляться:
Append a callback to be executed every frame (even if the rendering is paused). Its purpose is to perform actions non-related to the actual rendering, e.g html/css manipulation. This method allows registration of multiple callbacks.
append_loop_cb

есть ещё render_callback, с ним работают методы set_render_callback и clear_render_callback, на него как раз пауза и будет действовать как нужно

Однако ещё заметил, что если вкладка не активна, то append_loop_cb() останавливается… Чувствую, где то в коде есть ещё одна пауза, которая отключает и append_loop_cb()
остановку делает сам браузер
02 августа 2016 11:32
Иван Любовников, спасибо за ответы не внимателен…
Не стой, где попало… Попадет еще раз.
http://naviris.ru/
02 августа 2016 11:39
Ответ на сообщение пользователя ДЕНИС
про отобразить картинку. проблема в том что свет динамический и любое небольшое изменение в картинке видно как дергаье изобраажения
Можно попробовать сделать плавную смену изображения на рендер средствами css3 или js.
Смотря что у вас будет производительней…

P.S. Да. Разработчики всё читают. Может чего ещё посоветуют))
Не стой, где попало… Попадет еще раз.
http://naviris.ru/
02 августа 2016 11:56
После выполнения команды resume() обновление картинки происходит не моментально, а только после наступления по таймингу обновления следующего кадра. Наверное из за этого вы и видите предыдущий кадр.

так и есть, собственно, вот строчки, где это происходит:
main.js
в случае ограничения в 1фпс шкала времени будет разбита на интервалы длиной в 1 сек; в том условии проверяется delta - время прошедшее с предыдущей отметки, момент resume попадает в произвольное место этого интервала и задержка может доходить до целой секунды, как повезет

отелось бы без костыликофф ((( обойтись тем более что разработчики тут где то есть, надеюсь услышат и ответят
сейчас вряд ли, ограничение фпс использовалось только для отладки, поэтому оно непроработанное; в будущем, думаю, перепишем это место

Костыль с выставлением >60 фпс должен нормально сработать.
04 августа 2016 18:33
Ответ на сообщение пользователя Иван Любовников
так и есть……
Костыль с выставлением >60 фпс должен нормально сработать.

интересно а так сразу если подрят выполнить должно сработать?

    
document.addEventListener("visibilitychange", function() {
        if (!document.hidden) {
        		m_cfg.set("max_fps", 60);
        		m_main.resume();
        		m_cfg.set("max_fps", 1);
        }
    });


что то не получатся вроде.. модет стало чуть короче время задержки или я просто придумываю ?
Денис
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.