Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Z-буффер

Автор: XaMMaX 20.09.2006 0:00

Вот надо отрисовать куб и что бы он отображался правильно тоесть задние части не видны =) Но не знаю как пользоваться z-буффером помогите пожалуйста!

Автор: Malice 20.09.2006 0:28

Для того чтобы отобразить куб, Z-буфер использовать необязательно, достаточно отрисовывать поверхности, начиная с самой дальней. В случае куба вообще можно рисовать только 3 передних, т.к. это максимум, что можно увидеть за раз. И вообще, раз кубик нужен - глянь сюда: http://forum.pascal.net.ru/index.php?showtopic=5854 smile.gif

Автор: XaMMaX 20.09.2006 20:12

Очень сложный для меня пример ещё и с ассемблером =( И всё же хотелось бы именно с z-буффером =)

достаточно отрисовывать поверхности, начиная с самой дальней.
-----
А как мне узнать какая самая дальняя?

Автор: Malice 20.09.2006 21:02

Цитата(XaMMaX @ 20.09.2006 17:12) *

Очень сложный для меня пример ещё и с ассемблером =( И всё же хотелось бы именно с z-буффером =)

Проще некуда smile.gif Ассемблерная функция kp - замена стандартной KeyPressed, добавлена чтоб "Uses crt" не делать smile.gif т.е. можно просто заменить.

Цитата
достаточно отрисовывать поверхности, начиная с самой дальней.
-----
А как мне узнать какая самая дальняя?

Отсортировать smile.gif

А с Z-буфером все равно не получится, либо придется писать свою процедуру FillPoly (и уже не с 2-мя координатами, а 3-мя) т.к. работает он в момент отрисовки.

Автор: XaMMaX 20.09.2006 22:21

Блин, а чё fillpoly только с массивами работает =( Мне нужно просто fillpoly(4,sx1,sy1,sx2,sy2,sx3,sy3,sx4,sy4);
Это возможно реализовать ?

Кстатей вот программа нельзяли кусок кода для неё? Она загружает модель куба из файла и отрисовывает по четыре точки =)


Прикрепленные файлы
Прикрепленный файл  3D.rar ( 887 байт ) Кол-во скачиваний: 204

Автор: volvo 20.09.2006 23:22

Цитата
Мне нужно просто fillpoly(4,sx1,sy1,sx2,sy2,sx3,sy3,sx4,sy4);

Ну, и в чем проблема? smile.gif Про директиву Absolute слышал?

var
sx1,sy1,sx2,sy2,sx3,sy3,sx4,sy4: integer;
arr: array[1 .. 4] of record X, Y: integer end absolute sx1; { <--- должно работать }

...
fillpoly(4, arr);
...


А чем массивы не нравятся? Что, по одной переменной обращаться удобнее? unsure.gif

Автор: Malice 20.09.2006 23:27

Цитата(XaMMaX @ 20.09.2006 19:21) *

Блин, а чё fillpoly только с массивами работает =( Мне нужно просто fillpoly(4,sx1,sy1,sx2,sy2,sx3,sy3,sx4,sy4);
Это возможно реализовать ?

Это очень просто реализовать. Но если ты не можешь переписать все эти значения в массив, то зря ты взялся за 3д (и тем более з-буфер), начни с чего нибудь попроще..

Автор: XaMMaX 21.09.2006 1:56

Это очень просто реализовать. Но если ты не можешь переписать все эти значения в массив, то зря ты взялся за 3д (и тем более з-буфер)
-----
Не впринципе я могу записать это в массив просто не хотелось код изменять =)

начни с чего нибудь попроще..
-----
Всмысле 2д что ли? Или 3д по другому принципу? На Z-буффер я уже забил =) Или есть какие-то программи для подготовки создания 3д?

2volvo
ладно надо попробывать прадо про директиву Absolute не слышал наверное должно быть стыдно =)Не очень понимаю код , но попробую разобраться =)

Автор: XaMMaX 21.09.2006 2:07

Ну вообщем закрашивать получилось теперь надо решить проблему невидимых линий и как-то отсортировать =) Как это сделать именно с этой программой??? Идеи есть?

Автор: XaMMaX 21.09.2006 2:23

program My_3D;
uses graph,crt;
const max=100;

procedure calc(var x,y,z,xt,yt,zt,xan,yan,zan:real); {поворот}
begin
Yt:= Y * COS(Xan) - Z * SIN(Xan);
Zt:= Y * SIN(Xan) + Z * COS(Xan);
Y:= Yt;
Z:= Zt;
Xt:= X * COS(Yan) - Z * SIN(Xan);
Zt:= X * SIN(Yan) + Z * COS(Xan);
X:= Xt;
Z:= Zt;
Xt:= X * COS(Zan) - Y * SIN(Zan);
Yt:= X * SIN(Zan) + Y * COS(Zan);
X:= Xt;
Y:= Yt;

end;

var
gd,gm,i,i1,color:integer;
modelx4,modely4,modelz4,modelx1,modely1,modelz1,modelx2,modely2,modelz2,modelx3,
modely3,modelz3:array[1..max] of real;
xan,yan,zan:real;
yt,xt,zt:real;
sx1,sx2,sx3,sx4,sy1,sy2,sy3,sy4,sz1,sz2,sz3,sz4:integer;
arr: array[1 .. 8] of integer;
modelfile:text;
path:string;
zoom:integer;
begin
gd:=detect;initgraph(gd,gm,'C:\bp\bgi');

xan:=0.03; {сила поворота =) }
yan:=0.03;
zan:=0.03;

zoom:=50;

path:='cube.dat'; {загрузка файла}
assign(modelfile,path);
reset(modelfile);
readln(modelfile,i);

for i1:=1 to i do {складываем числа из файла в массивы с учётом того что мы будем рисовать по квадрату из 4 точек}
begin
readln(modelfile,modelx1[i1],modely1[i1],modelz1[i1],modelx2[i1],modely2[i1],mod
elz2[i1],
modelx3[i1],modely3[i1],modelz3[i1],modelx4[i1],modely4[i1],modelz4[i1]);
end;

repeat

setcolor(white);
for i1:=1 to i do {расчёт и отрисовка}
begin
calc(modelx1[i1],modely1[i1],modelz1[i1],xt,yt,zt,xan,yan,zan);
calc(modelx2[i1],modely2[i1],modelz2[i1],xt,yt,zt,xan,yan,zan);
calc(modelx3[i1],modely3[i1],modelz3[i1],xt,yt,zt,xan,yan,zan);
calc(modelx4[i1],modely4[i1],modelz4[i1],xt,yt,zt,xan,yan,zan);
sx1:=round(zoom*modelx1[i1])+320;
sy1:=round(zoom*modely1[i1])+240;
sx2:=round(zoom*modelx2[i1])+320;
sy2:=round(zoom*modely2[i1])+240;
sx3:=round(zoom*modelx3[i1])+320;
sy3:=round(zoom*modely3[i1])+240;
sx4:=round(zoom*modelx4[i1])+320;
sy4:=round(zoom*modely4[i1])+240;
line(sx1,sy1,sx2,sy2);
line(sx2,sy2,sx3,sy3);
line(sx3,sy3,sx4,sy4);
line(sx4,sy4,sx1,sy1);
arr[1]:=sx1;
arr[2]:=sy1;
arr[3]:=sx2;
arr[4]:=sy2;
arr[5]:=sx3;
arr[6]:=sy3;
arr[7]:=sx4;
arr[8]:=sy4;
color:=i1;
setfillstyle(1,color);
fillpoly(4,arr);
end;

delay(1000);

setcolor(black); {стирание}
for i1:=1 to i do
begin
sx1:=round(zoom*modelx1[i1])+320;
sy1:=round(zoom*modely1[i1])+240;
sx2:=round(zoom*modelx2[i1])+320;
sy2:=round(zoom*modely2[i1])+240;
sx3:=round(zoom*modelx3[i1])+320;
sy3:=round(zoom*modely3[i1])+240;
sx4:=round(zoom*modelx4[i1])+320;
sy4:=round(zoom*modely4[i1])+240;
line(sx1,sy1,sx2,sy2);
line(sx2,sy2,sx3,sy3);
line(sx3,sy3,sx4,sy4);
line(sx4,sy4,sx1,sy1);
arr[1]:=sx1;
arr[2]:=sy1;
arr[3]:=sx2;
arr[4]:=sy2;
arr[5]:=sx3;
arr[6]:=sy3;
arr[7]:=sx4;
arr[8]:=sy4;
setfillstyle(1,black);
fillpoly(4,arr);
end;

until keypressed;
closegraph;
end.

Как здесь отсортировать? wub.gif Мне кажется или придётся тут всё менять nea.gif Плиз помогите мысли перестали поступать в мою голову =)

Автор: Coder_perm 21.09.2006 12:29

