Широкоэкранный монитор и игра, расчитанная на формат 4:3
Задача состоит в следующем: есть игровой тренажер написанный под разрешение 800х600 (т.е. с соотношением сторон 4х3), нужно этот тренажер без искажений отображать на широкоэкранном мониторе (с соотношением 16х9). Как это сделать? Есть конечно вариант брать разрешение 1280х800 и просто центрировать картинку, но сами понимаете вариант не супер (мягко говоря). Другой вариант, который мне приходит еще в голову - все-таки выставлять разрешение 800х600, но при этом менять размер отображаемой картинки пропорционально соотношению сторон, чтобы не возникало искажений. Поделитесь, пожалуйста, своим мнением. На самом деле вопрос здесь даже гораздо глубже - как понять что программа отображается на мониторе с соотношением сторон 16х9, а не 4х3? Я пытался искать ответ в интернете, но, если честно, то не смог для поисковика сформулировать запрос, чтобы он меня понял:)
>> как понять что программа отображается на мониторе с соотношением сторон 16х9, а не 4х3?
aspect1 равен 1.(7) aspect2 равен 1.(7) aspect3 равен 1.(3)
Игры надо строить по принципам HTML, вот как форум gdru, он работает отлично как на 4:3 так и на 16:10, вы видимо плохо знаете устройство вьюпорта (окно в игровой мир) и выравнивания, растайливания, графики (HTML), отсюда и проблемы с какими-то полосками по краям и прочим.
Lolmen Вот интересно как ты пиксельарт без "полосок по краям" будешь отображать при разных форматах?
Lolmen >Игры надо строить по принципам HTML, вот как форум gdru, он работает отлично >как на 4:3 так и на 16:10,
Ага, а управление реализовывать вводом данных через консоль.
И по существу: Если интересует способ обрезки неиспользуемого пространства монитора - в Present(NULL,NULL,NULL,NULL) посмотри описание параметров. Один из NULL это указатель на Rectangle в который нужно вписывать рендер. Задействуй его в случае широкого монитора.
Lolmen Что то я не понял как форум dgru мне поможет. Если это была реклама сайта, то не совсем удачная, правда может я не на тот сайт зашел (www.dgru.ru).
Огромное спасибо за помощь. Я эту функцию даже как то использовал лет 5 назад. Выскочило из головы совсем:)
Megabyte-Ceercop Из предложенного вами варианта я нашел только следующее (вырезка из MSDN): The Present function notifies the user-mode display driver that an application finished rendering and requests that the driver display the source surface by either copying or flipping or that the driver perform a color-fill operation.
HRESULT (APIENTRY *PFND3DDDI_PRESENT)( HANDLE hDevice, D3DDDIARG_PRESENT* pData);
Parameters hDevice [in] A handle to the display device (graphics context). pData [in] A pointer to a D3DDDIARG_PRESENT structure that describes the resource to display. Return Value Present returns one of the following values:
S_OK The resource was successfully displayed. E_OUTOFMEMORY Present could not allocate memory that was required for it to complete.
Headers Declared in D3dumddi.h. Include D3dumddi.h.
Comments The Microsoft Direct3D runtime calls the user-mode display driver's Present function to notify the user-mode display driver that an application finished rendering and to request that the driver display out the source surface or that the driver perform a color-fill operation. If the hSrcResource member of the D3DDDIARG_PRESENT structure that the pData parameter points to is non-NULL, Present requests that the user-mode display driver display new content to the screen; if hSrcResource is NULL, Present requests that the user-mode display driver perform a color-fill operation to the screen.
If the hDstResource member of the D3DDDIARG_PRESENT structure is NULL, the destination surface is unknown. In addition, the destination surface and a list of clipping rectangles are determined in kernel mode before sending the hardware command stream through DMA to the graphics processor.
As a result, the user-mode display driver cannot generate hardware instructions to perform the present operation. These hardware instructions must be generated by the display miniport driver. However, when the hSrcResource member of D3DDDIARG_PRESENT is non-NULL, the user-mode display driver must derive the allocation handle to the source surface and insert this handle in the hSrcAllocation member of the D3DDDICB_PRESENT structure in a call to the pfnPresentCb function. The display miniport driver can then successfully generate the hardware instructions. The user-mode display driver typically derives the allocation handle from the resource information in the D3DDDIARG_PRESENT structure.
If the hDstResource member of D3DDDIARG_PRESENT is non-NULL, the destination surface for the present is known and the user-mode display driver must fill in the hDstAllocation member of D3DDDICB_PRESENT with the corresponding allocation handle.
If a user-mode display driver exposes a DDI version of less than 0x0000000C (the driver returns this value in the DriverVersion member of the D3D10DDIARG_OPENADAPTER structure in a call to the driver's OpenAdapter function), the Direct3D runtime first calls the user-mode display driver's Flush function to submit any outstanding hardware commands in the command buffer before the runtime calls the user-mode display driver's Present function. In this way, the user-mode display driver's Present function is serialized with render operations (that is, calls to the pfnRenderCb function). If a user-mode display driver exposes a DDI version of 0x0000000C or greater and the calling application runs in windowed mode, the runtime also calls Flush before it calls Present. If a user-mode display driver exposes a DDI version of 0x0000000C or greater and the calling application runs in full-screen mode, the runtime will not call Flush before it calls Present. This behavior allows drivers that implement their own threading to queue present calls. A driver that exposes a DDI version of 0x0000000C or greater must call pfnRenderCb to internally flush any outstanding command buffers before the driver calls the pfnPresentCb function.
Мне это кажется совсем не подходит, да и не использую я 3D.
И так, остается первый вопрос открытым: как отображать на экран с соотношением сторон 16:9 (у меня аж 16:10 - широкоформатный 17'' ноутбук:) ) картинки разрешением 800х600. Программа работает в полноэкранном режиме, написана с использованием DirectX7 (большего просто не требовалось:) ). Вариант со сжатием картинки по оси Х перед отображением не самый лучший, потому что в тренажере есть графический редактор для детишек, где они могут рисовать картинки, которые потом в тренажере могут использоваться. Так вот если холст отображать сжатым, то после того как сохранишь художество ребенка со сжатого холста, а потом посмотришь на нормальном разрешении, не будет ли искажения самого рисунка? И по поводу сжатия: верно ли я понял что для сжатия изображения по оси Х можно использовать функцию ModifyWorldTransform в которую передается HDC, матрица преобразования XFORM и режим изменения? И вообще если кто знает, как такие вещи реализовывают в нормальных играх.
>И так, остается первый вопрос открытым: как отображать на экран с соотношением сторон 16:9 (у меня аж 16:10 - широкоформатный 17'' ноутбук:) ) картинки разрешением 800х600.
очевидно, что картинка размером 4:3 не может быть отображена на холсте 16:9 одновременно и без искажений, и без черных полос, и без потерь изображения. поэтому она может быть выведена в лучшем случае с одним из перечисленных недостатков: 1) с искажением пропорций, 2) с черными полосами, 3) с потерянными полосами. выбирай.
Разумеется отображение будет с черными полосами (ИМХО - это наиболее адекватный и наименее затратный вариант). Лично я у себы (Дельфи + OpenGL, базовое разрешение 1024х768) реализовал так: