Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: Не могу сообразить :-(, выручайте! Добавлено: 13.01.08 04:25  

Автор вопроса:  ника
Ребят, делаю приложение что то типа слайд-шоу. Сейчас застряла на эффектах. Вернее не на самих эффектах а на их расчетах. Моя проблема заключается в том, что я не могу рассчитать скорость показа того или иного эффекта - слишком много неизвестных получается..
Изначально мы знаем
1.размер картинки (скажем 400*300 пикселов, значит в итоге имеем 120к пикселов) пусть будет pixelCount
2.на первой итерации эффекта можем вычислить время 1 итерации (ticks), скажем iterationTime. Оно зависит от многих показателей, от производительности машины, от количества операций по копированию пиксела(ов), от способа копирования (либо просто пикселом, либо побайтно, либо через указатели и т.д.), от сложности рассчета эффекта ...
3. заданное пользователем время выполнения эффекта пусть будет duration=2.5 сек
Вот ,наверное, пожалуй и все входные данные ( во всяком случае те, которые мне пришли в голову)
Хотя, наверное, еще можно учесть что в кино показывают 24 кадра в секунду и возможно надо учитывать время вывода самой картинки (копирование на контекст) каждый кадр хотя врядли это будет играть существенную роль. Возможно это тоже придется учитывать

Как рассчитать зависимость через сколько скопированных пикселов мне надо обновить изображение чтобы уложиться в заданное время, и в тоже время присутствовала плавность показа эффекта.
На данные момент у меня внутри цикла примерно так: if (counter % speed == 0) ShowImage(); (% - это целочисленное деление ,аналог Mod из VB на всякий случай:) speed - это просто подобранное число..
Но это не то, потому что на разных размерах картинки разная скорость получается, и вообще это кривое решение((
С одной стороны если картинка маленькая, а время задано большое, и итерация выполняется довольно быстро на простом эффекте, то можно либо усыпить поток на какое то время на каждой итерации(чтобы с временем не пролететь), а с другой стороны можно уменьшить количество пикселов через которые надо обновлять картинку, что даст бОльшую плавность при перерисовках контекста.

ВОт как рассчитать эту зависимость по уму? Может кто дельное что подскажет, а то с математикой у меня всегда проблемы были?

Ответить

  Ответы Всего ответов: 26  

Номер ответа: 1
Автор ответа:
 Боцман



ICQ: 295725312 

Вопросов: 53
Ответов: 830
 Web-сайт: Rus-Skipper.narod.ru
 Профиль | | #1
Добавлено: 13.01.08 09:48
ника, а может пойти вообще другим путем?
Ведь пользователь выбирает время просмотра, а не время открытия + просмотр, так и дай в конце выполнения эфекта код на запуск таймера на время которое он указал и все, будет тебе и плавность и все остальное.

Ответить

Номер ответа: 2
Автор ответа:
 ника



Вопросов: 1
Ответов: 111


 Профиль | | #2 Добавлено: 13.01.08 12:02
Т.е. ты предлогаешь разложить изображение грубо говоря на сотню кадров, а потом по таймеру их показывать??? Не думаю, что это хороший вариант.. держать в памяти сотню картинок - по меньшей мере расточительно

Ответить

Номер ответа: 3
Автор ответа:
 Боцман



ICQ: 295725312 

Вопросов: 53
Ответов: 830
 Web-сайт: Rus-Skipper.narod.ru
 Профиль | | #3
Добавлено: 13.01.08 13:24
Ты-же сказала что с эффектами нет проблем?
Для их реализации нужно всего 2 или 3 как захочешь Picture, я предлагал выбор времени между эффектами, а не все время просмотра.То есть 3 сек например, эатем следующий эффект & картинка и так далее.

Ответить

Номер ответа: 4
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #4 Добавлено: 13.01.08 13:51
Как насчет того, чтобы реализовать стандартными средствами два потока: в одном просчитывается эффект с заданным интервалом (в памяти вычисление происходит по-любому быстрее), а во втором выводится текущее состояние эффекта с максимально возможной скоростью для данного компа (это более медленная операция, чем просчет эффекта)?

Ответить

Номер ответа: 5
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #5
Добавлено: 13.01.08 14:18
Сначала определись, какими средствами ты будешь выводить изображение. Желательно делать с помощью низкоуровневых графических АПИ (OGL, DX). Они позволят добиться плавности эффектов.
//-------
Неплохо примеры посмотреть.
Я бы рад помочь, но у меня под рукой пример движка на С++, с использованием OGL да еще и под Symbian:)

Ответить

Номер ответа: 6
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #6
Добавлено: 13.01.08 15:08
(% - это целочисленное деление ,аналог Mod из VB на всякий случай:)

Это не целочисленное деление, а взятие остатка

Ответить

Номер ответа: 7
Автор ответа:
 Docal



ICQ: 408802757 

Вопросов: 9
Ответов: 147
 Профиль | | #7 Добавлено: 13.01.08 15:23
vito я вижу ты понемного кодиш под Symbian.
У тебя есть аська?Нада поговорить

Ответить

Номер ответа: 8
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #8
Добавлено: 13.01.08 18:07
Docal
Если майл указан верно - ушло.
Но в онлайне я не часто.
Так, что если что пиши на майл.

Ответить

Номер ответа: 9
Автор ответа:
 ника



Вопросов: 1
Ответов: 111


 Профиль | | #9 Добавлено: 13.01.08 18:12
Боцман, ты по видимому недопонял о чем речь. С самими эффектами нет проблем, и мне не нужны куча Picture, куда я буду выводить изображение значение тоже не имеет - это может быть и форма и кнопка и что угодно, на что можно перенести изображение..
Суть в следующем:
Я через указатель получаю из памяти исходный массив байт картинки (он не прикосновенный), далее создаю еще один массив байт - пустой. Для создания какого либо эффекта мне необходимо из исходного в пустой скопировать в опреленной последовательности определенное количество байт и показать картинку на каждой (или через какое то количество) итерации алгоритма создания эффекта с полученным промежуточным результатом.
Я не спрашиваю как мне вывести изображение, или как преобразовать массив байт в картинку и т.д.
Мой вопрос заключается в том, чтобы рассчитать через какое количество скопированных байт(или пикселов) мне показать промежуточную картинку для соблюдения условия времени длительности эффекта независимо от размеров картинки и производительности машины...

vito: я использую только GDI+ (С#) , не факт что DX будет стоять на машине клиента

Как насчет того, чтобы реализовать стандартными средствами два потока: в одном просчитывается эффект с заданным интервалом

el-paso: Примерно так и сделано. В отдельном потоке идет просчет эффекта и копирование из одного массива в другой затем промежуточный результат передается в основной поток для отображения юзеру. Задача и заключается именно в том,чтобы рассчитать этот интервал когда надо передавать промежуточный результат в основной поток. Если привязаться ко врмения эффекта, то скажем каждые 100мс показывать картинку, но если картинка маленькая - то за эти 100мс весь эффект просчитается и визуально ничего не будет заметно (( Вообщем я пока в полном тупике, тут надо учитывать при расчетах кучу параметров - тут просто голая математика :-(

Ответить

Номер ответа: 10
Автор ответа:
 ника



Вопросов: 1
Ответов: 111


 Профиль | | #10 Добавлено: 13.01.08 18:15
Sharp, разумеется вы правы - опечаталась

Ответить

Номер ответа: 11
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #11
Добавлено: 13.01.08 19:34
Ну если C#, и все так серьезно, возможно поможет.

// ---------------------------------------------------------
// CSlideshowContainer::DrawCallBack( TAny* aInstance )
// Called by the CPeriodic in order to draw the graphics
// ---------------------------------------------------------
//
TInt CSlideshowContainer::DrawCallBack( TAny* aInstance )
{
    CSlideshowContainer* instance = (CSlideshowContainer*) aInstance;
    // Update the frame counts
    instance->iFrame++;

    // Compute the elapsed time in seconds since the startup of the example
#ifdef __WINS__

    // In the emulator the tickcount runs at 200Hz
    GLfloat timeSecs = ( (GLfloat) ( User::NTickCount() - instance->iStartTimeTicks ) ) / 200.f;

#else

    // In the device the tickcount runs at 1000hz (as intended)
    GLfloat timeSecs = ( (GLfloat) ( User::NTickCount() - instance->iStartTimeTicks ) ) / 1000.f;

#endif

    // Compute the elapsed time since last frame was drawn. Note that due to the
    // resolution of the system timer this value can be 0.0 even though new frames are being rendered.
    // This applies especially when running the emulator on a PC.
    GLfloat deltaTimeSecs = instance->iLastFrameTimeSecs - timeSecs;

    // Set the current time to be the last frame time for the upcoming frame
    instance->iLastFrameTimeSecs = timeSecs;

    if ( instance->iSlideshow->GetState() == CSlideshow::ERunning )
{
        // Call the main OpenGL ES Symbian rendering 'loop'
        instance->iSlideshow->AppCycle( instance->iFrame, timeSecs, deltaTimeSecs );

        // Call eglSwapBuffers, which blit the graphics to the window
        eglSwapBuffers( instance->iEglDisplay, instance->iEglSurface );

        // Suspend the current thread for a short while. Give some time
        // to other threads and AOs, avoids the ViewSrv error in ARMI and
        // THUMB release builds. One may try to decrease the callback
// function instead of this.
        if ( !(instance->iFrame % 50) )
{
        // Reset inactivity timer to keep the background light on
    User::ResetInactivityTime();

            User::After(0);
}
}


// ----------------------------------------------------------------------------
// CSlideshow::AppCycle
// Draws and animates the objects.
// aFrame = Number of the frame to be rendered.
// aTimeSecs = Seconds elapsed since the application started running.
// aDeltaTimeSecs = Seconds elapsed since last call to AppCycle().
// ----------------------------------------------------------------------------
//
void CSlideshow::AppCycle( TInt /*aFrame*/,
                       TReal /*aTimeSecs*/,
                       TReal aDeltaTimeSecs )
{
  // Make sure the timestep is non-zero, since otherwise the animation wouldn't progress at all.
  if (aDeltaTimeSecs < 0.04)
    aDeltaTimeSecs = 0.04;

    // Stop the transition if it's complete
    if (iTransitionRenderer && iTransitionTime <= 0)
        {
        delete iTransitionRenderer;
        iTransitionRenderer = 0;
        iCurrentPicture = iNextPicture;
        }

    // Advance the slideshow if we have been requested to
    if (iRequestedPictureDelta && !iTransitionRenderer)
        {
        iTransitionRenderer = CreateTransitionRenderer((iRequestedPictureDelta > 0) ? ENext : EPrevious);
        iTransitionTime = 1.0;

        TInt direction = (iRequestedPictureDelta > 0) ? 1 : -1;
        iNextPicture = (iCurrentPicture + direction + iPictureCount) % iPictureCount;
        iRequestedPictureDelta -= direction;
        }

    // Render the current picture. If there is no transition going on, enable
    // bilinear filtering to improve image quality.
    iStaticRenderer.Render(iPictures[iCurrentPicture], iTransitionRenderer == NULL);

    // Render the transition and the next picture
    if (iTransitionTime > 0 && iTransitionRenderer)
        {
        iTransitionRenderer->Render(iPictures[iNextPicture], iTransitionTime);
        // Accelerate the transition speed if we are many pictures behind
        iTransitionTime -= aDeltaTimeSecs * (Abs(iRequestedPictureDelta) + 1);
        }
}

Ответить

Номер ответа: 12
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #12
Добавлено: 13.01.08 19:37
Как видишь, время и еще раз время. Посмотри, интересно.

Ответить

Номер ответа: 13
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #13
Добавлено: 13.01.08 20:59
Зачем что-то рассчитывать? Нельзя просто в каждой итерации проверять, сколько времени прошло с последнего отображения, либо запустить рядом тред, который будет нужное время спать, а потом просыпаться и выводить картинку?

Ответить

Номер ответа: 14
Автор ответа:
 ника



Вопросов: 1
Ответов: 111


 Профиль | | #14 Добавлено: 13.01.08 23:11
vito: Огромное спасибо, кажется это именно то что надо, буду разбираться.

Sharp: Что то я не совсем поняла вашу мысль, можно подробней описать вашу идею? :(
либо запустить рядом тред, который будет нужное время спать, а потом просыпаться и выводить картинку?
А откуда этот тред будет брать картинку для вывода? Из какого нибудь массива? Тогда Ваш способ подразумевает хранение всех промежуточных кадров в памяти ( что и предлогали тут ранее) Разве это не расточительство памяти? Или я что то не так поняла?

Ответить

Номер ответа: 15
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #15
Добавлено: 14.01.08 01:36
Из того самого массива, в котором идет обработка. Обернуть его на всякий случай в критическую секцию, чтобы не было беды.

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам