Функция GetGUID() применяется для получения GUID (глобального уникального идентификатора) идентифицирующего создаваемое функцией CreateDeviceFromClipper() устройство. Если вместо вызова функции GetGUID() использовать значение NULL, функция CreateDeviceFromClipper() автоматически выберет устройство с цветовой моделью Ramp. Мы вызываем функцию GetGUID() чтобы иметь возможность выбрать цветовую модель Ramp или RGB. Текст функции GetGUID() приведен в листинге 4.2.
Листинг 4.2. Функция GetGUID() | |
GUID* RMWin::GetGUID() { static GUID* lpguid; HRESULT r;
D3DFINDDEVICESEARCH searchdata; memset(&searchdata, 0, sizeof searchdata); searchdata.dwSize = sizeof searchdata; searchdata.dwFlags = D3DFDS_COLORMODEL; searchdata.dcmColorModel = colormodel; static D3DFINDDEVICERESULT resultdata; memset(&resultdata, 0, sizeof resultdata); resultdata.dwSize = sizeof resultdata; LPDIRECTDRAW ddraw; r = DirectDrawCreate(NULL, &ddraw, NULL); if (r != DD_OK) { TRACE("DirectDrawCreate failed\n"); return NULL; } LPDIRECT3D d3d; r = ddraw->QueryInterface(IID_IDirect3D, (void**)&d3d); if (r != D3DRM_OK) { TRACE("d3drm->QueryInterface failed\n"); ddraw->Release(); return NULL; } r = d3d->FindDevice(&searchdata, &resultdata); if (r == D3D_OK) lpguid = &resultdata.guid; else { TRACE("FindDevice failure\n"); lpguid = NULL; } d3d->Release(); ddraw->Release(); return lpguid; } |
Перед тем, как продолжить, посмотрим, почему функция GetGUID() такая сложная. Наша задача — получить GUID для заданного устройства Direct3D. Казалось бы, интерфейс Direct3DRM должен предоставлять функцию, выполняющую эту работу. Возможно, библиотека Direct3D и могла бы быть разработана таким способом, но этого не произошло.
Мы применяем абстрактный режим Direct3D, а абстрактный режим в свою очередь зависит от непосредственного режима, который фактически выполняет визуализацию. Это означает, что устройство Direct3D является конструкцией непосредственного режима, и для поиска требуемого устройства необходимо воспользоваься интерфейсом непосредственного режима.
Функции непосредственного режима доступны через COM-интерфейс Direct3D.
Мы можем получить указатель на интерфейс Direct3D создав интерфейс DirectDraw и вызвав его функцию QueryInterface(). Это возможно, поскольку объект DirectDraw начиная с DirectX версии 2 поддерживает интерфейс Direct3D. Если бы мы работали с DirectX версии 1, такой вызов QueryInterface() закончился бы неудачей.
Давайте взглянем на начало функции GetGUID() (листинг 4.2). Первое, что делает функция, — это подготовка двух структур, применяемых для хранения информации об устройстве. Структура searchdata используется для указания запрашиваемой цветовой модели, а в структуре resultdata хранятся результаты поиска. Ниже приведен фрагмент программы, создающий и инициализирующий эти структуры:
D3DFINDDEVICESEARCH searchdata; memset(&searchdata, 0, sizeof searchdata); searchdata.dwSize = sizeof searchdata; searchdata.dwFlags = D3DFDS_COLORMODEL; searchdata.dcmColorModel = colormodel;
static D3DFINDDEVICERESULT resultdata; memset(&resultdata, 0, sizeof resultdata); resultdata.dwSize = sizeof resultdata;
Функция memset() обнуляет все поля, после чего полю dwSize присваивается размер структуры.
СОВЕТ | Поле dwSize. Требование, чтобы поле структуры содержало размер самой структуры, может показаться довольно глупым, но это сделано, чтобы позволить расширение функциональности без модификации старых программ. Microsoft может увеличить размер структуры в будущей версии Direct3D, а программы, написанные сегодня, будут работать, потому что Direct3D сможет определить, основываясь на значении поля dwSize, какая версия структуры используется. |