XaMMaX, Когда-то давным давно, когда ещё не было графических акселераторов, я этим всем увлекался... Пороюсь в архивал, выложу, что найду!

Автор: XaMMaX 22.09.2006 22:46

Спасибо, а то я сварганил, но чего-то не помjгло не капли =(

min:=1;

for i1:=1 to i-1 do
begin
sum1:=modelz1[min]+modelz2[min]+modelz3[min]+modelz4[min];
sum2:=modelz1[i+1]+modelz2[i+1]+modelz3[i+1]+modelz4[i+1];
if sum1<sum2 then
begin
modelz1[i+1]:=buf1;
modelz2[i+1]:=buf2;
modelz3[i+1]:=buf3;
modelz4[i+1]:=buf4;
buf1:=modelz1[min];
buf2:=modelz2[min];
buf3:=modelz3[min];
buf4:=modelz4[min];
min:=i+1;
end;
end;


Принцип такой: Я отрисовываю по 4 точки так что чтобы узнать какая сторона самая дальняя то я вычесляю сумму и сравниваю со следущими в массиве т.к. у меня всё отрисоввывается в порядке массива!

Плиз хелп по чему не работает разьясните не могу понять вроде всё правильно !!!

Ну, а если вдруг нужен весь код то я разместил исходник!


Прикрепленные файлы
Прикрепленный файл  MY_3D_CO.PAS ( 3.16 килобайт ) Кол-во скачиваний: 246

Автор: XaMMaX 23.09.2006 14:18

Я вас прошу помогите в понедельник надо отдавать прогу!! Плиз что не так в сортировке??? Не могу понять плизз хелп!!

Автор: Mlc 23.09.2006 20:25

А в чем сокраментальный смысл вот этих строк:

Код
   modelz1[i+1]:=buf1;
...
   buf1:=modelz1[min];
...

?
Т.е. сначала координате Z присваивается неопределенное значение buf1, потом определяется buf1. Это во-первых, во-вторых раз уж меняешь местами Z координаты, то меняй и X,Y.

Автор: Гость 23.09.2006 22:36

Блин какой я идиот =( Спасибо большое действительно идиотская ошибка =)

Автор: XaMMaX 23.09.2006 23:06

Блин не помогает

min:=1;

repeat

for i1:=1 to i-1 do
begin
sum1:=modelz1[min]+modelz2[min]+modelz3[min]+modelz4[min];
sum2:=modelz1[i+1]+modelz2[i+1]+modelz3[i+1]+modelz4[i+1];
if sum1<sum2 then
begin
buf1:=modelz1[i+1];
buf2:=modelz2[i+1];
buf3:=modelz3[i+1];
buf4:=modelz4[i+1];
modelz1[i+1]:=modelz1[min];
modelz2[i+1]:=modelz2[min];
modelz3[i+1]:=modelz3[min];
modelz4[i+1]:=modelz4[min];
modelz1[min]:=buf1;
modelz2[min]:=buf2;
modelz3[min]:=buf3;
modelz4[min]:=buf4;

buf1:=modelx1[i+1];
buf2:=modelx2[i+1];
buf3:=modelx3[i+1];
buf4:=modelx4[i+1];
modelx1[i+1]:=modelx1[min];
modelx2[i+1]:=modelx2[min];
modelx3[i+1]:=modelx3[min];
modelx4[i+1]:=modelx4[min];
modelx1[min]:=buf1;
modelx2[min]:=buf2;
modelx3[min]:=buf3;
modelx4[min]:=buf4;

buf1:=modely1[i+1];
buf2:=modely2[i+1];
buf3:=modely3[i+1];
buf4:=modely4[i+1];
modely1[i+1]:=modely1[min];
modely2[i+1]:=modely2[min];
modely3[i+1]:=modely3[min];
modely4[i+1]:=modely4[min];
modely1[min]:=buf1;
modely2[min]:=buf2;
modely3[min]:=buf3;
modely4[min]:=buf4;
min:=i+1;
end;
end;

Чё то мне кажется что условия никогда не выполняется, но почему? Плизз понедельник уже близиться, а ещё не готово!!

Автор: Гость 24.09.2006 13:50

Ну кто-нибудь завтра уже понедельник =( Плизз помогите!

Автор: Malice 24.09.2006 14:26

1. сортировать по удаленности грани нужно только _после_ их поворота, а не перед. Т.е.делать надо в 3 цикла : повернули, отсортировали, вывели. Выводить можно будет с 4-той грани по 6-ю - меньше моргать будет.
2. в процедуре calc напутал с углами - проверь (будет незаметно при одинаковых xan, yan, zan)
3. вместо перерисовки черным поставь просто Cleardevice; smile.gif
4. И вообще, поворачивая фигуру ты новые координаты записываещь в тот же массив, т.е. первоначальной фигуры уже нигде нет, накапливаются ошибки и фигура со временем исказится, захочешь добавить перспективу - не выйдет. Лучше повернутую в другое место.

Автор: Гость 24.09.2006 21:41

Спасибо щас попробую =) Если чего отпишусь =)

Автор: Гость 25.09.2006 2:05

Блин чё-то вроде сортировку сворганил онаработает не идеально вот проверьте плиз в компиляторе

program My_3D;
uses graph,crt;
const max=100;

procedure calc(var x,y,z,xt,yt,zt,xan,yan,zan:real);
begin
Yt:= Y * COS(Xan) - Z * SIN(Xan);
Zt:= Y * SIN(Xan) + Z * COS(Xan);
Y:= Yt;
Z:= Zt;
Xt:= X * COS(Yan) - Z * SIN(Xan);
Zt:= X * SIN(Yan) + Z * COS(Xan);
X:= Xt;
Z:= Zt;
Xt:= X * COS(Zan) - Y * SIN(Zan);
Yt:= X * SIN(Zan) + Y * COS(Zan);
X:= Xt;
Y:= Yt;

end;

var
gd,gm,i,i1,color:integer;
modelx4,modely4,modelz4,modelx1,modely1,modelz1,modelx2,modely2,modelz2,modelx3,
modely3,modelz3:array[1..max] of real;
xan,yan,zan:real;
yt,xt,zt:real;
sx1,sx2,sx3,sx4,sy1,sy2,sy3,sy4,sz1,sz2,sz3,sz4:integer;
arr: array[1 .. 8] of integer;
modelfile:text;
path:string;
zoom:integer;
buf1,buf2,buf3,buf4:real;
sum1,sum2:integer;
j1,j2,j3,j4,j1a,j2a,j3a,j4a:integer;

begin
gd:=detect;initgraph(gd,gm,'C:\bp\bgi');

xan:=0.01;
yan:=0.01;
zan:=0.01;

zoom:=50;

path:='cube.dat';
assign(modelfile,path);
reset(modelfile);
readln(modelfile,i);

for i1:=1 to i do
begin
readln(modelfile,modelx1[i1],modely1[i1],modelz1[i1],modelx2[i1],modely2[i1],mod
elz2[i1],
modelx3[i1],modely3[i1],modelz3[i1],modelx4[i1],modely4[i1],modelz4[i1]);
end;

repeat

setcolor(white);
for i1:=1 to i do
begin
calc(modelx1[i1],modely1[i1],modelz1[i1],xt,yt,zt,xan,yan,zan);
calc(modelx2[i1],modely2[i1],modelz2[i1],xt,yt,zt,xan,yan,zan);
calc(modelx3[i1],modely3[i1],modelz3[i1],xt,yt,zt,xan,yan,zan);
calc(modelx4[i1],modely4[i1],modelz4[i1],xt,yt,zt,xan,yan,zan);
end;

for i1:=1 to i-1 do
for i1:=1 to i-1 do
begin
j1:=round(modelz1[i1]);
j2:=round(modelz2[i1]);
j3:=round(modelz3[i1]);
j4:=round(modelz4[i1]);
sum1:=j1+j2+j3+j4;
j1a:=round(modelz1[i1+1]);
j2a:=round(modelz2[i1+1]);
j3a:=round(modelz3[i1+1]);
j4a:=round(modelz4[i1+1]);
sum2:=j1a+j2a+j3a+j4a;


if sum1<sum2 then
begin
buf1:=modelz1[i1+1];
buf2:=modelz2[i1+1];
buf3:=modelz3[i1+1];
buf4:=modelz4[i1+1];
modelz1[i1+1]:=modelz1[i1];
modelz2[i1+1]:=modelz2[i1];
modelz3[i1+1]:=modelz3[i1];
modelz4[i1+1]:=modelz4[i1];
modelz1[i1]:=buf1;
modelz2[i1]:=buf2;
modelz3[i1]:=buf3;
modelz4[i1]:=buf4;

buf1:=modelx1[i1+1];
buf2:=modelx2[i1+1];
buf3:=modelx3[i1+1];
buf4:=modelx4[i1+1];
modelx1[i1+1]:=modelx1[i1];
modelx2[i1+1]:=modelx2[i1];
modelx3[i1+1]:=modelx3[i1];
modelx4[i1+1]:=modelx4[i1];
modelx1[i1]:=buf1;
modelx2[i1]:=buf2;
modelx3[i1]:=buf3;
modelx4[i1]:=buf4;

buf1:=modely1[i1+1];
buf2:=modely2[i1+1];
buf3:=modely3[i1+1];
buf4:=modely4[i1+1];
modely1[i1+1]:=modely1[i1];
modely2[i1+1]:=modely2[i1];
modely3[i1+1]:=modely3[i1];
modely4[i1+1]:=modely4[i1];
modely1[i1]:=buf1;
modely2[i1]:=buf2;
modely3[i1]:=buf3;
modely4[i1]:=buf4;
end;
end;

for i1:=4 to i do
begin
sx1:=round(zoom*modelx1[i1])+320;
sy1:=round(zoom*modely1[i1])+240;
sx2:=round(zoom*modelx2[i1])+320;
sy2:=round(zoom*modely2[i1])+240;
sx3:=round(zoom*modelx3[i1])+320;
sy3:=round(zoom*modely3[i1])+240;
sx4:=round(zoom*modelx4[i1])+320;
sy4:=round(zoom*modely4[i1])+240;
line(sx1,sy1,sx2,sy2);
line(sx2,sy2,sx3,sy3);
line(sx3,sy3,sx4,sy4);
line(sx4,sy4,sx1,sy1);
arr[1]:=sx1;
arr[2]:=sy1;
arr[3]:=sx2;
arr[4]:=sy2;
arr[5]:=sx3;
arr[6]:=sy3;
arr[7]:=sx4;
arr[8]:=sy4;
color:=i1;
setfillstyle(1,color);
fillpoly(4,arr);
end;

delay(5000);
cleardevice;

until keypressed;
closegraph;
end.

Сами видете как рисуется =( Есть предложение?? Плизз срочно!!

Автор: XaMMaX 25.09.2006 2:18

Вообщем понятно почему так происходит так что думаю нужен другой способ сортировки так что хелпппп!!!

Автор: Гость 25.09.2006 12:06

Интересный цикл: smile.gif

Код
for i1:=1 to i-1 do
for i1:=1 to i-1 do

поменяй на
Код
for i1:=1 to i-1 do
for i2:=i1+1 to i do

и в цикле "i1+1" меняй на i2.

Автор: XaMMaX 25.09.2006 22:27

Спасибо конечно , но сути проблемы это не решает =(

Автор: Malice 26.09.2006 16:41

Цитата(XaMMaX @ 25.09.2006 19:27) *

Спасибо конечно , но сути проблемы это не решает =(

Решает, только ты зачем-то по ходу исправления добавляешь новых багов там, где все было правильно.

Код
  j1:=round(modelz1[i1]);
  j2:=round(modelz2[i1]);
  j3:=round(modelz3[i1]);
  j4:=round(modelz4[i1]);
  sum1:=j1+j2+j3+j4;
  j1a:=round(modelz1[i1+1]);
  j2a:=round(modelz2[i1+1]);
  j3a:=round(modelz3[i1+1]);
  j4a:=round(modelz4[i1+1]);
  sum2:=j1a+j2a+j3a+j4a;


У тебя все координаты в пределах [-1,1], после Round там будет не то, что должно и сортировка не сработает. Делай sum1 и sum2 тип real и суммируй сразу без round и кучи переменных.

Автор: XaMMaX 26.09.2006 18:54

Ух ты и правда проблема в этом и была!! Спасибо тебе огромное!!!!

Автор: Coder_perm 28.09.2006 12:06

XaMMaX, вот я и порылся в архивах, как обещал. Прикрепляю исходник.

Реализовано текстурирование и Z-буфер smile.gif
Комментарии отсутствуют, так что думаю возникнет куча вопросов... отвечу с удовольствием.

Прикрепленный файл  Cube_tl.rar ( 29.34 килобайт ) Кол-во скачиваний: 374


А http://forum.pascal.net.ru/index.php?showtopic=12859 выложил то, что в итоге получилось. Там вся математика целочисленная.

Автор: XaMMaX 28.09.2006 19:13

Ух ты класс =) Только действительно сложно для моего понимания сразу с текстурами и отражением wacko.gif
Мне всё это надо поэтапно =) но в дальнейшим прегодится =) Как избавлюсь от мерцания дальше свет->Z-буффер->текстуры и путь будет оч сложным я думаю =(