forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Xors3D (http://forum.boolean.name/forumdisplay.php?f=126)
-   -   Image и артефакты (http://forum.boolean.name/showthread.php?t=16434)

Randomize 02.03.2012 01:57

Ответ: Не работает на Win XP SP 3.0
 
Демо поможет.

impersonalis 02.03.2012 02:02

Ответ: Не работает на Win XP SP 3.0
 
Цитата:

Сообщение от Randomize (Сообщение 221198)
Демо поможет.

да с этой функцией ладно: там простое вычисление может ограничить координаты (это скорее было лирическое размышление на счёт картинок). Но вот рисование и установка маски (демки были здесь и в теме про маску) для больших картинок - проблема актуальная (особенно первое).
Да, виноват, надо сопровождать посты и примерами "под ключ" - но сейчас ограничен по времени. Прошу извинить.
Постараюсь завтра реализовать что-то портативное для теста больших картинок.
Ещё раз спасибо всем принявшим участие в обсуждении!

зыж посты потом солью в одну тему по мере конкретизации

Жека 02.03.2012 06:56

Ответ: Не работает на Win XP SP 3.0
 
Цитата:

Сообщение от impersonalis (Сообщение 221188)
апд4: если картинку не грузить, а создавать - то всё работает

на этот счёт мне вспомнились картинки из j2me: те что загружаешь из файла имеют статус immutable, рисовать в них нельзя, а самим созданные имеют статус mutable, в них можно фигачить.
так, к "слову".

impersonalis 02.03.2012 11:21

Ответ: Не работает на Win XP SP 3.0
 
Цитата:

Сообщение от Жека (Сообщение 221210)
на этот счёт мне вспомнились картинки из j2me: те что загружаешь из файла имеют статус immutable, рисовать в них нельзя, а самим созданные имеют статус mutable, в них можно фигачить.
так, к "слову".

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

* - т.е. больше размеров экрана (см. выше).

impersonalis 04.03.2012 03:36

Image и артефакты
 
Вложений: 1
Все тесты могут работать по-разному на разных конфигурациях. Причём дело не в новизне: так, программа, которая заработала у меня некорректно, работала безбажно на древнем конфиге.
Вложение 16272
Тест 1. Работа с буфером.
Тест показывает невозможность рисовать что-либо в загруженную картинку
Код:

    xAppTitle("sample");
        xGraphics3D(800, 600, 32, false, true);
        xSetBuffer(xBackBuffer());
        int FRGM=200;
        bool MOD=false;
    int IMstd;

    IMstd=xLoadImage("Funivia_Rote_Nase_alt_small.jpg");
    if(IMstd==0)
        xAppTitle("n load");
    else
        xAppTitle("OK");


    int CB=xGraphicsBuffer();

    if(MOD){
        xSetBuffer(xImageBuffer(IMstd));
            xLine(0,0,10,10);

    }
    xSetBuffer(CB);

        while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
        {
            xCls();
            xRenderWorld();
        xDrawBlockRect(IMstd,10,10,10,10,FRGM,FRGM);
            xFlip();
        }

    xFreeImage(IMstd);

    return 0;

Если переменную MOD поднять, то будет выполняться дополнительно следующий код
Код:

xSetBuffer(xImageBuffer(IMstd));
            xLine(0,0,10,10);

Который приведёт к краху приложения.

impersonalis 04.03.2012 03:42

Ответ: Image и артефакты
 
Тест 2. Поведение функций при неоднозначных аргументах.
Если в приведённом выше коде исправить значение переменной FRGM, например:
Код:

int FRGM=300;
Вместо рисунка вы увидите чёрный экран, т.к. запросили отрисовать фрагмент изображения, превышающий размер самого изображения.
Согласен: сказать, что это баг - нельзя, но всё же :mad:

SBJoker 04.03.2012 03:47

Ответ: Image и артефакты
 
Кношмаре сказал что загруженные картинки рид-онли.

impersonalis 04.03.2012 04:14

Ответ: Image и артефакты
 
Вложений: 1
Тест 3. Работа с буфером через посредника.
Нет возможности работать с буфером загруженных картинок. Вывод: надо создать картинку в памяти и нарисовать в неё загруженную. Проверим:
Код:

xAppTitle("sample");
        xGraphics3D(800, 600, 32, false, true);
        xSetBuffer(xBackBuffer());

        bool MOD=true;
    int IMstd;

    int IMstd0=xLoadImage("Funivia_Rote_Nase_alt_small.jpg");
    IMstd=xCreateImage(xImageWidth(IMstd0),xImageHeight(IMstd0));


    if(IMstd==0)
        xAppTitle("n load");
    else
        xAppTitle("OK");


    int CB=xGraphicsBuffer();
    xSetBuffer(xImageBuffer(IMstd));
    xDrawBlock(IMstd0,0,0);
    xSetBuffer(CB);
    xFreeImage(IMstd0);

    if(MOD){
        xSetBuffer(xImageBuffer(IMstd));
            xLine(0,0,10,10);
    }
    xSetBuffer(CB);

        while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
        {
            xCls();
            xRenderWorld();
        xDrawBlock(IMstd,10,10);
            xFlip();
        }

    xFreeImage(IMstd);

    return 0;

Всё действительно работает!
Отмечу, что код
Код:

xSetBuffer(xImageBuffer(IMstd));
    xDrawBlock(IMstd0,0,0);
    xSetBuffer(CB);

В принципе может быть заменён на
Код:

xCopyRect(0,0,xImageWidth(IMstd0),xImageHeight(IMstd0),0,0,
              xImageBuffer(IMstd0),xImageBuffer(IMstd));

Но у меня, почему-то в одном месте не заработал - постараюсь разобраться с этим.

Попробуем картинку побольше:
Вложение 16273
Теперь, если выполнить такой код:
Код:

  xAppTitle("sample");
        xGraphics3D(800, 600, 32, false, true);
        xSetBuffer(xBackBuffer());

        bool MOD=true;
    int IMstd;

    int IMstd0=xLoadImage("Funivia_Rote_Nase_alt_med.jpg");
    IMstd=xCreateImage(xImageWidth(IMstd0),xImageHeight(IMstd0));


    if(IMstd==0)
        xAppTitle("n load");
    else
        xAppTitle("OK");


    int CB=xGraphicsBuffer();
    xSetBuffer(xImageBuffer(IMstd));
    xDrawBlock(IMstd0,0,0);
    xSetBuffer(CB);
    xFreeImage(IMstd0);


    if(MOD){
        xSetBuffer(xImageBuffer(IMstd));
            xLine(0,0,10,10);
    }
    xSetBuffer(CB);

        while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
        {
            xCls();
            xRenderWorld();
        xDrawBlock(IMstd,10,10);
            xFlip();
        }

    xFreeImage(IMstd);

    return 0;

Вы вообще ничего не увидите (даже если опустите флаг MOD), а если такой:
Код:

    xAppTitle("sample");
        xGraphics3D(800, 600, 32, false, true);
        xSetBuffer(xBackBuffer());

        bool MOD=true;
    int IMstd;

    int IMstd0=xLoadImage("Funivia_Rote_Nase_alt_med.jpg");
    IMstd=xCreateImage(xImageWidth(IMstd0),xImageHeight(IMstd0));


    if(IMstd==0)
        xAppTitle("n load");
    else
        xAppTitle("OK");


    int CB=xGraphicsBuffer();
    xCopyRect(0,0,xImageWidth(IMstd0),xImageHeight(IMstd0),0,0,
              xImageBuffer(IMstd0),xImageBuffer(IMstd));

    xFreeImage(IMstd0);


    if(MOD){
        xSetBuffer(xImageBuffer(IMstd));
            xLine(0,0,10,10);
    }
    xSetBuffer(CB);

        while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
        {
            xCls();
            xRenderWorld();
        xDrawBlock(IMstd,10,10);
            xFlip();
        }

    xFreeImage(IMstd);

    return 0;

То увидите картинку, но без нарисованной на ней прямой линии.

Выводы:
1) Чтобы иметь возможность работать с буфером загруженной картинки, её необходимо впечатать во вновь созданную.
2) Если размеры картинки превышают размеры окна - описанный выше способ не поможет:
2.1) если вы будете использовать функцию попиксельного копирования xCopyRect, то загруженное изображение корректно перенесётся в буфер созданного в памяти, но рисовать в буфер всё равно не получится - команды не возымеют результата;
2.2) если вы попробуете нарисовать загруженную картинку в буфер созданной - то не получите вообще ничего.

impersonalis 04.03.2012 04:23

Ответ: Image и артефакты
 
Промежуточные выводы:
0)
Рассмотренные особенности могут проявляться, а могут и нет, вне зависимости от новизны железа, битности и версии ОС.
1)
Цитата:

Сообщение от SBJoker (Сообщение 221487)
Кношмаре сказал что загруженные картинки рид-онли.

Используйте посредника.
2)
Лучше отдавать предпочтение рисованию попиксельно (в том числе xCopyRect), нежели xLine, xRect, xDrawImage и прочее.
3)
С изображениями, размеры которых превышают размер окна работать (изменять буфер) всё равно не получится.
Для своей задачи (если кому вдруг интересно) буду использовать свой класс, реализующий разбиение большой картинки на сегменты и предоставляющий интерфейс для работы с получившимся набором как с единым целым.
4)
Команда xMaskImage тоже начинает работать нестабильно на больших изображениях (причём это может наблюдаться даже если остальные описанные здесь артефакты не проявляются).
5) Причины кроются в модели представления картинок в современных движках: картинка=текстура. Отсюда возникают дополнительные требования к размерам и кратности сторон. Подробнее - к SBJoker.
6) Картинка, используемая в тестах - взята отсюда http://commons.wikimedia.org/wiki/Fi...JPG?uselang=ru

