Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

ZBuffer


dmk ©   (16.04.17 22:46

Смастерил свой ZBuffer. Алгоритм простой, но у меня не работает в некоторых случаях. Может глаз замылился, может не вижу очевидного.
Смысл в том, что отсечение по глубине делается попиксельно, а соответственно должно работать независимо от порядки отрисовки объектов, но выходит так, что дальний объект рисуется поверх ближнего.
Вот и думаю как такое может быть?

Тут картинка: https://hostingkartinok.com/show-image.php?id=19e75764f790be54b1b68c67cf4e2e09

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


const
 MAXZDEPTH = $7FFFFFFF;

procedure TBitmap64.ClearZBuffer;
begin
 if (FZBuffer <> nil) then StoreDWords(FZBufferAddr, (FZBufferSize shr 2), MAXZDEPTH);
end;



Все объекты на картинке нарисованы этими двумя процедурами.
Логика ZPixel простая — всегда рисуется самый ближний пиксел.


procedure TBitmap64.ZPixel32(x, y, z: integer; dColor: TColorRef);
var
 zA: TAddress;

begin
 if FClipRegion.PtInRegion(x, y) then
 begin
   zA := ZAddress32(x, y);
   if (z < PInteger(zA)^) then //Всегда рисуем более ближний пиксел
   begin
     PInteger(zA)^ := z; //Новая позиция в Z-Buffer
     PDWord(PixelAddress32(x, y))^ := dColor;
   end;
 end;
end;

procedure TBitmap64.ZLine(x0, y0, z0, x1, y1, z1 : integer; dColor: TColorRef);
var
 x, y: integer;
 fX, fY, fZ: float;
 cr: TClipStruct;
 lp: integer;
 gradX, gradY, gradZ: float;
 i: integer;
 z: integer;
 dZ, dL: integer;
 w, h: integer;

begin
 //2D-отсечение
 if not ClipLine(x0, y0, x1, y1, cr) then exit;

 //Длинная сторона линии
 dL := Max(cr.W, cr.H);
 //глубина линии по Z
 dZ := Abs(z1 - z0);
 //Стартовая глубина
 z := z0;
 //Стартовая глубина для приращения
 fZ := z;

 //Шаг по Z
 if (z0 = z1) then
 begin
   gradZ := 0;
 end
 else
 if (z1 > z0) then
 begin
   //Шаг приращения Z
   gradZ := Abs(dZ / dL);
 end
 else
 if (z0 > z1) then
 begin
   //Шаг приращения Z
   gradZ := -(dZ / dL);
 end;

 //Учет последней точки
 if FDrawLastPoint then lp := 0 else lp := 1;

 x := cr.x0;
 y := cr.y0;

 //Горизонтальная линия
 if (cr.dx > cr.dy) then
 begin
   //Приращение по Y
   gradY := (cr.gradY * cr.yinc);

   //Горизонтальная ПРЯМАЯ линия
   if (gradY = 0) then
   begin
     //Выбор первой точки с которой начинается отрисовка линии
     if (cr.xinc = 1) then x := cr.x0 else x := cr.x1;

     //Цикл по ширине линии
     for i := 1 to (cr.W - lp) do
     begin
       //Точка
       ZPixel32(x, y, z, dColor);
       //Приращение X
       x := (x + cr.xinc);
       //Приращение Z
       fZ := (fZ + gradZ);
       //Целочисленный Z
       z := Round(fZ);
     end;
   end
   else
   //НЕ прямая горизонтальная линия
   begin
     //Приращение по Y
     fY := y;

     //Цикл по ширине линии
     for i := 1 to (cr.W - lp) do
     begin
       //Точка
       ZPixel32(x, y, z, dColor);
       //Приращение X
       x := (x + cr.xinc);
       //Приращение Y
       fY := (fY + gradY);
       //Приращение Z
       fZ := (fZ + gradZ);
       //Целочисленный Y
       y := Round(fY);
       //Целочисленный Z
       z := Round(fZ);
     end;
   end;
 end
 //Вертикальная линия
 else
 begin
   //Приращение по X
   gradX := (cr.gradX * cr.xinc);

   //Вертикальная ПРЯМАЯ линия
   if (gradX = 0) then
   begin
     //Выбор первой точки с которой начинается отрисовка линии
     if (cr.yinc = 1) then y := cr.y0 else y := cr.y1;

     //Цикл по высоте линии
     for i := 1 to (cr.H - lp) do
     begin
       //Целочисленный Z
       z := Round(fZ);
       //Точка
       ZPixel32(x, y, z, dColor);
       //Приращение Y
       y := (y + cr.yinc);
       //Приращение Z
       fZ := (fZ + gradZ);
     end;
   end
   else
   //НЕ прямая вертикальная линия
   begin
     //Приращение по X
     fX := x;

     //Цикл по высоте линии
     for i := 1 to (cr.H - lp) do
     begin
       //Точка
       ZPixel32(x, y, z, dColor);
       //Приращение X
       fX := (fX + gradX);
       //Приращение Y
       y := (y + cr.yinc);
       //Приращение Z
       fZ := (fZ + gradZ);
       //Целочисленный X
       x := Round(fX);
       //Целочисленный Z
       z := Round(fZ);
     end;
   end;
 end;
end;


dmk ©   (16.04.17 23:30[1]

Вопрос отпал. Это я лошара. Буфер очищался каждый раз при отрисовке объектов.
Вынес за цикл отрисовки - все исправилось. Извиняшки!


dmk ©   (17.04.17 00:08[2]

Работает ;)
https://hostingkartinok.com/show-image.php?id=9eda56acf0e5e4beb24472f9b8f41ec6


D7   (24.04.17 11:56[3]

Я пытался скачать ваши разные демки (ссылки из разных тем), но все ссылки дохлые.
Если можно - загрузите куда-то на Яндекс.Диск что ли, очень любопытно посмотреть. Спасибо!


dmk ©   (24.04.17 19:47[4]

>Я пытался скачать ваши разные демки (ссылки из разных тем), но все ссылки дохлые.
Удалил. Попозже выложу. Только это не демки - это просто разработка своей 3D-библиотеки. Она сыровата во многих местах.


dmk ©   (24.04.17 21:27[5]

Здесь EXE(64):
https://cloud.mail.ru/public/FRPk/owdwz7dgR

Здесь картинка:
https://hostingkartinok.com/show-image.php?id=105a8ff7a70052f7de9fd108b999e3a1

Еще в процессе разработки, поэтому DivideByZero и AV вполне возможны.
F - на полный экран
На 3D-объекты камерой лучше не наезжать.


dmk ©   (29.04.17 18:43[6]

Тут полетать вокруг объектов можно
https://cloud.mail.ru/public/MBsB/czGvVeK2n

WSAD - обычная раскладка
QE - вверх/вниз

ALT - вращение по X

Колесо мыши - масштаб.

ESC - прервать тест или если не тест, то выход

В 3D-массив добавлена поддержка потоков.
У меня 50 тыс. объектов с включенной заливкой ~60 fps ;)
Для софтверного движка и начала думаю неплохо.


dmk ©   (29.04.17 19:00[7]

SHIFT - ускорение.
Не 50 тыс, а 5 тысяч. Извиняюсь.
Разрешение 2560×1600.


dmk ©   (22.06.17 03:10[8]

Новый вариант. Теперь добавил свет.
https://hostingkartinok.com/show-image.php?id=3eecb14661b03bf92057c1ed64d41df9

Тут EXE64: https://cloud.mail.ru/public/3YxC/kqXfVsj9k

gray +, gray- : Вращение света. Свет глобальный.

WSAD - передвижение
QE - вверх/вниз
с ALT - свободный полет
C - точкой вращения будет источник света.
Стрелки - передвигать объекты
NumPad 4 и 6 - вращать объекты

Массив объектов - просто летящие треугольники.
https://hostingkartinok.com/show-image.php?id=8bf2072e54f09da0bc7427059de4d531

Сначала включить 3д-объекты для инициализации света, а потом можно переключить на массив. Включить заливку и другой фон, а то почти ничего не видно по умолчанию.
Все еще пилю :)


Pavia ©   (24.06.17 16:47[9]

Меню с лева не помещается на экране 1366х768


dmk ©   (24.06.17 20:30[10]

ну да. В новой версии помещается. Потом выложу. Сейчас фруструм и отсечение дописываю.


dmk ©   (24.06.17 23:38[11]

Самое главное, что видеокарта здесь не используется вообще. И все написано на Delphi.
Тяжеловато с математикой. Говорили мне «учи матчасть» :)


Игорь Шевченко ©   (25.06.17 10:30[12]


> И все написано на Delphi.


компилятор Delphi генерирует не самый оптимальный код, особенно для 64-х разрядной платформы. "Все написано на Delphi" - не повод для хвастовства.


dmk ©   (25.06.17 13:20[13]

>генерирует не самый оптимальный код
критические участки оптимизированы на ассемблере, в основном отрисовка и трансформация. Да и не хвастался я в общем. Меня просили выкладывать, что получается.
а ссылки мне нужны самому для проверки на других машинах.


dmk ©   (25.06.17 13:32[14]

Сделал 3 уровня оптимизации. 1. На «чистом Delphi» 2. MMX 3. SIMD.
На чистом Delphi около 25 fps. На MMX около 50 fps. SIMD - 70 и выше fps. Хотя в целом все зависит от кол-ва полигонов. 30K-50K полигонов при 30 fps стабильно на одном ядре.
Можно еще AVX, AVX2 использовать, но к сожалению пока AVX не на всех процессорах присутствует. Потом все распараллелю на другие ядра.


dmk ©   (25.06.17 14:05[15]

Новый EXE  с укороченным меню.
https://cloud.mail.ru/public/LFYU/mYd1C2Per

F - FullScreen.
Вращение объекта: NumPad 4/6 + shift + отпустить NumPad 4/6.
Остановить вращение: NumPad 4/6.

gray +, gray- : Вращение света по Z, а с Ctrl по Y


Pavia ©   (25.06.17 21:13[16]

Из явных глюков:
1) При старте не обновляется форма. Скорее всего при ресайзе.
https://yadi.sk/i/cehpw0ff3KSRaM
2) 4 поточный https://yadi.sk/i/KTIwNayA3KSRCu
3) 3D-массив просит выключить 3D объекты?!

Если не трудно, можете провести испытание скорости на TLazyBitmap;
https://yadi.sk/d/6wtcRRaN3KSRqS


dmk ©   (26.06.17 03:47[17]

Потоки не работают пока на 3D. Только на 2D. Если включить например 20-40к линий, то будет видна разница между 1 потоком и несколькими. Потоки пока только на линии, круги и треугольники работают. Мне нужно чтобы понять как с потоками работать и насколько шустрее рисует. На моем компе раз в 7-10 быстрее. у меня 10-и ядерник. Мне это для теста стабильности надо. Я например включаю 750 тысяч линий и жду. + глюки хорошо выявляет.

Тест Лэзи
https://hostingkartinok.com/show-image.php?id=5f0814b8510a4838c5ea1f61117806bd


dmk ©   (26.06.17 04:12[18]

>3) 3D-массив просит выключить 3D объекты?!
Да. Общие переменные используются. Если их вместе включить, то будет AV.

Это просто тестовая площадка. Пытаюсь игрушку написать :)
Вот кусочек уровня: https://hostingkartinok.com/show-image.php?id=c04e41c84e7ea7d2f616f052d51ffe11


dmk ©   (26.06.17 04:27[19]

Или шахматишки очередные можно ;)
https://hostingkartinok.com/show-image.php?id=cfe5152555e11892ec2bf8b1d8d808d3


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо