📄 dx_2d.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / DirectX audio and video render module * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "dx_hw.h"#define DDCONTEXT DDContext *dd = (DDContext *)dr->opaque;#define DDBACK DDSurface *pBack = (DDSurface *) gf_list_get(dd->surfaces, 0);static GF_Err DD_ClearBackBuffer(GF_VideoOutput *dr, u32 color){ HRESULT hr; RECT rc; DDBLTFX ddbltfx; DDCONTEXT; // Erase the background ZeroMemory( &ddbltfx, sizeof(ddbltfx) ); ddbltfx.dwSize = sizeof(ddbltfx); switch (dd->pixelFormat) { case GF_PIXEL_RGB_565: ddbltfx.dwFillColor = GF_COL_TO_565(color); break; case GF_PIXEL_RGB_555: ddbltfx.dwFillColor = GF_COL_TO_555(color); break; default: ddbltfx.dwFillColor = color; break; } rc.left = rc.top = 0; rc.right = dd->width; rc.bottom = dd->height;#ifdef USE_DX_3 hr = IDirectDrawSurface_Blt(dd->pBack, &rc, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );#else hr = IDirectDrawSurface7_Blt(dd->pBack, &rc, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );#endif return FAILED(hr) ? GF_IO_ERR : GF_OK;}GF_Err CreateBackBuffer(GF_VideoOutput *dr, u32 Width, u32 Height){ HRESULT hr; const char *opt; #ifdef USE_DX_3 DDSURFACEDESC ddsd;#else DDSURFACEDESC2 ddsd;#endif DDCONTEXT; if (dd->pBack && !dd->fullscreen && (dd->width == Width) && (dd->height == Height) ) { return GF_OK; } if (dd->pBack) SAFE_DD_RELEASE(dd->pBack); /*create backbuffer*/ ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; if (dd->systems_memory==2) { ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; } else { opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "UseHardwareMemory"); if (opt && !strcmp(opt, "yes")) { dd->systems_memory = 0; } else { ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; dd->systems_memory = 1; } } ddsd.dwWidth = Width; ddsd.dwHeight = Height;#ifdef USE_DX_3 if( FAILED( hr = IDirectDraw_CreateSurface(dd->pDD, &ddsd, &dd->pBack, NULL ) ) ) return GF_IO_ERR;#else if( FAILED( hr = IDirectDraw7_CreateSurface(dd->pDD, &ddsd, &dd->pBack, NULL ) ) ) return GF_IO_ERR;#endif /*store size*/ if (!dd->fullscreen) { dd->width = Width; dd->height = Height; } else { dd->fs_store_width = Width; dd->fs_store_height = Height; } DD_ClearBackBuffer(dr, 0xFF000000); if (!dd->yuv_init) DD_InitYUV(dr); return GF_OK;}GF_Err InitDirectDraw(GF_VideoOutput *dr, u32 Width, u32 Height){ HRESULT hr; DWORD cooplev; LPDIRECTDRAW ddraw;#ifdef USE_DX_3 DDSURFACEDESC ddsd;#else DDSURFACEDESC2 ddsd;#endif DDPIXELFORMAT pixelFmt; LPDIRECTDRAWCLIPPER pcClipper; DDCONTEXT; if (!dd->cur_hwnd || !Width || !Height) return GF_BAD_PARAM; DestroyObjects(dd); if( FAILED( hr = DirectDrawCreate(NULL, &ddraw, NULL ) ) ) return GF_IO_ERR;#ifdef USE_DX_3 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw, (LPVOID *)&dd->pDD);#else hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (LPVOID *)&dd->pDD);#endif IDirectDraw_Release(ddraw); if (FAILED(hr)) return GF_IO_ERR; dd->switch_res = 0; cooplev = DDSCL_NORMAL; /*Setup FS*/ if (dd->fullscreen) { /*change display mode*/ if (dd->switch_res) {#ifdef USE_DX_3 hr = IDirectDraw_SetDisplayMode(dd->pDD, dd->fs_width, dd->fs_height, dd->video_bpp);#else hr = IDirectDraw7_SetDisplayMode(dd->pDD, dd->fs_width, dd->fs_height, dd->video_bpp, 0, 0 );#endif if( FAILED(hr)) return GF_IO_ERR; } dd->NeedRestore = 1; cooplev = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN; } #ifdef USE_DX_3 hr = IDirectDraw_SetCooperativeLevel(dd->pDD, dd->cur_hwnd, cooplev);#else hr = IDirectDraw7_SetCooperativeLevel(dd->pDD, dd->cur_hwnd, cooplev);#endif if( FAILED(hr) ) return GF_IO_ERR; /*create primary*/ ZeroMemory( &ddsd, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;#ifdef USE_DX_3 if( FAILED(IDirectDraw_CreateSurface(dd->pDD, &ddsd, &dd->pPrimary, NULL ) ) ) return GF_IO_ERR;#else if( FAILED(hr = IDirectDraw7_CreateSurface(dd->pDD, &ddsd, &dd->pPrimary, NULL ) ) ) return GF_IO_ERR;#endif /*get pixel format of video board*/ memset (&pixelFmt, 0, sizeof(pixelFmt)); pixelFmt.dwSize = sizeof(pixelFmt); hr = IDirectDrawSurface_GetPixelFormat(dd->pPrimary, &pixelFmt); if( FAILED(hr) ) return GF_IO_ERR; switch(pixelFmt.dwRGBBitCount) { case 16: if ((pixelFmt.dwRBitMask == 0xf800) && (pixelFmt.dwGBitMask == 0x07e0) && (pixelFmt.dwBBitMask == 0x001f)) dd->pixelFormat = GF_PIXEL_RGB_565; else if ((pixelFmt.dwRBitMask == 0x7c00) && (pixelFmt.dwGBitMask == 0x03e0) && (pixelFmt.dwBBitMask == 0x001f)) dd->pixelFormat = GF_PIXEL_RGB_555; else return GF_NOT_SUPPORTED; dd->video_bpp = 16; break; case 24: if ((pixelFmt.dwRBitMask == 0x0000FF) && (pixelFmt.dwGBitMask == 0x00FF00) && (pixelFmt.dwBBitMask == 0xFF0000)) dd->pixelFormat = GF_PIXEL_BGR_24; else if ((pixelFmt.dwRBitMask == 0xFF0000) && (pixelFmt.dwGBitMask == 0x00FF00) && (pixelFmt.dwBBitMask == 0x0000FF)) dd->pixelFormat = GF_PIXEL_RGB_24; dd->video_bpp = 24; break; case 32: /*i always have color pbs in 32 bpp !!!*/ if ((pixelFmt.dwRBitMask == 0x0000FF) && (pixelFmt.dwGBitMask == 0x00FF00) && (pixelFmt.dwBBitMask == 0xFF0000)) dd->pixelFormat = GF_PIXEL_BGR_32; else if ((pixelFmt.dwRBitMask == 0xFF0000) && (pixelFmt.dwGBitMask == 0x00FF00) && (pixelFmt.dwBBitMask == 0x0000FF)) dd->pixelFormat = GF_PIXEL_RGB_32; dd->video_bpp = 32; break; default: return GF_IO_ERR; }#ifdef USE_DX_3 if( FAILED( hr = IDirectDraw_CreateClipper(dd->pDD, 0, &pcClipper, NULL ) ) ) return GF_IO_ERR;#else if( FAILED( hr = IDirectDraw7_CreateClipper(dd->pDD, 0, &pcClipper, NULL ) ) ) return GF_IO_ERR;#endif if( FAILED( hr = IDirectDrawClipper_SetHWnd(pcClipper, 0, dd->cur_hwnd) ) ) { IDirectDrawClipper_Release(pcClipper); return GF_IO_ERR; } if( FAILED( hr = IDirectDrawSurface_SetClipper(dd->pPrimary, pcClipper ) ) ) { IDirectDrawClipper_Release(pcClipper); return GF_IO_ERR; } IDirectDrawClipper_Release(pcClipper); dd->ddraw_init = 1; return CreateBackBuffer(dr, Width, Height);}static GF_Err DD_LockSurface(DDContext *dd, GF_VideoSurface *vi, void *surface){ HRESULT hr;#ifdef USE_DX_3 DDSURFACEDESC desc;#else DDSURFACEDESC2 desc;#endif if (!dd || !vi || !surface) return GF_BAD_PARAM;#ifdef USE_DX_3 ZeroMemory(&desc, sizeof(DDSURFACEDESC)); desc.dwSize = sizeof(DDSURFACEDESC); if (FAILED(hr = IDirectDrawSurface_Lock( (LPDIRECTDRAWSURFACE)surface, NULL, &desc, DDLOCK_SURFACEMEMORYPTR | /*DDLOCK_WRITEONLY | */ DDLOCK_WAIT, NULL))) { return GF_IO_ERR; } #else ZeroMemory(&desc, sizeof(DDSURFACEDESC2)); desc.dwSize = sizeof(DDSURFACEDESC2); if (FAILED(hr = IDirectDrawSurface7_Lock( (LPDIRECTDRAWSURFACE7) surface, NULL, &desc, DDLOCK_SURFACEMEMORYPTR | /*DDLOCK_WRITEONLY | */ DDLOCK_WAIT, NULL))) { return GF_IO_ERR; } #endif vi->video_buffer = desc.lpSurface; vi->width = desc.dwWidth; vi->height = desc.dwHeight; vi->pitch = desc.lPitch; vi->is_hardware_memory = !dd->systems_memory; return GF_OK;}static GF_Err DD_UnlockSurface(DDContext *dd, void *surface){ HRESULT hr; if (!dd || !dd->ddraw_init) return GF_IO_ERR;#ifdef USE_DX_3 hr = IDirectDrawSurface_Unlock( (LPDIRECTDRAWSURFACE)surface, NULL);#else hr = IDirectDrawSurface7_Unlock((LPDIRECTDRAWSURFACE7)surface, NULL);#endif return FAILED(hr) ? GF_IO_ERR : GF_OK;}static GF_Err DD_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock){ DDCONTEXT; if (do_lock) { vi->pixel_format = dd->pixelFormat; return DD_LockSurface(dd, vi, dd->pBack); } else return DD_UnlockSurface(dd, dd->pBack);}static void *LockOSContext(GF_VideoOutput *dr, Bool do_lock){ DDCONTEXT; if (do_lock) { if (!dd->lock_hdc && ! IDirectDrawSurface_IsLost(dd->pBack)) { if (FAILED(IDirectDrawSurface_GetDC(dd->pBack, &dd->lock_hdc)) ) dd->lock_hdc = NULL; } } else if (dd->lock_hdc) { IDirectDrawSurface_ReleaseDC(dd->pBack, dd->lock_hdc); dd->lock_hdc = NULL; } return (void *)dd->lock_hdc ;}static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 *key){ HRESULT hr; u32 dst_w, dst_h, src_w, src_h, flags; RECT r_dst, r_src; u32 left, top; src_w = src_wnd ? src_wnd->w : src->width; src_h = src_wnd ? src_wnd->h : src->height; dst_w = dst_wnd ? dst_wnd->w : dd->width; dst_h = dst_wnd ? dst_wnd->h : dd->height; if (src_wnd != NULL) MAKERECT(r_src, src_wnd); if (dst_wnd != NULL) MAKERECT(r_dst, dst_wnd); if (key) { DDCOLORKEY ck; ck.dwColorSpaceHighValue = ck.dwColorSpaceLowValue = *key; hr = IDirectDrawSurface_SetColorKey(src->pSurface, DDCKEY_SRCBLT, &ck); if (FAILED(hr)) return GF_IO_ERR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -