|
|
|
Привет всем! Если вы читаете эту статью, вам очень хочется попробовать себя в роли не простого игрока, а полноценного разработчика игр. Прочитав данную статью вы научитесь Инициализировать Direct3D девятой версии. Для получения "эффекта" от этой статьи вам необходимо обзавестись:   1. MicroSoft Visual C++ 6.0. Я пользуюсь шестой версией, но теоретически исходники должны скомпилиться и под более поздними версиями.   2. DirectX 9.0 SDK (Software Developement Kit). Взять его можно с официального сайта Microsoft, а именно здесь. Правда весит он НЕСКОЛЬКО-СОТ-МЕГОВ:( Поэтому для тех кто не имеет скоростного интернета, я выложил библиотеки и заголовочные файлы DirectX 9.0:   DX9.0_Include.rar - (~987Kb) Header'ы для директаикса.   DX9.0_Lib.rar - (~4341Kb) А здесь библиотеки. С ними вы сразу же сможете начать программировать программы под любые компоненты DirectX 9.0 :) Да, и на последок: если вы не скачивали SDK, а брали от сюда хедеры и либы, то, чтобы ваш VisualC++ нашел их надо сделать следующее:   1. Открываем MSVisualC++ 6.0   2. Идем в Tools->Options...   3. Там идем в закладку Directories   4. В Show directories for: выбираем Include files   5. В списке Directories: добаляем путь до папки, в которую вы распаковали архив DX9.0_Include.rar   6. В Show directories for: выбираем Library files   7. В списке Directories: добаляем путь до папки, в которую вы распаковали архив DX9.0_Lib.rar   8. Жмем OK. Теперь ваш компилятор готов к работе. Вот и всЁ. Приступим. Чтобы начать создание нашей супер-пупер:) игры надо создать новый проект. Делается это так:   1. Загружаете MicroSoft Visual C++ 6.0.   2. Идете в меню File->New...   3. Из списка возможных типов проектов выбираете Win32 Application.   4. В поле Project name вводите название проекта (например, MyFirstProgram).   4. В поле Location вводите путь где будет создана папка с вашим проектом.   5. Кликаете на кнопке OK.   6. Выбираете An empty project.   7. Кликаете на кнопке Finish, затем OK. Все проект создан. Теперь добавим первый файл, в котором мы будем набирать код нашей программы:   8. Идете в меню File->New...   9. Из списка выбираем C++ Source File. 10. В поле File name вводим название файла (например, main). 11. Жмете OK. Все теперь можно приступать к работе! Сначала включаем библиотеки: |
#pragma comment(lib, "d3d9.lib") // Ссылка на d3d9.lib #pragma comment(lib, "d3dx9.lib") // Ссылка на d3dx9.lib #pragma comment(lib, "winmm.lib") // Ссылка на winmm.lib |
|
А теперь заголовочные файлы: |
//Включаемые заголовочные файлы |
|
Далее идут переменные |
//Макрос для освобождения интерфейсов
#define SAFE_RELEASE(x) if(x != NULL){ x->Release(); x = NULL; }
#define APPNAME "\"Первая программа под Direct3D 9.0\" by L1f" // Название окна
#define CLASSNAME "DIRECT3D" // Название класса окна
bool isProcess=true; // Флаг процесса рендеринга
RECT WindowRect;
int Width=640, Height=480; // Высота и Ширина окна
bool fullscreen = false; // Оконный/Полноэкранный режим
bool keys[256]; // Массив для работы с клавиатурой
HWND hWnd; // Здесь хранится экземпляр нашего окна
|
|
Далее идут переменные отвечающие за работу с Direct3D |
LPDIRECT3D9 g_pD3D = NULL;// Используется для создания Устройство рендеринга LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;// Устройство рендеринга D3DPRESENT_PARAMETERS d3dpp; // Параметры для создания Direct3D |
|
У нас в приложении будет несколько функций. Это: 1. WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) - С нее начинается выполнение нашей программы. В ней создается наше окно, инициализируются все объекты и т.д. 2. MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) - Обработчик сообщений поступающих нашему окну от Windows. 3. bool AllInit() - Здесь производится инициализация всех необходимых нам интерфейсов. 4. void AllShutdown() - А здесь - их удаление. 5. bool InitD3D(int width, int height, bool fscreen) - Эта функция будет инициализировать наше устройство рендеринга - g_pd3dDevice. 6. bool ResetWindow(int width, int height, bool fscreen) - Этой функцией можно изменить наше окно. Например, можно перейти из оконного режима в полноэкранный или изменить размеры окна.   7. Функция void ReSizeD3DScene(int width, int height) будет изменять пропорции экрана при изменении размеров окна, чтобы изображение оставалось неизменным. 8. Две функции bool Cleanup() и bool ReInit() пока нам не нужны. 9. И наконец самая важная (для нас) функция void Render() - Она рисует нашу сцену. Однако пока кроме очищения экрана в различные цвета (для того, чтоб вы видели, что все работает) она не делает, но вскоре всЁ изменится и тогда... А пока рассмотрим эти функции поподробней: Итак функция WinMain: |
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Регистрирование класса окна
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_CLASSDC;
wc.lpfnWndProc = MsgProc;
wc.cbClsExtra = 0L;
wc.cbWndExtra = 0L;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_HAND); // Стандартный значек
wc.hCursor = LoadCursor(NULL, IDC_ARROW);// Стандартный курсор
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASSNAME;
wc.hIconSm = NULL;
RegisterClassEx( &wc ); // Регистрируем класс окна
DWORD WindowStyle, WindowExStyle;
if(fullscreen)
{
WindowExStyle=WS_EX_APPWINDOW; // Расширенный стиль окна
WindowStyle=WS_POPUP; // Стиль окна
}
else
{
WindowExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Расширенный стиль окна
WindowStyle=WS_OVERLAPPEDWINDOW; // Стиль окна
};
WindowRect.left=(long)0; // Устанавливаем позицию окна по оси X
WindowRect.right=(long)Width; // Устанавливаем ширину окна
WindowRect.top=(long)0; // Устанавливаем позицию окна по оси X
WindowRect.bottom=(long)Height; // Устанавливаем высоту окна
// согласовываем размеры окна со стилем
AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, WindowExStyle);
// Создаем окно
if (!(hWnd=CreateWindowEx(
WindowExStyle, // Расширенный стиль
CLASSNAME, // Имя класса
APPNAME, // Заголовок окна
WindowStyle | // Наш стиль окна
WS_CLIPSIBLINGS | // Нужен оконный стиль
WS_CLIPCHILDREN, // Нужен оконный стиль
0, 0, // Позиция окна
WindowRect.right-WindowRect.left, // Просчет ширины окна
WindowRect.bottom-WindowRect.top, // Просчет высоты окна
NULL, // Нет родительского окна
NULL, // Не нада нам меню
wc.hInstance, // Instance
NULL))) // Ничего не создавать
{
MessageBox(NULL,"Не могу создать окно!","ОШИБКА",MB_OK|MB_ICONEXCLAMATION);
}
ShowCursor(false); // Скрываем курсов
ShowWindow( hWnd, SW_SHOWNORMAL ); // Показываем окно
SetFocus(hWnd); // Устанавливаем фокус окна
UpdateWindow( hWnd ); // Обновляем окно
SetForegroundWindow(hWnd); // Немного высокий приоритет
// Инициализация
if( AllInit() )
{
MSG msg;
//Начинаем главный процесс рендеринга
while (isProcess)
{
// Обработка всех сообщений
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// Если нажат ESCAPE то выходим из цикла
if(keys[VK_ESCAPE])
isProcess=false;
if(keys[VK_F1]) // Если нажат F1
{
//Оконный/полноэкранный режим
fullscreen=!fullscreen;
ResetWindow(Width, Height, fullscreen);
}
Render(); // Прорисовываем сцену
}
}
}
AllShutdown(); // Вызываем функцию удаления всего что наваяли
ShowCursor(true); // Показываем курсор
UnregisterClass( CLASSNAME, wc.hInstance );
return 1;
}
|
|
Следующей функцией, которую мы рассмотрим будет InitD3D, инициализирующая Direct3D 9.0: |
bool InitD3D(int width, int height, bool fscreen)
{
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
// Если не удалось создать Direct3D выведем сообщение о ошибке
MessageBox(NULL,"Не могу создать Direct3D9!","ОШИБКА",MB_OK|MB_ICONEXCLAMATION);
ZeroMemory( &d3dpp, sizeof(d3dpp) ); // Очищаем память из-под d3dpp
// Если поноэкранное приложение
if(fscreen)
{
d3dpp.BackBufferWidth = width; // Устанавливаем ширину заднего буфера
d3dpp.BackBufferHeight = height;// Устанавливаем высоту заднего буфера
d3dpp.BackBufferCount = 1; // Устанавливаем кол-во задниих буферов
// Двойная буферизация
// Устанавливаем чатоту экрана и Вертикальную синхронизацию по дефолту
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
else
{
d3dpp.FullScreen_RefreshRateInHz =0;
d3dpp.PresentationInterval =0;
};
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_R5G6B5; // Формат заднего буфера
d3dpp.EnableAutoDepthStencil = true; // Юзать Буфер глубины и стенсил
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // Формат буфера глубины и стенсила
d3dpp.Windowed = !fscreen;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// Создаем устройство рендеринга:
// Пытаемся создать устройство рендеринга с использованием возможностей видеокарты
if(FAILED( g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))
{
// Если не получилось
// Пытаемся создать устройство рендеринга без использования
// возможностей видеокарты
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))
{
// Иначе выводим сообщение об ошибке
MessageBox(NULL,"Не могу создать устройство рендеринга!",
"ОШИБКА",MB_OK|MB_ICONEXCLAMATION);
return false;
}
}
return true;
}
|
|
И на последок рассмотрим рендеринг ( Render ). |
void Render()
{
HRESULT hr;
// Проверяем Direct3dDevice на потерянность
hr = g_pd3dDevice->TestCooperativeLevel();
// если окно не в фокусе выходим из цикла рендеринга
if(hr==D3DERR_DEVICELOST)
return;
// если окно опять в фокусе пытаемся восстановить устройство рендеринга
if(hr==D3DERR_DEVICENOTRESET)
{
Cleanup();
g_pd3dDevice->Reset(&d3dpp);
if( g_pd3dDevice )
ReInit();
}
if( NULL == g_pd3dDevice )
return;
// Начинаем отрисовку нашей сцены
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Очищаем задний буфер и буфер глубины
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(rand()%255, rand()%255, rand()%255), 1.0f, 0L);
// За счет этих rand'омов на экран будет выводиться разные цвета
//--------------------------//
// Здесь мы будем рисовать! //
//--------------------------//
// Закончили рисовать
g_pd3dDevice->EndScene();
// Отображаем задний буфер на экран
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
}
|
|
Всё остальное смотрите в исходнике!!! Если че будет непонятно обращайтесь: "Обратная связь" ждет ваших вопросов... Теперь скачайте исходник к этой статье: ЗДЕСЬ (~94Kb). И продолжайте изучать DirectX Управление: Esc - Выход F1 - Переключение между полноэкранным и оконным режимами. Также приложение хорошо "реагирует" на Alt-Tab. Продолжение следует... Автор: L1f 
|
|
|