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
实现文件.cpp
主程序.
这是24位的位图片..填写像素的时候只要忽略Alpha分量即可..如果是16位的话还要转化为 24 位..详见 RGB565 转 RGB888(CSDN也有很多相关内容)
窗口模式下的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也有很多相关内容)
相关文章推荐
- 32BPP窗口模式下24位位图的像素操作(2)
- C# WinForm 弹出模式窗口操作滚动条
- 模式窗口对父窗口的操作
- 解决CMS在IE8下模式窗口下操作又开启新窗口
- 56、vi常见用法,多窗口模式,标记,多文件编辑,快捷操作及设置
- 运维日记007 - vim操作总结(三、可视化模式与多窗口)
- 模式字母窗口操作
- ASP.NET 清除模式窗口数据缓存的操作方式
- 32BPP窗口模式下24位位图的像素操作(1)
- 如何用请求字符串传值给用模式窗口打开的aspx页面。
- 模式窗口showModalDialog的用法总结
- DIRECTX中独占模式与窗口模式的切换
- 使用模式窗口 并更新父窗口
- SCORM——共享式、互操作的在线教育模式
- 一个窗口模式的文件属性修改器LXA 0.56,为以后扩展方便,可复用的代码比较多
- 模式窗口的刷新问题
- String操作,单例模式实现
- 使用CallByName“代替”模式窗口。
- 子父窗口之间的操作之小例子