Укрощение Direct3D

Структура движка

По мере роста нашего движка, постепенно меняется и его структура. Посмотрите:

Появился новый класс - tD3D, отвечающий за инициализацию Direct3D. Он же будет базовым для будущих классов для работы с графикой. Немного сместился tLogFile, став общим для всех классов.

Direct3D

Как я говорил выше, класс tD3D отвечает за инициализацию Direct3D. Производится она вызовом функции InitD3D с указанием размеров и положении окна, в котором будет выводиться графика, и если игра запускается в полноэкранном режиме, то дополнительно указывается глубина цвета. Рассмотрим подробнее работу этой функции:

/*--------------------------------------------------------------
tD3D::InitD3D()

Инициализация D3D
--------------------------------------------------------------*/
void tD3D::InitD3D(int x,int y,int width,int height,int color)
{
    HRESULT hResult;
    D3DADAPTER_IDENTIFIER8 adapterIdentifier;
    D3DDISPLAYMODE displayMode;

    try {
        // Создание окна
        tWindow::InitWindow(x,y,width,height);
    }
    catch(tError &error) {
        error.AddErrorHistory(" <-tD3D::InitD3D");
    throw;
    }

Сперва создаем окно.

    tLogFile::LogMessage("Create D3D ... ");
    // Создаем Direct3D
    m_d3d = Direct3DCreate8(D3D_SDK_VERSION);
    if(!m_d3d) throw tError(__FILE__,__LINE__,"tD3D::InitD3D",
                                "Can't create D3D!");
    tLogFile::LogMessage("Ok.\n");

    // Получаем информацию о видео-адаптере
     hResult = m_d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT,0,&adapterIdentifier);
     if(hResult!=D3D_OK)
         throw tError(__FILE__,__LINE__,"tD3D::InitD3D",
                        "Fail to get adapter information! (%s)",DXGetErrorString8(hResult));

     // Выводим информацию о видео-адаптере в log-файл
     tLogFile::LogMessage(" Description: %s\n",adapterIdentifier.Description);
     tLogFile::LogMessage(" Driver: %s\n",adapterIdentifier.Driver);
     tLogFile::LogMessage(" Driver Version: %d.%d.%d.%d\n",
                                HIWORD(adapterIdentifier.DriverVersion.HighPart),
                                LOWORD(adapterIdentifier.DriverVersion.HighPart),
                                HIWORD(adapterIdentifier.DriverVersion.LowPart),
                                LOWORD(adapterIdentifier.DriverVersion.LowPart));

    // Выводим информацию о видео-режимах в log-файл
     tLogFile::LogMessage(" Available video modes:\n");
     for(int i=0;i<tD3D::GetD3DDisplayModeCount();i++) {
    
     tD3D::GetD3DDisplayMode(i,&displayMode);
    
     tLogFile::LogMessage(" %dx%dx%d %d\n",
    
                                   displayMode.Width,
    
                                   displayMode.Height,
    
                                   tD3D::ConvertD3DFormat(displayMode.Format),
    
                                   displayMode.RefreshRate);
    
}

Потом создаем Direct3D - первый объект, который должен быть получен в любой программе, которая работает с графикой. Через него мы дальше получаем информацию о видеокарте и доступных видеорежимах, выводя все это в log-файл (вот зачем я сделал класс tLogFile общим для всех).

     tLogFile::LogMessage("Create D3D Device ... ");
    
// Создаем устройство Direct3D
    
if(!color) {
    
     // Получаем текущий режим дисплея
    
     m_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displayMode);
    
     // Параметры создания устройства D3D
    
     m_d3dPP.BackBufferWidth = width;
    
     m_d3dPP.BackBufferHeight = height;
    
     m_d3dPP.BackBufferFormat = displayMode.Format;
    
     m_d3dPP.BackBufferCount = 1;
    
     //
    
     m_d3dPP.MultiSampleType = D3DMULTISAMPLE_NONE;
    
     //
    
     m_d3dPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
    
     m_d3dPP.hDeviceWindow = m_hWindow;
    
     m_d3dPP.Windowed = TRUE;
    
     //
    
     m_d3dPP.EnableAutoDepthStencil = TRUE;
    
     m_d3dPP.AutoDepthStencilFormat = D3DFMT_D16;
    
}
    
else {
    
     // Параметры создания устройства D3D
    
     m_d3dPP.BackBufferWidth = width;
    
     m_d3dPP.BackBufferHeight = height;
    
     if(color==32)
    
          m_d3dPP.BackBufferFormat = D3DFMT_X8R8G8B8;
    
     else
    
          m_d3dPP.BackBufferFormat = D3DFMT_R5G6B5;
    
     m_d3dPP.BackBufferCount = 1;
    
     //
    
     m_d3dPP.MultiSampleType = D3DMULTISAMPLE_NONE;
    
     //
    
     m_d3dPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
    
     m_d3dPP.hDeviceWindow = m_hWindow;
    
     m_d3dPP.Windowed = FALSE;
    
     //
    
     m_d3dPP.EnableAutoDepthStencil = TRUE;
    
     m_d3dPP.AutoDepthStencilFormat = D3DFMT_D16;
    
}

Перед тем, как создать устройство Direct3D, сперва мы должны заполнить структуру D3DPRESENT_PARAMETERS, которая определить некоторые параметры этого устройства. Как вы понимаете, для оконного и полноэкранного режимов есть отличия в заполнении. Во-первых, в оконном режиме в m_d3dPP.BackBufferFormat заносится формат пикселя соответствующий формату текущего режима дисплея, а в полноэкранном - значения D3DFMT_X8R8G8B8 или D3DFMT_R5G6B5, в зависимости от требуемой глубины цвета. И во-вторых, m_d3dPP.Windowed определяет какой режим мы хотим использовать.

     // Создаем устройство Direct3D с программной обработкой вершин
    
hResult = m_d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWindow,
    
                                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    
                                             &m_d3dPP,&m_d3dDevice);
    
if(hResult!=D3D_OK)
    
     throw tError(__FILE__,__LINE__,"tD3D::InitD3D",
    
                    "Can't create D3D Device! / x - %d, y - %d, width - %d, height - %d, color - %d / (%s)",
    
                    x,y,width,height,color,DXGetErrorString8(hResult)); tLogFile::LogMessage("Ok.\n");

И последним этапом, создаем устройство Direct3D. Пока мы будем использовать программную обработку вершин, потому что GeForce 3 у меня еще нет :).

Пример

Пример я взял из 7-го урока с сайта directxdesign.narod.ru. Немного переправил функции, и теперь выводится знакомый нам чайник.

Кстати, загляните после работы программы в log-файл, найдете немного информации о вашей видеокарте :).

Сайт создан в системе uCoz