impersonalis 05.03.2012 13:42

Ответ: Image и артефакты
 
Вложений: 1
Тест 4. Отрисовка примитивов
Попробуем нарисовать примитив в картинку. Размеры картинки выберем с учётом возможных артефактов: не превосходящими размеры окна. Усложним задачу, назначив точку вывода на 50 пикселей левее и выше начала картинки.
Код:

    xAppTitle("sample");
        xGraphics3D(800, 600, 32, false, true);
    xColor(190,0,0);
    int img=xCreateImage(600,600);
    xSetBuffer(xImageBuffer(img));
    xOrigin(-50,-50);
        xRect(0,0,650,650,true);
        xColor(255,100,0);
        xOval(0,0,650,650,true);
    xSetBuffer(xBackBuffer());
    xOrigin(0,0);
    xColor(255,255,0);
        while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
        {

            xCls();
            xRenderWorld();
        xDrawBlock(img,0,0);
        xRect(0,0,xImageWidth(img),xImageHeight(img),false);
            xFlip();
        }
    return 0;

Что я получаю на выходе:
Вложение 16280
Прямоугольник должен занять всю область т.к. -50+650=600 (начало_вывода+размер=конец_вывода). Визуально - до рамки он не дотягивает. Для контроля вывожу поверх круг, с такими же аргументами - он действительно касается рамки. :4to: Но почему квадрат рисуется неправильно?

impersonalis 05.03.2012 15:27

Ответ: Image и артефакты
 
Такое ощущение, что длина и высота (иначе - размеры) прямоугольника считаются* по формуле:
D=B-abs(A)
(вместо D=B-A)
То есть в рассмотренном выше случае, вместо прямоугольника в 650 пкс длиной мы получаем 650-abs(-50)=650-50=600.
А вот если мы укажем длину 650+50, т.е. 700, и выполним код, то результат буде идеален (получаемое изображение соответствует ожидаемому). Длина при этом как раз равна 700-50=650.
Эта же закономерность была мной проверена на остальных размерах.
Я конечно, заделаю поправку - но не комильфо.

* - вы, конечно, понимаете условность оборота: можно сказать "соответствует в пересчёте", "подчиняется закону", а в следствие чего такая зависимость наступает - известно лишь разработчику.

SBJoker 05.03.2012 16:02

Ответ: Image и артефакты
 
Это всё конечно хорошо, но разработчика, как я понимаю больше нет.

moka 05.03.2012 16:40

Ответ: Image и артефакты
 
Офф форум он посещает ( area.xors3d.com ), а сюда не заходит видимо.

impersonalis 07.03.2012 00:02

Ответ: Image и артефакты
 
Цитата:

Сообщение от SBJoker (Сообщение 221659)
Это всё конечно хорошо, но разработчика, как я понимаю больше нет.



Часовой пояс GMT +4, время: 13:47.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot