Автоматика и управление в технических системах
Использование Win32 API для создания оконных приложений в операционной системе Windows XP. Подключение графической библиотеки Direct3D, каркасная модель куба при помощи простейшей микропрограммы, метод Ламберта и Фонга, учет времени синтеза кадра.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | лабораторная работа |
Язык | русский |
Дата добавления | 17.06.2014 |
Размер файла | 3,4 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
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
Таблица 2
№ варианта |
Тип фигуры и номер параметров из таблицы 1 |
||||||
1 |
2 |
3 |
4 |
5 |
6 |
||
1 |
Куб, 3 |
Куб, 5 |
Куб, 12 |
Куб, 1 |
Плоскость, 4 |
Сгл. куб, 15 |
|
2 |
Плоскость, 13 |
Плоскость, 7 |
Сгл. куб, 15 |
Сгл. куб, 8 |
Куб, 4 |
Куб, 10 |
|
3 |
Сгл. куб, 3 |
Куб, 11 |
Куб, 5 |
Плоскость, 4 |
Куб, 1 |
Сгл. куб, 2 |
|
4 |
Плоскость, 11 |
Куб, 1 |
Сгл. куб, 2 |
Сгл. куб, 3 |
Плоскость, 13 |
Куб, 5 |
|
5 |
Куб, 1 |
Сгл. куб, 15 |
Куб, 4 |
Сгл. куб, 8 |
Сгл. куб, 2 |
Плоскость, 12 |
|
6 |
Сгл. куб, 2 |
Куб, 3 |
Плоскость, 12 |
Куб, 6 |
Куб, 7 |
Сгл. куб, 5 |
|
7 |
Плоскость, 11 |
Куб, 10 |
Плоскость, 13 |
Сгл. куб, 3 |
Куб, 6 |
Куб, 12 |
|
8 |
Куб, 5 |
Плоскость, 4 |
Плоскость, 12 |
Сгл. куб, 8 |
Сгл. куб, 1 |
Сгл. куб, 14 |
|
9 |
Куб, 12 |
Куб, 15 |
Куб, 6 |
Куб, 5 |
Куб, 2 |
Сгл. куб, 14 |
|
10 |
Куб, 6 |
Сгл. куб, 3 |
Куб, 4 |
Плоскость, 7 |
Куб, 14 |
Куб, 1 |
|
11 |
Плоскость, 11 |
Куб, 1 |
Плоскость, 7 |
Сгл. куб, 15 |
Куб, 3 |
Куб, 14 |
|
12 |
Куб, 11 |
Сгл. куб, 5 |
Плоскость, 12 |
Куб, 10 |
Сгл. куб, 15 |
Куб, 1 |
|
13 |
Сгл. куб, 2 |
Куб, 12 |
Куб, 2 |
Сгл. куб, 15 |
Куб, 14 |
Куб, 7 |
|
14 |
Куб, 1 |
Куб, 6 |
Сгл. куб, 8 |
Сгл. куб, 3 |
Куб, 2 |
Сгл. куб, 5 |
|
15 |
Сгл. куб, 10 |
Плоскость, 12 |
Куб, 7 |
Куб, 4 |
Сгл. куб, 2 |
Куб, 3 |
|
16 |
Плоскость, 4 |
Плоскость, 11 |
Куб, 10 |
Плоскость, 7 |
Куб, 5 |
Сгл. куб, 8 |
|
17 |
Куб, 10 |
Куб, 3 |
Плоскость, 13 |
Куб, 6 |
Куб, 2 |
Плоскость, 12 |
|
18 |
Куб, 2 |
Куб, 1 |
Сгл. куб, 8 |
Куб, 4 |
Плоскость, 7 |
Куб, 11 |
|
19 |
Плоскость, 11 |
Сгл. куб, 2 |
Плоскость, 7 |
Куб, 5 |
Сгл. куб, 15 |
Сгл. куб, 3 |
|
20 |
Куб, 5 |
Куб, 11 |
Плоскость, 4 |
Сгл. куб, 8 |
Куб, 10 |
Сгл. куб, 15 |
Необходимо добавить фигуры согласно варианту из таблицы 2, параметры фигур взять из таблицы 1 по номеру. Название классов фигур: плоскость - s_plane, куб - s_cube, сглаженный куб - c_cube_smooth.
Лабораторная работа №6
Создание микропрограммы для расчета освещения по методу Ламберта для направленного источника света
Цель работы: Добавить описание направленного источника света, создать микропрограмму, рассчитывающую освещение сцены источником света с заданными параметрами.
Необходимое оборудование и ПО: лабораторная работа №5.
Общие сведения
Для повышения реалистичности синтезируемых изображений необходимо рассчитывать освещенность каждого элемента трехмерной сцены, которая визуализируется. Такой расчет целесообразно производить, используя вычислительные мощности ускорителя трехмерной графики. Для этого необходимые вычисления необходимо поместить во фрагментную микропрограмму (файл shader.fx).
Для освещения сцены используем два источника:
1) источник фонового освещения (ambient), который характеризуется цветом излучаемого света Ca и равномерно освещает объекты со всех направлений;
2) источник направленного освещения (directional), который освещает объекты с заданного направления L, цвет источника Cd.
Для расчета освещенности используем правило Ламберта, которое гласит, что интенсивность освещения i зависит от угла a между нормалью к поверхности N и направлением падающего света по закону косинуса i = cos a.
Для определения величины cos a, необходимо нормализировать векторы L и N и рассчитать скалярное произведение между ними (вместо вектора L используется вектор L' имеющий противоположное направление): i = max( 0, |L'|.|N| ). Так как интенсивность освещения не может принимать отрицательные значения, нужно взять максимум из 0 и величины полученного скалярного произведения. Полученное выражение реализуется в функции lambert_law().
Суммарная освещенность is двумя источниками вычисляется следующим образом is = I * Cd + Ca. Данная величина умножается на цвет объекта и возвращается в качестве результата фрагментной микропрограммой ps_lambert().
Для правильного расчета освещенности необходимо рассчитать для каждой вершины фигур нормаль, эту операцию производит функция ComputeNormals, которая вызывается в методе comp_normals() интерфейса s_figure во время конструирования фигур.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №5.
Внести изменения в файлы проекта согласно приложению А.
Отладить и запустить программу. На экране должны появиться объекты сцены: согласно варианту из лабораторной работы №5.
Задать параметры источника света в функции InitScene() согласно номеру варианта. Вместо знаков AAAA, LLLL, DDD должны быть заданы коды цветов фонового и направленного источников света, направление на источник света (см. приложение Б).
Отладить и запустить программу. На экране должны появиться объекты сцены освещенные источником света с заданными в задании параметрами.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- схематичный рисунок объектов сцены с указанием направления света излучаемого источником;
- значение нормализованного вектора DDD;
- текст программ (scene.cpp, shader.fx).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…namespace render
{enum
{RM_WIRE,
RM_LAMBERT,
RM_MAX,
};
Изменить строку const int CurRenderMethod = … на
const int CurRenderMethod = RM_LAMBERT;
…Добавить метод comp_normals() в структуру s_figure (в самый конец, перед закрывающей скобкой):
struct s_figure
{…void comp_normals();
};Добавить вызов метода comp_normals() в конструктор каждой фигуры для автоматического расчета нормалей:
namespace figures
{usingnamespace directx;
struct s_cube : public scene::s_figure
{…scene::s_figure( pos_, rot_, scale_, color_, level_, spower_ ) { comp_normals(); }
};struct s_plane : public scene::s_figure
{…scene::s_figure( pos_, rot_, scale_, color_, level_, spower_, false ) { comp_normals(); }
};struct s_cube_smooth : public scene::s_figure
{…scene::s_figure( pos_, rot_, scale_, color_, level_, spower_ ) { comp_normals(); }
};}; //namespace figures
Добавить в файл render.cpp:
bool LoadResources( IDirect3DDevice9* Dev )
{…if( !pEffect ){main::message_box_( L"Шейдер не найден!" );
return false;
}// if( !pEffect )
static const char* tnames[RM_MAX] = { "wire", "lambert" };
for( int i = 0; i < RM_MAX; ++i )
…Добавить в файл scene.cpp:
namespace scene
{s_figure* pSceneRoot = 0;
s_vector4 vLigColor;
s_vector4 vAmbColor;
s_vector4 vLigDir;
s_vector4 vLigPos;
…void color2vec( DWORD color_, s_vector4& obj_color )
{…}
void ComputeNormals( s_vertex* verts, int vcnt, const t_index* inds, int icnt )
{for( int v = 0; v < vcnt; ++v )
{verts[v].Norm = vec0;
}// for( int v = 0; v < vcnt; ++v )
int tris = icnt / 3;
for( int t = 0; t < tris; ++t )
{int i = t * 3;
const D3DXVECTOR3& v0 = verts[ inds[i + 0] ].Pos;
const D3DXVECTOR3& v1 = verts[ inds[i + 1] ].Pos;
const D3DXVECTOR3& v2 = verts[ inds[i + 2] ].Pos;
s_vector3 ledge, redge;
D3DXVec3Subtract( &ledge, &v0, &v1 );
D3DXVec3Subtract( &redge, &v0, &v2 );
s_vector3 norm, nnorm;
D3DXVec3Cross( &norm, &ledge, &redge );
D3DXVec3Normalize( &nnorm, &norm );
for( int v = 0; v < 3; ++v )
{s_vertex& vert = verts[inds[i + v]];
D3DXVec3Add( &vert.Norm, &vert.Norm, &nnorm );
}// for( int v = 0; v < 3; ++v )
}// for( int t = 0; t < tris; ++t )
for( int v = 0; v < vcnt; ++v )
{D3DXVec3Normalize( &verts[v].Norm, &verts[v].Norm );
}// for( int v = 0; v < vcnt; ++v )
}void RenderFigures( IDirect3DDevice9* Dev, LPD3DXEFFECT pEffect )
{pEffect->SetVector( hLigColor, &vLigColor );
pEffect->SetVector( hAmbColor, &vAmbColor );
pEffect->SetVector( hLigDir, &vLigDir );
pEffect->SetVector( hLigPos, &vLigPos );
…s_figure::s_figure()
{…}
void s_figure::comp_normals()
{DWORD vcnt = 0, icnt = 0;
s_vertex* v = (s_vertex*) verts( vcnt );
const t_index* i = inds( icnt );
ComputeNormals( v, vcnt, i, icnt );
}const s_matrix& s_figure::matrix() const
{…void InitScene()
{vEyePos = vec0;
vAtPos = s_vector3( 0.f, 0.f, 1.f );
fFovY = 60.f;
color2vec( LLLL, vLigColor );
color2vec(AAAA, vAmbColor );
vLigDir = s_vector4( DDD, 0.f );
vLigPos = s_vector4( 0.f, 0.f, 20.f, 35.f );
AddFigure( new figures::
Внимание! В функции InitScene() вместо знаков AAAA, LLLL, DDD должны быть заданы коды цветов фонового и направленного источников света, направление на источник света (см. приложение Б).
Добавить в файл shader.fx:
…technique wire
{pass …
}}float3 lambert_law( float3 L, float3 N )
{float LdN = max( 0.0, dot( L, N ) );
return v_lig_color.rgb * LdN;
}float4 ps_lambert( s_output2 i ) : COLOR
{float3 color = v_obj_color.rgb;
float3 N = normalize( i.nor );
float3 L = normalize( v_lig_dir.xyz );
float3 ambient = v_amb_color.rgb;
float3 diffuse = lambert_law( L, N );
return float4( ( ambient + diffuse ) * color, 1.f );
}technique lambert
{pass P0
{FillMode = solid;
FogEnable = false;
AlphaBlendEnable = false;
AlphaTestEnable = false;
ZEnable = true;
ZFunc = lessequal;
CullMode = ccw;
VertexShader = compile vs_2_0 vs_simple();
PixelShader = compile ps_2_0 ps_lambert();
}}Приложение Б. Параметры источников света
№ варианта |
Цвет фонового источника (AAAA) |
Цвет направленного источника (LLLL) |
Направление на источник (DDD) |
|
1 |
Темно-красный |
Белый |
10.f, 20.f, 10.f |
|
2 |
Черный |
Желтый |
-30.f, 30.f, 30.f |
|
3 |
Темно-зеленый |
Красный |
10.f, 30.f, -10.f |
|
4 |
Темно-синий |
Белый |
-30.f, 10.f, 0.f |
|
5 |
Темно-серый |
Оранжевый |
-10.f, 10.f, 0.f |
|
6 |
Темно-синий |
Белый |
-15.f, 3.f, 38.f |
|
7 |
Темно-зеленый |
Светло-серый |
10.f, 20.f, 10.f |
|
8 |
Темно-серый |
Белый |
-10.f, 50.f, -5.f |
|
9 |
Темно-серый |
Циан |
-30.f, 10.f, 0.f |
|
10 |
Темно-синий |
Зеленый |
-15.f, 3.f, 38.f |
|
11 |
Темно-красный |
Циан |
-30.f, 30.f, 30.f |
|
12 |
Темно-серый |
Оранжевый |
-30.f, 10.f, 0.f |
|
13 |
Черный |
Циан |
-20.f, 30.f, 30.f |
|
14 |
Темно-синий |
Белый |
-10.f, 50.f, -5.f |
|
15 |
Темно-зеленый |
Зеленый |
-15.f, 3.f, 38.f |
|
16 |
Темно-серый |
Светло-серый |
-10.f, 10.f, 0.f |
|
17 |
Темно-синий |
Белый |
10.f, 30.f, -10.f |
|
18 |
Темно-красный |
Зеленый |
-30.f, 10.f, 0.f |
|
19 |
Темно-синий |
Оранжевый |
10.f, 30.f, -10.f |
|
20 |
Темно-зеленый |
Зеленый |
-10.f, 10.f, 0.f |
Внимание! Перед заданием вектора DDD его необходимо нормализовать: рассчитать его длину и каждую компоненту вектора разделить на нее.
Лабораторная работа №7
Создание микропрограммы для расчета освещения по методу Фонга для направленного источника света
Цель работы: Изучить принцип расчета освещения сцены по методу Фонга.
Необходимое оборудование и ПО: лабораторные работы №5 и №6.
Общие сведения
Для повышения реалистичности синтезируемых изображений помимо рассеянного освещения необходимо рассчитывать бликовую составляющую освещения. Такой расчет целесообразно производить, используя вычислительные мощности ускорителя трехмерной графики. Для этого необходимые вычисления необходимо поместить во фрагментную микропрограмму (файл shader.fx).
Для расчета бликов воспользуемся методом Фонга, для этого дополнительно добавим два параметра для направленного источника света: интенсивность блика Cs и размер блика p.
Интенсивность блика согласно методу Фонга: iф = Cs * ( V.R )p. Для проведения расчетов необходимо вычислить вектор отраженного света: R = L' - 2 * N * ( L'.N ), где N - нормаль к поверхности в точке для которой ведется расчет освещения, а L' - направление на источник света, и вектор направления на наблюдателя V = |E - P|, где E - позиция камеры, а P - координаты точки для которой ведется расчет.
Для расчета вектора отражения R используется функция reflect().
Полученную интенсивность iф необходимо модулировать величиной L.N для того чтобы блики не возникали на затененной стороне объектов. В микропрограмме эта модуляция производится путем домножения интенсивности на величину max( 1, L.N * 10 ).
Суммарная освещенность is' (с учетом бликов) вычисляется следующим образом is' = Cd *( I + iф ) + Ca. Расчет интенсивности блика ведется в фрагментной микропрограмме ps_phong().
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №6.
Внести изменения в файлы проекта согласно приложению А.
Отладить и запустить программу. На экране должны появиться объекты сцены: согласно варианту из лабораторной работы №6 освещенные источниками света согласно приложению Б лабораторной работы №6.
Задать параметры бликов для каждого из объектов в функции InitScene() согласно номеру варианта. Вместо знаков SSS, PPP должны быть заданы: интенсивность блика и размер блика (см. приложение Б).
Отладить и запустить программу. На экране должны появиться объекты сцены освещенные источником света с заданными в задании параметрами.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- текст программ (scene.cpp, shader.fx).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…namepace render
{enum{RM_WIRE,
RM_LAMBERT,
RM_PHONG,
RM_MAX,
};const int CurRenderMethod = RM_PHONG;
const DWORD BackColor = 0xff000000UL;
bool LoadResources( IDirect3DDevice9* Dev );
void RenderScene( IDirect3DDevice9* Dev, int TN );
…Добавить в файл scene.cpp для фигур создаваемых функцией AddFigure() согласно варианту:
Пример:
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, SSS, PPP ) );
Вместо параметров SSS и PPP подставить для каждого объекта интенсивность и размер блика согласно варианту (см. приложение Б). Остальные параметры оставить неизменными.
Добавить в конец файла shader.fx:
…float3 phong_law( float3 L, float3 N, float3 V )
{float LdN = max( 0.0, dot( L, N ) );
float3 R = reflect( -L, N );
float3 specular = v_lig_color.rgb * f_spec_level * pow( max( 0.0, dot( V, R ) ), f_power );
specular *= min( 1.0, LdN * 10.0 );
return specular;
}float4 ps_phong( s_output2 i ) : COLOR
{float3 color = v_obj_color.rgb;
float3 N = normalize( i.nor );
float3 V = -normalize( i.eye );
float3 L = normalize( v_lig_dir.xyz );
float3 ambient = v_amb_color.rgb;
float3 diffuse = lambert_law( L, N );
float3 specular = phong_law( L, N, V );
return float4( ( ambient + diffuse ) * color + specular, 1.f );
}technique phong
{pass P0
{FillMode = solid;
FogEnable = false;
AlphaBlendEnable = false;
AlphaTestEnable = false;
ZEnable = true;
ZFunc = lessequal;
CullMode = ccw;
VertexShader = compile vs_2_0 vs_simple();
PixelShader = compile ps_2_0 ps_phong();
}}Добавить в файл render.cpp:
bool LoadResources( IDirect3DDevice9* Dev )
{…if( !pEffect )
{main::message_box_( L"Шейдер не найден!" );
return false;
}// if( !pEffect )
static const char* tnames[RM_MAX] = { "wire", "lambert", "phong" };
for( int i = 0; i < RM_MAX; ++i )
{…}
Приложение Б. Параметры бликов
№ варианта |
Интенсивность блика для фигур с четными номерами (SSS) |
Интенсивность блика для фигур с нечетными номерами (SSS) |
Размер блика для фигур с четными номерами (PPP) |
Размер блика для фигур с нечетными номерами (PPP) |
|
1 |
0.5f |
1.0f |
128.f |
32.f |
|
2 |
0.25f |
0.75f |
32.f |
120.f |
|
3 |
1.0f |
0.4f |
64.f |
4.f |
|
4 |
0.75f |
0.5f |
96.f |
16.f |
|
5 |
0.25f |
1.0f |
4.f |
128.f |
|
6 |
0.4f |
0.75f |
16.f |
80.f |
|
7 |
0.5f |
0.25f |
8.f |
16.f |
|
8 |
1.0f |
0.8f |
32.f |
64.f |
|
9 |
0.8f |
1.0f |
80.f |
128.f |
|
10 |
0.75f |
0.5f |
56.f |
10.f |
|
11 |
0.25f |
0.8f |
64.f |
32.f |
|
12 |
0.8f |
0.75f |
128.f |
20.f |
|
13 |
1.0f |
0.4f |
15.f |
100.f |
|
14 |
0.5f |
0.25f |
28.f |
80.f |
|
15 |
0.8f |
1.0f |
64.f |
35.f |
|
16 |
0.75f |
0.5f |
3.f |
120.f |
|
17 |
0.3f |
0.75f |
10.f |
80.f |
|
18 |
0.3f |
1.0f |
30.f |
96.f |
|
19 |
0.5f |
0.25f |
70.f |
10.f |
|
20 |
0.25f |
0.75f |
28.f |
89.f |
Внимание! Номера фигур для определения четности и нечетности брать из Таблицы 2 (приложение Б) лабораторной работы №5.
Лабораторная работа №8
Анимация объектов сцены
Цель работы: Исследовать принципы анимации объектов сцены с учетом времени синтеза кадра.
Необходимое оборудование и ПО: лабораторная работа №7.
Общие сведения
Для приложений запущенных под ОС Windows, а так же других многозадачных ОС затруднительно добиться постоянного времени синтеза кадра, для последовательных кадров. При запуске процессов ОС, других программ время, выделяемое приложению, может варьироваться в широких переделах. Так же конфигурации ПК на которых запускается приложение могут быть различными. Это ведет к тому, что гарантированно, заранее (во время компиляции программы) невозможно задать точные временные интервалы.
Для создания плавной анимации объектов в сцене (вращения или смещения) необходимо учитывать время, прошедшее с момента начала синтеза предыдущего кадра. Для получения времени в Win32 API существует ряд функций. В лабораторной работе воспользуемся простейшей GetTickCount() - эта функция позволяет получить время в миллисекундах прошедшее с момента запуска ОС.
Для того чтобы рассчитать время прошедшее с момента начала синтеза предыдущего кадра до начала синтеза текущего необходимо запомнить время t1 которое вернет функция GetTickCount(), а затем, перед началом синтеза кадра рассчитать разницу между текущим временем t2, которое вернет GetTickCount() и t1. Полученное значение deltaT = t2 - t1, после масштабирования (преобразования в секунды) можно использовать для масштабирования шага анимации.
В лабораторной работе функция PeekTimeDelta() возвращает величину deltaT в секундах. В функции UpdateSceneObjects() происходит вычисление шага анимации с учетом масштабирования. Далее все объекты находящиеся в сцене, для которых установлен флаг анимации поворачиваются на вновь вычисленные углы.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №7.
Добавить в проект файл animation.cpp.
Внести изменения в файлы проекта согласно приложению А.
Задать параметры скорости вращения по осям (вместо знаков RX, RY) в функции UpdateSceneObjects() согласно номеру варианта (см. приложение Б).
Отладить и запустить программу. На экране должны появиться вращающиеся объекты сцены: согласно варианту из лабораторной работы №6.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- текст программ (animation.cpp).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…struct s_figure
{…bool is_anim() const { return anim; }
};…namespace scene
{…void InitScene();
void AddFigure( s_figure* pFig );
void UpdateScene();
}; //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, bool anim_ = true ) :
scene::s_figure( pos_, rot_, scale_, color_, level_, spower_, anim_ ) { comp_normals(); }
};…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, bool anim_ = true ) :
scene::s_figure( pos_, rot_, scale_, color_, level_, spower_, anim_ ) { comp_normals(); }
};…}; //namespace figures
namespace animation
{using namespace directx;
float PeekTimeDelta();
void UpdateSceneObjects( scene::s_figure* pRoot );
};// namespace animation
Добавить в файл scene.cpp:
void UpdateSceneMatrices( LPD3DXEFFECT pEffect )
{…}
void UpdateScene()
{animation::UpdateSceneObjects( pSceneRoot );
}}; /namespace scene
Добавить в файл directx.cpp:
void Pump()
{if( !main::boActive )
Sleep( 20 );
scene::UpdateScene();
Paint();
}Добавить в файл animation.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace animation
{float fYaw = 0.f;
float fPitch = 0.f;
//получение времени прошедшего со времени прошлого кадра
float PeekTimeDelta()
{static int t = GetTickCount();
int dt = GetTickCount() - t;
t = GetTickCount();
return 0.001f * dt;
}void UpdateSceneObjects( scene::s_figure* pRoot )
{float dt = PeekTimeDelta();
fYaw += dt * RX;
fPitch += dt * RY;
while( pRoot )
{if( pRoot->is_anim() )
pRoot->rotate( s_vector3( fYaw, fPitch, 0.f ) );
pRoot = pRoot->next();
}// while( f )
}Приложение Б. Скорости вращения
№ варианта |
Вращение RX |
Вращение RY |
|
1 |
30.f |
0.f |
|
2 |
-100.f |
10.f |
|
3 |
50.f |
50.f |
|
4 |
-20.f |
-5.f |
|
5 |
120.f |
30.f |
|
6 |
-5.f |
-100.f |
|
7 |
-20.f |
0.f |
|
8 |
10.f |
10.f |
|
9 |
-5.f |
-20.f |
|
10 |
30.f |
-5.f |
|
11 |
-5.f |
120.f |
|
12 |
-100.f |
-5.f |
|
13 |
10.f |
50.f |
|
14 |
0.f |
10.f |
|
15 |
-5.f |
-20.f |
|
16 |
-20.f |
120.f |
|
17 |
-5.f |
30.f |
|
18 |
50.f |
-100.f |
|
19 |
-5.f |
0.f |
|
20 |
120.f |
10.f |
Лабораторная работа №9
Освещение объектов сцены точечным источником света
Цель работы: Исследовать принципы работы точечного источника света.
Необходимое оборудование и ПО: лабораторная работа №8.
Общие сведения
Более сложным является моделирование освещения от точечного источника света. Для такого типа источника дополнительно необходимо задавать позицию и радиус R освещаемой источником сферы (в лабораторной храниться в переменной vLigPos - позиция в полях x, y, z, а радиус в поле w).
Объекты, находящиеся на расстоянии более R от центра источника им не освещаются. Чем ближе точка объекта находится к источнику света, тем более интенсивно она освещается. Для моделирования такого затухания используется квадратичная зависимость от расстояния. Коэффициент затухания att рассчитывается в пиксельной микропрограмме по следующей формуле att = 1 - min( 0, L / R )2, где L - расстояние от фрагмента до центра источника света.
Еще одним отличием точечного источника от направленного является то, что направление на источник света не является константой, а рассчитывается для каждой точки индивидуально L' = Lp - P, где Lp - позиция источника света, а P - координаты точки.
Расчет освещения ведется по правилам Фонга и Ламберта, аналогично направленному источнику света. Полученные интенсивности модулируются (умножаются) коэффициентом затухания att.
В лабораторной работе анимация источника света ведется путем изменения его позиции по вертикали с определенной скоростью.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №8.
Внести изменения в файлы проекта согласно приложению А.
Задать параметры скорости и размаха смещения источника по оси Y (вместо знаков SSS, DDD) в функции UpdateSceneObjects() согласно номеру варианта (см. приложение Б).
Задать радиус источника света (вместо знака RRR) в функции InitScene() согласно номеру варианта (см. приложение Б).
Отладить и запустить программу. На экране должны появиться вращающиеся объекты сцены: согласно варианту из лабораторной работы №6. И анимированный источник света, который перемещается в вертикальной плоскости.
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- текст программ (animation.cpp, shader.fx).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h:
…namespace render
{enum
{RM_WIRE,
RM_LAMBERT,
RM_PHONG,
RM_PHONG_POINT,
RM_MAX,
};const int CurRenderMethod = RM_PHONG_POINT;
const DWORD BackColor = 0xff000000UL;
bool LoadResources( IDirect3DDevice9* Dev );
…namespace scene
{…void InitScene();
void AddFigure( s_figure* pFig );
void UpdateScene();
extern s_vector4 vLigPos;
}; //namespace scene
Добавить в файл render.cpp:
bool LoadResources( IDirect3DDevice9* Dev )
{…if( !pEffect )
{main::message_box_( L"Шейдер не найден!" );
return false;
}// if( !pEffect )
static const char* tnames[RM_MAX] = { "wire", "lambert", "phong", "phong_point" };
for( int i = 0; i < RM_MAX; ++i )
{…}
Добавить в файл animation.cpp:
#include "stdafx.h"
#include "kg_lab.h"
namespace animation
{float fYaw = 0.f;
float fPitch = 0.f;
float fLightH = 0.f;
…void UpdateSceneObjects( scene::s_figure* pRoot )
{…pRoot = pRoot->next();
}// while( f )
fLightH += dt * SSS;
if( fLightH > 1.f )
fLightH -= (int) fLightH;
scene::vLigPos.y = sinf( fLightH * 3.14f ) * DDD - 7.5f;
}}; //namespace animation
Заменить в файле scene.cpp:
…void InitScene()
{vEyePos = vec0;
vAtPos = s_vector3( 0.f, 0.f, 1.f );
fFovY = 60.f;
color2vec( 0xffffffffUL, vLigColor );
color2vec( 0xff404040UL, vAmbColor );
vLigDir = s_vector4( 0.5f, 1.f, 0.5f, 0.f );
vLigPos = s_vector4( 0.f, 0.f, 20.f, RRR );
…Добавить в конец файла shader.fx:
…float4 ps_phong_point( s_output2 i ) : COLOR
{float3 color = v_obj_color.rgb;
float3 N = normalize( i.nor );
float3 V = -normalize( i.eye );
float3 D = v_lig_pos.xyz - i.wpos;
float3 L = normalize( D );
float3 ambient = v_amb_color.rgb;
float3 diffuse = lambert_law( L, N );
float3 specular = phong_law( L, N, V );
float rad = v_lig_pos.w, ln = length( D );
float att = 1.0 - saturate( ln / rad ), att2 = sqrt( att );
specular *= att;
diffuse *= att;
return float4( ( ambient + diffuse ) * color + specular, 1.f );
}technique phong_point
{pass P0
{FillMode = solid;
FogEnable = false;
AlphaBlendEnable = false;
AlphaTestEnable = false;
ZEnable = true;
ZFunc = lessequal;
CullMode = ccw;
VertexShader = compile vs_2_0 vs_simple();
PixelShader = compile ps_2_0 ps_phong_point();
}
Приложение Б. Скорость, размах смещения источника по оси Y, радиус освещения
№ варианта |
Скорость смещения SSS |
Размах смещения DDD |
Радиус освещения RRR |
|
1 |
0.1f |
35.f |
50.f |
|
2 |
0.2f |
25.f |
35.f |
|
3 |
0.2f |
25.f |
45.f |
|
4 |
0.05f |
50.f |
25.f |
|
5 |
0.05f |
45.f |
50.f |
|
6 |
0.1f |
35.f |
40.f |
|
7 |
0.25f |
25.f |
25.f |
|
8 |
0.05f |
45.f |
35.f |
|
9 |
0.2f |
50.f |
40.f |
|
10 |
0.25f |
25.f |
45.f |
|
11 |
0.1f |
45.f |
40.f |
|
12 |
0.05f |
25.f |
50.f |
|
13 |
0.25f |
35.f |
35.f |
|
14 |
0.05f |
50.f |
25.f |
|
15 |
0.2f |
50.f |
45.f |
|
16 |
0.25f |
25.f |
40.f |
|
17 |
0.1f |
45.f |
50.f |
|
18 |
0.05f |
50.f |
40.f |
|
19 |
0.2f |
35.f |
35.f |
|
20 |
0.1f |
25.f |
45.f |
Лабораторная работа №10
Создание модели комплексной геометрической фигуры и добавление ее в сцену
Цель работы: Создание модели сложной геометрической фигуры.
Необходимое оборудование и ПО: лабораторная работа №9, задание №3 из РГЗ.
Общие сведения
Для описания геометрической фигуры в лабораторной работе используется общий интерфейс s_figure, который позволяет проводить конструирование фигуры, изменение ее параметров и получать описание геометрии и топологии фигуры. Описание фигур помещается в пространство имен figures. Новая фигура создается путем наследования интерфейса s_figure. Например, следующим образом: struct s_my_figure : public scene::s_figure {};.
Для каждой фигуры необходимо определить две функции: verts() - возвращающую список вершин фигруы и inds() возвращающую топологию фигуры (тройки индексов описывающие треугольники). Внутри каждой из функций содержится массив вершин в локальной системе координат и массив индексов, соответсвенно.
Для задания вершин используется структура s_vertex, конструктор которой принимает 1 обязательный аргумент типа s_vector3 (вектор из 3-х компонент), который содержит координаты вершины. Объявление вершины производится следующим образом: s_vertex( s_vector3( x, y, z ) ), где x, y, z - координаты вершины.
Вершины помещаются в массив в функции verts() и разделяются запятыми.
Для задания топологии фигуры используются тройки индексов (номеров вершин), которые определяют треугольники из которых состоит фигура. Нумерация вершин начинается с 0-го элемента.
Номера вершин задаются в массиве в функции inds() и отделяются друг от друга запятыми. Помните, что номер вершины не должен превышать количество вершин в массиве вершин заданном в функции verts(). Например, для плоскости номера вершин будут: 1, 0, 2, 1, 2, 3. При этом количество вершин равно четырем.
Для задания треугольников важен порядок обхода вершин. В лабораторной работе принято что видимые треугольники задаются по часовой стрелке, а невидимые против часовой. Этот порядок устанавливается в файле shader.fx в параметре CullMode. При значении ccw - удаляются треугольники имеющие порядок против часовой стрелки, при значении cw - по часовой, а при значении none удаления не происходит.
Ход выполнения
Запустить среду разработки Microsoft Visual C++ Express Edition.
Открыть проект лабораторной работы №9.
Создать структуру описания фигуры s_my_figure согласно варианту из РГЗ (см. приложение А).
Заменить одну из фигур находящихся в сцене вновь созданной фигурой. Для этого в функции InitScene() в одном из вызовов функций AddFigure() изменить тип фигуры на s_my_figure, остальные параметры оставить прежними.
Отладить и запустить программу. На экране должны появиться фигуры, добавленные в сцену, освещенные точечным источником света.
Для отладки вновь созданной фигуры можно переключить режим визуализации на каркасную модель, заменив константу CurRenderMethod в файле kg_lab.h на RM_WIRE:
const int CurRenderMethod = RM_WIRE;
Подготовить отчет о лабораторной работе, который должен содержать:
- задание;
- фигуру из РГЗ в виде сверху и в виде справа;
- текст программ (figures.cpp).
Приложение А. Исходный код работы
Добавить в файл kg_lab.h структуру описания новой фигуры s_my_figure:
…namespace figures
{…struct s_my_figure : public scene::s_figure
{virtual const s_vertex* verts( DWORD& cnt ) const;
virtual const t_index* inds( DWORD& cnt ) const;
s_my_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 ) :
scene::s_figure( pos_, rot_, scale_, color_, level_, spower_, anim_ ) { comp_normals(); }
};}; //namespace figures
…Добавить в конец файла figures.cpp описание вершин и топологии (треугольников) новой фигуры s_my_figure согдасно заданию №3 из РГЗ:
…const s_vertex* s_my_figure::verts( DWORD& cnt ) const
{static s_vertex verts[] =
{//в этом месте разместить координаты вершин фигуры //s_vertex( s_vector3( X.f, Y.f, Z.f ) ), где X, Y, Z - координаты вершин.
…};cnt = sizeof( verts ) / sizeof( verts[0] );
return verts;
}const t_index* s_my_figure::inds( DWORD& cnt ) const
{static const t_index inds[] =
{//в этом месте разместить тройки индексов описывающие топологию фигуры //(разделяя их запятыми)
…};cnt = sizeof( inds ) / sizeof( inds[0] );
return inds;
}}; //namespace figures
Размещено на Allbest.ru
...Подобные документы
Основы программирования графических приложений на основе 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