![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Рендеринг на рабочем столе (OpenGL) [D6, D7, WinXP]
Хой © (2004-01-18 19:51:00)Собственно как это сделать под средством OpenGL ну или DirectX
////
Sapersky (2004-01-20 00:38:00) [1]В примере FLip поверхности заменить на FlipToGDI (название процедуры не помню).
Если FliptoGDISurface, то это переключение на страницу GDI перед выводом окна в полноэкранном режиме - не то. Вообще, в данном случае о полноэкранном режиме речь (вроде) не идёт.
Или просто брать DC поверхности и BitBlt с нее.
А зачем тогда DX?
На самом деле, DirectDraw (и Direct3D7) даже в кооперативном режиме (в эксклюзивном - само собой) всегда рисует на экран (рабочий стол), по умолчанию игнорируя любые окна (в т.ч. handle в SetCooperativeLevel).
miek (2004-01-19 21:54:00) [2]Под DirectX - очень просто. В примере FLip поверхности заменить на FlipToGDI (название процедуры не помню). Или просто брать DC поверхности и BitBlt с нее.
program Project1;
uses
DirectDraw, windows, messages, kol;
var
WindowClass: TWndClass; // Объявляем класс будущего окна
Instance: HWnd; // Объявляем переменную потока
Handle: HWnd; // Дескриптор окна
msg: TMsg; // переменная, через которую будут приниматься сообщения от системы
DDResult: Hresult; // Сюда возвращается флаг результата после каждой операции
// при инициализации объектов DirectDraw
DDrawObject: IDirectDraw; // Это ключевой объект !!! Без него все напрасно.
PrimarySurface: IDirectDrawSurface; //Объявили первичную поверхность
SecondarySurface: IDirectDrawSurface; //Объявили вторичную поверхность
SurfaceDescription: TDDSurfaceDesc; // Этот объект нам потребуется при создании
// самих поверхностей в этой структуре описывается структура (масло масляное :-))
// будущей поверхности. Она используется многократно.
BackCaps: TDDSCaps; // флаг, который указывает режим для вторичной поверхности
t, passed, frames: cardinal;
dc: hdc;
fpsstring: string;
dispmodes: array of TDDSurfaceDesc;
const
DDSCAPS_BACKBUFFER = $00000004;
function EnumDisplayModesProc( const lpTDDSurfaceDesc: TDDSurfaceDesc;
lpContext: Pointer): HRESULT; stdcall;
begin
setlength( dispmodes, length( dispmodes)+1);
dispmodes[ length( dispmodes)-1]:= lpTDDSurfaceDesc;
Result := DDENUMRET_OK;
end;
procedure FreeAll;
begin
ddrawobject.RestoreDisplayMode;
SecondarySurface._Release;
pointer( SecondarySurface):= nil;
PrimarySurface._Release;
pointer( PrimarySurface):= nil;
DDrawObject._Release;
pointer( DDrawObject):= nil;
showcursor( true);
end;
procedure repaintme;
var
dc: hdc;
r: trect;
begin
secondarysurface.GetDC( dc);
r:= makerect( 0, 0, 100, 100);
drawtext( dc, pchar( fpsstring), length( fpsstring), r, dt_left);
PrimarySurface.Flip( nil, DDFLIP_WAIT);
secondarysurface.releasedc( dc);
end;
function windowproc( Hwn, msg, wpr, lpr: longint): longint; stdcall;
begin
result:= defwindowproc( hwn, msg, wpr, lpr);
if (msg=wm_destroy) or ((msg=wm_KeyDown) and (wpr=VK_ESCAPE)) then
begin
FreeAll;
Halt;
end;
if msg=wm_paint then
begin
result:= ord( true);
repaintme;
exit;
end;
if msg=wm_erasebkgnd then
begin
result:= ord( true);
exit;
end;
end;
begin
instance:= GetModuleHandle( nil);
with WindowClass do
begin
style:= CS_HRedraw or CS_VRedraw;
Lpfnwndproc:= @windowproc;
Hinstance:= Instance;
HbrBackground:= color_btnface;
LpszClassName:= 'DXtest 1';
Hcursor:= 0;
end; // описали класс нашего окна
RegisterClass( WindowClass); // Регистрируем его в системе
showcursor( false);
Handle:= CreateWindowEx( 0, 'DXtest 1', nil,
WS_POPUP, 5,5, GetSystemMetrics( SM_CXSCREEN), GetSystemMetrics( SM_CYSCREEN),
0, 0, instance, nil);
DDResult:= DirectDrawCreate( nil, DDrawObject, nil);
//Создали управляющий объект DirectDraw
DDResult:= DDrawObject.SetCooperativeLevel( handle,
DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN or DDSCL_ALLOWMODEX or DDSCL_FPUSETUP);
// Установили флаги приоритета
DDResult:= DDrawObject.SetDisplayMode( 640, 480, 16);
// Установили видеорежим
{Начинаем описывать первичную поверхность}
with SurfaceDescription do
begin
dwSize:= sizeof( SurfaceDescription);
dwFlags:= DDSD_CAPS or DDSD_BACKBUFFERCOUNT or DDSD_REFRESHRATE;
dwRefreshRate:= 80;
// Устанавливаем флаги этой поверхности
ddsCaps.dwCaps:= DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX;
// Установили свойства как первичная, переключаемая поверхность.
DwBackBufferCount:= 1;
// Наша первичная поверхность имеет одну вторичную.
end;
DDResult:= DDrawObject.CreateSurface( SurfaceDescription, PrimarySurface, nil);
// Ну вот мы и создали первичную поверхность
{Теперь еще легче. Теперь нам нужно просто подключить вторичную поверхность к первичной.}
BackCaps.dwCaps:= DDSCAPS_BACKBUFFER or DDSCAPS_FLIP;
// Указываем, что создаваемая нами поверхность является вне экранной (невидимой)
PrimarySurface.GetAttachedSurface( BackCaps, SecondarySurface);
// Ну вот, наконец то присоединили вторую поверхность
primarysurface.GetDC( dc);
patblt( dc, 0, 0, 640, 480, blackness);
primarysurface.ReleaseDC( dc);
secondarysurface.GetDC( dc);
patblt( dc, 0, 0, 640, 480, blackness);
secondarysurface.ReleaseDC( dc);
// Чтобы проверить, действительно ли происходит переключение между поверхностями
PrimarySurface.Flip( nil, DDFLIP_WAIT);
frames:= 0;
t:= gettickcount;
while true do
begin
if ( PeekMessage( msg, 0, 0, 0, PM_REMOVE)) then
// Check if there is a message for this window
begin
translatemessage( msg);
dispatchmessage( msg);
end;
repaintme;
PrimarySurface.Flip( nil, DDFLIP_NOVSYNC or DDFLIP_DONOTWAIT);
inc( frames);
passed:= gettickcount-t;
if passed>300 then
begin
fpsstring:= 'FPS: '+int2str( frames*1000 div passed)+' ';
t:= gettickcount;
frames:= 0;
end;
end;
end.