Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005

.pdf
Скачиваний:
306
Добавлен:
13.08.2013
Размер:
1.14 Mб
Скачать

190 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

//Заполняем вершины данными. //Задаем размеры конуса: float zoom1 = -1;

float zoom2 = -1;

float theta = (float)(2 * Math::PI * i) / 49; //Вращающийся конус с одной неподвижной вершиной. //Рассчитываем координаты вершин:

Vertex[2 * i].Position = Vector3((float)Math::Sin(theta), zoom1, (float)Math::Cos(theta));

//Рассчитываем нормали в вершинах: Vertex[2 * i + 1].Normal =

Vector3((float)Math::Sin(theta), zoom2, (float)Math::Cos(theta));

}

//Разблокируем буфер вершин: myVertexBuffer->Unlock();

}

//Включаем таймер и выполняем матричные преобразования: private: void SetupMatrices()

{

//Используем глобальную матрицу (world matrix), //чтобы вращать фигуру вокруг оси y: myDevice->Transform->World = Matrix::RotationAxis(

Vector3(

(float)Math::Cos(Environment::TickCount / 250.0f), 1,

(float)Math::Sin(Environment::TickCount / 250.0f)), Environment::TickCount / 3000.0f);

//Задаем координаты глаза наблюдателя

//в матрице вида (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);

}

//Определяем освещение фигуры цветом формата ARGB: private: void SetupLights()

{

//Устанавливаем материал и его цвет.

//Можно одновременно использовать только один материал: Material myMaterial = Material();

Глава 37. Методика проектирования пространственных фигур

191

Color myColor = Color::White; myMaterial.Diffuse = myColor; myMaterial.Ambient = myColor; myDevice->Material = myMaterial; //Устанавливаем белое освещение //с изменяющимся направлением:

myDevice->Lights[0]->Type = LightType::Directional; myDevice->Lights[0]->Diffuse = Color::DarkTurquoise; myDevice->Lights[0]->Direction = Vector3(

(float)Math::Cos(Environment::TickCount / 250.0f), 1.0f,

(float)Math::Sin(Environment::TickCount / 250.0f)); //Включаем освещение:

myDevice->Lights[0]->Enabled = true; //Включаем немного отраженного (Ambient) //равномерно рассеянного света: myDevice->RenderState->Ambient =

Color::FromArgb(0x202020);

}

//Останавливаем вращение фигуры и изменяем ее размеры //во время изменения размеров формы:

protected: void OnResize(EventArgs^ e)

{

myPause = ((this->WindowState == FormWindowState::Minimized) || !this->Visible);

}

Теперь в файле Form1.cpp находим главный метод Main, комментируем весь имеющийся в этом методе автоматически сгенерированный код и записываем код со следующего листинга (для вывода формы Form1 и рисования на ней графики).

Листинг 37.3. Код для вывода формы и рисования на ней графики.

//В классе Form1 объявляем объект myForm1

//и после знака равентства создаем его экземпляр: Form1^ myForm1 = gcnew Form1();

if (!myForm1->InitializeDirectX())

{

MessageBox::Show("Ошибка при инициализации DirectX."); return 0;

}

//Показываем форму Form1: myForm1->Show();

//Рисуем графику на форме Form1: while (myForm1->Created)

{

myForm1->myRendering();

192 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

Application::DoEvents();

}

return 0;

Листинг 37.4. Методы для визуализации преобразованных вершин фигуры.

//Объявляем и инициализируем глобальные переменные. //Для устройства 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; 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()

{

Глава 37. Методика проектирования пространственных фигур

193

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(); //Показываем сцену: 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;

194 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

//Для рисования трехмерной фигуры включаем 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++)

{

//Заполняем вершины данными.

//Вращающийся цилиндр с динамичным освещением. //Задаем размеры цилиндра:

float zoom1 = -1.5; float zoom2 = 1.5;

float theta = (float)(2 * Math::PI * i) / 49; //Рассчитываем координаты (Position) и //нормали (Normal) вершин:

Vertex[2 * i].Position = Vector3((float)Math::Sin(theta), zoom1, (float)Math::Cos(theta)); Vertex[2 * i].Normal = Vector3((float)Math::Sin(theta), 0, (float)Math::Cos(theta)); Vertex[2 * i + 1].Position = Vector3((float)Math::Sin(theta), zoom2, (float)Math::Cos(theta)); Vertex[2 * i + 1].Normal = Vector3((float)Math::Sin(theta), 0, (float)Math::Cos(theta));

}

//Разблокируем буфер вершин: myVertexBuffer->Unlock();

}

//Включаем таймер и выполняем матричные преобразования: private: void SetupMatrices()

{

//Используем глобальную матрицу (world matrix),

Глава 37. Методика проектирования пространственных фигур

195

//чтобы вращать фигуру вокруг оси y: myDevice->Transform->World = Matrix::RotationAxis(

Vector3(

(float)Math::Cos(Environment::TickCount / 250.0f), 1,

(float)Math::Sin(Environment::TickCount / 250.0f)), Environment::TickCount / 3000.0f);

//Задаем координаты глаза наблюдателя

//в матрице вида (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);

}

//Определяем освещение фигуры цветом формата ARGB: private: void SetupLights()

{

//Устанавливаем материал и его цвет.

//Можно одновременно использовать только один материал: Material myMaterial = Material();

Color myColor = Color::White; myMaterial.Diffuse = myColor; myMaterial.Ambient = myColor; myDevice->Material = myMaterial; //Устанавливаем белое освещение //с изменяющимся направлением:

myDevice->Lights[0]->Type = LightType::Directional; myDevice->Lights[0]->Diffuse = Color::DarkTurquoise; myDevice->Lights[0]->Direction = Vector3(

(float)Math::Cos(Environment::TickCount / 250.0f), 1.0f,

(float)Math::Sin(Environment::TickCount / 250.0f)); //Включаем освещение:

myDevice->Lights[0]->Enabled = true; //Включаем немного отраженного (Ambient) //равномерно рассеянного света: myDevice->RenderState->Ambient =

Color::FromArgb(0x202020);

}

//Останавливаем вращение фигуры и изменяем ее размеры //во время изменения размеров формы:

protected: void OnResize(EventArgs^ e)

196 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

{

myPause = ((this->WindowState == FormWindowState::Minimized) || !this->Visible);

}

Листинг 37.5. Методы для визуализации преобразованных вершин фигуры.

//Объявляем и инициализируем глобальные переменные. //Устройство myDevice класса Device для визуализации вершин: static Device^ myDevice = nullptr;

//Буфер вершин VertexBuffer:

static VertexBuffer^ myVertexBuffer = nullptr; //Объявляем и инициализируем объект myTexture //класса Texture:

static Texture^ myTexture = nullptr;

static PresentParameters^ myPresentParameters = gcnew PresentParameters();

static bool myPause = false; //Устанавливаем параметры Direct3D: public: bool InitializeDirectX()

{

try

{

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;

}

}

Глава 37. Методика проектирования пространственных фигур

197

//Метод для начала и окончания визуализации (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();

//Используем матрицы для выполнения преобразований: SetupMatrices();

//Устанавливаем нашу текстуру: myDevice->SetTexture(0, myTexture); myDevice->TextureState[0]->ColorOperation =

TextureOperation::Modulate; myDevice->TextureState[0]->ColorArgument1 =

TextureArgument::TextureColor; myDevice->TextureState[0]->ColorArgument2 =

TextureArgument::Diffuse; myDevice->TextureState[0]->AlphaOperation =

TextureOperation::Disable; //Рисуем фигуру:

myDevice->SetStreamSource(0, myVertexBuffer, 0); myDevice->VertexFormat =

CustomVertex::PositionNormalTextured::Format; myDevice->DrawPrimitives(

PrimitiveType::TriangleStrip, 0, (4 * 25) - 2); //Заканчиваем сцену:

myDevice->EndScene(); //Показываем сцену: myDevice->Present();

}

//Создаем устройство, буфер вершин фигуры и их данные: public: void OnCreateDevice(Object^ sender, EventArgs^ e)

{

Device^ myDev = (Device^)sender; //Создаем буфер для вершин фигуры: myVertexBuffer = gcnew VertexBuffer(

typeid<CustomVertex::PositionNormalTextured>, 100, myDev, Microsoft::DirectX::Direct3D::Usage::WriteOnly, CustomVertex::PositionNormalTextured::Format, Pool::Default);

//Создаем геометрические данные при помощи обработки

//события myVertexBuffer->Created:

198 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

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; //Выключаем трехмерное освещение: myDev->RenderState->Lighting = false;

//Для рисования трехмерной фигуры включаем Z - буфер: myDevice->RenderState->ZBufferEnable = true; //Загружаем в проект наш рисунок Texture_1: myTexture = TextureLoader::FromFile(myDev,

"D:\\MyDocs\\Texture_1.bmp");

}

//Массив параметров вершин. Строим фигуру в буфере вершин: public: static void OnCreateVertexBuffer(

Object^ sender, EventArgs^ e)

{

//Для фигуры с любым количеством вершин //объявляем массив и выполняем преобразование типов:

array<CustomVertex::PositionNormalTextured>^ Vertex = (array<CustomVertex::PositionNormalTextured>^) myVertexBuffer->Lock(0, Microsoft::DirectX::Direct3D::LockFlags::None);

//В классе (структуре) PositionNormal

//создаем массив из 100 пользовательских вершин: for (int i = 0; i < 50; i++)

{

//Заполняем вершины данными. //Задаем размеры конуса: float zoom1 = 1;

float zoom2 = 0;

float theta = (float)(2 * Math::PI * i) / 49; //Вращающийся конус с одной неподвижной вершиной. //Рассчитываем нормали в вершинах:

Vertex[2 * i].Normal = Vector3((float)Math::Sin(theta), zoom2, (float)Math::Cos(theta));

//Добавляем в вершину v-компоненту текстуры: Vertex[2 * i].Tv = 1.0f;

Глава 37. Методика проектирования пространственных фигур

199

//Рассчитываем координаты вершин: Vertex[2 * i + 1].Position =

Vector3((float)Math::Sin(theta), zoom1, (float)Math::Cos(theta));

//Добавляем в вершину u-компоненту текстуры: Vertex[2 * i + 1].Tu = ((float)i) / (50 - 1);

}

//Открываем буфер вершин: myVertexBuffer->Unlock();

}

//Включаем таймер и выполняем матричные преобразования: private: void SetupMatrices()

{

//Используем глобальную матрицу (world matrix), //чтобы вращать фигуру вокруг оси y: myDevice->Transform->World = Matrix::RotationAxis(

Vector3(

(float)Math::Cos(Environment::TickCount / 250.0f), 1,

(float)Math::Sin(Environment::TickCount / 250.0f)), Environment::TickCount / 1000.0f);

//Задаем координаты глаза наблюдателя

//в матрице вида (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.6. Методы для визуализации преобразованных вершин фигуры.

//Объявляем и инициализируем глобальные переменные. //Устройство myDevice класса Device для визуализации вершин: static Device^ myDevice = nullptr;

//Буфер вершин VertexBuffer:

Соседние файлы в предмете Программирование на C++