Автоматика и управление в технических системах
Использование Win32 API для создания оконных приложений в операционной системе Windows XP. Подключение графической библиотеки Direct3D, каркасная модель куба при помощи простейшей микропрограммы, метод Ламберта и Фонга, учет времени синтеза кадра.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | лабораторная работа |
Язык | русский |
Дата добавления | 17.06.2014 |
Размер файла | 3,4 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Лабораторные работы
по курсу: "Компьютерная графика"
Кафедра "Автоматика и управление в технических системах"
Лабораторная работа №1
Создание простейшего оконного Win32 приложения
Цель работы: Научиться использовать Win32 API для создания оконных приложений в операционной системе Windows XP (2000, Vista) в среде Microsoft Visual.
Необходимое оборудование и ПО: персональный компьютер с установленной операционной системой (ОС) Windows XP (2000, Vista), оболочка Microsoft Visual C++ 2008 Express Edition.
Общие сведения
Для разработки приложений ОС Windows предлагает программисту универсальный механизм доступа к функциям программного интерфейса Win32 API (Application Programming Interface). Этот механизм является прослойкой между пользовательской программой и, собственно операционной системой. Такой подход обеспечивает стандартизированный доступ к функциям и инструментам операционной системы с одной стороны, с другой стороны обеспечивается необходимый уровень безопасности операционной системы. Кроме того ОС Windows является многозадачной операционной системой. Для взаимодействия приложений реализован механизм на основе событий - сообщений. С точки зрения приложения, сообщение является уведомлением о том, что произошло некоторое событие, которое может требовать, а может и не требовать выполнения определенных действий. Это событие может быть следствием действий пользователя, например перемещения курсора или щелчка кнопкой мыши, изменения размеров окна или выбора пункта меню. Кроме того, событие может генерироваться приложением, а также операционной системой. Сообщение -- это структура данных, содержащая следующие элементы:
Дескриптор (описатель) окна, которому адресовано сообщение;
Код (номер) сообщения;
Дополнительную информацию, зависящую от кода сообщения.
С момента старта программы, операционная система создает в памяти глобальный объект, называемый системной очередью сообщений. Все сообщения, генерируемые как аппаратурой, так и приложениями, помещаются в эту очередь. ОС периодически опрашивает эту очередь и, если она не пуста, посылает очередное сообщение нужному адресату, определяемому при помощи дескриптора окна.
Точкой входа в оконное Win32 приложение созданное на языке С++ является функция WinMain() (_tWinMain). Для работы с Win32 API, необходимо подключить заголовочный файл #include <windows.h>.
Для обработки приложением поступающих к нему сообщений используется оконная процедура. Оконная процедура обычно имеет заголовок со стандартным синтаксисом:
LRESULT CALLBACK Имя_функции(HWND hWnd. UINT uMsg. WPARAM wParam. LPARAM IParam)
В этом определении LRESULT -- тип возвращаемого значения, hWnd -- дескриптор окна, которому адресовано сообщение, uMsg -- код сообщения, wParam и IParam -- параметры сообщения. Имя функции может быть произвольным, но для главного окна приложения обычно используется имя WndProc. графика приложение windows микропрограмма
Так же непременным компонентом всех Windows-приложений является цикл обработки сообщений. Функция WinMain обычно содержит вызовы функций для инициализации и создания окон (InitInstance, RegisterClass), после чего следует цикл обработки сообщений и необходимый код для закрытия приложения. Извлечение сообщения из очереди осуществляет функция PeekMessage. Если очередное сообщение имеет код WM_QUIT, то происходит выход из цикла, после чего приложение завершает свою работу. Если очередное сообщение не является сообщением WM_QUIT, то оно передается функции DispatchMessage, которая возвращает сообщение обратно в ОС Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре -- иными словами, Windows вызывает оконную процедуру. После возврата из оконной процедуры Windows передает управление оператору, который расположен после DispatchMessage, и работа цикла продолжается.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Создать новый (пустой) проект.
В папке «Source Files» создать главный файл приложения kg_lab.cpp.
В папке «Header Files» создать заголовочные файлы приложения kg_lab.h, stdafx.h.
В файле stdafx.h подключить необходимые библиотеки (см. приложение Б).
В главном файле приложения создать необходимые функции, поместив их в пространство имен main (см. приложение Б) и добавить их описание в заголовочный файл kg_lab.h.
Создать в конце файла kg_lab.cpp функцию обработки сообщений WndProc, которая обрабатывает сообщения WM_DESTROY и WM_ACTIVATEAPP.
Отладить и запустить программу. После запуска программа должна выводить пустое окно приложения с названием "Компьютерная графика. Лабораторная работа" и закрываться по нажатию комбинации клавиш Alt+F4 или крестика в системном меню.
Подготовить отчет о лабораторной работе, отчет должен содержать задание и текст программы (файлы kg_lab.h и kg_lab.cpp).
Приложение А. Создание проекта
Выбрать File -> New -> Project. В диалоговом окне установить:
В новом окне нажать кнопку «Next» и в следующем окне установить:
Добавление заголовочных файлов в проект.
Правой клавишей кликнуть на папке «Header files» в «Solution Explorer». Далее выбрать «Add» -> «New Item»
В диалоговом окне выбрать следующее:
И нажать кнопку «Add».
Добавление программных файлов в проект.
Правой клавишей кликнуть на папке «Header files» в «Solution Explorer». Далее выбрать «Add» -> «New Item»
В диалоговом окне выбрать следующее:
Приложение Б. Исходный код работы
Файл stdafx.h:
#pragma once
#ifndef WINVER
#define WINVER 0x0501
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0410
#endif
#ifndef _WIN32_IE
#define _WIN32_IE 0x0600
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <objbase.h>
Файл kg_lab.h:
#pragma once
#pragma warning ( disable:4100 )
namespace main
{xtern HWND hWnd;
extern bool boActive;
void message_box_( const TCHAR* Mes );
TOM RegisterClass( HINSTANCE hInstance );
bool InitInstance( HINSTANCE, int );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
}; // namespace main
Файл kg_lab.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace main
{HINSTANCE hInst;
bool boActive = false;
HWND hWnd = 0;
const TCHAR* szClass = L"KG Lab Class";
const TCHAR* szTitle = L"Компьютерная графика. Лабораторная работа.";
void message_box_( const TCHAR* Mes )
{::MessageBox( 0, Mes, 0, MB_OK | MB_ICONERROR | MB_TASKMODAL );}
ATOM RegisterClass( HINSTANCE hInstance )
{WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = main::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor( 0, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
wcex.lpszMenuName = 0;
wcex.lpszClassName = szClass;
wcex.hIconSm = 0;
return RegisterClassEx( &wcex );
}bool InitInstance( HINSTANCE hInstance, int nCmdShow )
{hInst = hInstance;
DWORD wid = GetSystemMetrics( SM_CXSCREEN ), hei = GetSystemMetrics( SM_CYSCREEN );
hWnd = CreateWindow( szClass, szTitle, WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_POPUP,
0, 0, wid, hei, 0, 0, hInstance, 0 );
if( !hWnd )
{message_box_( L"Невозможно создать окно приложения!" );
return false;
}// if( !hWnd )
ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );
return true;}LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{switch( Message )
{case WM_ACTIVATEAPP:
{boActive = wParam == 1;
break;}
case WM_DESTROY:
{PostQuitMessage(0);
break;}default:
return DefWindowProc( hWnd, Message, wParam, lParam );
}return 0;}
};// namespace main
int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
int nCmdShow )
{CoInitializeEx( 0, COINIT_MULTITHREADED );
main::RegisterClass( hInstance );
if( !main::InitInstance( hInstance, nCmdShow ) )
return -1;
MSG msg;
do{if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{continue;}// if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
TranslateMessage( &msg );
DispatchMessage( &msg );
}while( WM_QUIT != msg.message );
return (int) msg.wParam;}
Лабораторная работа №2
Подключение библиотеки DirectX к Win32 приложению
Цель работы: Ознакомиться с особенностями подключения и использования графической библиотеки Direct3D в приложениях Win32
Необходимое оборудование и ПО: установленный пакет DirectX SDK, лабораторная работа №1.
Общие сведения
DirectX и его компонента Direct3D -- это низкоуровневый графический API (программный интерфейс для приложений), позволяющий отображать трехмерные сцены, используя аппаратные ускорители трехмерной графики. Direct3D можно представлять как посредника между приложением и графическим устройством (аппаратурой трехмерной графики).
Direct3D представляет набор документированных интерфейсов и функций, которые охватывают полный набор функциональных возможностей по управлению процессом визуализации трехмерных сцен.
Для разработки приложений с использованием функций Direct3D необходимо выполнить подключение библиотеки Direct3D. Библиотека Direct3D основана на применении т.н. COM интерфейсов. Модель компонентных объектов (Component Object Model, COM) - это технология, позволяющая библиотеке быть независимой от языка программирования и совместимой со всеми предыдущими версиями. Для получения указателя на COM- интерфейс необходимо вызвать специальную функцию или метод другого COM-интерфейса (обычно название такой функции начинается со слова Create). Кроме того, завершив работу с COM-интерфейсом, следует вызвать его метод Release. COM-объекты самостоятельно осуществляют управление памятью. В коде для обозначения COM-интерфейсов используется заглавная буква I. Например, COM-интерфейс, представляющий устройство визуализации (видеоадаптер) называется IDirect3DDevice9.
Для инициализации библиотеки необходимо выполнить следующие этапы:
Запросить интерфейс IDirect3D9. Этот интерфейс применяется для получения информации об установленных в компьютере устройствах визуализации и для создания интерфейса IDirect3DDevice9 представляющего аппаратное устройство, используемое для вывода трехмерной графики.
Инициализировать экземпляр структуры D3DPRESENT_PARAMETERS. Эта структура содержит ряд параметров, позволяющих задать характеристики вывода для устройства, которое будет использоваться для визуализации.
Создать объект IDirect3DDevice9, основываясь на инициализированной структуре D3DPRESENT_PARAMETERS.
Приложение работающее с графической библиотекой Direct3D должно выполнить три основных этапа: инициализация, расчет и рисование сцены, освобождение графических ресурсов перед завершением приложения.
В приложении набор перечисленных функций целесообразно реализовать в отдельных .cpp файлах.
Для компиляции приложения с использованием библиотеки Direct3D необходимо выполнить ряд настроек среды разработки и самого проекта. Так в среде разработки необходимо установить пути к заголовочным файлам и библиотекам DirectX SDK (см. приложение А). В самом проекте необходимо указать библиотеку d3d9.lib. Функции для работы с Direct3D необходимо поместить в пространство имен directx.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №1.
В папке «Source Files» и создать файл для работы с библиотекой Direct3D directx.cpp.
В среде разработки установить пути к заголовочным файлам и библиотекам DirectX SDK
Подключить библиотеки "d3d9.lib" и "d3dx9.lib" в заголовочном файле kg_lab.h.
Набрать текст программы в файле directx.cpp и внести изменения в другие файлы проекта согласно приложению Б.
Добавить описание функций в файле kg_lab.h.
Внимание! В функции Paint() (в файле directx.cpp) в вызове функции Clear вместо знаков #### должен быть задан код цвета в 16-ти ричной системе согласно варианту (см. приложение В).
Отладить и запустить программу, программа должна выводить пустое окно приложения, окрашенное в заданный согласно варианту цвет.
Подготовить отчет о лабораторной работе, отчет должен содержать задание, описание и назначение основных использованных функций библиотеки Direct3D и текст программы (directx.cpp).
Приложение А. Настройка проекта для доступа к библиотеке DirectX SDK
Подключение заголовочных файлов DirectX SDK
Выбрать Tools -> Options. В диалоговом окне установить:
Подключение файлов библиотек DirectX SDK
Выбрать Tools -> Options. В диалоговом окне установить:
Приложение Б. Исходный код работы
Добавить в файл stdafx.h:
…#include <memory.h>
#include <tchar.h>
#include <objbase.h>
#include <d3d9.h>
#include <d3dx9.h>
Добавить в файл kg_lab.h:
#pragma once
#pragma warning ( disable:4100 )
#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "d3dx9.lib" )
namespace main
{extern HWND hWnd;
extern bool boActive;
…LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
}; // namespace main
namespace directx
{void FillParams();
bool InitDX();
void CloseDX();
void FlipPages();
void Invalidate();
void Restore();
bool TestAvailDev();
void Paint();
void Pump();
typedef D3DXVECTOR3 s_vector3;
typedef D3DXVECTOR4 s_vector4;
typedef D3DXMATRIX s_matrix;
typedef WORD t_index;
const float deg2rad = 3.14f / 180.f;
const s_vector3 vec0 = s_vector3( 0.f, 0.f, 0.f );
const s_vector3 vec1 = s_vector3( 1.f, 1.f, 1.f );
struct s_vertex
{s_vertex() {}
s_vertex( const s_vector3& Pos_, const s_vector3& Norm_ = vec0 ) :
Pos( Pos_ ), Norm( Norm_ ) {}
s_vector3 Pos;
s_vector3 Norm;
};
extern D3DPRESENT_PARAMETERS PP;
}; // namespace directx
Добавить в файл kg_lab.cpp (в функцию InitInstance):
…if( !hWnd )
{message_box_( L"Невозможно создать окно приложения!" );
return false;
}// if( !hWnd )
if( !directx::InitDX() )
{PostMessage( hWnd, WM_CLOSE, 0, 0 );
return false;
}// if( !directx::InitDX() )
…Добавить в файл kg_lab.cpp (в функцию WndProc):
LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{switch( Message )
{case WM_ERASEBKGND: return 1;
case WM_ACTIVATEAPP:
{boActive = wParam == 1;
directx::TestAvailDev();
break;}
case WM_PAINT:
{PAINTSTRUCT ps;
BeginPaint( hWnd, &ps );
directx::Paint();
EndPaint(hWnd, &ps);
break;}case WM_DESTROY:
{…Добавить в файл kg_lab.cpp (в функцию _tWinMain):
MSG msg;
do
{if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{directx::Pump();
continue;
}// if( !PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
TranslateMessage( &msg );
DispatchMessage( &msg );
}while( WM_QUIT != msg.message );
directx::CloseDX();
…В файл directx.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace directx
{IDirect3D9* pD3D = 0;
IDirect3DDevice9* pD3DDev = 0;
bool boInvalid = false;
D3DPRESENT_PARAMETERS PP = { 0 };
void FillParams()
{RECT rc = { 0 };
GetClientRect( main::hWnd, &rc );
PP.BackBufferWidth = rc.right - rc.left;
PP.BackBufferHeight = rc.bottom - rc.top;
PP.BackBufferFormat = D3DFMT_X8R8G8B8;
PP.BackBufferCount = 0;
PP.MultiSampleType = D3DMULTISAMPLE_NONE;
PP.MultiSampleQuality = 0;
PP.SwapEffect = D3DSWAPEFFECT_DISCARD;
PP.hDeviceWindow = main::hWnd;
PP.Windowed = true;
PP.EnableAutoDepthStencil = true;
PP.AutoDepthStencilFormat = D3DFMT_D24S8;
PP.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
PP.FullScreen_RefreshRateInHz = 0;
PP.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}bool InitDX()
{pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if( !pD3D )
return false;
FillParams();
pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, main::hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &PP, &pD3DDev );
if( !pD3DDev )
{pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, main::hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PP, &pD3DDev );if( !pD3DDev )
{main::message_box_( L"Невозможно инициализировать DirectX!" );
return false;
}// if( !pD3DDev )
}// if( !pD3DDev )
return true;}
void CloseDX()
{if( pD3DDev )
{pD3DDev->Release();
pD3DDev = 0;
}// if( pD3DDev )
if( pD3D )
{pD3D->Release();
pD3D = 0;
}// if( pD3D )
CoUninitialize();
}void FlipPages()
{pD3DDev->Present( 0, 0, 0, 0 );
}void Invalidate()
{if( !pD3DDev || boInvalid )
return;
pD3DDev->EvictManagedResources();
boInvalid = true;
}void Restore()
{if( !pD3DDev || !boInvalid )
return;
boInvalid = pD3DDev->Reset( &PP ) != S_OK;
}bool TestAvailDev()
{if( !pD3DDev )
return false;
switch( pD3DDev->TestCooperativeLevel() )
{case D3DERR_DEVICELOST: { Invalidate(); break; }
case D3DERR_DEVICENOTRESET: { Restore(); break; }
}// switch( pD3DDev->TestCooperativeLevel() )
return !boInvalid;
}void Paint()
{if( !pD3DDev )
return;
if( !TestAvailDev() || pD3DDev->BeginScene() != D3D_OK )
return;
pD3DDev->Clear( 0, 0, D3DCLEAR_STENCIL | D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
#####, 1.f, 0 );
pD3DDev->EndScene();
FlipPages();
}void Pump()
{if( !main::boActive )
Sleep( 20 );
Paint();
}}; //namespace directx
Внимание! В функции Paint() в вызове функции Clear вместо знаков #### должен быть задан код цвета в 16-ти ричной системе (см. приложение В).
Приложение В. Цвета для функции Clear
№ варианта |
Цвет |
|
1 |
Темно-синий |
|
2 |
Красный |
|
3 |
Светло-зеленый |
|
4 |
Серый |
|
5 |
Черный |
|
6 |
Коричневый |
|
7 |
Желтый |
|
8 |
Циан |
|
9 |
Пурпурный |
|
10 |
Оранжевый |
|
11 |
Фиолетовый |
|
12 |
Розовый |
|
13 |
Темно-красный |
|
14 |
Янтарный |
|
15 |
Бронзовый |
|
16 |
Лазурный |
|
17 |
Аквамариновый |
|
18 |
Кремовый |
|
19 |
Изумрудный |
|
20 |
Золотой |
Код цвета представляется в виде 32-х разрядного числа в 16-ти ричной системе исчисления. Каждые 8 бит числа (две цифры) отвечают за свою компоненту цвета в системе RGB - начиная со старших к младшим битам: A (дополнительный канал), R, G, B.
Например, для лимонного цвета код будет следующим: 0xFFFDE910.
Канал |
A |
R |
G |
B |
|
Биты |
31-24 |
23-16 |
15-8 |
7-0 |
|
Значение |
FF |
FD |
E9 |
10 |
Для задания цвета целесообразно воспользоваться программой Paint (нажать сочетание клавиш Win+R, и в строке ввода ввести pbrush и нажать Enter). В диалоге выбора цветов передвинуть ползунки на заданный цвет, скорректировать яркость. Перевести 3 кода (Red, Green Blue) в 16-ти ричную систему исчисления и записать в соответствующих позициях. Код в канале A взять равным 255 (FF). Полученное значение записать в вызове функции Clear вместо знаков ####.
Лабораторная работа №3
Настройка процесса рендеринга
Цель работы: Ознакомиться с особенностями организации процесса рендеринга при помощи графической библиотеки Direct3D.
Необходимое оборудование и ПО: установленный пакет DirectX SDK, лабораторная работа №2.
Общие сведения
Для управления процессом рендеринга в библиотеке Direct3D используются эффекты, описанные в файлах с расширением fx. На этапе запуска программы файл с эффектом загружается и компилируется. В процессе визуализации каждого кадра выбирается техника рендеринга для каждого объекта, устанавливаются параметры рендеринга (матрицы, параметры метериалов и источника света) и производится расчет изображения. Перед закрытием программы, эффект освобождается.
Эффект состоит из 4-х частей:
1) Переменные, константы и структуры, используемые в процессе визуализации. Для задания матрицы используется тип float4x4, для задания вектора из 4-х элементов - float4, для задания числа с плавающей запятой - float.
2) Вершинная микропрограмма (вершинный шейдер) - микропрограмма для графического процессора, которая описывает, каким образом осуществляется обработка геометрии визуализируемых моделей.
3) Фрагментная микропрограмма (пиксельный шейдер) - описывает, каким образом осуществляется обработка каждого визуализируемого пикселя.
4) Описание техники рендеринга - содержит настройки конвейера рендеринга Direct3D, а так же вершинную и пиксельную микропрограммы, используемые для визуализации.
Техника рендеринга (technique) wire задает параметры отрисовки:
-тип вывода графики: каркасная модель (FillMode = wireframe);
-режим отсечения невидимых граней: против часовой стрелки (CullMode = ccw);
-режим сортировки фрагментов по глубине (ZEnable = true, ZFunc = lessequal);
-режимы комбинирования фрагментов;
-вершинную микропрограмму;
-фрагментную микропрограмму.
В проекте необходимо добавить два файла: render.cpp, в котором будет содержаться работа с эффектами и shader.fx, в котором будет содержаться текст микропрограмм и техники рендеринга.
Функции для работы с эффектом необходимо поместить в пространство имен render.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №2.
В папке «Source Files» и создать файл для организации рендеринга render.cpp.
В папке «Source Files» и создать файл описания техник рендеринга и микропрограмм shader.fx.
Набрать текст программы в файле render.cpp и внести изменения в другие файлы проекта согласно приложению А.
Набрать текст эффекта в файле shader.fx.
Добавить описание функций в файле kg_lab.h.
Отладить и запустить программу, проверить в отладчике и записать порядок выполнения функций: TestAvailDev(), LoadResources(), OnExit(), RenderScene(), FillParams(), InitDX(), CloseDX(), FlipPages(), Paint(), Pump(), RegisterClass(), InitInstance().
Для этого установить в начале функций (на первой строке функции) точки прерывания (F9) и запустить приложение в режиме отладки (F5), после остановки на точке прерывания необходимо записать название функции в отчет и продолжить выполнение программы (F5). Если какие-то функции выполняются циклически, необходимо записать последовательность 3 раза, а затем завершить программу.
Подготовить отчет о лабораторной работе, отчет должен содержать задание, порядок выполнения функций из п.п. № 8 и текст программы (render.cpp, shader.fx).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…extern D3DPRESENT_PARAMETERS PP;
}; // namespace directx
namespace render
{enum
{RM_WIRE,
RM_MAX,
};constint CurRenderMethod = RM_WIRE;
const DWORD BackColor = 0xff000000UL;
bool LoadResources( IDirect3DDevice9* Dev );
void RenderScene( IDirect3DDevice9* Dev, int TN );
void OnLostDevice( IDirect3DDevice9* Dev );
void OnRestoreDevice( IDirect3DDevice9* Dev );
void OnExit( IDirect3DDevice9* Dev );
extern D3DXHANDLE hMatWorld;
extern D3DXHANDLE hObjColor;
extern D3DXHANDLE hPower;
extern D3DXHANDLE hSpecLevel;
extern D3DXHANDLE hLigColor;
extern D3DXHANDLE hAmbColor;
extern D3DXHANDLE hLigDir;
extern D3DXHANDLE hLigPos;
extern D3DXHANDLE hMatViewProj;
extern D3DXHANDLE hMatIView;
}; // namespace render
Добавить в файл shader.fx:
//параметры камеры
float4x4 m_view_proj;
float4x4 m_iview;
//источник света
float4 v_lig_dir;
float4 v_lig_pos;
float4 v_lig_color, v_amb_color;
//параметры объекта
float4x4 m_world;
float4 v_obj_color;
float f_power, f_spec_level;
technique wire
{pass P0
{FillMode = wireframe;
FogEnable = false;
AlphaBlendEnable = false;
AlphaTestEnable = false;
ZEnable = true;
ZFunc = lessequal;
CullMode = ccw;
}}Добавить в файл render.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace render
{IDirect3DVertexDeclaration9* pDecl = 0;
LPD3DXEFFECT pEffect = 0;
D3DXHANDLE hMatViewProj = 0;
D3DXHANDLE hMatIView = 0;
D3DXHANDLE hMatWorld = 0;
D3DXHANDLE hObjColor = 0;
D3DXHANDLE hPower = 0;
D3DXHANDLE hSpecLevel = 0;
D3DXHANDLE hLigColor = 0;
D3DXHANDLE hAmbColor = 0;
D3DXHANDLE hLigDir = 0;
D3DXHANDLE hLigPos = 0;
void OnLostDevice( IDirect3DDevice9* Dev )
{if( pEffect )
pEffect->OnLostDevice();
}voidOnRestoreDevice( IDirect3DDevice9* Dev )
{if( pEffect )
pEffect->OnResetDevice();
}void OnExit( IDirect3DDevice9* Dev )
{if( pEffect )
{pEffect->Release();
pEffect = 0;
}// if( pEffect )
if( pDecl )
{pDecl->Release();
pDecl = 0;
}// if( pDecl )
}bool LoadResources( IDirect3DDevice9* Dev )
{LPD3DXBUFFER errors = 0;
D3DXCreateEffectFromFile( Dev, L"shader.fx", 0, 0, 0, 0, &pEffect, &errors );
if( errors )
{const char* e = (const char*) errors->GetBufferPointer();
TCHAR buf[512];
::MultiByteToWideChar( CP_ACP, 0, e, -1, buf, sizeof( buf ) / sizeof( buf[0] ) );
main::message_box_( buf );
errors->Release();
return false;
}// if( errors )
if( !pEffect )
{main::message_box_( L"Шейдер не найден!" );
return false;
}// if( !pEffect )
static const char* tnames[RM_MAX] = { "wire" };
for( int i = 0; i < RM_MAX; ++i )
{hTechnique[i] = pEffect->GetTechniqueByName( tnames[i] );
if( !hTechnique[i] )
{main::message_box_( L"Подходящий метод рендера не найден!" );
return false;
}// if( !hTechnique[i] )
}// for( int i = 0; i < RM_MAX; ++i )
hMatViewProj = pEffect->GetParameterByName( 0, "m_view_proj" );
hMatIView = pEffect->GetParameterByName( 0, "m_iview" );
hMatWorld = pEffect->GetParameterByName( 0, "m_world" );
hObjColor = pEffect->GetParameterByName( 0, "v_obj_color" );
hPower = pEffect->GetParameterByName( 0, "f_power" );
hSpecLevel = pEffect->GetParameterByName( 0, "f_spec_level" );
hLigColor = pEffect->GetParameterByName( 0, "v_lig_color" );
hAmbColor = pEffect->GetParameterByName( 0, "v_amb_color" );
hLigDir = pEffect->GetParameterByName( 0, "v_lig_dir" );
hLigPos = pEffect->GetParameterByName( 0, "v_lig_pos" );
static const D3DVERTEXELEMENT9 dcl[] =
{{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_NORMAL, 0 },
D3DDECL_END()
};Dev->CreateVertexDeclaration( dcl, &pDecl );
if( !pDecl )
return false;
return true;}void RenderScene( IDirect3DDevice9* Dev, int TN )
{if( !pEffect || !hTechnique || !pDecl )
return;
pEffect->SetTechnique( hTechnique[TN] );
Dev->SetVertexDeclaration( pDecl );
UINT passes = 0;
if( pEffect->Begin( &passes, 0 ) != D3D_OK )
return;
for( UINT i = 0; i < passes; ++i )
{if( pEffect->BeginPass( i ) != D3D_OK )
break;
pEffect->EndPass();
}// for( UINT i = 0; i < passes; ++i )
pEffect->End();
}}; //namespace render
Добавить в файл directx.cpp:
…bool InitDX()
{…}// if( !pD3DDev )
if( !render::LoadResources( pD3DDev ) )
return false;
return true;
}void CloseDX()
{render::OnExit( pD3DDev );
if( pD3DDev )
{pD3DDev->Release();
…void Invalidate()
{if( !pD3DDev || boInvalid )
return;render::OnLostDevice( pD3DDev );
pD3DDev->EvictManagedResources();
boInvalid = true;
}void Restore()
{if( !pD3DDev || !boInvalid )
return;boInvalid = pD3DDev->Reset( &PP ) != S_OK;
if( !boInvalid )
render::OnRestoreDevice( pD3DDev );
}…void Paint()
{if( !pD3DDev )
return;
if( !TestAvailDev() || pD3DDev->BeginScene() != D3D_OK )
return;
pD3DDev->Clear( 0, 0, D3DCLEAR_STENCIL | D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
render::BackColor, 1.f, 0 );
render::RenderScene( pD3DDev, render::CurRenderMethod );
pD3DDev->EndScene();
FlipPages();
}…
Лабораторная работа №4
Визуализация каркасной модели куба при помощи микропрограммы
Цель работы: Получить изображение каркасной модели куба при помощи простейшей микропрограммы.
Необходимое оборудование и ПО: лабораторная работа №3, микропрограмма для видеоадаптера из лабораторной работы №3.
Общие сведения
Все микропрограммы записываются на языке HLSL сходном по синтаксису с языком C/C++. Для задания матрицы используется тип float4x4, для задания вектора из 4-х элементов - float4, для задания числа с плавающей запятой - float. Для задания константы, перед типом ставится ключевое слово const.
Для каждой микропрограммы необходимо задать входные и выходные данные в виде структуры. Для вершинной микропрограммы vs_simple входными данными будет описание вершины: позиция и нормаль в локальной системе координат (задаются в структуре s_vertex2), а выходными: позиция в проекционной системе координат, нормаль, позиция наблюдателя и позиция в мировой системе координат (задаются в структуре s_output2). Эта же структура будет являться входными данными для фрагментной микропрограммы ps_wire. На выходе фрагментной микропрограммы формируется цвет пикселя и его прозрачность (вектор из 4-х элементов).
В проекте необходимо добавить два файла: scene.cpp и figures.cpp в которых, будет содержаться описание интерфейса геометрического объекта и описание куба в виде списка троек индексов вершин задающих треугольники и координат вершин.
Для описания геометрической фигуры используется общий интерфейс s_figure, который позволяет проводить конструирование фигуры, изменение ее параметров и получать описание геометрии и топологии фигуры. Описание фигур помещается в пространство имен figures. Новая фигура создается путем наследования интерфейса s_figure. Например, куб создается следующим образом: struct s_cube : public scene::s_figure {};.
Для каждой фигуры необходимо определить две функции: verts() - возвращающую список вершин фигруы и inds() возвращающую топологию фигуры (тройки индексов описывающие треугольники). Внутри каждой из функций содержится массив вершин в локальной системе координат и массив индексов, соответсвенно.
При запуске программы в функции InitScene() создается модель куба с заданными параметрами. Во время формирования изображения в функции UpdateSceneMatrices() рассчитываются устанавливаются матрицы описывающие систему координат наблюдателя: в примере камера расположена в начале координат мировой системы и направление наблюдения совпадает с направлением оси Z.
В функции RenderFigures() производится расчет матрицы объекта, ее установка в микропрограмму и вывод геометрии (вершин и индексов) фигуры на экран.
В функции s_figure::matrix() производится расчет матрицы объекта преобразующей его вершины из локальной системы координат в мировую. Для формирования матрицы масштабирования используется функция D3DXMatrixScaling(), для создания матрицы вращения D3DXMatrixRotationYawPitchRoll(), а для создания матрицы смещения D3DXMatrixTranslation(). Полученные матрицы последовательно перемножаются при помощи функции D3DXMatrixMultiply() в результате чего получается общая матрица объекта, которая сохраняется в поле структуры s_figure - world.
В вершинной микропрограмме vs_simple для преобразования матрицей объекта m_world его позиции i.pos в локальной системе координат используется функция mul, следующим образом float4 P = mul( i.pos, m_world ).
Для преобразования нормали (поворота) используется подматрица 3х3 матрицы объекта m_world - o.nor = mul( i.nor, (float3x3) m_world ).
Для передачи значений матриц и векторов из основной программы в микропрограмму (эффект) используются функции SetMatrix() и SetVector(). Для отправки геометрии и топологии объекта на визуализацию используется функция DrawIndexedPrimitiveUP().
Во фрагментной микропрограмме ps_wire цвет фрагмента формируется из заданного цвета объекта v_obj_color с уровнем прозрачности 1 (полностью непрозрачный фрагмент). Цвет в микропрограммы задается в виде ветора из 4х элементов: RGBA. Диапазон изменения каждого элемента от 0 до 1, при этом 1 соответсвует значению 255 (0xFF) используемому при задании цвета в основной программе. Для приведения цвета к диапазону от 0 до 1 используется функция color2vec().
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №3.
В папке «Source Files» и создать файлы scene.cpp и figures.cpp.
Добавить микропрограммы в файл shader.fx.
Набрать текст программы в файлах scene.cpp и figures.cpp и внести изменения в другие файлы проекта согласно приложению А.
Добавить описание функций и структур в файле kg_lab.h.
В функции InitScene() в вызове конструктора figures::s_cube() вместо знаков ####, TTT, RRR, SSS должны быть заданы код цвета, смещение, вращение и масштаб фигуры согласно варианту (см. приложение Б).
Отладить и запустить программу. На экране должна появиться каркасная модель куба с заданными параметрами на черном фоне.
Установить точку прерывания в функции s_figure::matrix(), на строке changes = false; (F9). Запустить программу в режиме отладки (F5) после остановки на точке прерывания записать элементы матрицы world, для чего нажать правой кнопкой мыши на слове world в тексте программы (D3DXMatrixMultiply( &world, &matSR, &matT ); ) и выбрать пункт меню Add Watch. В окне просмотра значений переменных возле слова world нажать кнопку '+' и записать появившиеся числа. Аналогично записать матрицы matS, matR, matT, matSR.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- схематичный рисунок модели куба и проекции пирамиды видимости в виде: сверху (против оси Y), справа (против оси X), спереди (вдоль оси Z);
- матрицы преобразований: matS, matR, matT, matSR, world (5 штук);
- текст программ и микропрограмм (scene.cpp, figures.cpp, kg_lab.h, shader.fx).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…extern D3DXHANDLE hMatIView;
}; // namespace render
namespace scene
{using namespace directx;
using namespace render;
void RenderFigures( IDirect3DDevice9* Dev, LPD3DXEFFECT pEffect );
void UpdateSceneMatrices( LPD3DXEFFECT pEffect );
void color2vec( DWORD color_, s_vector4& obj_color );
struct s_figure
{s_vector3 obj_scale, obj_rot, obj_pos;
s_vector4 obj_color;
float level, spower;
mutable s_matrix world;
mutable bool changes;
bool anim;
virtual const s_vertex* verts( DWORD& cnt ) const = 0;
virtual const t_index* inds( DWORD& cnt ) const = 0;
const s_matrix& matrix() const;
const s_vector4& color() const { return obj_color; }
float spec_level() const { return level; }
float power() const { return spower; }
void init();
void scale( const s_vector3& scale_ ) { obj_scale = scale_; changes = true; }
void rotate( const s_vector3& rot_ ) { obj_rot = rot_; changes = true; }
void translate( const s_vector3& pos_ ) { obj_pos = pos_; changes = true; }
void set_color( DWORD color_ ) { color2vec( color_, obj_color ); }
s_figure( const s_vector3& pos_, const s_vector3& rot_ = vec0,
const s_vector3& scale_ = vec1, DWORD color_ = 0xff808080UL,
float level_ = 0.5f, float spower_ = 16.f, bool anim_ = true );
};void ReleaseScene();
void InitScene();
}; //namespace scene
namespace figures
{using namespace directx;
struct s_cube : public scene::s_figure
{virtual const s_vertex* verts( DWORD& cnt ) const;
virtual const t_index* inds( DWORD& cnt ) const;
s_cube( const s_vector3& pos_, const s_vector3& rot_ = vec0,
const s_vector3& scale_ = vec1, DWORD color_ = 0xff808080UL,
float level_ = 0.5f, float spower_ = 16.f ) :
scene::s_figure( pos_, rot_, scale_, color_, level_, spower_ ) {}
};}; //namespace figures
Добавить в файл figures.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace figures
{const s_vertex* s_cube::verts( DWORD& cnt ) const
{static s_vertex verts[] =
{s_vertex( s_vector3( -1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, 1.f ) ),
s_vertex( s_vector3( -1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, 1.f ) ),
s_vertex( s_vector3( -1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( -1.f, 1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, -1.f, 1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, -1.f ) ),
s_vertex( s_vector3( 1.f, 1.f, 1.f ) ),
};cnt = sizeof( verts ) / sizeof( verts[0] );
return verts;
}const t_index* s_cube::inds( DWORD& cnt ) const
{static const t_index inds[] =
{1, 0, 2, 1, 2, 3, //дальняя грань
4, 5, 6, 5, 7, 6, //ближняя грань
8, 9, 10, 9, 11, 10, //верхняя грань
14, 13, 12, 14, 15, 13, //нижняя грань
16, 17, 19, 16, 19, 18, //левая грань
21, 20, 23, 20, 22, 23, //правая грань
};
cnt = sizeof( inds ) / sizeof( inds[0] );
return inds;
}}; //namespace figures
Добавить в файл scene.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace scene
{s_figure* pSceneRoot = 0;
s_vector3 vEyePos;
s_vector3 vAtPos;
float fFovY;
void color2vec( DWORD color_, s_vector4& obj_color )
{DWORD red = ( color_ >> 16 ) & 0xff;
DWORD green = ( color_ >> 8 ) & 0xff;
DWORD blue = color_ & 0xff;
DWORD alpha = ( color_ >> 24 ) & 0xff;
obj_color = s_vector4( red / 255.f, green / 255.f, blue / 255.f, alpha / 255.f );
}void RenderFigures( IDirect3DDevice9* Dev, LPD3DXEFFECT pEffect )
{const s_figure* f = pSceneRoot;
DWORD vcnt = 0, icnt = 0;
const s_vertex* v = f->verts( vcnt );
const t_index* i = f->inds( icnt );
DWORD tri_cnt = icnt / 3;
const s_matrix& MatWorld = f->matrix();
const s_vector4& vObjColor = f->color();
pEffect->SetMatrix( hMatWorld, &MatWorld );
pEffect->SetVector( hObjColor, &vObjColor );
pEffect->CommitChanges();
Dev->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, vcnt, tri_cnt, i, D3DFMT_INDEX16,
v, sizeof( s_vertex ) );
}s_figure::s_figure( const s_vector3& pos_, const s_vector3& rot_, const s_vector3& scale_,
DWORD color_, float level_, float spower_, bool anim_ ) :
obj_scale( scale_ ), obj_rot( rot_ ), obj_pos( pos_ ), level( level_ ), spower( spower_ ),
changes( true )
{D3DXMatrixIdentity( &world );
set_color( color_ );
}
cost s_matrix& s_figure::matrix() const
{if( changes )
{s_matrix matS, matR, matT, matSR;
D3DXMatrixScaling( &matS, obj_scale.x, obj_scale.y, obj_scale.z );
D3DXMatrixRotationYawPitchRoll( &matR, obj_rot.x * deg2rad, obj_rot.y * deg2rad,
obj_rot.z * deg2rad );
D3DXMatrixTranslation( &matT, obj_pos.x, obj_pos.y, obj_pos.z );
D3DXMatrixMultiply( &matSR, &matS, &matR );
D3DXMatrixMultiply( &world, &matSR, &matT );
changes = false;
}// if( changes )
return world;
}void ReleaseScene()
{delete pSceneRoot;
pSceneRoot = 0;
}void InitScene()
{vEyePos = vec0;
vAtPos = s_vector3( 0.f, 0.f, 1.f );
fFovY = 60.f;
pSceneRoot = new figures::s_cube( s_vector3( TTT ), s_vector3( RRR ), s_vector3( SSS ), #### );
}Внимание! В функции InitScene() в вызове конструктора figures::s_cube( вместо знаков ####, TTT, RRR, SSS должны быть заданы код цвета, смещение, вращение и масштаб фигуры (см. приложение Б).
void UpdateSceneMatrices( LPD3DXEFFECT pEffect )
{const s_vector3 Up( 0.f, 1.f, 0.f );
s_matrix MatView, MatIView;
D3DXMatrixLookAtLH( &MatView, &vEyePos, &vAtPos, &Up );
float FOV = fFovY * deg2rad;
float Aspect = (float) PP.BackBufferWidth / PP.BackBufferHeight;
float ZNear = 1.f;
float ZFar = 100.f;
s_matrix MatProj;
D3DXMatrixPerspectiveFovLH( &MatProj, FOV, Aspect, ZNear, ZFar );
s_matrix MatViewProj;
D3DXMatrixMultiply( &MatViewProj, &MatView, &MatProj );
float det;
D3DXMatrixInverse( &MatIView, &det, &MatView );
pEffect->SetMatrix( hMatIView, &MatIView );
pEffect->SetMatrix( hMatViewProj, &MatViewProj );
}}; //namespace scene
Добавить вызовы функций ReleaseScene(),InitScene(), UpdateSceneMatrices(),RenderFigures():
в файл render.cpp
void OnExit( IDirect3DDevice9* Dev )
{scene::ReleaseScene();
…bool LoadResources( IDirect3DDevice9* Dev )
{…if( !pDecl )
return false;
scene::InitScene();
return true;
}void RenderScene( IDirect3DDevice9* Dev, int TN )
{…pEffect->SetTechnique( hTechnique[TN] );
Dev->SetVertexDeclaration( pDecl );
scene::UpdateSceneMatrices( pEffect );
…for( UINT i = 0; i < passes; ++i )
{if( pEffect->BeginPass( i ) != D3D_OK )
break;
scene::RenderFigures( Dev, pEffect );
pEffect->EndPass();
…Добавить в файл shader.fx:
…
//параметры объекта
float4x4 m_world;
float4 v_obj_color;
float f_power, f_spec_level;
struct s_vertex2
{float4 pos : POSITION;
float3 nor : NORMAL;
};
struct s_output2
{float4 pos : POSITION;
float3 nor : TEXCOORD0;
float3 eye : TEXCOORD1;
float3 wpos : TEXCOORD2;
};s_output2 vs_simple( s_vertex2 i )
{s_output2 o;
float4 P = mul( i.pos, m_world );
o.wpos = P.xyz;
o.pos = mul( P, m_view_proj );
o.nor = mul( i.nor, (float3x3) m_world );
o.eye = mul( float3( 0.f, 0.f, 1.f ), (float3x3) m_iview );
return o;
}float4 ps_wire( s_output2 i ) : COLOR
{return float4( v_obj_color.rgb, 1.0 );
}technique wire
{pass P0
{ZFunc = lessequal;
CullMode = ccw;
VertexShader = compile vs_2_0 vs_simple();
PixelShader = compile ps_2_0 ps_wire();
Приложение Б. Цвет и параметры каркасной модели куба
№ варианта |
Цвет (####) |
Масштаб (SSS) |
Вращение (RRR) |
Смещение (TTT) |
|
1 |
Красный |
2.f, 2.f, 2.f |
45.f, 0.f, 0.f |
10.f, -4.f, 30.f |
|
2 |
Зеленый |
3.f, 3.f, 3.f |
30.f, 30.f, 0.f |
-4.f, -4.f, 25.f |
|
3 |
Белый |
1.f, 1.f, 1.f |
0.f, 0.f, 0.f |
1.f, 0.f, 10.f |
|
4 |
Серый |
2.f, 3.f, 3.f |
45.f, 0.f, 0.f |
-5.f, 8.f, 25.f |
|
5 |
Желтый |
3.f, 3.f, 3.f |
30.f, 30.f, 0.f |
-4.f, -4.f, 25.f |
|
6 |
Циан |
2.f, 3.f, 3.f |
0.f, 0.f, 0.f |
1.f, 0.f, 25.f |
|
7 |
Пурпурный |
2.f, 2.f, 2.f |
0.f, 0.f, 60.f |
-1.f, -0.5f, 8.f |
|
8 |
Синий |
2.f, 3.f, 3.f |
30.f, 30.f, 0.f |
-8.f, 0.f, 35.f |
|
9 |
Фиолетовый |
3.f, 1.f, 2.f |
45.f, 0.f, 0.f |
1.f, 0.f, 25.f |
|
10 |
Оранжевый |
5.f, 1.f, 1.f |
0.f, 0.f, 60.f |
-4.f, -4.f, 25.f |
|
11 |
Зеленый |
1.f, 1.f, 1.f |
0.f, 0.f, 0.f |
-5.f, 8.f, 25.f |
|
12 |
Красный |
3.f, 3.f, 3.f |
0.f, 0.f, 60.f |
-8.f, 0.f, 35.f |
|
13 |
Синий |
2.f, 3.f, 3.f |
30.f, 30.f, 0.f |
10.f, -4.f, 30.f |
|
14 |
Циан |
3.f, 1.f, 2.f |
0.f, 0.f, 60.f |
-4.f, -4.f, 25.f |
|
15 |
Белый |
2.f, 3.f, 3.f |
0.f, 0.f, 0.f |
-5.f, 8.f, 25.f |
|
16 |
Зеленый |
2.f, 2.f, 2.f |
45.f, 0.f, 0.f |
1.f, 0.f, 25.f |
|
17 |
Красный |
2.f, 3.f, 3.f |
30.f, 30.f, 0.f |
-4.f, -4.f, 25.f |
|
18 |
Синий |
3.f, 1.f, 2.f |
0.f, 0.f, 60.f |
-5.f, 8.f, 25.f |
|
19 |
Желтый |
3.f, 3.f, 3.f |
45.f, 0.f, 0.f |
10.f, -4.f, 30.f |
|
20 |
Зеленый |
1.f, 1.f, 1.f |
30.f, 30.f, 0.f |
2.f, 0.f, 8.f |
Лабораторная работа №5
Создание объектов сцены
Цель работы: Создать несколько разнотипных объектов и поместить их в сцену.
Необходимое оборудование и ПО: лабораторная работа №4.
Общие сведения
На практике возникает необходимость визуализировать более одного объекта одновременно. Для этого целесообразно организовать визуализируемые объекты в виде списка. Совместно с общим интерфейсом s_figure это позволит единообразно создавать, обрабатывать и удалять объекты.
Для организации такого списка необходимо в каждом объекте запоминать указатель на объект следующий за ним, а начало списка запоминать в глобальной переменной. Таким образом, последовательно перемещаясь от начала к концу списка можно визуализировать все объекты.
Для создания объектов используется функция AddFigure(), а функции RenderFigures() и ReleaseScene() модифицируются таким образом чтобы обрабатывать все объекты списка. В функции InitScene() создается несколько объектов, которые помещаются в список.
Функция AddFigurе добавляет объект в список, и связывает его с предыдущим созданным объектом. Для получения указателя на следующий объект в списке используется интерфейсная функция s_figure::next(). Указатель на первый объект в списке хранится в переменной s_figure* pSceneRoot.
Фигура создается оператором new с указанием параметров, полученный указатель передается в функцию AddFigure. Название классов фигур: плоскость - s_plane, куб - s_cube, сглаженный куб - c_cube_smooth.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №4.
Внести изменения в файлы проекта согласно приложению А.
Добавить описание плоскости и куба со сглаженными углами в файл figures.cpp.
Добавить описание функций в файле kg_lab.h.
Отладить и запустить программу. На экране должны появиться объекты сцены: три разноцветных куба по центру и серая плоскость снизу экрана.
Модифицировать объекты сцены согласно варианту в функции InitScene(), заменив функции AddFigure, которые показаны в примере (см. приложение Б).
Отладить и запустить программу. На экране должны появиться объекты сцены с заданными в задании параметрами.
На экране должно появиться 6 объектов. Если часть объектов не видна, необходимо определить их и скорректировать координаты и/или угол поворота, таким образом, чтобы фигуры появились в области видимости (на экране). Помните, что плоскость фигура односторонняя, и если она ориентирована от наблюдателя - не будет отображаться на экране. В этом случае, необходимо ее повернуть таким образом чтобы лицевые грани повернулись к наблюдателю.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- схематичный рисунок объектов сцены и проекции пирамиды видимости в виде: сверху (против оси Y), справа (против оси X) и спереди (вдоль оси Z);
- текст программ (scene.cpp, figures.cpp, kg_lab.h).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…
struct s_figure
{s_vector3 obj_scale, obj_rot, obj_pos;
…s_figure( const s_vector3& pos_, const s_vector3& rot_ = vec0,
const s_vector3& scale_ = vec1, DWORD color_ = 0xff808080UL,
float level_ = 0.5f, float spower_ = 16.f, bool anim_ = true );
s_figure* child;
s_figure* next() const { return child; }
void set_child( s_figure* child_ ) { child = child_; }
};
void ReleaseScene();
void InitScene();
void AddFigure( s_figure* pFig );
}; //namespace scene
namespace figures
{using namespace directx;
struct s_cube : public scene::s_figure
{…};
struct s_plane : public scene::s_figure
{virtual const s_vertex* verts( DWORD& cnt ) const;
virtual const t_index* inds( DWORD& cnt ) const;
s_plane( const s_vector3& pos_, const s_vector3& rot_ = vec0,
const s_vector3& scale_ = vec1,
DWORD color_ = 0xff808080UL, float level_ = 0.5f, float spower_ = 16.f ) :scene::s_figure( pos_, rot_, scale_, color_, level_, spower_, false ) {}
};struct s_cube_smooth : public scene::s_figure
{virtual const s_vertex* verts( DWORD& cnt ) const;
virtual const t_index* inds( DWORD& cnt ) const;
s_cube_smooth( const s_vector3& pos_, const s_vector3& rot_ = vec0,
const s_vector3& scale_ = vec1,
DWORD color_ = 0xff808080UL, float level_ = 0.5f, float spower_ = 16.f ) :scene::s_figure( pos_, rot_, scale_, color_, level_, spower_ ) {}
};
}; //namespace figures
Добавить и изменить в файле scene.cpp:
void RenderFigures( IDirect3DDevice9* Dev, LPD3DXEFFECT pEffect )
{const s_figure* f = pSceneRoot;
while( f ){DWORD vcnt = 0, icnt = 0;
const s_vertex* v = f->verts( vcnt );
const t_index* i = f->inds( icnt );
DWORD tri_cnt = icnt / 3;
const s_matrix& MatWorld = f->matrix();
const s_vector4& vObjColor = f->color();
pEffect->SetMatrix( hMatWorld, &MatWorld );
pEffect->SetVector( hObjColor, &vObjColor );
pEffect->SetFloat( hPower, f->power() );
pEffect->SetFloat( hSpecLevel, f->spec_level() );
pEffect->CommitChanges();
Dev->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, vcnt, tri_cnt, i,
D3DFMT_INDEX16, v, sizeof( s_vertex ) );
f = f->next();
}// while( f )
}s_figure::s_figure( const s_vector3& pos_, const s_vector3& rot_, const s_vector3& scale_,
DWORD color_, float level_, float spower_, bool anim_ ) :
obj_scale( scale_ ), obj_rot( rot_ ), obj_pos( pos_ ),
level( level_ ), spower( spower_ ), changes( true ), anim( anim_ ), child( 0 )
{D3DXMatrixIdentity( &world );
set_color( color_ );
}…void AddFigure( s_figure* pFig )
{pFig->set_child( pSceneRoot );
pSceneRoot = pFig;
}void ReleaseScene()
{s_figure* f = pSceneRoot;
while( f ){s_figure* f1 = f;
f = f->next();
delete f1;
}// while( f )
pSceneRoot = 0;
}void InitScene()
{vEyePos = vec0;
vAtPos = s_vector3( 0.f, 0.f, 1.f );
fFovY = 60.f;
AddFigure( new figures::s_plane( s_vector3( 0.f, -8.f, 20.f ), s_vector3( 0.f, 0.f, 0.f ),
s_vector3( 15.f, 1.f, 35.f ), 0xff808080UL, 0.2f, 64.f ) );
AddFigure( new figures::s_cube( s_vector3( 10.f, -4.f, 30.f ), s_vector3( 0.f, 0.f, 0.f ),
s_vector3( 3.f, 3.f, 3.f ), 0xff0000ffUL, 1.f, 32.f ) );
AddFigure( new figures::s_cube_smooth( s_vector3( 0.f, 5.f, 35.f ), s_vector3( 0.f, 0.f, 0.f ),
s_vector3( 2.f, 2.f, 2.f ), 0xff00ff00UL, 0.5f, 16.f ) );
AddFigure( new figures::s_cube_smooth( s_vector3( -10.f, -2.f, 25.f ), s_vector3( 0.f, 0.f, 0.f ),
s_vector3( 3.f, 2.f, 1.f ), 0xffff0000UL, 0.5f, 3.f ) );
}Добавить в файл figures.cpp:
…const t_index* s_cube::inds( DWORD& cnt ) const
{…21, 20, 23, 20, 22, 23,//правая грань
};cnt = sizeof( inds ) / sizeof( inds[0] );
return inds;
}const s_vertex* s_plane::verts( DWORD& cnt ) const
{static s_vertex verts[] =
{s_vertex( s_vector3( -1.f, 0.f, -1.f ) ),
s_vertex( s_vector3( 1.f, 0.f, -1.f ) ),
s_vertex( s_vector3( -1.f, 0.f, 1.f ) ),
s_vertex( s_vector3( 1.f, 0.f, 1.f ) ),
};
cnt = ...
Подобные документы
Основы программирования графических приложений на основе DirectX для операционной системы Windows. Работа с различными интерфейсами. Описание некоторых функций, используемых для работы с Direct3D. Взаимосвязь между приложением, Direct3D и аппаратурой.
курсовая работа [156,2 K], добавлен 10.02.2015История создания и развития операционной системы Microsoft Windows. Особенности каждой из ее версий. Новшества в интерфейсе, встроенных программах, системе управления и использования ОС, увеличение скорости выполнения приложений возможностями мультимедиа.
реферат [29,5 K], добавлен 30.11.2013Программирование в операционной системе Windows. Работа с потоками и процессами ОС. Методы их создания. Основы вызова API-функций. Пример создания диалогового окна без использования файла ресурсов. Разработка программы с помощью 32-битного ассемблера.
курсовая работа [107,6 K], добавлен 18.05.2014Программирование оконных Windows-приложений, средства TASM для их разработки. Углубленное программирование на ассемблере для Win32, минимальная программа. Организация высокоуровневого консольного ввода-вывода. Наборы символов и функции Wlndows APL.
курсовая работа [51,6 K], добавлен 23.06.2015Сущность основных аспектов эффективного функционирования в операционной системе Windows. Способ создания локальных сетей в операционной системе Windows XP, изучение их возможностей. Глобальная сеть Интернет в ОС Windows, структура и основные программы.
курсовая работа [352,8 K], добавлен 15.02.2009Создание компанией Microsoft операционной системы MS-DOS и повсеместное использование персональных компьютеров. Необходимость создания более удобной для пользователя операционной системы, разработка и эволюция Windows, появление интернет-приложений.
презентация [3,6 M], добавлен 29.10.2012Возможности Win32 для нахождения списка запущенных процессов. Использование библиотеки Process Status Helper, счетчиков производительности, Windows Management Instrumentation. Описание программы, ее алгоритм и составление инструкции пользователя.
курсовая работа [819,0 K], добавлен 21.03.2011Прикладные программы и утилиты. Простейшие функции операционной системы. История разработки корпорацией Microsoft Corporation графической операционной оболочки Windows. Версия семейства сетевых ОС Windows NT (Millennium Edition, 2000, XP, Vista, Seven)
презентация [965,2 K], добавлен 12.10.2013Совместное функционирование всех устройств компьютера и доступ к его ресурсам. Понятие и функции графической операционной системы Windows. Справочная служба Windows. Управление файловой системой. Технология "Plug and Play". Графический интерфейс Windows.
контрольная работа [22,2 K], добавлен 22.01.2011Установка операционной системы Windows 2000/XP/2003. Компоненты служб удаленной установки. Автоматическая (unattended) установка ОС из общего каталога на сервере. Установка ОС и приложений из образа, созданного при помощи ПО сторонних производителей.
реферат [22,4 K], добавлен 03.04.2010Общее понятие об оперативной системе Windows Vista. Сравнительный анализ систем Windows XP и Windows Vista. Специфика процесса установки, трехмерный интерфейс Aero Glass, действие некоторых мини-приложений. Новости управления папками, работа в интернете.
реферат [2,4 M], добавлен 01.02.2010Теоретические основы написания Windows-приложений с использованием библиотеки MFC. Основы программирования под Windows. Проектирование приложений в среде Microsoft Visual C++. Описание логической структуры приложения, его функциональное назначение.
курсовая работа [1,3 M], добавлен 12.12.2011Основы работы операционной системы Windows XP. Работа в текстовом процессоре Microsoft Word: ввода, редактирования и форматирования текста, автоматизации разработки документа, создания графических объектов, создания комплексного текстового документа.
курсовая работа [3,6 M], добавлен 25.04.2009Операционная система от компании Microsoft. Понятие Windows 8, ее особенности. Использование мыши и приложений в интерфейсе Метро. Самый проблемный жест при работе с Windows 8. Направленность операционной системы на устройства с сенсорным экраном.
реферат [30,1 K], добавлен 16.05.2013Основы работы с многооконным графическим пользовательским интерфейсом операционной системы Windows95/NT. Основы работы с прикладными программами Windows и DOS. Разработка простого приложения для Windows при помощи средства разработки приложений DELPHI.
контрольная работа [281,0 K], добавлен 15.01.2009Взаимодействие процессов и потоков в операционной системе, основные алгоритмы и механизмы синхронизации. Разработка школьного курса по изучению процессов в операционной системе Windows для 10-11 классов. Методические рекомендации по курсу для учителей.
дипломная работа [3,2 M], добавлен 29.06.2012Использование стандартных библиотек Windows. Установка и настройка дополнительных устройств ввода/вывода. Использование камеры, динамиков, сканера, дисков и портов ввода/вывода. Драйверы внешних устройств. Безопасность данных в операционных системах.
контрольная работа [1,8 M], добавлен 13.10.2022Понятие процесса и потока, характеристика их свойств и особенности создания. Требования к алгоритмам синхронизации, суть взаимного исключения на примере монитора и семафора. Методика изучения элективного курса "Процессы в операционной системе Windows".
дипломная работа [1,7 M], добавлен 03.06.2012Программное регулирование громкости. Использование программы Windows Media Player, интерфейс программы. Запись музыкального компакт–диска с помощью Windows Media Player. Использование стандартных средств звукозаписи в операционной системе Windows.
контрольная работа [31,0 K], добавлен 20.01.2011Разработка Windows-приложений с использованием библиотеки MFC. Базовый набор классов, написанных на языке С++ и предназначенных для упрощения процесса программирования под Windows. Фундаментальные идеи объектно-ориентированного программирования.
курсовая работа [348,1 K], добавлен 02.07.2011