DirectDraw.cpp
资源名称:视频会议系统.rar [点击查看]
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:8k
源码类别:
IP电话/视频会议
开发平台:
Visual C++
- // DDraw.cpp: implementation of the CDirectDraw class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "..stdafx.h"
- #include "DirectDraw.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #pragma comment(lib,"ddraw.lib")
- #pragma comment(lib,"dxguid.lib")
- CDirectDraw::CDirectDraw()
- {
- this->m_hWnd=NULL;
- this->wndText = "";
- memset(&this->ddsd,0,sizeof(this->ddsd));
- this->lpDD=NULL;
- this->lpDDSPrimary=NULL;
- this->lpDDSOffscreen=NULL;
- this->lpClipper=NULL;
- this->bitmap_width=0;
- this->bitmap_height=0;
- this->bitmap_depth=0;
- this->bitmap_size=0;
- this->screen_width=0;
- this->screen_height=0;
- this->screen_depth=0;
- this->ddraw_buffer=NULL;
- }
- CDirectDraw::~CDirectDraw()
- {
- this->ReleaseDirectDraw( );
- }
- BOOL CDirectDraw::InitDirectDraw( HWND hwnd , int width , int height , int depth )
- {
- if( ! ::IsWindow( hwnd ) ) return FALSE;
- LPDIRECTDRAW lpdd = NULL;
- //创建DirectDraw
- if( FAILED( DirectDrawCreate( NULL ,&lpdd , NULL ) ) )
- return FALSE;
- lpdd->QueryInterface( IID_IDirectDraw7 ,( void** )( &lpDD ) );
- lpdd->Release();
- if(this->lpDD == NULL)
- return FALSE;
- //与窗口建立关系
- if( FAILED ( this->lpDD->SetCooperativeLevel( hwnd , DDSCL_NORMAL ) ) )
- {
- this->ReleaseDirectDraw();
- return FALSE;
- }
- ZeroMemory( &ddsd,sizeof( ddsd ) );
- this->ddsd.dwSize = sizeof(DDSURFACEDESC2);
- this->ddsd.dwFlags = DDSD_CAPS;
- this->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
- //创建主表面
- if( FAILED( this->lpDD->CreateSurface( &this->ddsd , &this->lpDDSPrimary , NULL ) ) )
- {
- this->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- if( FAILED( this->lpDD->CreateSurface( &this->ddsd , &this->lpDDSPrimary , NULL ) ) )
- {
- this->ReleaseDirectDraw();return FALSE;
- }
- }//取屏幕分辨率
- if( FAILED( this->lpDD->GetDisplayMode( &this->ddsd ) ) )
- {
- this->ReleaseDirectDraw(); return FALSE;
- }
- this->screen_width = this->ddsd.dwWidth;
- this->screen_height = this->ddsd.dwHeight;
- this->screen_depth = this->ddsd.ddpfPixelFormat.dwRGBBitCount;
- //设定屏外图像大小
- this->ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
- this->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
- //屏外表面图像的宽度
- this->ddsd.dwWidth = width;
- //屏外表面图像的高度
- this->ddsd.dwHeight = height;
- //创建屏外表面
- if( FAILED( this->lpDD->CreateSurface( &this->ddsd , &this->lpDDSOffscreen , NULL ) ) )
- {
- this->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- if( FAILED( this->lpDD->CreateSurface( &this->ddsd , &this->lpDDSOffscreen,NULL ) ) )
- {
- this->ReleaseDirectDraw(); return FALSE;
- }
- }
- //创建翻转表面
- if(FAILED( this->lpDD->CreateClipper( 0 , &this->lpClipper , NULL ) ) )
- {
- this->ReleaseDirectDraw(); return FALSE;
- }//联系窗口
- if( FAILED( this->lpClipper->SetHWnd( 0 , hwnd ) ) )
- {
- this->ReleaseDirectDraw(); return FALSE;
- }//联系主表面
- if( FAILED( this->lpDDSPrimary->SetClipper( this->lpClipper ) ) )
- {
- this->ReleaseDirectDraw(); return FALSE;
- }//保存位图大小
- this->bitmap_width = width;
- this->bitmap_height = height;
- this->bitmap_depth = depth;
- this->bitmap_size = width * height * depth / 8;
- if(this->ddraw_buffer == NULL )
- this->ddraw_buffer = new char [ this->bitmap_width * this->bitmap_height * this->screen_depth/8 ];
- //保存窗口句柄
- this->m_hWnd = hwnd;
- //保存窗口标题
- CWnd::FromHandle( this->m_hWnd )->GetWindowText( this->wndText );
- return TRUE;
- }
- void CDirectDraw::ReleaseDirectDraw( void )
- {
- if( this->lpClipper )
- {
- this->lpClipper->Release(); this->lpClipper=NULL;
- }
- if( this->lpDDSOffscreen )
- {
- this->lpDDSOffscreen->Release(); this->lpDDSOffscreen=NULL;
- }
- if( this->lpDDSPrimary )
- {
- this->lpDDSPrimary->Release(); this->lpDDSPrimary=NULL;
- }
- if( this->lpDD )
- {
- this->lpDD->Release(); this->lpDD=NULL;
- }
- if( this->ddraw_buffer )
- {
- delete this->ddraw_buffer; this->ddraw_buffer=NULL;
- }
- }
- //转换位图使之可以用DirextDraw画图
- void * CDirectDraw::ConvertImageToDDraw( void * buffer )
- { //不支持带调色板的位图
- if( ! buffer || this->bitmap_depth == 8 || this->screen_depth == 8 )
- return NULL;
- switch( this->bitmap_depth )
- {
- case 8 : break;
- case 16 :
- switch(this->screen_depth)
- {
- case 8 : break;
- case 16 : c_color_space::rgb555_to_rgb565(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 24 : c_color_space::rgb555_to_rgb888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 32 : c_color_space::rgb555_to_rgb8888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- }break;
- case 24 :
- switch(this->screen_depth)
- {
- case 8 : break;
- case 16 : c_color_space::rgb888_to_rgb565(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 24 : c_color_space::rgb888_to_rgb888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 32 : c_color_space::rgb888_to_rgb8888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- }break;
- case 32 :
- switch(this->screen_depth)
- {
- case 8 : break;
- case 16 : c_color_space::rgb8888_to_rgb565(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 24 : c_color_space::rgb8888_to_rgb888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- case 32 : c_color_space::rgb8888_to_rgb8888(this->ddraw_buffer,buffer,this->bitmap_size);break;
- }break;
- }
- return this->ddraw_buffer;
- }
- BOOL CDirectDraw::DrawDirectDraw( void * buffer , BOOL m_bCaption , int time )
- {
- if( buffer==NULL || !::IsWindow( this->m_hWnd ) )
- return FALSE;
- try
- {
- //显示图像
- HRESULT dd_result = this->lpDDSOffscreen->Lock( NULL , &this->ddsd , DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR , NULL );
- if( dd_result != DD_OK )
- { //没有锁定视频表面,则判断视频表面是否丢失,如果丢失则要重置表面;否则直接返回
- if( dd_result==DDERR_SURFACELOST )
- { //恢复视频表面
- this->lpDDSOffscreen->Restore();this->lpDDSPrimary->Restore();
- }
- else
- return FALSE;
- }//显示位图到directdraw屏外表面
- this->CopyToDDraw( this->ddsd.lpSurface , this->ConvertImageToDDraw( buffer ) );
- this->lpDDSOffscreen->Unlock( NULL );
- CRect rc;
- //画标题
- if( m_bCaption && ( ! this->wndText.IsEmpty( ) || time ) )
- {
- HDC hdc=NULL;
- this->lpDDSOffscreen->GetDC( &hdc );
- ::SetBkMode( hdc , TRANSPARENT );
- ::GetClipBox( hdc , &rc );
- rc.DeflateRect( 5 , 5 );
- ::SetTextColor( hdc , RGB( 225 , 0 , 0 ) );
- ::DrawText( hdc , this->wndText , this->wndText.GetLength( ) , &rc , DT_LEFT );
- CTime tm( time );
- ::DrawText( hdc , tm.Format( "%Y-%m-%d %H:%M:%S" ) , tm.Format( "%Y-%m-%d %H:%M:%S" ).GetLength( ) , &rc , DT_RIGHT );
- this->lpDDSOffscreen->ReleaseDC( hdc );
- }
- ::GetWindowRect( this->m_hWnd , &rc );
- this->lpDDSPrimary->Blt( &rc , this->lpDDSOffscreen , NULL , DDBLT_WAIT , NULL );
- return TRUE;
- }
- catch( ... )
- {
- return FALSE;
- }
- }
- void CDirectDraw::CopyToDDraw( void * destination_buffer , void * source_buffer )
- {
- if( ! destination_buffer || ! source_buffer )
- return;
- //一条扫描线的大小
- int pitch=this->bitmap_width * this->screen_depth / 8;
- BYTE* ps=( BYTE * )source_buffer;
- BYTE* pd=( BYTE * )destination_buffer;
- ps += this->bitmap_height * pitch;
- //每次扫描一条线
- for( int i = 0 ; i < this->bitmap_height ; i++ )
- {
- memcpy( pd , ps , pitch );
- //从底部拷贝每一条扫描线
- ps-=pitch;
- pd += this->ddsd.lPitch;
- }
- }