Привет всем! Если вы читаете эту статью, вам очень хочется попробовать себя в роли не простого игрока, а полноценного разработчика игр. Прочитав данную статью вы научитесь Инициализировать 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

А теперь заголовочные файлы:

//Включаемые заголовочные файлы

#include <windows.h>		// Заголовочный файл  для Windows
#include <d3d9.h>			// Заголовочный файл  для DirectX3D
#include <d3dx9.h>			// Заголовочный файл  для некоторых 
				// функций DirectX3D

Далее идут переменные

//Макрос  для освобождения интерфейсов
#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 );	
	}
}

Управление:
Esc - Выход
F1 - Переключение между полноэкранным и оконным режимами.

Также приложение хорошо "реагирует" на Alt-Tab.

Продолжение следует...