先上一段代码
//不使用交换链: IDirect3DSurface9 *pBackBuffer; // 取得后缓存表面 m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); // 将后缓存表面保存为文件(D3DXIFF_*为保存的图片格式,有bmp,jpg,tga,png,dds等) D3DXSaveSurfaceToFile(TEXT("C:\\temp.jpg"), D3DXIFF_JPG, pBackBuffer, NULL, NULL); pBackBuffer->Release();
这一段代码是将后台缓存表面保存为一张图片,但我现在需要将后台缓存表面的数据保存到内存以BYTE形式的保存(这个BYTE数据应该是一个点阵图),交由其它方法去处理这个数据.不知如何操作,有哪位仁兄知道如何处理,还请指教,在下先谢过了。
由于分数不多了,只有10分了!解决问题发红包以表酬谢!
楼主你好,请问这个问题解决了吗?我也遇到了这个问题,想问下解决方案,谢谢!
.h代码 #pragma once #include <d3d9.h> #include <d3dx9.h> #include <dxerr.h> #include <fstream> #include <atlimage.h> #include "WHThread.h" #include "CameraDS.h" #include "DX7GL.h" #include <vector> #include <gdiplus.h> using namespace std; #pragma comment (lib,"dxerr.lib") #pragma comment (lib,"dxguid.lib") #pragma comment (lib,"d3dx9d.lib") #pragma comment (lib,"d3d9.lib") //顶点结构和灵活顶点格式 struct CUSTOMVERTEX { FLOAT x, y, z; //位置 FLOAT tu, tv; //纹理 }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1) class CDirectHlsl:public CWHThread { public: CDirectHlsl(); ~CDirectHlsl(); //定义变量 public: int m_mpValue; //磨皮强度 int m_mbValue; //美白强度 int m_nWidth; //窗口宽度 int m_nHeight; //窗口高度 WNDCLASSEX m_wc; //窗口变量 HWND m_hWnd; //窗口句柄 LPDIRECT3D9 m_pD3D; //Direct3D对象 LPDIRECT3DTEXTURE9 m_pTexture; //纹理 LPDIRECT3DDEVICE9 m_pd3dDevice; //Direct3D设备对象 LPDIRECT3DVERTEXBUFFER9 m_pVB; //顶点缓冲区 LPD3DXEFFECT m_pEffect; //效果 IDirect3DSurface9* m_pBufferSurface; //渲染表面 IDirect3DSurface9* m_pBackBuffer; //后台表面 PDIRECT3DSURFACE9 m_pTextureSurface; //纹理的Surface LPD3DXFONT m_pFont; //字体对象 LPDIRECTDRAWSURFACE7 m_lpdds_off; //离屏表面 BYTE* m_CameraImageData; //帧图的数据 int m_nCameraLength; //帧图数据包 BYTE* m_ImageRotateData; //旋转图像数据 int m_nImageRotateLength; //旋转图像数据包 int m_nSumFps; //FPS总量 int m_nTimer; RECT m_clientRect; bool m_bDeviceLost; //设备丢失状态 ////DX7Graph //DX7Graph m_Graphic; //INTS CON; //INTS MARIO; //DDSURFACEDESC2 m_External_ddsd ; //额外的主表面及其描述设备.. //LPDIRECTDRAWSURFACE7 m_External_surface ; //摄像头数据相关变量 vector <CCameraDS> cameralist; //摄像头ID数组 int m_cam_count; //定义方法 public: //初始化 bool InitDirectHlsl(int nWidth, int nHeight,HWND hwnd); //初始化窗口 bool InitWindows(); //初始化D3D bool InitD3D(); //初始化D3D数据 bool InitD3DData(); //初始化摄像头数据 bool InitCamera(); //版本检测 bool CheckShaderVersion(); //清理数据 void Cleanup(); //窗口消息 static LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); //旋转图像 bool ImageRotate(BYTE *src, int width, int height, int nBit); //获取当前FPS int GetFpsValue(); //保存为图片 void SavaImage(); //读取图片 void GetImageData(BYTE *pData,long Length); //运行事件 virtual bool OnEventThreadRun(); }; .cpp代码 #include "DirectHlsl.h" // pRenderSurface是pRenderTexture 对应的Surface // pBackBuffer用于保存原来的Render Target //获取D3D默认交换链中的后台缓存 CDirectHlsl::CDirectHlsl() { m_mpValue = 50; m_mbValue = 50; m_nWidth = 0; m_nHeight = 0; m_hWnd = NULL; m_pD3D = NULL; m_pTexture = NULL; m_pd3dDevice = NULL; m_pVB = NULL; m_pEffect = NULL; m_pTextureSurface = NULL; m_pFont = NULL; m_CameraImageData = NULL; m_ImageRotateData = NULL; m_pBufferSurface = NULL; m_pBackBuffer = NULL; m_nCameraLength = 0; m_nImageRotateLength = 0; m_nSumFps = 0; m_nTimer = 0; m_cam_count = 0; m_bDeviceLost = true; ZeroMemory(&m_clientRect, sizeof(m_clientRect)); } CDirectHlsl::~CDirectHlsl() { Cleanup(); } //初始化数据 bool CDirectHlsl::InitDirectHlsl(int nWidth, int nHeight, HWND hwnd) { m_nWidth = nWidth; m_nHeight = nHeight; m_hWnd = hwnd; //初始化D3D if (InitD3D() == false) { return false; } //初始化D3D数据 if (InitD3DData() == false) { return false; } //初始化摄像头类 InitCamera(); return true; } //初始化窗口 bool CDirectHlsl::InitWindows() { //初始化窗口类信息 ZeroMemory(&m_wc, sizeof(m_wc)); m_wc.cbSize = sizeof(WNDCLASSEX); m_wc.style = CS_HREDRAW | CS_VREDRAW; m_wc.lpfnWndProc = MsgProc; m_wc.cbClsExtra = 0; m_wc.cbWndExtra = 0; m_wc.hInstance = GetModuleHandle(NULL); m_wc.hIcon = NULL; m_wc.hCursor = NULL; m_wc.hbrBackground = NULL; m_wc.lpszMenuName = NULL; m_wc.lpszClassName = TEXT("MDY_HLSL_WINDOWS"); m_wc.hIconSm = NULL; //注册窗口类 RegisterClassEx(&m_wc); //创建窗口 m_hWnd = CreateWindow(TEXT("MDY_HLSL_WINDOWS"), TEXT("MDY_HLSL"), WS_OVERLAPPEDWINDOW, 2000, 0, m_nWidth, m_nHeight, NULL, NULL, m_wc.hInstance, NULL); if (m_hWnd == NULL) { return false; } //显示主窗口 ShowWindow(m_hWnd, SW_SHOWDEFAULT); UpdateWindow(m_hWnd); return true; } //初始化D3D bool CDirectHlsl::InitD3D() { HRESULT hr = NULL; //创建Direct3D对象,该对象用来创建Direct3D设备对象 if (NULL == (m_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) { return false; } //设置D3DPRESENT_PARAMETERS结构,准备创建Direct3D设备对象 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //创建Direct3D设备对象 if (m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pd3dDevice) != S_OK) { return false; } //版本不支持 if (CheckShaderVersion() == false) { return false; } return true; } //初始化D3D数据 bool CDirectHlsl::InitD3DData() { //创建顶点缓冲区 m_pd3dDevice->CreateVertexBuffer(50 * 2 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVB, NULL); //顶点数据 CUSTOMVERTEX Vertices[] = { { -4.5, -3.5, 0.0f, 0.0f, 1.0f }, { -4.5, 3.35, 0.0f, 0.0f, 0.0f }, { 5, -3.5, 0.0f, 1.0f, 1.0f }, { 5, 3.35, 0.0f, 1.0f, 0.0f }, }; //填充顶点缓冲区 CUSTOMVERTEX* pVertices; m_pVB->Lock(0, 0, (void**)&pVertices, 0); memcpy(pVertices, Vertices, sizeof(Vertices)); m_pVB->Unlock(); //存储异常信息 ID3DXBuffer* errorBuffer = 0; //创建效果 if (D3DXCreateEffectFromFile(m_pd3dDevice, TEXT("C:\\EffectTexture.fx"), NULL, NULL, D3DXSHADER_DEBUG, NULL, &m_pEffect, &errorBuffer) != S_OK) { return false; } if (errorBuffer) { return false; } //设置磨皮参数 m_pEffect->SetFloat("mpValue", (float)m_mpValue / 100.00);; //设置美白参数 m_pEffect->SetFloat("mbValue", m_mbValue); //构造世界矩阵 D3DXMATRIX matWorld; D3DXMatrixIdentity(&matWorld); //构造观察矩阵 D3DXMATRIXA16 matView; D3DXVECTOR3 vEyePt(0.0f, 0.0f, -8); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); D3DXMATRIXA16 matProj; //构造投影矩阵 float fAspectRatio = (float)m_nWidth / m_nHeight; D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, fAspectRatio, 1.0f, 100.0f); //为效果设置组合变换矩阵 D3DXMATRIX mWorldViewProj = matWorld * matView * matProj; m_pEffect->SetMatrix("matWorldViewProj", &mWorldViewProj); //设置剔出模式,为不剔出任何面 m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); //创建一个渲染表面 m_pd3dDevice->CreateOffscreenPlainSurface(m_nWidth, m_nHeight, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_pBufferSurface, 0); m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer); //创建ID3DXFont字体对象 D3DXCreateFont(m_pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_pFont); //获取渲染场景对象 D3DXHANDLE hTechnique = m_pEffect->GetTechniqueByName("TShader"); //使用渲染场景对象 m_pEffect->SetTechnique(hTechnique); //获取窗口客户区 GetClientRect(m_hWnd, &m_clientRect); m_clientRect.left = m_clientRect.right - 300; m_clientRect.bottom = 100; m_pd3dDevice->CreateTexture(m_nWidth, m_nHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &m_pTexture, NULL); //获得纹理的Surface m_pTexture->GetSurfaceLevel(0, &m_pTextureSurface); ////离屏渲染/////////////////////////////////////////// //// 实现映射.. //DX7Graph_Mapper_Slot(&m_Graphic,NULL,NULL); ////实现映射.. //INTS_Init(&CON); ////实现映射.. //INTS_Init(&MARIO); //// 此时调用映射函数mapper_Init_Main_Surface初始化并创建一个主表面.. //m_Graphic.Init_Main_Surface(&m_Graphic,m_hWnd) ; //// 此时调用映射函数mapper_Create_OffScreen_Surface初始化并创建一个离屏缓冲.. //m_Graphic.Extra_OffScreen(&m_Graphic,m_External_ddsd,&m_External_surface,564,323,false,0); ////时调用映射函数mapper_Extra_OffScreen初始化并创建另一个一个离屏缓冲.. //m_Graphic.Extra_OffScreen(&m_Graphic,m_External_ddsd,&m_External_surface,564,323,false,0); return true; } //初始化摄像头数据 bool CDirectHlsl::InitCamera() { //摄像头数据 m_cam_count = CCameraDS::CameraCount(); cameralist.resize(m_cam_count); //打开摄像头 if (!cameralist[m_cam_count - 1].OpenCamera(1, false, 640, 480)) { return false; } return true; } //版本检测 bool CDirectHlsl::CheckShaderVersion() { if (m_pd3dDevice == NULL) { return false; } // Get g_pDevice capabilities D3DCAPS9 caps; m_pd3dDevice->GetDeviceCaps(&caps); // Make sure vertex shader version greater than 2.0 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0)) { return false; } // Make sure pixel shader version greater than 2.0 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0)) { return false; } return true; } //清理数据 void CDirectHlsl::Cleanup() { if (m_pD3D) { m_pD3D->Release(); m_pD3D = NULL; } if (m_pTexture) { m_pTexture->Release(); m_pTexture = NULL; } if (m_pd3dDevice) { m_pd3dDevice->Release(); m_pd3dDevice = NULL; } if (m_pVB) { m_pVB->Release(); m_pVB = NULL; } if (m_pEffect) { m_pEffect->Release(); m_pEffect = NULL; } if (m_pTextureSurface) { m_pTextureSurface->Release(); m_pTextureSurface = NULL; } if (m_pFont) { m_pFont->Release(); m_pFont = NULL; } if (m_pBufferSurface) { m_pBufferSurface->Release(); m_pBufferSurface = NULL; } //if (m_pBackBuffer) //{ // m_pBackBuffer->Release(); //} if (m_CameraImageData) { free(m_CameraImageData); m_CameraImageData = NULL; } if (m_ImageRotateData) { free(m_ImageRotateData); m_ImageRotateData = NULL; } m_nCameraLength = 0; m_nImageRotateLength = 0; m_nSumFps = 0; m_nTimer = 0; cameralist.clear(); //UnregisterClass(TEXT("MDY_HLSL"), m_wc.hInstance); } //窗口消息 LRESULT WINAPI CDirectHlsl::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: { PostQuitMessage(0); return 0; } case WM_PAINT: { ValidateRect(hWnd, NULL); return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam); } //图像旋转 bool CDirectHlsl::ImageRotate(BYTE *src, int width, int height, int nBit) { int nLength = width*height * nBit; //优化创建内存的时间 if (m_nImageRotateLength != nLength) { if (m_ImageRotateData) { free(m_ImageRotateData); } m_ImageRotateData = (BYTE*)malloc(nLength); m_nImageRotateLength = nLength; } for (int i = 0, j = nLength; i < nLength, j >= 0; i += nBit, j -= nBit) { m_ImageRotateData[i] = src[j - 4]; m_ImageRotateData[i + 1] = src[j - 3]; m_ImageRotateData[i + 2] = src[j - 2]; m_ImageRotateData[i + 3] = src[j - 1]; } memcpy(src, m_ImageRotateData, nLength); return true; } //运行事件 void CDirectHlsl::GetImageData(BYTE *pData,long Length) { HRESULT hr = NULL; //拷贝数据 D3DLOCKED_RECT d3d_rect; if (!FAILED(m_pBufferSurface->LockRect(&d3d_rect, 0, D3DLOCK_DISCARD))) { memcpy((BYTE*)(d3d_rect.pBits), pData, Length); m_pBufferSurface->UnlockRect(); }; //m_Graphic.sub_surface->Lock(NULL,&m_Graphic.sub_ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // m_External_surface->Lock(NULL,&m_External_ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL) ; //static unsigned char* primary_buffer = (unsigned char*)m_External_ddsd.lpSurface ; //m_Graphic.Paint(&m_Graphic,hwnd,323,564,primary_buffer,CON.image_PTR,m_External_ddsd.lPitch) ; //m_Graphic.sub_surface->Unlock(NULL) ; //m_External_surface->Unlock(NULL) ; //清理背景 m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); if (SUCCEEDED(m_pd3dDevice->BeginScene())) { //使用自定义渲染表面填充后台缓存 m_pd3dDevice->StretchRect(m_pBufferSurface, 0, m_pBackBuffer, 0, D3DTEXF_NONE); //释放缓存 m_pBackBuffer->Release(); IDirect3DSurface9* pBackBufferSurface = NULL; m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBufferSurface); m_pd3dDevice->StretchRect(pBackBufferSurface, 0, m_pTextureSurface, 0, D3DTEXF_NONE); m_pd3dDevice->UpdateSurface(pBackBufferSurface, 0, m_pTextureSurface, NULL); pBackBufferSurface->Release(); //设置纹理 if (m_pTexture) { //设置纹理 m_pEffect->SetTexture("TextureMapping",m_pTexture); } //使用渲染 UINT nPasses; m_pEffect->Begin(&nPasses, 0); for (UINT iPass = 0; iPass < nPasses; iPass++) { m_pEffect->BeginPass(iPass); m_pd3dDevice->SetStreamSource(0, m_pVB, 0, sizeof(CUSTOMVERTEX)); m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); m_pEffect->EndPass(); } m_pEffect->End(); m_nSumFps++; int nCurFps = GetFpsValue(); CString strDesc; strDesc.Format(TEXT("当前FPS:%d 累计FPS:%d 消耗时长:%d"), nCurFps, m_nSumFps, time(NULL) - m_nTimer); //绘制字体 m_pFont->DrawText(NULL, strDesc.GetBuffer(0), strDesc.GetLength(), &m_clientRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER, D3DXCOLOR(1.0f, 0.75f, 0.0f, 1.0f)); m_pd3dDevice->EndScene(); LPD3DXBUFFER bufferedImage = NULL; hr = D3DXSaveSurfaceToFileInMemory(&bufferedImage, D3DXIFF_PNG,m_pBufferSurface,NULL,NULL); bufferedImage->Release(); //保存图片 SavaImage(); } //将交换链中的后台缓存显示 hr = m_pd3dDevice->Present(0, 0, 0, 0); if (hr == D3DERR_DEVICELOST) { m_bDeviceLost = true; } if (m_CameraImageData) { free(m_CameraImageData); } if (m_ImageRotateData) { free(m_ImageRotateData); } } //运行事件 bool CDirectHlsl::OnEventThreadRun() { while (1) { if (m_bDeviceLost) { //Cleanup(); //初始化D3D if (InitD3D() && InitD3DData()) { InitCamera(); m_bDeviceLost = false; } else { continue; } } if (m_nTimer == 0) { m_nTimer = time(NULL); } HRESULT hr = NULL; //读取帧图 m_nCameraLength = cameralist[m_cam_count - 1].QueryFrame3(&m_CameraImageData, m_nCameraLength); //图像旋转 ImageRotate(m_CameraImageData, m_nWidth, m_nHeight, 4); //拷贝数据 D3DLOCKED_RECT d3d_rect; if (!FAILED(m_pBufferSurface->LockRect(&d3d_rect, 0, D3DLOCK_DISCARD))) { memcpy((BYTE*)(d3d_rect.pBits), m_CameraImageData, m_nCameraLength); m_pBufferSurface->UnlockRect(); }; //清理背景 m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); if (SUCCEEDED(m_pd3dDevice->BeginScene())) { //使用自定义渲染表面填充后台缓存 m_pd3dDevice->StretchRect(m_pBufferSurface, 0, m_pBackBuffer, 0, D3DTEXF_NONE); //释放缓存 m_pBackBuffer->Release(); IDirect3DSurface9* pBackBufferSurface = NULL; m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBufferSurface); m_pd3dDevice->StretchRect(pBackBufferSurface, 0, m_pTextureSurface, 0, D3DTEXF_NONE); m_pd3dDevice->UpdateSurface(pBackBufferSurface, 0, m_pTextureSurface, NULL); pBackBufferSurface->Release(); //设置纹理 if (m_pTexture) { //设置纹理 m_pEffect->SetTexture("TextureMapping", m_pTexture); } //使用渲染 UINT nPasses; m_pEffect->Begin(&nPasses, 0); for (UINT iPass = 0; iPass < nPasses; iPass++) { m_pEffect->BeginPass(iPass); m_pd3dDevice->SetStreamSource(0, m_pVB, 0, sizeof(CUSTOMVERTEX)); m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); m_pEffect->EndPass(); } m_pEffect->End(); m_nSumFps++; int nCurFps = GetFpsValue(); CString strDesc; strDesc.Format(TEXT("当前FPS:%d 累计FPS:%d 消耗时长:%d"), nCurFps, m_nSumFps, time(NULL) - m_nTimer); //绘制字体 m_pFont->DrawText(NULL, strDesc.GetBuffer(0), strDesc.GetLength(), &m_clientRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER, D3DXCOLOR(1.0f, 0.75f, 0.0f, 1.0f)); m_pd3dDevice->EndScene(); //保存图片 SavaImage(); } //将交换链中的后台缓存显示 hr = m_pd3dDevice->Present(0, 0, 0, 0); if (hr == D3DERR_DEVICELOST) { m_bDeviceLost = true; } } if (m_CameraImageData) { free(m_CameraImageData); } if (m_ImageRotateData) { free(m_ImageRotateData); } return true; } //获取当前FPS int CDirectHlsl::GetFpsValue() { //计算Fps=总帧数/时长 int nCurTimer = time(NULL); int nDiff = abs(nCurTimer - m_nTimer); int nCurFps = 0; if (nDiff > 0) { nCurFps = m_nSumFps / nDiff; } else { nCurFps = m_nSumFps; } return nCurFps; } //保存为图片 void CDirectHlsl::SavaImage() { //不使用交换链: IDirect3DSurface9 *pBackBuffer; // 取得后缓存表面 m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); // 将后缓存表面保存为文件(D3DXIFF_*为保存的图片格式,有bmp,jpg,tga,png,dds等) D3DXSaveSurfaceToFile(TEXT("C:\\temp.jpg"), D3DXIFF_JPG, pBackBuffer, NULL, NULL); pBackBuffer->Release(); }
:
你参考下。
@zbyhi: 感谢回帖,我下去研究下。