Михаил Краснов - Графика DirectX в Delphi

Тут можно читать онлайн Михаил Краснов - Графика DirectX в Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Графика DirectX в Delphi
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    3.56/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Михаил Краснов - Графика DirectX в Delphi краткое содержание

Графика DirectX в Delphi - описание и краткое содержание, автор Михаил Краснов, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Графика DirectX в Delphi - читать онлайн бесплатно ознакомительный отрывок

Графика DirectX в Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Михаил Краснов
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

x := random(NumX - 3) + 1;

z := random(NumZ - 3) + 1;

Land[x,z].h := random(500);

end;

// Усредняем высоты соседних точек, чтобы получить плавные холмы

for k := 1 to FlatLand do

for i:= 2 to NumX. do

for j := 2 to NumZ do

Land[i,j].h := (Land[i,j].h +

Land[(i + 1) mod NumX,j].h +

Land[i - 1, j].h +

Land[i, (j + 1) mod NumZ].h +

Land[i, j - 1].h) / 5;

// Приводим данные к удобному виду, задаем цвет вершин

for i := 1 to NumX do

for j := 1 to NumZ do

with Land[i,j] do begin

h := h / 100; if h > 0.85 then h := 0.85;

if h > 0.4 // Высокие вершины окрашиваем белым цветом

then Land[i,j].Color := $00FFFFFF else

if h > 0.2 // Точки чуть ниже - коричневым

then Land[i,j].Color := $00804000 else

if h > 0.1 // Вершины еще ниже - желтые

then Land[i,j].Color := $00FFFF00

// Точки на равнине - зеленые

else Land[i,j].Color := $0000FF00;

end;

// Рассчитываем нормали к вершинам

for i := 1 to NumX - 1 do

for j := 1 to NumZ do

CalcNormals (D3DVector (i * Step, Landfi, j - 1].h, (j - 1) * Step),

D3DVector (i * Step, Land[i, j].h, j * Step),

DSDVector ((i + 1) * Step, Landfi + 1, j - l].h,

(j - 1) * Step), Land[i, j].VecNormal);

end;

Данные модели считываются из текстового файла. В буфере вершин первые четыре вершины отводятся для построения отдельного квадрата ландшафта:

function TfrmDSD.InitVB : HRESULT;

var

Vertices : ^TCustomVertex;

hRet : HRESULT;

t : TextFile;

wrkVec : TD3DVector;

begin

FDSDDevice.CreateVertexBuffer(20665 * SizeOf(TCustomVertex), 0,

DSD FVF_CUSTOMVERTEX,

D3DPOOL_DEFAULT, FD3DVB);

FD3DDevice.SetStreamSource(0, FD3DVB, SizeOf(TCustomVertex));

FD3DVB.Lock(0, 20665 * SizeOf(TCustomVertex), PByte(Vertices), 0);

Inc (Vertices); // Первые четыре вершины отводятся для построения

Inc (Vertices); // отдельного квадрата ландшафта

Inc (Vertices);

Inc (Vertices);

AssignFile (t, 'Boeing.txt1);

Reset (t);

while not EOF(t) do begin

Readln (t, wrkVec.X); // Считываем вектор нормали

Readln (t, wrkVec.Y);

Readln (t, wrkVec.Z);

// Считываем вершины очередного треугольника

Readln (t, Vertices.X);

Readln (t, Vertices.Y);

Readln (t, Vertices.Z); .

// Исходные данные модели масштабируются

Vertices.X := Vertices.X / 3;

Vertices.Y := Vertices.Y / 3;

Vertices.Z := Vertices.Z / 3;

Vertices.normVector := wrkVec;

Vertices.Color := $00808080; // Цвет - серебристый

Inc (Vertices);

Readln (t, Vertices.X);

Readln (t, Vertices.Y);

Readln (t, Vertices.Z);

Vertices.X := Vertices.X / 3;

Vertices.Y := Vertices.Y / 3;

Vertices.Z := Vertices.Z / 3;

Vertices.normVector := wrkVec;

Vertices.Color := $00808080;

Inc (Vertices);

Readln (t, Vertices.X);

Readln (t, Vertices.Y);

Readln (t, Vertices.Z) ;

Vertices.X := Vertices.X / 3;

Vertices.Y := Vertices.Y / 3;

Vertices.Z := Vertices.Z / 3;

Vertices.normVector := wrkVec;

Vertices.Color := $00808080;

Inc (Vertices);

end;

CloseFile (t); FD3DVB.Unlock;

Result := FD3DDevice.SetVertexShader(D3DFVF_CUSTOMVERTEX);

end;

После считывания данных модели поворачиваем ее вокруг собственных осей:

procedure TfrmD3D.FormCreate(Sender: TObject);

var

hRet : HRESULT;

matView, matProj : TD3DMatrix;

matWrkl, matWrk2 : TDSDMatrix;

begin

Randomize; // Ландшафт генерируется каждый раз по-новому

ShowCursor (False); // Устанавливаем полноэкранный режим

hRet := InitD3D;

if Failed (hRet) then ErrorOut ('InitD3D', hRet);

hRet := InitVB;

if Failed (hRet) then ErrorOut ('InitVertex', hRet);

SetupLights;

// Поворачиваем самолет

SetRotateXMatrix(matWrkl, Pi / 2);

SetRotateZMatrix(matWrk2, Pi);

SetTranslateMatrix (matAirplan, 7.0, 2.0, 5.0);

// Первоначальная матрица трансформаций для самолета

matAirplan := MatrixMul (matAirplan, MatrixMul (matWrk2, matWrkl));

GenLand; // Генерируем ландшафт пейзажа

SetViewMatrix(matView, D3DVector(16, 2.5, 5),

D3DVector(0, 0, 5), D3DVector(0, 1, 0));

FD3DDevice.SetTransform(D3DTS_VIEW, matView);

SetProjectionMatrix(matProj, 1, 1, 1, 15);

FD3DDevice.SetTransform(D3DTS_PROJECTION, matProj);

end;

Ландшафт рисуется на основе данных массива, по отдельным квадратикам:

arocedure TfrmDSD.DrawArea(const x, у : Integer);

var

Vertices : ATCustomVertex;

b egin

FD3DVB.Lock(0, 4 * SizeOf(TCustomVertex), PByte(Vertices), 0) ;

Vertices.X := x * Step;

Vertices.Y := Land[x, у - 1].h;

Vertices.Z := (y - 1) * Step;

Vertices.normVector := Land[x, у - 1].VecNormal;

Vertices.Color := Land[x, у - 1].Color;

Inc (Vertices);

Vertices.X := x * Step;

Vertices.Y := Landfx, y].h;

Vertices.Z := у * Step;

Vertices.normVector := Land[x, y].VecNormal;

Vertices.Color := Landfx, y].Color;

Inc (Vertices);

Vertices.X := (x + 1) * Step;

Vertices.Y := Landfx + 1, у - 1].h;

Vertices.Z := (y - 1) * Step;

Vertices.normVector := Land[x + 1, у - 1].VecNormal;

Vertices.Color := Land[x + 1, у - 1].Color;

Inc (Vertices);

Vertices.X := (x + 1) * Step;

Vertices.Y := Land[x +1, y].h;

Vertices.Z := у * Step;

Vertices.normVector := Land[x + 1, y].VecNormal;

Vertices.Color := Land[x + 1, y].Color;

FD3DVB.Unlock;

FD3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) ;

end;

function TfrmD3D.Render : HRESULT;

var

hRet : HRESULT;

i, j :Integer;

begin

// Экран окрашивается голубоватым цветом

FD3DDevice.Clear(0, nil, D3DCLEARJTARGET or D3DCLEAR_ZBUFFER,

$00000FFF, 1.0, 0);

FD3DDevice.BeginScene; with FD3DDevice do begin

SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

// Треугольники ландшафта перечисляются по часовой стрелке

SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

// Вершины ландшафта сгенерированы в мировой системе координат

SetTransform(D3DTS_WORLD, IdentityMatrix);

end;

// Выводим квадратики ландшафта

for j := 2 to NumZ - 1 do

for i := 1 to NumX - 5 do DrawArea(i,j);

with FD3DDevice do begin

// Устанавливается матрица трансформаций самолета

SetTransform(D3DTS_WORLD, matAirplan);

// Вершины модели перечисляются против часовой стрелки

SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

// Данные располагаются, начиная с четвертой вершины

DrawPrimitive(D3DPT_TRIANGLELIST, 4, 20661 div 3);

end;

FD3DDevice.EndScene;

Result := FDSDDevice.Present(nil, nil, 0, nil) ;

end;

После того, как нарисован самолет, текущей трансформацией мировой матрицы остается матрица трансформаций нашей модели, поэтому перед рисованием ландшафта задаем здесь матрицу идентичности.

При каждой перерисовке кадра ландшафт циклически сдвигается, а самолет поворачивается вокруг своей оси на небольшой угол:

procedure MoveLand; // Циклическое движение пейзажа

var

i, j : Integer;

TempLand : array [l..NumX] of LandParam; // Вспомогательный массив begin

// Запомнили строку массива ландшафта

for i := 1 to NuraX do TempLand[i] := Land[i,NumZ];

// Сдвигаем ландшафт

for j := NumZ downto 2 do

for i := 1 to NumX do Land[i,j] := Landfi,j-1]; // Круговое появление последней строки массива

for i := 1 to NumX do Land[i,l] := TempLand[i];

end;

procedure TfrmDSD.ApplicationEventslIdle(Sender: TObject;

var Done: Boolean);

var

matWrk : TD3DMatrix;

begin

if FActive then begin

Render; // Нарисовали кадр

MoveLand; // Передвинули ландшафт

SetRotateYMatrix(matWrk, 0.1); // Матрица для небольшого поворота

matAirplan := MatrixMul (matAirplan, matWrk); // Поворот самолета

end;

Done := False;

end;

Для оптимизации в коде программы я матрицу поворота вычисляю один раз.

Обратите внимание на то, что в программе используется два направленных источника света, и, самое главное, на то, что формат вершин с указанием нормали и цвета позволяет воспроизводить объекты без дополнительных ухищрений. В самом деле, в программе отсутствуют материалы, и такой способ окрашивания примитивов является самым простым и быстрым.

Однако в этом примере мы сильно перерасходуем память, ведь две тысячи треугольников модели окрашиваются одним цветом, а для каждой вершины модели мы вынуждены задавать цвет. При использовании же материала память сильно экономится, но мы не получим тогда сглаживание цветов для треугольников ландшафта.

Пример проекта каталога Ех09 подсказывает возможное решение. Здесь на фоне того же ландшафта, что и в предыдущем примере, гордо парит орел (рис. 9.10).

Вкратце суть решения можно передать следующими словами в программе применяются - фото 84

Вкратце суть решения можно передать следующими словами: в программе применяются два буфера вершин различных форматов, один из которых не имеет цветового компонента:

type

TCUSTOMVERTEXLand = packed record

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Михаил Краснов читать все книги автора по порядку

Михаил Краснов - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Графика DirectX в Delphi отзывы


Отзывы читателей о книге Графика DirectX в Delphi, автор: Михаил Краснов. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x