Михаил Краснов - Графика 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 - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Михаил Краснов
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

JType := D3DLIGHT_POINT;

Diffuse.r := 0.5;

Diffuse.g := 0.5;

Diffuse.b := 0.5;

Specular := Diffuse;

Ambient := Diffuse;

Position := DSDVector(0.0, 1.0, 0.0);

Attenuation0 := 1.0;

Attenuationl := 0.0;

Attenuation2 := 0.0;

Range := 2.5;

end;

with FD3DDevice do begin SetLight(0, LightO);

SetLight(l, Lightl);

SetLight(2, Light2);

LightEnable(0, True);

LightEnable(1, True);

LightEnable (2, True);

end;

end;

Все объекты сцены, за исключением человечков, освещаются тремя источниками света. При воспроизведении человечков точечный источник выключается.

При воспроизведении сцены голову наблюдателя "помещаем" в точку, соответствующую его текущему положению в пространстве, и поворачиваем ее в направлении RotY:

procedure TfrmDSD.DrawScene;

var

i : Integer;

matView : TD3DMatrix;

begin

// Видовая матрица, в соответствии с текущими параметрами игрока

SetViewMatrix(matView, D3DVector(XPos, 0.25, ZPos).,

D3DVector (XPos + cos (RotY) ,* 0.25 + Lookupdown,

ZPos - sin (RotY)), ZVector);

with FD3DDevice do begin

SetTransform(D3DTS_VIEW, matView);

SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

SetRenderState(D3DRS_LIGHTING, DWORD (True));

end;

// При необходимости выводим значение

FPS if flgFPS then DrawLetters; // Рисуем человечков

DrawManl; // Красный

DrawMan2; // Синий

DrawMan3; // Зеленый

// Подготовка к рисованию стен

with FD3DDevice do begin

// Учитывать освещение

SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

// Проводить интерполяцию текстур

SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTEXF_LINEAR);

SetTextureStageState(0,D3DTSS_MINFILTER, D3DTEXF_LINEAR);

// He учитывать диффузию треугольников окружения

SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);

SetRenderState(D3DRS_AMBIENT, $OOOFOFOF);

// Задаем белый материал

SetMaterial(MaterialWhite);

// Направляем потоки на буфер вершин описания мира

SetStreamSource(0, FD3DVB, SizeOf(TNormDiffTextVertex));

SetVertexShader(D3DFVF_NORMDIFFTEXTVERTEX);

// Координаты треугольников заданы в глобальной системе координат

SetTransform(D3DTS_WORLD, IdentityMatrix);

end;

// Цикл вывода треугольников окружения

for i := 0 to NumTriangles - 1 do with FDSDDevice do begin

// Устанавливаем нужную текстуру в соответствии с описанием

SetTexture(0, FD3DTextures[World [i].NumTexture]);

DrawPrimitive(D3DPT_TRIANGLELIST, i * 3, 1); // Вывод треугольника

end;

FD3Ddevice.SetTexture(0, nil); // Текстура больше не используется

end;

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

Учтите, что использование интерполяции существенно снижает работу приложения, поэтому обычно ее включают только при приближении к поверхности, покрытой текстурой. Другой способ достижения мелкой зернистости - использование чередующихся текстур. В зависимости от расстояния до объекта на него накладываются текстуры различной детализации.

Также я должен напомнить, что для оптимизации работы приложения следует применять запомненные блоки состояний.

Три человечка, присутствующие на сцене, перемещаются по различным законам. Первый, одетый в красную футболку, беспрерывно кружит вокруг центра комнаты:

procedure TfrmD3D.MoveManl;

begin

// Поворот вокруг вертикальной оси

SetRotateYMatrix (rotManl, Angle + Pi);

// Перемещение по кругу

transManl._41 := cos (-Angle) / 2;

transManl._43 := sin(-Angle) / 2;

// Опорная трансформация первого человечка

matManl := MatrixMul(transManl, MatrixMul(rotManl, matWrkl));

Второй человечек пересекает комнату, появляясь из одной стены и исчезая в противоположной:

procedure TfrmD3D.MoveMan2;

begin

// Изменение Х-координаты

transMan2._41 := transMan2._41 - 0.01;

// При прохождении комнаты процесс начинается сначала

if transMan2._41 < -3.1 then transMan2._41 := 3.1;

matMan2 := MatrixMul(transMan2, matWrk2);

Третий человечек назойливо преследует игрока, перемещается в направлении к наблюдателю, всегда разворачиваясь к нему лицом:

procedure TfrmD3D.MoveMan3;

var

wrkAngle : Single;

distX, distZ : Single;

begin

// Расстояния до игрока

distX := XPos - МапЗРозХ;

distZ := ZPos - ManSPosZ;

// Вычисляем угол поворота человечка

if distZ < 0

then wrkAngle := arctan (distX / distZ) - Pi / 2 else

wrkAngle := arctan (distX / distZ) + Pi / 2; // Разворот человечка лицом к игроку

SetRotateYMatrix (rotMan3, wrkAngle);

// Если человечек удален от зрителя, то двигается,в его направлении

if (abs(distX) > 0.02) and (abs (distZ) > 0.02) then begin

МапЗРозХ := МаnЗРозХ + distX / 20; // Новое положение человечка

Man3PosZ := Man3PosZ + distZ / 20;

transMan3._41 := МаnЗРозХ;

transMan3._43 := Man3PosZ;

end;

// Опорная матрица третьего человечка

matMan3 := MatrixMul(transManS, MatrixMul(rotMan3, matWrk2));

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

Для вывода значения FPS треугольники символов цифр и точки объединены мною в один файл numbers.txt. Процедура piaceLetter определяет в потоке положение и количество треугольников для нужного символа:

procedure TfrmD3D.DrawLetters;

var

i : Integer; nS, nW : Integer;

begin

with FDSDDevice do begin

// Некоторые треугольники построены против часовой

SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

//Не тратить время на освещение

SetRenderState(D3DRS_LIGHTING, DWORD (False));

// Направляем поток на буфер символов

SetStreamSource(0, FD3DVBLetter, SizeOf(TNormVertex));

SetVertexShader(D3DFVF_NORMVERTEX);

end;

// Цикл вывода в пространстве символов FPS for i := 1 to Length(FpsOut) do begin

// Получаем положение треугольников символа

PiaceLetter (FpsOut[i], nS, nW);

// Сдвигаемся в пространстве для вывода очередного символа

LetTrans._41 := i * 0.1;

FD3DDevice.SetTransform(D3DTS_WORLD, LetTrans);

FD3DDevice.DrawPrimitive(D3DPTJTRIANGLELIST, nS, nW);

end;

// Возвращаем обычные установки with FD3DDevice do begin

SetRenderState(D3DRS_COLLMODE, D3DCULL_CCW);

SetRenderState(D3DRS_LIGHTING, DWORD (True) ) ;

end;

end;

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

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

function TfrmD3D.BukupTexture (var FDSTextBMP : IDIRECT3DTEXTURE8;

const FileName : String) : HRESULT;

var

hRet : HRESULT;

d3dlr : TD3DLOCKED__RECT;

dwDstPitch : DWORD;

X, Y : DWORD;

Bmp : TBitmap;

R, G, В : Byte;

begin

Bmp := TBitmap.Create;

try

Bmp.LoadFromfile (FileName);

except

raise EAbort.Create ('Can''t open file: ' + FileName);

Result := S_FALSE;

Exit;

end;

hRet := FD3DDevice.CreateTexture (Bmp.Width, Bmp.Height, 0, 0,

D3DFMT_A8R8G8B8, D3DPOOL MANAGED, FD3TextBMP);

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

hRet := FD3TextBMP.LockRect(0, d3dlr, nil, 0) ;

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

dwDstPitch := d3dlr.Pitch;

for Y := 0' to Bmp.Height - 1 do

for X := 0 to Bmp.Width - 1 do begin

R := GetRValue (Bmp.Canvas.Pixels [X,

DWORD (Bmp.Height -1) - Y] ) ;

G := GetGValue (Bmp.Canvas.Pixels [X,

DWORD (Bmp.Height -I) - Y] ) ;

В := GetBValue (Bmp.Canvas.Pixels [X,

DWORD (Bmp.Height -I) - Y] ) ;

PDWORD(DWORD(d3dlr.pBits)+Y*dwDstPitch+X*4)л :=

D3DCOLOR_XRGB(R, G, B);

end;

// Резервируем место для копии первоначального растра

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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