DirectX.
Использование возможностей ОС по выводу графики

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Содержание

Содержание

Введение

Обзор Direct3D

Работа с интерфейсами

Описание некоторых функций, используемых для работы с Direct3D

Демонстрационная программа

Листинг

Результат выполнения

Заключение

Список литературы

Введение

DirectX представляет собой набор технологий и инструментов, которые позволяют создавать разработчику игры и мультимедиа приложения с неслыханным во времена MS-DOS качеством графики и звука. Кроме этого, DirectX служит для обработки клавиатуры, мыши, джойстика, а также для сетевого сообщения.

DirectX подразделяется на несколько частей, каждая из которых отвечает за что-то свое:

· DirectDraw — служит для ускорения отображения и обработки двумерной графики

· Direct3D — для ускорения трехмерной графики

· DirectSound — работает со звуком — микширование и 3D звук

· DirectInput — для обработки клавиатуры, мыши, джойстика и так далее

· DirectPlay — служит в основном для сетевой игры

DirectX разрабатывался специально, чтобы превратить платформу Windows как в основную для разработки игр. До этого разработчики использовали только MS-DOS и лишь совсем незначительная часть игр делалась для Windows 3. xx Одной из более ранних попыток Microsoft был выпуск WinG, который позволял разработчикам не писать бесконечные поддержки для различных типов аудио-видеоадаптеров, однако появление DirectX полностью изменило дело в пользу Windows. Теперь, разработчики могли почти не отвлекаться на подержки различных карт, потому что если у карты была поддержка DirectX, то несовместимость больше не была проблемой.

DirectX — это интефейс довольно низкого уровня. С помощью своих API он предоставляет программисту прямой доступ к памяти адаптеров, где программист может создавать изображение, хранить графические образы, звуки и т. д. За счет непосредственной работы с памятью достигается ускорение, то есть теоретически частота, с которой программист сможет заставить прорисоваваться экран будет зависеть только от частоты, поддерживаемой монитором. Реально же, человек уже слабо воспринимает различия в частоте обновления, если она более 33 FPS (Frame Per Second — кадров в секунду), поэтому будет очень хорошо, если Вы сможете подвести Вашу частоту к этой.

Современные графические адаптеры позволяют доводить FPS двумерной графики до всех разумных пределов, поэтому все задержки с ее отображением от того, что компьютер не успел подготовить новое изображение, а это уже зависит от чатоты процессора и объема оперативной памяти. В трехмерной же графике все сложнее. Здесь скорость отображения зависит как и от мощности компьютера, так и от качества и способности ускорения графической карты. Разработчики видеоускорителей применяют все более и более навороченные технологии ускорения и все для того, чтобы увеличить FPS еще на десяток кадров, а также улучшить качетво картинки (устранить пикселизацию, сгладить цвета…) [6]

Обзор Direct3D

Direct3D -- это низкоуровневый графический API (программный интерфейс для приложений), позволяющий отображать трехмерные миры используя аппаратные ускорители трехмерной графики. Direct3D можно представлять как посредника между приложением и графическим устройством (аппаратурой трехмерной графики). Например, чтобы приказать графическому устройству очистить экран, приложение должно вызвать метод Direct3D IDirect3DDevice9: :Clear. Взаимоотношения между приложением, Direct3D и аппаратурой компьютера показаны на рис. 1.1.

Рис. 1.1. Взаимосвязь между приложением, Direct3D и аппаратурой

На рис. 1.1 блок с названием Direct3D представляет набор документированных интерфейсов и функций, которые Direct3D предоставляет приложениям и программистам. Эти интерфейсы и функции охватывают полный набор функциональных возможностей, предлагаемых данной версией Direct3D. Обратите внимание, что предложение возможости Direct3D не означает, что она будет поддерживаться аппаратурой.

На рис. 1.1 изображена промежуточная стадия между Direct3D и графическим устройством -- уровень абстрагирования от аппаратуры (Hardware Abstraction Layer, HAL). Direct3D не может напрямую взаимодействовать с аппаратурой, поскольку продаются сотни различных видеокарт и каждая видеокарта отличается набором поддерживаемых функций и способом реализации тех функций, которые поддерживаются. Например, две разные видеокарты могут совершенно по-разному выполнять очистку экрана. Поэтому Direct3D требует, чтобы производители оборудования реализовали уровень абстрагирования от оборудования (HAL), который представляет собой зависящий от аппаратуры код, указывающий устройству ка выполнять те или иные операции. Благодаря этому Direct3D не требуется знать специфику конкретных устройств, и его спецификации не зависят от используемого оборудования.

Производители видеокарт встраивают поддержку всех предлагаемых их оборудованием возможностей в HAL. Те возможности, которые предлагает Direct3D, но которые не поддерживает устройство, в HAL не реализованы. Попытка использования тех возможностей Direct3D, которые не реализованы в HAL приводит к ошибке, за исключением тех случаев, когда требуемая функция может быть воспроизведена программно, как, например, программная обработка вершин в библиотеке времени выполнения Direct3D. [4]

Работа с интерфейсами

DirectX основан на технологии COM (Component Object Model — Компонентная Модель Объектов). Возможно, эта технология имеет ряд преимуществ и упрощает жизнь разработчику подобных продуктов, в данном случае тем, кто разрабатывал DirectX, однако для пользователей это означает дополнительное изучение порядка работы с такой моделью.

Основная идея COM заключается в работе с указателями на виртуальную таблицу функций. В терминологии DirectX вместо слова функция используется понятие интерфейс и методы. Приблизительная схема организации таких таблиц изображена на рисунке:

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

1. Создать объект

2. Получить указатель на соответствующий интерфейс этого объекта.

3. Используя данный указатель вызвать нужный метод.

Создав один раз объект, и получив указатель на нужный интерфейс, можно сколь угодно вызывать необходимые методы.

Если в языке C++ данный механизм реализован в таком виде:

// Создали объект и получили указатель на интерфейс IDirect3D9

pd3d9 = Direct3DCreate9 (D3D_SDK_VERSION);

// Вызвали метод CreateDevice

pd3d9 -> CreateDevice (arg1, arg2, arg3, arg4, arg5, arg6, arg7);

То в ассемблере это будет выглядеть так:

invoke Direct3DCreate9, D3D_SDK_VERSION; Создали объект

mov pd3d9, eax; получили указатель

push arg7

push arg6

push arg5

push arg4

push arg3

push arg2

push arg1

push pd3d9

mov eax, pd3d9

mov eax, [eax]

call dword ptr [eax+3Ch]

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

Подобные операции с вычислением истинного адреса метода способны отбить желание работать на ассемблере с COM моделью. Избежать этого можно используя макрос d3d9.

Программа, которая совершает то же самое, что и указанная выше, но уже с использованием такого макроса:

invoke Direct3DCreate9, D3D_SDK_VERSION; Создали объект

mov pd3d9, eax; получили указатель

d3d9 CreateDevice, pd3d9, Arg1, …, Arg7

Макрос автоматически выполняет всю рутинную работу за нас, и вызов метода выглядит почти также как вызов обычной функции API Windows. [5]

Макросы d3dev9, d3dxmesh тем же образом позволяют обращаться к методам соответствующих классов.

Описание некоторых функций, используемых для работы с Direct3D

Исходя из [3]:

Direct3DCreate9,D3D_SDK_VERSION

Direct3DCreate9 -- запрос указателя на интерфейс IDirect3D9.

Единственным параметром функции Direct3DCreate9 всегда должна быть константа D3D_SDK_VERSION, гарантирующая, что при построении приложения будут использованы правильные заголовочные файлы. Если при работе функции возникли ошибки, она возвращает нулевой указатель.

CreateDevice, pd3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd ,

D3DCREATE_SOFTWARE_VERTEXPROCESSING,

ADDR BackBufferWidth, ADDR pd3dDevice

Метод CreateDevice создает объект IDirect3DDevice9.

HRESULT IDirect3D9: :CreateDevice (

UINT Adapter,

D3DDEVTYPE DeviceType,

HWND hFocusWindow,

DWORD BehaviorFlags,

D3DPRESENT_PARAMETERS *pPresentationParameters,

IDirect3DDevice9** ppReturnedDeviceInterface

);

§ Adapter -- указывает физический видеоадаптер, который будет представлять создаваемый объект IDirect3DDevice9.

§ DeviceType -- задает тип используемого устройства (т.е. аппаратное устройство (D3DDEVTYPE_HAL) или программное устройство (D3DDEVTYPE_REF)).

§ hFocusWindow -- дескриптор окна с которым будет связано устройство. Обычно это то окно, в которое будет выводиться изображение и для наших целей мы здесь задаем тот же дескриптор, который указан в члене d3dpp. hDeviceWindow структуры D3DPRESENT_PARAMETERS.

§ BehaviorFlags -- в этом параметре указывается значение D3DCREATE_HARDWARE_VERTEXPROCESSING либо D3DCREATE_SOFTWARE_VERTEXPROCESSING.

§ pPresentationParameters -- указывается инициализированный экземпляр структуры D3DPRESENT_PARAMETERS, задающий параметры устройства.

§ ppReturnedDeviceInterface -- возвращает указатель на созданное устройство.

D3DXMatrixRotationY, ADDR WorldMatrix, NULL

D3DXMatrixRotationY — Вращение по оси Y.

D3DXMATRIX* D3DXMatrixRotationY (

D3DXMATRIX *pOut,

FLOAT Angle

);

Параметры:

§ pOut -- указатель на структуру D3DXMATRIX, в которую помешается исходный результат операции;

§ Angle -- угол вращения в радианах по оси Y

D3DXMatrixRotationZ, ADDR WorldMatrix, RotZ

D3DXMatrixRotationZ — Вращение по оси Z.

D3DXMATRIX* D3DXMatrixRotationZ (

D3DXMATRIX *pOut,

FLOAT Angle

);

Параметры:

§ pOut -- указатель на структуру D3DXMATRIX, в которую помешается исходный результат операции;

§ Angle -- угол вращения в радианах по оси Z

D3DXMatrixLookAtLH, ADDR ViewMatrix, ADDR EyeVector, ADDR LookAtVector, ADDR UpVector

D3DXMatrixLookAtLH — вычислить матрицу преобразования вида.

D3DXMATRIX *D3DXMatrixLookAtLH (

D3DXMATRIX* pOut, // указатель на возвращаемую матрицу преобразования

CONST D3DXVECTOR3* pEye, // местоположение камеры в сцене

CONST D3DXVECTOR3* pAt, // точка, на которую направлена камера

CONST D3DXVECTOR3* pUp // вектор, задающий направление вверх — (0, 1, 0)

);

Параметр pEye задает точку пространства, в которой располагается камера. Параметр pAt задает ту точку сцены, на которую направлена камера. Параметр pUp -- это вектор, который задает направление «вверх» для нашей сцены. Почти всегда это вектор, совпадающий с осью Y -- (0, 1, 0).

D3DXMatrixPerspectiveFovLH, ADDR ProjectionMatrix, FieldOfView, AspectRatio, NearViewPlanZ, FarViewPlanZ

D3DXMatrixPerspectiveFovLH — создает матрицу проекции на основании описания усеченной пирамиды видимого пространства.

D3DXMATRIX *D3DXMatrixPerspectiveFovLH (

D3DXMATRIX* pOut, // возвращает матрицу проекции

FLOAT fovY, // вертикальный угол поля зрения в радианах

FLOAT Aspect, // форматное соотношение = ширина / высота

FLOAT zn, // расстояние до передней полскости

FLOAT zf // расстояние до задней плоскости

);

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

форматноеСоотношение = ширинаЭкрана / высотаЭкрана

D3DXLoadMeshFromXA, addr Teapot, D3DXMESH_DYNAMIC, pd3dDevice, 0, 0, NULL, 0, addr TeapotP

D3DXLoadMeshFromXA — загружает в приложение X-Файл.

HRESULT D3DXLoadMeshFromX (

LPCTSTR pFilename,

DWORD Options,

LPDIRECT3DDEVICE9 pDevice,

LPD3 DXBUFFER* ppAdjacency,

LPD3DXBUFFER* ppMaterials,

LPD3DXBUFFER* ppEffeetInstances,

DWORD* pNumMaterials,

LPD3DXMESH* ppMesh

);

§ pFilename -- указатель на строку, в которой приведено имя загружаемого Х-файла;

§ Options -- член перечисляемого типа d3dxmesh, определяет комбинацию одного или более флагов для различных вариантов создания мэша. Рассмотрим несколько из имеющихся флагов:

o d3dxmesh_vb_systemmem -- этот флаг необходимо использовать с флагом D3DPOOL_SYSTEMMEM для определения класса памяти буфера вершин;

o D3DXMESH_VB_MANAGED -- применяется с флагом D3DPOOL_MANAGED для определения класса памяти буфера вершин;

o D3DXMESH_IB_SYSTEMMEM -- этот флаг необходимо использовать с флагом D3DPOOL_SYSTEMMEM для определения памяти индексного буфера;

o D3DXMESH_IB_MANAGED -- применяется с флагом D3DPOOL_MANAGED для определения памяти индексного буфера;

o D3DXMESH_USEHWONLY -- используется для обработки только аппаратных средств;

o D3DXMESH_MANAGED -- эквивалент комбинации двух флагов D3DXMESH_VB_MANAGED И D3DXMESH_IB_MANAGED;

o D3DXMESH_SYSTEMMEM -- Он эквивалентен комбинации двух флагов D3DXMESH_VB_SYSTEMMEM и D3DXMESH_IB_SYSTEMMEM;

§ pDevice -- это указатель pDirect3DDevice на интерфейс IDirect3DDevice9, связывающий Х-файл с устройством Direct3D;

§ ppAdjacency -- адрес указателя на буфер, содержащий данные о смежности. В этом параметре используется указатель на интерфейс ID3DXBuffer

§ ppMaterials -- адрес указателя на интерфейс ID3DXBuffer. По возвращению функции этот параметр заполнится данными структуры D3DXMATERIAL для Х-файла;

§ ppEffeetInstances -- адрес указателя на интерфейс ID3DXBuffer, содержащий специфические эффекты.

§ pNumMatегiа1s -- указатель на массив данных для структуры D3DXMATERIAL.

§ ppMesh -- адрес указателя на интерфейс ID3DXMesh, результат всей операции.

d3dxmesh GetFVF, TeapotP

DWORD GetFVF () -- Возвращает значение типа DWORD, описывающее формат вершин сетки.

d3dxmesh GetNumBytesPerVertex, TeapotP

DWORD GetNumBytesPerVertex () -- Возвращает количество байт, занимаемых описанием одной вершины.

d3dxmesh GetNumVertices, TeapotP

DWORD GetNumVertices () -- Возвращает количество вершин в буфере вершин.

d3dxmesh GetNumFaces, TeapotP

DWORD GetNumFaces () -- Возвращает количество граней (треугольных ячеек) в сетке.

d3dxmesh GetVertexBuffer, TeapotP, addr TeapotP_VB

HRESULT GetVertexBuffer (LPDIRECT3DVERTEXBUFFER9* ppVB); - Получает буфер вершин для данной сетки.

d3dxmesh GetIndexBuffer, TeapotP, addr TeapotP_IB

HRESULT GetIndexBuffer (LPDIRECT3DINDEXBUFFER9* ppIB); - Получает буфер индексов для данной сетки.

D3DXAssembleShaderFromFile, addr f_VS, 0, 0, D3DXSHADER_DEBUG, addr a_VS, 0

D3DXAssembleShaderFromFile — сборка шейдера из файла

HRESULT D3DXAssembleShaderFromFile (

LPCTSTR pSrcFile,

CONST D3DXMACR0* pDefines,

LPD3DXINCLUDE plnclude,

DWORD Flags,

LPD3DXBUFFER* ppShader,

LPD3DXBUFFER* ppErrorMsgs

);

Функция D3DXAssembieShaderFromFile () имеет следующие параметры:

§ pSrcFile -- имя зафужаемого файла, содержащего программу вершинного шейдера;

§ pDefines -- указатель препроцессора;

§ pInciude ~ опциональный указатель интерфейса ID3DXInciude;

§ Flags -- флаги, идентифицирующие шейдер;

§ ppShader -- возвращает буфер, содержащий откомпилированный код шейдера. Здесь используется указатель Code на буфер LPD3DXBUFFER;

§ ppErrorMsgs -- сообщение о возврате ошибок.

d3dev9 CreateVertexShader, pd3dDevice, b_VS, addr c_VS

CreateVertexShader — создает вершинный шейдер.

HRESULT CreateVertexShader (

const DWORD* pFunction,

IDirect3DVertexShader9** ppShader

);

Функция CreateVertexShader () имеет следующие параметры:

§ рFunction -- указатель, содержащий данные, возвращаемые функцией GetBufferPointer. Эта функция не имеет параметров и возвращает указатель на буфер данных.

§ ppShader -- указатель на интерфейс IDirect3DVertexShader9.

d3dev9 SetVertexShaderConstantF, pd3dDevice, 0, addr m_VS1, 4

SetVertexShaderConstantF -занесение матрицы в необходимый константный регистр

HRESULT SetVertexShaderConstantF (

UINT StartRegister,

CONST float* pConstantData,

UINT Vector4fCount

);

Функция SetVertexShaderConstantFO имеет следующие параметры:

§ StartRegister -- первый номер регистра, в который будут записаны данные;

§ pConstantData -- указатель, содержащий данные для записи в регистр;

§ vector4fCount -- количество необходимых регистров для размещения данных.

d3dev9 SetVertexShader, pd3dDevice, c_VS

SetVertexShader — устанавливает массив векторов.

HRESULT SetVertexShader (

D3DXHANDLE hParameter,

LPDIRECT3DVERTEXSHADER9 pVertexShader

);

Инициализирует идентифицируемый дескриптором hParameter объект вершинного шейдера в файле эффекта на основании вершинного шейдера, на который указывает pVertexShader

d3dev9 SetPixelShader, pd3dDevice, c_PS

HRESULT SetPixelShader (

D3DXHANDLE hParameter,

LPDIRECT3DPIXELSHADER9 pPShader

);

Инициализирует идентифицируемый дескриптором hParameter объект пиксельного шейдера в файле эффекта на основании пиксельного шейдера, на который указывает pPShader

d3dev9 Clear, pd3dDevice, 0, NULL, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, Clearcolor, Zvalue, 0

Clear. — очищает различные буферы цветом

HRESULT Clear (

DWORD Count,

CONST D3DRECT* pRects,

DWORD Flags,

D3DCOLOR Color,

float Z,

DWORD Stencil

);

Функция clear о имеет следующие параметры:

§ Count -- счетчик, указывает число прямоугольников, подвергающихся очистке. Вся область рендеринга состоит из массива прямоугольников. Если указать значение 0, то будет использована вся поверхность, т. е. весь массив прямоугольников или вся область рендеринга;

§ pRect -- указатель на структуру D3DRECT, описывающей массив очищаемых прямоугольников.

§ Flags -- параметр, определяющий флаги, указывающие, какие из поверхностей должны быть очищены. Этим параметром может быть любая комбинация из следующих флагов:

o D3DCLEAR_STENCIL -- очистит буфер трафарета до значения в параметре Stencil;

o D3DCLEAR_TARGET -- очистит буфер поверхности до цвета в параметре color. Воспользуемся данным флагом для очистки буфера поверхности в заданный цвет;

o D3DCLEAR_ZBUFFER -- очистит буфер глубины до значения в параметре z;

§ Сolor -- цвет;

§ z -- этот параметр задает значения для Z-буфера. Значение может находится в диапазоне от 0.0 -- это самое близкое расстояние для средства просмотра и 1.0 -- дальнее расстояние.

§ Stencil -- значение буфера трафарета, может быть в диапазоне от 0 до 2n-1 где n разрядная глубина буфера трафарета.

d3dev9 SetStreamSource, pd3dDevice, 0, TeapotP_VB, 0, TeapotPB

SetStreamSource — Связывает буфер вершин с потоком данных.

HRESULT SetStrearSourse (

UINT StreamNumber,

IDlrect3DVertexBuffer* pStreamData,

UINT OffsetInBytes,

UINT Stride)

Параметры:

§ StreamNumber -- определяет поток данных в диапазоне от 0 до -I,

§ pStrearxData -- это указатель на интерфейс IDirect3DvertexBuffer, созданный для представления буфера вершин, который связывается с определенным потоком данных;

§ OffsetInBytes -- смешение от начата потока до начала данных вершин. Измеряется в байтах. Здесь вы указываете, с какой вершины наминается вывод. Если поставить 0. то вывод будет происходить от первой вершины;

§ Stride -- это своего рода «шаг в байтах», от одной вершины до другой

d3dev9 Present, pd3dDevice, NULL, NULL, NULL, NULL

Present — Предстаазяет содержимое буфера на дисплей.

HRESULT Present (

CONST RECT* pSourceRect,

CCIJST RECT* pDestRect,

HKND hDestWindowOverride,

CONST RGNCDATA* pDirtyRegion

);

Параметры:

§ pSourceRect -- указатель на структуру RECT исходной поверхности. Если использовать значение null, то будет представлена полная исходная поверхность;

§ pDestRect -- указатель на структуру RECT поверхности адресата;

§ hDestWindowOverride -- указатель на окно адресата, чья клиентская область взята как адрес для этого параметра представления Установив значение null, мы тем самым говорим, что используем поле

§ hWndDeviceWindow в структуре D3DPRESENT_PARAMETERS;

§ pDirtyReqion -- последний параметр, «отголосок» прежних версий DirectX и уже не используется. Оставлен просто для совместимости, по-этому устанавливается всегда в значение null.

d3dev9 DrawIndexedPrimitive, pd3dDevice, D3DPT_TRIANGLELIST, 0, 0, TeapotP_NV, 0, TeapotP_NF

DrawIndexedPrimitive — нарисовать примитив из индексного буфера.

HRESULT DrawIndexedPrimitive (

D3DPRIMITIVETYPE Type,

INT BaseVertexIndex,

UINT MinIndex,

UINT NumVertices,

UINT StartIndex,

UINT PrimitiveCount

);

Параметры:

§ Type -- Тип рисуемого примитива.

§ BaseVertexIndex -- Базисная величина, которая будет прибавлена к используемым в данном вызове индексам.

§ MinIndex -- Минимальное значение индекса, которое будет использовано.

§ NumVertices -- Количество вершин, которые будут обработаны данным вызовом.

§ StartIndex -- Номер элемента буфера индексов, который будет отмечен как стартовая точка с которой начнется чтение индексов.

§ PrimitiveCount -- Количество рисуемых примитивов.

Демонстрационная программа

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

Листинг

. 586

. MMX

. XMM

. MODEL FLAT, STDCALL

OPTION CASEMAP: none

INCLUDE Masm32Includewindows. inc; Структуры, константы …

INCLUDE Masm32Includekernel32. inc; Системные функции приложения …

INCLUDE Masm32Includeuser32. inc; Интерфейс …

INCLUDE Masm32Includegdi32. inc; Графический вывод …

INCLUDE masm32includewinmm. inc; Функция timeGetTime

INCLUDELIB Masm32Libkernel32. lib

INCLUDELIB Masm32Libuser32. lib

INCLUDELIB Masm32Libgdi32. lib

INCLUDELIB masm32libwinmm. lib

INCLUDE masm32Dxsdk90Include2005_jund3d9_all. inc

INCLUDELIB masm32Dxsdk90lib2005_jund3d9. lib

INCLUDELIB masm32Dxsdk90lib2005_jund3dx9. lib; Подключение D3DX функций (динамическая библиотека)

; ПРОТОТИПЫ: :

Init_Direct3D PROTO; Текст этих функций можно найти ниже

Destroy_Direct3D PROTO

Set_Render_Parameters PROTO

Init_Scene PROTO

Render_Scene PROTO

; ======================================================

; Основная часть

; ======================================================

. DATA; :

szClassName db «MyClass», 0

szAppName db «8−78−3 Baranov I.V. «, 0

; WNDCLASSEX --------------------------------------------

cbSize dd 12*4

style dd CS_HREDRAW+CS_VREDRAW+20h

lpfnWndProc dd OFFSET WndProc

cbClsExtra dd 0

cbWndExtra dd 0

hInstance dd 40 0000h

hIcon dd 0

hCursor dd 0

hbrBackground dd BLACK_PEN

lpszMenuName dd 0

lpszClassName dd OFFSET szClassName

hIconSm dd 0

; Сообщения об ошибках ----------------------------------

szDirect3D9 db «Не удалось создать обьект Direct3D9», 9,9,0

szD3DDevice9 db «Не удалось создать устройство Direct3D9», 9,0

. DATA?; :

msg MSG < >

hwnd HWND ?

clientwindow RECT < >

. CONST; :

WIN_X EQU 640; Размер окна по горизонтали

WIN_Y EQU 480; Размер окна по вертикали

. CODE; :

Start:

invoke GetModuleHandle, NULL

mov hInstance, eax

invoke LoadCursor, NULL, IDC_ARROW

mov hCursor, eax

invoke RegisterClassEx, ADDR cbSize

invoke GetSystemMetrics, SM_CXSCREEN

push eax

invoke GetSystemMetrics, SM_CYSCREEN

sub eax, WIN_Y

shr eax, 1

pop ebx

sub ebx, WIN_X

shr ebx, 1

invoke CreateWindowEx, NULL, ADDR szClassName, ADDR szAppName,

WS_SYSMENU or WS_VISIBLE,

ebx, eax, WIN_X, WIN_Y, NULL, NULL, hInstance, NULL

mov hwnd, eax

invoke GetClientRect, eax, ADDR clientwindow

invoke Init_Direct3D; Создаем устройство

msg_loop:

invoke PeekMessageA, ADDR msg, 0, 0, 0, PM_REMOVE;

test eax, eax;

jne message; Если у окна нет сообщений…

;

invoke Render_Scene; … то отрисовывается сцена

jmp msg_loop;

;

message:;

mov eax, DWORD PTR msg. message;

cmp eax, WM_QUIT;

je end_loop;

;

invoke TranslateMessage, ADDR msg;

invoke DispatchMessage, ADDR msg;

jmp msg_loop

end_loop:

mov eax, msg. wParam; Если цикл обработки сообщений прерван,

; то код выхода из программы передается в поле wParam

Exit:; сообщения MSG.

invoke ExitProcess, eax

ret

; ======================================================

WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM

; ======================================================

cmp uMsg, WM_CREATE; Это сообщение посылается окну, когда оно создается

je wmCreate

cmp uMsg, WM_DESTROY; Это сообщение посылается окну, когда оно должно быть уничтожено.

je wmDestroy

cmp uMsg, WM_KEYDOWN; Это сообщение посылается окну, когда нажали клавишу на клавиатуре.

je wmKeydown

invoke DefWindowProc, hWnd, uMsg, wParam, lParam; Если Мы Н Е ХОТИМ обрабатывать полученное сообщение, то

ret; нам надо вызвать DefWindowProc с параметрами, которые Мы получили.

; Эта функция API обрабатывает не интересующие Нас события.

wmDestroy:; ------------------------------------------

invoke Destroy_Direct3D

invoke PostQuitMessage, NULL

xor eax, eax

ret

wmCreate:; ------------------------------------------

xor eax, eax

ret

wmKeydown:; ------------------------------------------

mov eax, wParam

cmp eax, VK_ESCAPE

jne noExit

invoke SendMessage, hwnd, WM_CLOSE, NULL, NULL

noExit:

xor eax, eax

ret

WndProc endp

; ======================================================

; Начинается работа с Direct3D

; ======================================================

Init_Direct3D proc; Создавать Direct3DDevice в сообщении WM_Create нельзя !

. DATA

; D3DPRESENT_PARAMETERS ------------------------------------------

BackBufferWidth dd 640; Ширина BackBuffer

BackBufferHeight dd 480; Высота BackBuffer

BackBufferFormat dd D3DFMT_X8R8G8B8; Формат используемой поверхности

BackBufferCount dd 3; число Back буферов.

MultiSampleType dd 0; уровни мультисэмплинга картинки. (обычно от 2-ух и выше)

MultiSampleQuality dd 0;

SwapEffect dd D3DSWAPEFFECT_FLIP; Эффект обмена поверхностей (BackBuffer)

hDeviceWindow dd 0; ID нашего окошка

Windowed dd 1; 0 — полноэкранный, 1 — в окошке

EnableAutoDepthStencil dd TRUE; 1 — Direct3D создает Z + Stencil буфер. Если 0 — ничего не будет создано

AutoDepthStencilFormat dd D3DFMT_D24S8; Формат используемой поверхности

Flags dd 1; 0 или D3DPRESENTFLAG_LOCKABLE_BACKBUFFER=1

FullScreen_RefreshRateInHz dd 0; Частота обновления экрана в Hz

FullScreen_PresentationInterval dd 1; Интервал показа на экране backbufferа. 1 = Ждать обратного хода луча

. DATA?

pd3d dd ?; или LPDIRECT3D9 (указатель на Direct3D9)

pd3dDevice dd ?; или LPDIRECT3DDEVICE9 (указатель на Direct3DDevice)

. CODE

invoke Direct3DCreate9, D3D_SDK_VERSION

mov pd3d, eax

test eax, eax

jnz @F

push OFFSET szDirect3D9

jmp Error_Message

@@:

push clientwindow. right

pop BackBufferWidth

push clientwindow. bottom

pop BackBufferHeight

d3d9 CreateDevice, pd3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd ,

D3DCREATE_SOFTWARE_VERTEXPROCESSING,

ADDR BackBufferWidth, ADDR pd3dDevice

test eax, eax; Если возникла ошибка при создании устройства

jz @F

push OFFSET szD3DDevice9

jmp Error_Message

@@:

invoke Init_Scene

invoke Set_Render_Parameters

ret

Init_Direct3D endp

; :

Destroy_Direct3D proc

mov eax, a_PS

test eax, eax

; jz @F

d3dev9 Release, eax

mov eax, c_PS

test eax, eax

; jz @F

d3dev9 Release, eax

mov eax, a_VS

test eax, eax

; jz @F

d3dev9 Release, eax

mov eax, c_VS

test eax, eax

; jz @F

d3dev9 Release, eax

mov eax, TeapotP

test eax, eax

; jz @F

mov eax, BackBufferP

test eax, eax

; jz @F

mov eax, pd3dDevice

test eax, eax

; jz @F

d3dev9 Release, eax

mov eax, pd3d

test eax, eax

; jz @F

d3dev9 Release, eax

ret

Destroy_Direct3D endp

; :

Init_Scene proc

. DATA

EyeVector D3DVECTOR <0. 0f, -300. 0f, 100. 0f>; Координаты камеры в пространстве

LookAtVector D3DVECTOR <0. 0f, 0. 0f, 0. 0f>; Указывает куда смотрит камера

UpVector D3DVECTOR <0. 0f, 1. 0f, 0. 0f>; Верх камеры. Обычно берется 0. 0,1. 0,0. 0

FieldOfView dd 0. 785 398 1635f

AspectRatio dd NULL; AspectRatio

NearViewPlanZ dd 1. 0f; Передняя отсекающая плоскость

FarViewPlanZ dd 10 000. 0f; Задняя отсекающая плоскость

Teapot db «modelTeapot. x», 0

f_VS db «shadersVS01. txt», 0

f_PS db «shadersPS01. txt», 0

. DATA?

m_VS1 D3DXMATRIX < ?>

WorldMatrix D3DMATRIX < ?>; Мировая матрица

ViewMatrix D3DMATRIX < ?>; Матрица вида

ProjectionMatrix D3DMATRIX < ?>; Матрица проекции

BackBufferP LPDIRECT3DSURFACE9 ?

TeapotP dd ?

TeapotPT dd ?

TeapotPB dd ?

TeapotP_VB dd ?

TeapotP_IB dd ?

TeapotP_NV dd ?

TeapotP_NF dd ?

a_VS LPD3DXBUFFER ?

b_VS dd ?

c_VS LPDIRECT3DVERTEXSHADER9 ?

a_PS LPD3DXBUFFER ?

b_PS dd ?

c_PS LPDIRECT3DVERTEXSHADER9 ?

. CODE

fild BackBufferWidth; Вычисление Aspect (можно просто сразу поместить 1. 33(3)f)

fild BackBufferHeight

fdiv

fstp AspectRatio

invoke D3DXMatrixRotationY, ADDR WorldMatrix, NULL; World Matrix (мировая матрица)

invoke D3DXMatrixLookAtLH, ADDR ViewMatrix, ADDR EyeVector,; View Matrix (матрица вида)

ADDR LookAtVector, ADDR UpVector

invoke D3DXMatrixPerspectiveFovLH, ADDR ProjectionMatrix, FieldOfView,; Matrix Projection (матрица проекции)

AspectRatio, NearViewPlanZ, FarViewPlanZ

; начальная загрузка

invoke D3DXLoadMeshFromXA, addr Teapot, D3DXMESH_DYNAMIC, pd3dDevice, 0, 0, NULL, 0, addr TeapotP

d3dxmesh GetFVF, TeapotP

mov TeapotPT, eax

d3dxmesh GetNumBytesPerVertex, TeapotP

mov TeapotPB, eax

d3dxmesh GetVertexBuffer, TeapotP, addr TeapotP_VB

d3dxmesh GetIndexBuffer, TeapotP, addr TeapotP_IB

d3dxmesh GetNumVertices, TeapotP

mov TeapotP_NV, eax

d3dxmesh GetNumFaces, TeapotP

mov TeapotP_NF, eax

invoke D3DXAssembleShaderFromFileA, addr f_VS, 0, 0, D3DXSHADER_DEBUG, addr a_VS, 0

d3dxbuf GetBufferPointer, a_VS

mov b_VS, eax

d3dev9 CreateVertexShader, pd3dDevice, b_VS, addr c_VS

invoke D3DXAssembleShaderFromFileA, addr f_PS, 0, 0, D3DXSHADER_DEBUG, addr a_PS, 0

d3dxbuf GetBufferPointer, a_PS

mov b_PS, eax

d3dev9 CreatePixelShader, pd3dDevice, b_PS, addr c_PS

ret

Init_Scene endp

Set_Render_Parameters proc

. CODE

d3dev9 SetRenderState, pd3dDevice, D3DRS_CULLMODE, D3DCULL_NONE

d3dev9 SetRenderState, pd3dDevice, D3DRS_ZENABLE, D3DZB_TRUE

d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC

d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC

ret

Set_Render_Parameters endp

; :

Render_Scene proc

. DATA

Zvalue dd 1. 0f; Значение для очистки Z буфера

Clearcolor dd 0; Цвет для очистки BackBuffer’а

. DATA?

. CODE

d3dev9 TestCooperativeLevel, pd3dDevice; Проверка кооперации

cmp eax, D3DERR_DEVICELOST; Если устройство потеряно то выход

jne noreset;

ret;

noreset:;

cmp eax, D3DERR_DEVICENOTRESET; Если устройство не потеряно и не сброшено то сбрасываем

jne noreset2;

d3dev9 Reset, pd3dDevice, ADDR BackBufferWidth;

invoke Set_Render_Parameters

noreset2:

d3dev9 BeginScene, pd3dDevice

d3dev9 SetRenderTarget, pd3dDevice, 0, BackBufferP

d3dev9 Clear, pd3dDevice, 0, NULL, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, Clearcolor, Zvalue, 0; Очистка BackBuffer’а и Z-буфера

invoke D3DXMatrixMultiply, ADDR m_VS1, ADDR WorldMatrix, ADDR ViewMatrix

invoke D3DXMatrixMultiply, ADDR m_VS1, ADDR m_VS1, ADDR ProjectionMatrix

invoke D3DXMatrixTranspose, ADDR m_VS1, ADDR m_VS1

d3dev9 SetVertexShader, pd3dDevice, c_VS

d3dev9 SetPixelShader, pd3dDevice, c_PS

d3dev9 SetVertexShaderConstantF, pd3dDevice, 0, addr m_VS1, 4; c0

d3dev9 SetFVF, pd3dDevice, TeapotPT

d3dev9 SetStreamSource, pd3dDevice, 0, TeapotP_VB, 0, TeapotPB

d3dev9 SetIndices, pd3dDevice, TeapotP_IB

d3dev9 DrawIndexedPrimitive, pd3dDevice, D3DPT_TRIANGLELIST, 0,0,TeapotP_NV, 0, TeapotP_NF

d3dev9 EndScene, pd3dDevice

; Анимируем сцену

. DATA

RotZ dd 0. 0f

Prib dd 0. 01f

. CODE

fld RotZ

fadd Prib

fstp RotZ

invoke D3DXMatrixRotationZ, ADDR WorldMatrix, RotZ

d3dev9 Present, pd3dDevice, NULL, NULL, NULL, NULL; Вывод BackBuffer’а на экран

ret

Render_Scene endp

Error_Message:; Вывод сообщения об ошибке и завершение работы приложения

mov eax, DWORD PTR [esp]

invoke MessageBox, hwnd, eax, ADDR szAppName, MB_ICONERROR

pop eax

invoke Destroy_Direct3D

jmp Exit

; :

end Start

Результат выполнения

Заключение

directx графический программирование приложение

В ходе выполнения данной курсовой работы были освещены основы программирования графических приложений на основе DirectX для операционной системы Windows. В работе используются макросы invoke, d3dev9, d3dxmesh что заметно сокращает код программы. Это достигается за счет того, что макросы сами заботятся о помещении передаваемых параметров в стек, что позволяет избавиться от множества команд PUSH, макросы d3d к тому же берут на себя заботу по обращению к виртуальной таблице функций.

Для реализации программы, иллюстрирующей теоритическую информацию был использован 32-битный ассемблер MASM.

Список литературы

1. Пирогов В. Ю. Ассемблер для Windows. -- СПб.: Петербург, 2002.

2. Фрэнк Д. Луна Введение в программирование трехмерных игр с DirectX 9.0. -- Wordware Publishing, 2003

3. «DirectX Graphics: Первый шаг», http: //vertexland. narod. ru/code/directx/dx_first. htm

4. «Что такое DirectX?», http: //citforum. ru/programming/digest/directxwhatis. shtml

5. «Уроки DirectX/OpenGL в masm32», http: //www. wasm. ru/wault/

ПоказатьСвернуть
Заполнить форму текущей работой