您的位置:首页 > 其它

Direct 窗口模式(非独占模式)贴图操作

2014-05-15 19:53 387 查看
窗口模式跟全屏模式差别..

窗口模式下的Direct不能使用页切换(Filp)

32位主机上位深一直是32..不能使用SetDisplayMode设置位深..(调用SetDisplayMode返回值都是 0x80004001..(无效的函数调用))

ddpixelformat.dwRGBBitCount返回值一直是 32 

不过窗口的目标还是全屏..但是我们使用的是窗口..所以要用 定义一个 RECT 结构再使用GetWindowRect追踪坐标

 

调用SetCooperativeLevel设置协调级的时候一般使用 DDSCL_NORMAL 标志位

关于位图

--------------------------------------------------------------

位图的RGB编码在内存中的是相反方向放置的.. 

位图文件的BITMAPINFOHEADER信息头的biHeight 部分的如果是正数

那么..位图的Y轴是反的(相当于垂直翻转)..如图..





这时候要写一个翻转函数..矫正Y轴..

code

位图头文件.h

#ifndef _LD_BITMAP_H_
#define _LD_BITMAP_H_

#include <windows.h>
#include <iostream>

int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height) ;

class frData
{
public:
frData::frData(LPWSTR) ;
int x,y,\
height,width,\
Bit,L_BYTE ;
unsigned char* image_PTR ;
RECT rect ;
frData::~frData(){free(image_PTR) ;}
private:
BITMAPFILEHEADER bitmapfileheader ;
BITMAPINFOHEADER bitmapinfoheader ;
} ;
#endif


实现文件.cpp

#include "LD-BITMAP.h"

int Flip_Bitmap(unsigned char* image, int bytes_per_line, int height)//Y轴矫正函数
{
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) ;
}
frData::frData(LPWSTR B_M_P)
{
FILE* fp ;
_wfopen_s(&fp,B_M_P,TEXT("rb")) ;

if(fp == 0)

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

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

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

if(this->Bit == 8)

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

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

image_PTR = (unsigned char*)malloc(L_BYTE* height) ;

if(fread(image_PTR,1,L_BYTE* height,fp) == 0)

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

if (this->bitmapinfoheader.biHeight < 0)

this->height = -(this->height) ;
else
Flip_Bitmap(image_PTR,L_BYTE,this->height) ;

fclose(fp) ;
}


主程序.

#define INITGUID

#include <Windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wx/wx.h>
#include <ddraw.h>
#include "LD-BITMAP.h"

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

#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
#define _RGB24BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) )
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))

frData OPS(wxT("K-ON.bmp")) ;

void 绘制像素(HWND hwnd,int height,int width,unsigned char* dx7_surface,unsigned char* image_buffer,long lPitch)
{
static RECT client ;
static unsigned char* PLA = image_buffer ;
GetWindowRect(hwnd, &client) ;

for(int x = 0 ; x < height ; x++)
{
for (int y=0 ; y < width ; y++)
{
*((DWORD*)(dx7_surface + (y + client.left)*4 + (client.top + x)* lPitch)) = \

_RGB32BIT(0,*(image_buffer + 2),*(image_buffer + 1),*image_buffer) ;

image_buffer = image_buffer + 3 ;
}
}
image_buffer = PLA ;
}
class MyApp : public wxApp  // 实例派生
{
public:
virtual bool OnInit();
};
class DX7Graph : public wxWindow // wxWindow基类 派生 DirectDraw
{
public:
DX7Graph::DX7Graph(wxWindow*) ;
void  DX7Graph::OnIdle(wxIdleEvent& event) ;
DX7Graph::~DX7Graph() ;

protected:
private:
HWND                  DX7Graph_hwnd ;
LPDIRECTDRAW7         lpdd ;
DDSURFACEDESC2        ddsd ;
LPDIRECTDRAWSURFACE7  lpddsprimary ;
LPDIRECTDRAWSURFACE7  lpddsback ;
DDSCAPS2              ddscaps ;
DECLARE_EVENT_TABLE()
} ;

class MyFrame : public wxFrame // 窗口派生
{
public:
MyFrame(const wxString& title);

private:
DECLARE_EVENT_TABLE()
};

DECLARE_APP(MyApp)	//实例

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame(wxT("wxWidgets App")) ;

frame->Show(true);

return true;
}

BEGIN_EVENT_TABLE(MyFrame, wxFrame) //事件表

END_EVENT_TABLE()

BEGIN_EVENT_TABLE(DX7Graph,wxWindow) //事件表
EVT_IDLE(DX7Graph::OnIdle)
END_EVENT_TABLE()

MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title,wxPoint(400,320),wxSize(564,323))
{
this->SetBackgroundColour(1);
DX7Graph* win = new DX7Graph(this) ;
}

DX7Graph::DX7Graph(wxWindow* TPTC) : wxWindow(TPTC,4299,wxPoint(400,320),wxSize(564,323))
{

DX7Graph_hwnd = (HWND)TPTC->GetHWND() ;

if(FAILED(DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL)))

wxMessageBox(wxT("DirectDrawCreateEx Failed"),wxT("DirectDraw7"),wxOK,this) ;

if (FAILED(lpdd->SetCooperativeLevel(DX7Graph_hwnd,DDSCL_NORMAL)))

wxMessageBox(wxT("SetCooperativeLevel Failed"),wxT("DirectDraw7"),wxOK,this) ;

DDSURFACEDESC2* LPDXSUR = &ddsd ; //BYTE:DDSURFACEDESC2 (124)

__asm PUSH ECX           __asm PUSH EDI
__asm PUSH EAX           __asm CLD
__asm MOV  EAX,0         __asm MOV ECX,1Fh
__asm MOV  EDI,LPDXSUR   __asm REP STOSD
__asm POP  EAX           __asm POP EDI  __asm POP ECX

ddsd.dwSize = sizeof(DDSURFACEDESC2) ;

ddsd.dwFlags = DDSD_CAPS ;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;

if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))

wxMessageBox(wxT("CreateSurface Failed"),wxT("DirectDraw7"),wxOK,this) ;

SetBackgroundColour(1) ;
// 1 is Black Yes My favourite Color
}

DX7Graph::~DX7Graph()
{
if(lpddsprimary)
lpddsprimary->Release() ;

if (lpdd)
lpdd->Release() ;
}
void DX7Graph::OnIdle(wxIdleEvent& event)
{

DDSURFACEDESC2 ddsd ;    // directdraw surface description

memset(&ddsd,0,sizeof(ddsd)) ;

ddsd.dwSize = sizeof(ddsd) ;

lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL) ;

unsigned char* primary_buffer = (unsigned char*)ddsd.lpSurface ;

static unsigned char* LP_S = OPS.image_PTR ;

绘制像素(DX7Graph_hwnd,323,564,primary_buffer,OPS.image_PTR,ddsd.lPitch) ;

Sleep(1) ;

lpddsprimary->Unlock(NULL) ;
}




这是24位的位图片..填写像素的时候只要忽略Alpha分量即可..如果是16位的话还要转化为 24 位..详见 RGB565 转 RGB888(CSDN也有很多相关内容)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: