关于 Direct Blt 0x887601AE (DDERR_SURFACEBUSY) 和函数指针

网上有这么一段描述

DXERROR

(0x887601ae, "DDERR_SURFACEBUSY", "Access to this surface is being refused because the surface is already locked by another thread.")

字面翻译是 表面访问被拒绝 ..已经被另一个线程锁定..

Blt操作在表面被Lock的时候不应该去调用的..只有当Unlock的时候调用才会正确..

举个例子

我创建了一个 离屏表面 和一个主表面.. 从离屏向主表面 Blt 位块的时候 ..你只需要 先锁定 离屏表面...这个锁定是为了向离屏表面写入像素对不对?

那么在Blt之前就一定要先Unlock离屏表面才可以使用Blt..从离屏表面向主表面Blt的时候主表面不需要进行任何加锁解锁操作也可以成功的..

写段代码吧..从离屏缓冲到主表面Blt位图(窗口模式)SDK的..(用的函数指针..)

K-ON.bmp 564*323                                    mario.bmp 192*160

DX7GL.h(C code排版会乱掉..选了其他风格的...所以没有语法高亮..)

#ifndef _DX7GL_H_
#define _DX7GL_H_

#define INITGUID
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)) ; ddstruct.dwSize = sizeof(ddstruct) ;}
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))

#include <windows.h>
#include <ddraw.h>
#include <objbase.h>
#include <initguid.h>
#include <Guiddef.h>
#include <stdio.h>

#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"dxguid.lib")

struct INTS
{
  int x,y,height,width,Bit,L_BYTE ;
	unsigned char* image_PTR ;

	   BITMAPFILEHEADER bitmapfileheader ;
       BITMAPINFOHEADER bitmapinfoheader ;

	 int (*Flip)(struct INTS*,unsigned char*,int,int) ;
	 int (*Load)(struct INTS*,LPWSTR) ;
     int (*Del)(struct INTS*) ; 
} ;

void INTS_Init(struct INTS*) ;

struct DX7Graph
{
    LPDIRECTDRAW7         major_lpdd ; 	// 接口

	DDSURFACEDESC2        major_ddsd ;		// 主表面及其描述设备..
	LPDIRECTDRAWSURFACE7  major_surface ;
	RECT                  major_rect ;

	DDSURFACEDESC2        sub_ddsd ;		 // 后备表面及其描述设备..
    LPDIRECTDRAWSURFACE7  sub_surface ;
	RECT                  sub_rect ;
   	
  int (*Init_Main_Surface)(struct DX7Graph*,HWND) ;		// 若干函数指针
  int (*Create_OffScreen_Surface)(struct DX7Graph*,int,int,bool,int) ;
  int (*Del_DX7Graph)(struct DX7Graph*) ;
  int (*Paint)(struct DX7Graph*,HWND,int,int,unsigned char*,unsigned char*,long) ;
  int (*Extra_OffScreen)(struct DX7Graph*,DDSURFACEDESC2&,LPDIRECTDRAWSURFACE7 FAR*,int,int,bool,int) ;
  // 此函数用于更多的额外的表面及其描述设备..
} ;

void DX7Graph_Mapper_Slot(struct DX7Graph*,LPRECT,LPRECT) ;
// 函数指针映射表声明..					 
#endif


DX7GL.cpp

#include "DX7GL.h"
// 映射函数声明..	 
static int mapper_Flip(struct INTS*,unsigned char*,int,int) ;

static int mapper_Load(struct INTS*,LPWSTR) ; 

static int mapper_Del(struct INTS*) ;

static int mapper_Init_Main_Surface(struct DX7Graph*,HWND) ;

static int mapper_Create_OffScreen_Surface(struct DX7Graph*,int,int,bool,int) ;

static int mapper_Paint(struct DX7Graph*,HWND,int,int,unsigned char*,unsigned char*,long) ;

static int mapper_Extra_OffScreen(struct DX7Graph*,DDSURFACEDESC2&,LPDIRECTDRAWSURFACE7 FAR*,int,int,bool,int) ;

static int mapper_Del_DX7Graph(struct DX7Graph *) ;


void INTS_Init(struct INTS* st)	 // 函数指针映射表实现..	
{  
   st->Flip = mapper_Flip ;
   st->Load = mapper_Load ;
   st->Del = mapper_Del ;
}

void DX7Graph_Mapper_Slot(struct DX7Graph* DX7_Slot,LPRECT m,LPRECT s)	// 函数指针映射表实现..
{
   DX7_Slot->Init_Main_Surface = mapper_Init_Main_Surface ;
   DX7_Slot->Create_OffScreen_Surface = mapper_Create_OffScreen_Surface ;
   DX7_Slot->Paint = mapper_Paint ;
   DX7_Slot->Extra_OffScreen = mapper_Extra_OffScreen ;
   DX7_Slot->Del_DX7Graph = mapper_Del_DX7Graph ;
  
   if(m == NULL)
		 goto kante ;
   else
       {
	      DX7_Slot->major_rect.left = m->left ;
       	  DX7_Slot->major_rect.top = m->top ;
	      DX7_Slot->major_rect.right = m->right ;
	      DX7_Slot->major_rect.bottom = m->bottom ;
       }
kante:if(s == NULL)
		  return ;
   else
       {
      	  DX7_Slot->sub_rect.left = s->left ;
	      DX7_Slot->sub_rect.top = s->top ;
     	  DX7_Slot->sub_rect.right = s->right ;
	      DX7_Slot->sub_rect.bottom = s->bottom ;
       }
	  return ;
}
 // 映射函数实现..当位图标志位为正时..使用此函数矫正Y轴
int mapper_Flip(struct INTS *st,unsigned char *image,int bytes_per_line,int height)
{
   unsigned char* buffer ; 
   int index ;    

          if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))

                 MessageBox(NULL,TEXT("malloc buffer failed"),TEXT("DirectDraw7"),MB_OK | MB_ICONERROR) ;

       memcpy(buffer,image,bytes_per_line*height);

                      for (index=0; index < height; index++)

                              memcpy(&image[((height-1) - index)*bytes_per_line],&buffer[index*bytes_per_line],bytes_per_line) ;

   free(buffer) ;

   return(1) ;
}
  // 映射函数实现..读取位图结构头..及数据段
int mapper_Load(struct INTS *st,LPWSTR TRG)
{
   FILE* fp ;
      _wfopen_s(&fp,TRG,TEXT("rb")) ;

         if(fp == 0) 

	           MessageBox(NULL,TEXT("Open bmp failed"),TEXT("DirectDraw7"),MB_OK | MB_ICONERROR) ;

   fread(&st->bitmapfileheader,sizeof(BITMAPFILEHEADER),1,fp) ;
   fread(&st->bitmapinfoheader,sizeof(BITMAPINFOHEADER),1,fp) ;

     st->height = st->bitmapinfoheader.biHeight ;
     st->width = st->bitmapinfoheader.biWidth ;
     st->Bit = st->bitmapinfoheader.biBitCount ;

        if(st->Bit == 8)
 	      
			MessageBox(NULL,TEXT("没写调色板代码...禁止使用8位图元.."),TEXT("载入位图错误"),MB_ICONERROR) ;

     st->L_BYTE = (st->width*st->Bit/8 + 3)/4*4 ;

     st->image_PTR = (unsigned char*)malloc((st->L_BYTE)*(st->height)) ;
	   
          if(fread(st->image_PTR,1,(st->L_BYTE)*(st->height),fp) == 0)

	           MessageBox(NULL,TEXT("read image data failed"),TEXT("s_Load"),MB_ICONERROR) ; 

		  if (st->bitmapinfoheader.biHeight < 0)

			     st->height = -(st->height) ;		 
		  else
		
			     st->Flip(st,st->image_PTR,st->L_BYTE,st->height) ; 
			   
 fclose(fp) ;
                return 0 ;
}
	// 映射函数实现..释放RES
int mapper_Del(struct INTS *st)
{
	free(st->image_PTR) ;
	return 0 ;
}
	// 映射函数实现..初始化Direct主表面..
int mapper_Init_Main_Surface(struct DX7Graph* DX7_Slot,HWND swnd)
{
   if (FAILED(DirectDrawCreateEx(NULL,(void **)(&(DX7_Slot->major_lpdd)),IID_IDirectDraw7,NULL)))

	  MessageBox(NULL,TEXT("DirectDrawCreateEx Failed"),TEXT("DirectDraw7"),MB_OK) ;

      if (FAILED(DX7_Slot->major_lpdd->SetCooperativeLevel(swnd,DDSCL_NORMAL)))

	      MessageBox(NULL,TEXT("SetCooperativeLevel Failed"),TEXT("DirectDraw7"),MB_OK) ;

			
       DDRAW_INIT_STRUCT(DX7_Slot->major_ddsd) ;

	   DX7_Slot->major_ddsd.dwFlags = DDSD_CAPS  ;

       DX7_Slot->major_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;

	         if(FAILED(DX7_Slot->major_lpdd->CreateSurface((&(DX7_Slot->major_ddsd)),(&(DX7_Slot->major_surface)),NULL)))
			
			     MessageBox(NULL,TEXT("CreateSurface Failed"),TEXT("DirectDraw7"),MB_OK) ;

			 return 5 ;

}
// 映射函数实现..初始化离屏表面..
int mapper_Create_OffScreen_Surface(struct DX7Graph *DX7_Slot,int width,int height,bool V,int KeyVaule)
{
	DDRAW_INIT_STRUCT(DX7_Slot->sub_ddsd) ;

	if(V == true)
	{
	   DX7_Slot->sub_ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = KeyVaule ;
       DX7_Slot->sub_ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = KeyVaule ;
	} 
	      DX7_Slot->sub_ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_CKSRCBLT ;
	     DX7_Slot->sub_ddsd.dwWidth = width ;
         DX7_Slot->sub_ddsd.dwHeight = height ;
		  DX7_Slot->sub_ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY ;

	   if(FAILED(DX7_Slot->major_lpdd->CreateSurface(&(DX7_Slot->sub_ddsd),&(DX7_Slot->sub_surface),NULL)))

           MessageBox(NULL,TEXT("创建离屏表面失败"),TEXT("DirectDraw7"),MB_OK) ; 
    
            return 6 ;

}
  	  // 映射函数实现..此函数用于写入表面像素..
int mapper_Paint(struct DX7Graph *DX7_Slot,HWND hwnd,int height,int width,unsigned char* dx7_surface,unsigned char* image_buffer,long lPitch) 
{
   static unsigned char* PLA = image_buffer ;  
 
      for(int x = 0 ; x < height ; x++)  
         {  
             for (int y=0 ; y < width ; y++)  
               {  
                   *((DWORD*)(dx7_surface + y*4 +  x * lPitch)) = _RGB32BIT(0,*(image_buffer + 2),*(image_buffer + 1),*image_buffer ) ;  
  
                   image_buffer = image_buffer + 3 ;  
               }      
        }  
   image_buffer = PLA ;

   return 5 ;
}
  		// 映射函数实现..用于创建更多的表面缓冲..
int mapper_Extra_OffScreen(struct DX7Graph* DX7_Slot,DDSURFACEDESC2& ddsdk,LPDIRECTDRAWSURFACE7 FAR* DS7_PTR,int width,int height,bool Q,int Color)
{
	DDRAW_INIT_STRUCT(ddsdk) ;

	if(Q == true)
	{
	   ddsdk.ddckCKSrcBlt.dwColorSpaceLowValue = Color ;
       ddsdk.ddckCKSrcBlt.dwColorSpaceHighValue = Color ;
	} 
	      ddsdk.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_CKSRCBLT ;
	     ddsdk.dwWidth = width ;
         ddsdk.dwHeight = height ;
		 ddsdk.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY ;

	   if(FAILED(DX7_Slot->major_lpdd->CreateSurface(&(ddsdk),DS7_PTR,NULL)))

           MessageBox(NULL,TEXT("创建离屏表面失败"),TEXT("DirectDraw7"),MB_OK) ; 
    
            return 6 ;
}		
// 映射函数实现..释放指针..
int mapper_Del_DX7Graph(struct DX7Graph* DX7_Slot)
{
 
	  if(DX7_Slot->sub_surface)
         {
           DX7_Slot->sub_surface->Release() ;
           DX7_Slot->sub_surface = NULL ;
         } 
	  if(DX7_Slot->major_surface)
         {
           DX7_Slot->major_surface->Release() ;
           DX7_Slot->major_surface = NULL ;
         }
	  if(DX7_Slot->major_lpdd)
         {
           DX7_Slot->major_lpdd->Release() ;
           DX7_Slot->major_lpdd = NULL ;
         } 
    return 0 ;
}
主程序..

#include "DX7GL.h"

DX7Graph Graphic ;
INTS CON,MARIO ;
RECT rect,sub_rect ;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

DDSURFACEDESC2        external_ddsd ;		// 额外的主表面及其描述设备..
LPDIRECTDRAWSURFACE7  external_surface ;

int WINAPI WinMain
(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)

{
   static TCHAR szAppName[] = TEXT ("Sample") ;
   HWND hwnd ;
   MSG msg ;

   WNDCLASS wndclass ;
   wndclass.style = CS_HREDRAW | CS_VREDRAW ;
   wndclass.lpfnWndProc = WndProc ;
   wndclass.cbClsExtra = 0 ;
   wndclass.cbWndExtra = 0 ;
   wndclass.hInstance = hInstance ;
   wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
   wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
   wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ;
   wndclass.lpszMenuName = NULL ;
   wndclass.lpszClassName = szAppName ;

       if (!RegisterClass (&wndclass))
          {
            MessageBox ( NULL, TEXT ("st program requires Windows NT!"),szAppName,MB_ICONERROR) ;
              return 0 ;
          }

hwnd = CreateWindow
                   (szAppName,TEXT("Program"),WS_OVERLAPPEDWINDOW,
                     0,
					 0,
					 600,
					 350,
                     NULL,NULL,
					 hInstance,NULL) ;

ShowWindow(hwnd,iCmdShow) ;
UpdateWindow(hwnd) ;

DX7Graph_Mapper_Slot(&Graphic,NULL,NULL) ; // 实现映射..

INTS_Init(&CON) ;	  // 实现映射..
INTS_Init(&MARIO) ;	   // 实现映射..

CON.Load(&CON,TEXT("K-ON.bmp")) ;   // 此时调用映射函数mapper_Load读取位图..
MARIO.Load(&MARIO,TEXT("mario.bmp")) ;	// 此时调用映射函数mapper_Load读取位图..

	rect.left = 0 ;
	rect.top = 0 ;
	rect.right = 192;
	rect.bottom = 160 ;

	sub_rect.left = 0 ;
	sub_rect.top = 0 ;
	sub_rect.right = 564 ;
	sub_rect.bottom = 323 ;
				
Graphic.Init_Main_Surface(&Graphic,hwnd) ;	 // 此时调用映射函数mapper_Init_Main_Surface初始化并创建一个主表面..
Graphic.Create_OffScreen_Surface(&Graphic,192,160,true,_RGB32BIT(0,255,255,255)) ;
// 此时调用映射函数mapper_Create_OffScreen_Surface初始化并创建一个离屏缓冲..
Graphic.Extra_OffScreen(&Graphic,external_ddsd,&external_surface,564,323,false,0) ;
// 此时调用映射函数mapper_Extra_OffScreen初始化并创建另一个一个离屏缓冲..
while(TRUE)	 
	{
	  if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
	     { 
           if(msg.message == WM_QUIT)
                break ;
	         TranslateMessage(&msg) ;

	         DispatchMessage(&msg) ;
	   } 


	   Graphic.sub_surface->Lock(NULL,&Graphic.sub_ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL) ;

	   external_surface->Lock(NULL,&external_ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL) ;

	   static unsigned char* sub_buffer = (unsigned char*)Graphic.sub_ddsd.lpSurface ;

	   static unsigned char* primary_buffer = (unsigned char*)external_ddsd.lpSurface ;

	   Graphic.Paint(&Graphic,hwnd,323,564,primary_buffer,CON.image_PTR,external_ddsd.lPitch) ;
	   Graphic.Paint(&Graphic,hwnd,160,192,sub_buffer,MARIO.image_PTR,Graphic.sub_ddsd.lPitch) ;

	   Graphic.sub_surface->Unlock(NULL) ;

	   external_surface->Unlock(NULL) ;

	   external_surface->Blt(&rect,Graphic.sub_surface,&rect,DDBLT_KEYSRC,NULL) ;

	   Graphic.major_surface->Blt(&sub_rect,external_surface,NULL,DDBLT_KEYSRC,NULL) ;
	    
	  Sleep(1) ;

	}

    CON.Del(&CON) ;		   //映射函数释放资源
	MARIO.Del(&MARIO) ;
    external_surface->Release() ;
    external_surface = NULL ;
	Graphic.Del_DX7Graph(&Graphic) ;

return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  HDC hdc ;
  PAINTSTRUCT ps ;
  RECT rect ;
   
    switch (message)
      {
         case WM_CREATE:
			 
         return 0 ;
 
		 case WM_PAINT:
                     hdc = BeginPaint (hwnd, &ps) ;
                     GetClientRect (hwnd, &rect) ;
                     EndPaint (hwnd, &ps) ;
         return 0 ;
         
		 case WM_DESTROY:
			         
					
                     PostQuitMessage (0) ;
         return 0 ;
      }
	    
    
  return DefWindowProc (hwnd, message, wParam, lParam) ;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值