Потом моя долбанутая система обрезания геометрии контролов scissor-ом начала фейлить – Tab внутри Tab-а начал бажить, если заходил за границы клиентской области родителя.
Теперь вроде всё ок. Скроллится, двигается, нажимается… Только скин надо на XML перенести, а то пока не совсем гибко :
Но написать надо! Ведь использование готового – не есть путь для настоящих джедаев (дада, напишу потом компилер, ОС, комп спаяю, генератор энергии сооружу и т.п.)
Итак, что изменилось:
1. Ололош, внутри опять всё переписал, на этот раз намного чётче! GUI теперь может хендлить разные виды топологии геометрии (юзаю для линий)
2. GUI теперь поддерживает рендеринг сплайнов! Юхуу!
3. ДОБАВИЛ НАКОНЕЦ Drag & Drop !! Вон на скрине у нодов есть синие хреньки – прямоугольники! Просто наживаем мышей на один и перетягиваем на другой, отпускаем мышь иии..БАЦ ) Сплайном соединились! Чотко же! = )
Осталось сделать удаление связей (и дохрена контролов типа TabControl ). WTF! Уже 4:25!!!!!!! Ушёл спать, срочно!
Вот оно, ребята, GUI моей мечты! 😀 Не, ну оформление конечно кака, но не суть ) Главное ведь что оно своё :3
upd: дада! Опять без скина GUI ) Скины поддерживаются но мне лениво их рисовать 😀
Что изменилось:
Теперь рендеринг всего GUI идёт обычно в 1-5 DIP-ов а не в 100500 как раньше. Сам по себе GUI не только может, но и рисуется ровно в 1 DIP, однако дополнительные ДИП-ы нужны, если в нём юзаются пользовательские текстуры! На скрине, приведённом выше, количество DIP-ов = 3 потому что вон та хренька красная сверху слева – это текстура сцены, которая какраз перед рендером GUI и рисуется. Из за неё и не 1 а 3 дипа: рисуем GUI до картинки, рисуем картинку, рисуем остальное.
То есть я вместо моего адски дебилоидного рендеринга (каждый элемент рисовал сам себя, имел СВОЙ вершинный и константный буфер..омг) сделал чоткий батчинг : )
На самом деле это конечно не сложно совсем. Но кое что изначально слегка напрягло: родительские контролы должны собой обрезать дочерние контролы, чтобы дочерние не рендерились за границами родительских. Раньше я рекурсивно рендерил, постоянно спуская ScissorRectangle и применяя его для каждого контрола. И было всё вздрыжне. НО! Теперь то у меня всё всё всё может нарисоваться за 1 DIP! И Scissor хардварный не применить ( Бида! Вот пришлось симулировать его – вручную обрезаю scissor-ом квады контролов (модифицирую геометрию и текстурные координаты квадов). Впринципе тоже детсвкая задача : ) Обрезание геометрии делается прямо во время её генерации, а генерация вызывается если изменился scissor. Всё просто.
На скрине новые контролы (сейчас сел и допилил их):
1. ScrollBar – он один для вертикального и горизонтального скроллирования! Конструктор требует, чтобы юзер указал направление скроллинга
2. ScrollablePlane – вон тот квадратик посреди скрина с 2 скроллами сразу. ScrollablePlane – наследник Plane + добавил скроллы. Можно скроллить теперь контент очень удобно : ) Надо бы прикрутить “кинетические скроллы” (точнее эти модифицировать), чтобы можо было дёрнуть ползунок, а он ещё будет некоторое время двигаться, останавливаясь (как сейчас на мобилах любят делать)
Adios, ушёл дальше болеть : (
Первое, что пришло в голову – подменить у класса виртуальный метод :3 Легального способа тут конечно нет, но just for fun можно VisualStudio-only намутить код ) Всё тут просто – у каждого объекта любого класса при наличии в классе виртуальных методов в самом начале записывается указатель на таблицу виртуальных методов этого класса. Таблица – просто набор указателей на методы! Осталось написать подложный метод и перезаписать указатель в таблице виртуальных методов ^^ Что я, собственно, и сделал. И.. и обломался: access violation writing location… )
vtable записывается в read-only память : Бида… казалось бы ) Но за что я люблю С++ (в отличае от шарпа на котором раньше писал) – в нём можно сделать всё, даже то, что запрещено 😀
VirtualQuery, VirtualProtect спасут отца Русской демократии.
struct Foo
{
virtual void VirtualMethod(){
printf(“VIRTUAL METHODn”);
}
};
void ReplacementFunc(){
printf(“LOL FUNCTION!!n”);
}
int _tmain(int argc, _TCHAR* argv[])
{
typedef void (*func)();
Foo* foo = new Foo();
size_t* vtbl;
memcpy(&vtbl, foo, sizeof(size_t));
func ptr = &ReplacementFunc;
MEMORY_BASIC_INFORMATION meminfo;
DWORD oldprotect;
VirtualQuery(&vtbl[0], &meminfo, sizeof(meminfo));
VirtualProtect(meminfo.BaseAddress, 4, PAGE_EXECUTE_READWRITE, &oldprotect);
memcpy(&vtbl[0], &ptr, sizeof(func));
foo->VirtualMethod(); //тадааам ) В консоли: LOL FUNCTION!!
getchar();
return 0;
}
Блджад, почему тут нету тега ? Или есть..
Буду искать новые извращения и потом добавлять сюда, а пока надо делами заниматься.
Продолжил пилить, фиксить баги и т.п. Ноды вроде работают без проблем! Но ноды эти надо связывать между собой! Т.е. выходы одних с входами других.
Для этого везде юзаются кривые Безье. Вот я и подумал – а чем я хуже? : ) Решил погуглить тему, так как раньше не нужна была – не занимался. Погуглил, покурил.. ох ёпт!! Я то думал там будет ацкая жесть с километровыми формулами, а там оказалась детская задачка ))
Вот на своём софтрендере замтил отрисовку этих самых кривых ^^ С-К-А-Ч-А-Т-Ь 90кб всего, статично слинковал с рантаймом (просить не должно). M$ Windows only.
Но главное что дописал – “обрезание” контролов scissor-ом родителя. Я думал, что я сделал это давно, а оказалось не сделал ) 😀 Теперь всё зачОтненько рендерится, быстро и правильно )
Слегка пофиксил сплит-контейнеры, допилил класс виджета-узла графа шейдерного редактора, сделал его ресайзинг )
Скины поддерживаются, однако я их пока не рисовал и контролы просто заливаются дефолтным цветом, который я рендомно выставил как-то однажды и забил : )
Вот WIP (work in progress) скрин того, с чем я работаю. Поясню:
1. Тут не все поддерживаемые контролы 😀 Тут только то, что я прямо сейчас тестирую, не более.
2. Тут нету скина (не применён) и т.е. нет текстур.
3. На скрине 2 сплит-контейнера, 2 кнопки, 1 pictureBox (в который выводится отрендеренная сцена), 1 shaderNode
Мой GUI – сразу же с первых минут жутко зафейлился по всем фронтам ( И началось его дописывание/переписывание. : )
1. Добавил SplitContainer контрол. Нужен мне для UI редактора (ну, это контрол где есть 2 панельки и полоса-разделитель. которую таскать можно). Работает теперь отлично!
2. Сегодня при поддержке одного друга пофиксил 100500 багов в моём текстовом классе! А именно: горизонтальное, вертикальное выравнивание, отступы букв друг от друга, правильное получение размеров строки (в пикселях) и много чего ещё попутно ). Теперь текст рендерится правильно и чётко по центру (если стоИт выравнивание по центру). В общем _теперь_ я доволен рендерингом текста )
3. Меняю иерархию классов “виджетов”. Теперь моего брутального и бессердечного кода нет. Всё чисто, лаконично и красиво )
Допиливаю другие контролы… скоро будут скрины ^^