Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdf180 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
static bool myPause = false;
//Устанавливаем параметры Direct3D: public: bool InitializeDirectX()
{
try
{
myPresentParameters->Windowed = true; myPresentParameters->SwapEffect =
SwapEffect::Discard;
//Создаем устройство для визуализации вершин фигуры: myDevice = gcnew Device(0, DeviceType::Hardware,
this, CreateFlags::SoftwareVertexProcessing, myPresentParameters);
myDevice->DeviceReset +=
gcnew System::EventHandler(this->OnResetDevice); //Вызываем разработанные нами методы: this->OnCreateDevice(myDevice, nullptr); this->OnResetDevice(myDevice, nullptr);
myPause = false; return true;
}
catch (DirectXException^)
{
//Перехвачена ошибка инициализации DirectX: return false;
}
}
//Метод для начала и окончания визуализации (rendering) //преобразованных вершин:
public: void myRendering()
{
if (myDevice == nullptr) return;
if (myPause) return;
//Задаем белый цвет (Color::White) форме Form1: myDevice->Clear(ClearFlags::Target,
System::Drawing::Color::White, 1.0f, 0); //Начинаем сцену:
myDevice->BeginScene();
//Используем матрицы для выполнения преобразований: SetupMatrices();
myDevice->SetStreamSource(0, myVertexBuffer, 0); myDevice->VertexFormat =
CustomVertex::PositionColored::Format; //Для треугольника: myDevice->DrawPrimitives(
Глава 36. Методика проектирования плоских фигур |
181 |
PrimitiveType::TriangleList, 0, 1); //Заканчиваем сцену: myDevice->EndScene();
//Показываем сцену: myDevice->Present();
}
//Создаем устройство, буфер вершин фигуры и их данные: public: void OnCreateDevice(Object^ sender, EventArgs^ e)
{
Device^ myDev = (Device^)sender;
//Создаем буфер для 3-x вершин треугольника: myVertexBuffer = gcnew VertexBuffer(
typeid<CustomVertex::PositionColored>, 3, myDev, Microsoft::DirectX::Direct3D::Usage::Points, CustomVertex::PositionColored::Format, Pool::Default);
//Создаем геометрические данные при обработке
//события myVertexBuffer->Created: myVertexBuffer->Created +=
gcnew System::EventHandler( this->OnCreateVertexBuffer);
this->OnCreateVertexBuffer(myVertexBuffer, nullptr);
}
//Настраиваем параметры устройства для рисования: public: static void OnResetDevice(Object^ sender, EventArgs^ e)
{
Device^ myDev = (Device^)sender; //Выключаем режим CullMode, чтобы мы видели //переднюю и заднюю поверхность фигуры: myDev->RenderState->CullMode = Cull::None;
//Выключаем освещение Direct3D, так как мы задали //наши собственные цвета в вершинах: myDev->RenderState->Lighting = false;
}
//Создаем массив вершин и задаем их параметры: public: static void OnCreateVertexBuffer( Object^ sender, EventArgs^ e)
{
//Для фигуры с любым количеством вершин //объявляем массив и выполняем преобразование типов: array<CustomVertex::PositionColored>^ Vertex =
(array<CustomVertex::PositionColored>^) myVertexBuffer->Lock(0, Microsoft::DirectX:: Direct3D::LockFlags::None);
//В классе (структуре) Color создаем объект myColor:
182 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
Color myColor = Color::FromArgb(0); //Используем метод ToArgb
//для получения 32-bit ARGB-значение myColor: myColor = Color::FromArgb(myColor.ToArgb()); //Вершина 0:
//Координаты вершины:
Vertex[0].X = -1.0f; Vertex[0].Y = -1.0f; Vertex[0].Z = 0.0f;
//Цвет вершины:
Vertex[0].Color = myColor.Black.ToArgb(); //Вершина 1:
//Координаты вершины:
Vertex[1].X = 1.0f; Vertex[1].Y = -1.0f; Vertex[1].Z = 0.0f;
//Цвет вершины:
Vertex[1].Color = myColor.MediumOrchid.ToArgb(); //Вершина 2:
//Координаты вершины:
Vertex[2].X = 0.0f; Vertex[2].Y = 1.0f; Vertex[2].Z = 0.0f;
//Цвет вершины:
Vertex[2].Color = myColor.LightPink.ToArgb(); //Разблокируем буфер вершин: myVertexBuffer->Unlock();
}
//Включаем таймер и выполняем матричные преобразования: private: void SetupMatrices()
{
//Используем структуру матриц Matrix, //чтобы вращать фигуру вокруг оси y.
//Один оборот на 2*PI радиан фигура совершит //за 1000 мс (1 секунду):
int iTime = Environment::TickCount % 1000; float fAngle =
iTime * (2.0f * (float)Math::PI) / 1000.0f; myDevice->Transform->World = Matrix::RotationY(fAngle); //Задаем координаты глаза наблюдателя
//в матрице вида (view matrix): myDevice->Transform->View = Matrix::LookAtLH(
Vector3(0.0f, 3.0f, -5.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 1.0f, 0.0f));
//При помощи матрицы проецирования (projection matrix) //выполняем перспективные преобразования: myDevice->Transform->Projection =
Matrix::PerspectiveFovLH( (float)Math::PI / 4, 1.0f, 1.0f, 100.0f);
Глава 36. Методика проектирования плоских фигур |
183 |
}
//Останавливаем вращение фигуры и изменяем ее размеры //во время изменения размеров формы:
protected: void OnResize(EventArgs^ e)
{
myPause = ((this->WindowState == FormWindowState::Minimized) || !this->Visible);
}
Листинг 36.7. Методы для визуализации преобразованных вершин фигуры.
//Объявляем и инициализируем глобальные переменные. //Для устройства myDevice класса Device:
static Device^ myDevice = nullptr; //Для буфера вершин VertexBuffer:
static VertexBuffer^ myVertexBuffer = nullptr; static PresentParameters^ myPresentParameters =
gcnew PresentParameters(); static bool myPause = false;
//Устанавливаем параметры Direct3D: public: bool InitializeDirectX()
{
try
{
myPresentParameters->Windowed = true; myPresentParameters->SwapEffect =
SwapEffect::Discard;
//Создаем устройство для визуализации вершин фигуры: myDevice = gcnew Device(0, DeviceType::Hardware,
this, CreateFlags::SoftwareVertexProcessing, myPresentParameters);
myDevice->DeviceReset +=
gcnew System::EventHandler(this->OnResetDevice); //Вызываем разработанные нами методы: this->OnCreateDevice(myDevice, nullptr); this->OnResetDevice(myDevice, nullptr);
myPause = false; return true;
}
catch (DirectXException^)
{
//Перехвачена ошибка инициализации DirectX: return false;
}
}
184 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Метод для начала и окончания визуализации (rendering) //преобразованных вершин:
public: void myRendering()
{
if (myDevice == nullptr) return;
if (myPause) return;
//Задаем белый цвет (Color::White) форме Form1: myDevice->Clear(ClearFlags::Target,
System::Drawing::Color::White, 1.0f, 0); //Начинаем сцену:
myDevice->BeginScene();
//Используем матрицы для выполнения преобразований: SetupMatrices();
myDevice->SetStreamSource(0, myVertexBuffer, 0); myDevice->VertexFormat =
CustomVertex::PositionColored::Format; //Для прямоугольника: myDevice->DrawPrimitives(
PrimitiveType::TriangleStrip, 0, 2); //Заканчиваем сцену: myDevice->EndScene();
//Показываем сцену: myDevice->Present();
}
//Создаем устройство, буфер вершин фигуры и их данные: public: void OnCreateDevice(Object^ sender, EventArgs^ e)
{
Device^ myDev = (Device^)sender;
//Создаем буфер для 4-x вершин прямоугольника: myVertexBuffer = gcnew VertexBuffer(
typeid<CustomVertex::PositionColored>, 4, myDev, Microsoft::DirectX::Direct3D::Usage::Points, CustomVertex::PositionColored::Format, Pool::Default);
//Создаем геометрические данные при обработке
//события myVertexBuffer->Created: myVertexBuffer->Created +=
gcnew System::EventHandler( this->OnCreateVertexBuffer);
this->OnCreateVertexBuffer(myVertexBuffer, nullptr);
}
//Настраиваем параметры Direct3D:
public: static void OnResetDevice(Object^ sender, EventArgs^ e)
Глава 36. Методика проектирования плоских фигур |
185 |
{
Device^ myDev = (Device^)sender; //Выключаем режим CullMode, чтобы мы видели //переднюю и заднюю поверхность фигуры: myDev->RenderState->CullMode = Cull::None;
//Выключаем освещение Direct3D, так как мы задали //наши собственные цвета в вершинах: myDev->RenderState->Lighting = false;
}
//Создаем массив вершин и задаем их параметры: public: static void OnCreateVertexBuffer( Object^ sender, EventArgs^ e)
{
//Для фигуры с любым количеством вершин //объявляем массив и выполняем преобразование типов: array<CustomVertex::PositionColored>^ Vertex =
(array<CustomVertex::PositionColored>^) myVertexBuffer->Lock(0, Microsoft::DirectX::Direct3D::LockFlags::None);
//В классе (структуре) Color создаем объект myColor: Color myColor = Color::FromArgb(0);
//Используем метод ToArgb
//для получения 32-bit ARGB-значение myColor: myColor = Color::FromArgb(myColor.ToArgb()); //Вершина 0:
//Координаты вершины:
Vertex[0].X = -1.0f; Vertex[0].Y = -1.0f; Vertex[0].Z = 0.0f;
//Цвет вершины:
Vertex[0].Color = myColor.Black.ToArgb(); //Вершина 1:
//Координаты вершины:
Vertex[1].X = -1.0f; Vertex[1].Y = 1.0f; Vertex[1].Z = 0.0f;
//Цвет вершины:
Vertex[1].Color = myColor.MediumOrchid.ToArgb(); //Вершина 2:
//Координаты вершины:
Vertex[2].X = 1.0f; Vertex[2].Y = -1.0f; Vertex[2].Z = 0.0f;
//Цвет вершины:
Vertex[2].Color = myColor.LightPink.ToArgb();
//Вершина 3:
Vertex[3].X = 1.0f; Vertex[3].Y = 1.0f; Vertex[3].Z = 0.0f;
186 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Цвет вершины:
Vertex[3].Color = myColor.Cornsilk.ToArgb(); //Разблокируем буфер вершин: myVertexBuffer->Unlock();
}
//Включаем таймер и выполняем матричные преобразования: private: void SetupMatrices()
{
//Используем структуру матриц Matrix, //чтобы вращать фигуру вокруг оси y.
//Один оборот на 2*PI радиан фигура совершит //за 1000 мс (1 секунду):
int iTime = Environment::TickCount % 1000; float fAngle =
iTime * (2.0f * (float)Math::PI) / 1000.0f; myDevice->Transform->World = Matrix::RotationY(fAngle); //Задаем координаты глаза наблюдателя
//в матрице вида (view matrix): myDevice->Transform->View = Matrix::LookAtLH(
Vector3(0.0f, 3.0f, -5.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 1.0f, 0.0f));
//При помощи матрицы проецирования (projection matrix) //выполняем перспективные преобразования: myDevice->Transform->Projection =
Matrix::PerspectiveFovLH( (float)Math::PI / 4, 1.0f, 1.0f, 100.0f);
}
//Останавливаем вращение фигуры и изменяем ее размеры //во время изменения размеров формы:
protected: void OnResize(EventArgs^ e)
{
myPause = ((this->WindowState == FormWindowState::Minimized) || !this->Visible);
}
Глава 37. Методика проектирования неподвижных и подвижных пространственных фигур
Листинг 37.1. Метод для вывода следующего вида формы и рисования графики.
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
//В классе Form1 создаем экземпляр формы myForm1: Form1^ myForm1 = gcnew Form1();
//Инициализируем DirectX:
if (!myForm1->InitializeDirectX())
{
MessageBox::Show("Ошибка инициализации DirectX."); return;
}
//Показываем форму Form1: myForm1->Show();
//Рисуем графику на форме Form1: while (myForm1->Created)
{
myForm1->myRendering(); Application::DoEvents();
}
}
Листинг 37.2. Методы для визуализации преобразованных вершин фигуры.
//Объявляем и инициализируем глобальные переменные. //Для устройства myDevice класса Device:
static Device^ myDevice = nullptr; //Для буфера вершин VertexBuffer:
static VertexBuffer^ myVertexBuffer = nullptr; static PresentParameters^ myPresentParameters =
gcnew PresentParameters(); static bool myPause = false;
//Устанавливаем параметры Direct3D: public: bool InitializeDirectX()
{
try
{
188 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
myPresentParameters->Windowed = true; myPresentParameters->SwapEffect =
SwapEffect::Discard; myPresentParameters->EnableAutoDepthStencil = true; myPresentParameters->AutoDepthStencilFormat =
DepthFormat::D16;
//Создаем устройство для визуализации вершин фигуры: myDevice = gcnew Device(0, DeviceType::Hardware,
this, CreateFlags::SoftwareVertexProcessing, myPresentParameters);
myDevice->DeviceReset +=
gcnew System::EventHandler(this->OnResetDevice); //Вызываем разработанные нами методы: this->OnCreateDevice(myDevice, nullptr); this->OnResetDevice(myDevice, nullptr);
myPause = false; return true;
}
catch (DirectXException^)
{
//Перехвачена ошибка инициализации DirectX: return false;
}
}
//Метод для начала и окончания визуализации (rendering) //преобразованных вершин:
public: void myRendering()
{
if (myPause) return;
//Задаем белый цвет (Color::White) форме Form1: myDevice->
Clear(ClearFlags::Target | ClearFlags::ZBuffer, System::Drawing::Color::White, 1.0f, 0);
//Начинаем сцену: myDevice->BeginScene(); //Устанавливаем освещение и матерал: SetupLights();
//Используем матрицы для выполнения преобразований: SetupMatrices();
myDevice->SetStreamSource(0, myVertexBuffer, 0); myDevice->VertexFormat =
CustomVertex::PositionNormal::Format; //Рисуем фигуру: myDevice->DrawPrimitives(
PrimitiveType::TriangleStrip, 0, (4 * 25) - 2); //Заканчиваем сцену:
myDevice->EndScene();
Глава 37. Методика проектирования пространственных фигур |
189 |
//Показываем сцену: myDevice->Present();
}
//Создаем устройство, буфер вершин фигуры и их данные: public: void OnCreateDevice(Object^ sender, EventArgs^ e)
{
Device^ myDev = (Device^)sender; //Создаем буфер для вершин фигуры: myVertexBuffer = gcnew VertexBuffer(
typeid<CustomVertex::PositionNormal>, 100, myDev, Microsoft::DirectX::Direct3D::Usage::WriteOnly, CustomVertex::PositionNormal::Format, Pool::Default);
//Создаем геометрические данные при помощи обработки
//события myVertexBuffer->Created: myVertexBuffer->Created +=
gcnew System::EventHandler( this->OnCreateVertexBuffer);
this->OnCreateVertexBuffer(myVertexBuffer, nullptr);
}
//Настраиваем параметры устройства для рисования: public: static void OnResetDevice(Object^ sender, EventArgs^ e)
{
Device^ myDev = (Device^)sender; //Выключаем режим CullMode, чтобы мы видели //переднюю и заднюю поверхность фигуры: myDev->RenderState->CullMode = Cull::None;
//Для рисования трехмерной фигуры включаем Z - буфер: myDevice->RenderState->ZBufferEnable = true;
//Делаем доступным освещение: myDevice->RenderState->Lighting = true;
}
//Массив и параметры вершин. Строим фигуру в буфере вершин: public: static void OnCreateVertexBuffer(
Object^ sender, EventArgs^ e)
{
//Для фигуры с любым количеством вершин //объявляем массив и выполняем преобразование типов: array<CustomVertex::PositionNormal>^ Vertex =
(array<CustomVertex::PositionNormal>^) myVertexBuffer->Lock(0, Microsoft::DirectX::Direct3D::LockFlags::None);
//В классе (структуре) PositionNormal
//создаем массив из 100 пользовательских вершин: for (int i = 0; i < 50; i++)
{