最近做的一个项目是基于WPF框架的,由于WPF是基于D3D显示的,所以将之前的显示部分移植过去之后,初始化不成功。对于遇到的问题做个整理,如下:

由于我们是视频的显示,实际上只用到D3D中的2D显示的功能,对于3D的渲染及纹理等部分的要求不高。

头文件

typedef struct IDirect3D9Ex *LPDIRECT3D9EX, *PDIRECT3D9EX;
typedef HRESULT (WINAPI *DIRECT3DCREATE9EXFUNCTION)(UINT SDKVersion, IDirect3D9Ex**);
#define IFC(x) { hr = (x); if (FAILED(hr)) goto Cleanup; }

struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color;        // The vertex color
FLOAT tu, tv; // The position for texture
};

class CVideoRender
{
public:
CVideoRender();
~CVideoRender();
int InitD3D(HWND hWnd);
bool CreateOneSurface(int index, int width, int height);
void FreeD3DAll();
void FreeOneSurface(int id);
void DisplayFrame(int index, BYTE* pVData, char* text = NULL, char* time = NULL, char* tips=NULL);
void SetDstShowMode(int showMode);

private:
void CopyToSurface(int index, BYTE *pVData);
HRESULT EnsureD3DObjects();

public:
LPDIRECT3DDEVICE9 m_pD3DDevice;
IDirect3DDevice9Ex *m_pd3dDeviceEx;

LPDIRECT3D9 m_pD3D;
IDirect3D9Ex *m_pD3DEx;

ID3DXFont *m_pD3DFontB;
ID3DXFont *m_pD3DFontS;
HWND                m_hWndMainView;
int                 m_showMode;

IDirect3DSurface9 *m_pD3DPlainSurface[MAX_SCREEN];
IDirect3DSwapChain9 *m_pSwapChain[MAX_SCREEN];
IDirect3DSurface9 *m_pBackBuffer[MAX_SCREEN];

RECT                m_rcDst,               //window primary surface rect
m_rcSrcFrame[MAX_SCREEN],
m_rcDstFrame[MAX_SCREEN]; 
CRITICAL_SECTION    m_cs;

char  m_Text[MAX_SCREEN][128];

bool _isInitialized;
bool _supportsD3dEx;
};

1. D3D的显示与系统上的DirectX_SDK的版本也是有关系的,在使用的过程中,第一步要确定系统上的DirectX_SDK的头文件中是否有你所使用的函数,

检测显示的环境

HRESULT EnsureD3DObjects()
{
    HRESULT hr = S_OK;
    HMODULE hD3D = NULL;

//加载动态库,在安装系统显示库后,会在C:\\WINDOWS\\SYSTEM32目录下生成该dll文件
    hD3D = LoadLibrary(TEXT("d3d9.dll"));
if (hD3D) {

//检测该动态库是否支持Direct3DCreate9Ex方法
DIRECT3DCREATE9EXFUNCTION pfnCreate9Ex = (DIRECT3DCREATE9EXFUNCTION)GetProcAddress(hD3D, "Direct3DCreate9Ex");
if (pfnCreate9Ex){
_supportsD3dEx = true;
printf("_supportsD3dEx is true\n");
hr = (*pfnCreate9Ex)(D3D_SDK_VERSION, &m_pD3DEx);
if (hr == S_OK) {
hr = m_pD3DEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&m_pD3D)); 
}

} else {
_supportsD3dEx = false;
printf("_supportsD3dEx is false\n");
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (!m_pD3D) {
hr = E_FAIL;
printf("Direct3DCreate9 failed\n");
}
}

FreeLibrary(hD3D);

} else {
hr = E_FAIL;
}

return hr;
}

2.创建D3D设备

int InitD3D(HWND hWnd)
{
if (_isInitialized)
return WP_PDVR_HAS_INITD3D;

m_hWndMainView = hWnd;

HRESULT hr = EnsureD3DObjects();
if (hr == S_OK) {
// printf("EnsureD3DObjects S_OK\n");
_isInitialized = true;
}

D3DCAPS9 caps;  
int vp = 0;
m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
printf("D3DCREATE_HARDWARE_VERTEXPROCESSING\n");
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
} else {
printf("D3DCREATE_SOFTWARE_VERTEXPROCESSING\n");
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

D3DPRESENT_PARAMETERS d3dpp;       //定义显示参数
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.BackBufferHeight = 1;
       d3dpp.BackBufferWidth = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

if (!_supportsD3dEx) {
// Create the D3DDevice
if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,     //D3DADAPTER_DEFAULT 标记来指定使用默认的显示器
D3DDEVTYPE_HAL, //D3DDEVTYPE_HAL来指定设备类型为硬件设备而不是软件设备
m_hWndMainView,
vp | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
&d3dpp, 
&m_pD3DDevice ))) {
//printf("CreateDevice failed D3DERR_INVALIDCALL\n");
//printf("m_pD3DDevice is null\n");
return WP_PDVR_INITD3D_FAILED;
}
} else {
HRESULT hr = S_OK;
        hr = m_pD3DEx->CreateDeviceEx(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_hWndMainView,
vp | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
&d3dpp,
NULL,
&m_pd3dDeviceEx);
//printf("CreateDeviceEx hr = %d\n", hr);
if (hr == S_OK) {
hr = m_pd3dDeviceEx->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void**>(&m_pD3DDevice));
}

if (hr != S_OK) {
//printf("D3D9x CreateDeviceEx failed\n");
return WP_PDVR_INITD3D_FAILED;
}
}

// HFONT hFont = CreateFont(24, 12, 0, 0, 500, 0, 0, 0, DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY, DEFAULT_PITCH, "锟斤拷锟斤拷");
// D3DXCreateFont(m_pD3DDevice, hFont, &m_pD3DFontB);
// DeleteObject(hFont);
//
// hFont = CreateFont(24, 12, 0, 0, 500, 0, 0, 0, DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY, DEFAULT_PITCH, "锟斤拷锟斤拷");
// D3DXCreateFont( m_pD3DDevice, hFont, &m_pD3DFontS );
// DeleteObject(hFont);

return WP_PDVR_NOERROR;
}

***只有在以上两步中会有IDirect3D9Ex 和IDirect3D9的区别,在后面的步骤,都是统一的IDirect3D9

3.显示

void SetDstShowMode(int showMode)
{
m_showMode = showMode;

GetClientRect(m_hWndMainView, &m_rcDst);

int width = m_rcDst.right,
height = m_rcDst.bottom;

//printf("SetDstShowMode width = %d height = %d\n", width, height);

int n = 0,
iY = 0,
iX = 0;

width = width/showMode;
height = height/showMode;

for (iY = 0; iY < showMode; iY++) {
for (iX = 0; iX < showMode; iX++) {
m_rcDstFrame[n].left = iX * width + 1;
m_rcDstFrame[n].right = (iX+1) * width - 2;
m_rcDstFrame[n].top = iY * height + 1;
m_rcDstFrame[n].bottom = (iY+1) * height - 2;    
n++;
}
}

InvalidateRect(m_hWndMainView, NULL, TRUE);
}

void CopyToSurface(int index, BYTE *pVData)
{
int bytescopy, 
height;

if (m_pD3DPlainSurface[index]) {
bytescopy = m_rcSrcFrame[index].right * 2;
height = m_rcSrcFrame[index].bottom;

D3DLOCKED_RECT  Drc = {0};

m_pD3DPlainSurface[index]->LockRect(&Drc, NULL, 0);

BYTE * pBits = (BYTE *)Drc.pBits;
if (NULL == pBits) {
m_pD3DPlainSurface[index]->UnlockRect();
return ;
}

for (int i = 0; i < height; i++) {
memcpy(pBits, pVData, bytescopy);
pBits += Drc.Pitch;
pVData += bytescopy;
}

m_pD3DPlainSurface[index]->UnlockRect();
}
}

#define COLORT D3DCOLOR_XRGB(0,255,255)
#define COLORW D3DCOLOR_XRGB(255,255,255)

void DisplayFrame(int index, BYTE *pVData, char *text, char *time, char *tips)
{
__try {
CopyToSurface(index, pVData);
EnterCriticalSection(&m_cs);
m_pD3DDevice->StretchRect(m_pD3DPlainSurface[index], NULL, m_pBackBuffer[index], NULL, D3DTEXF_LINEAR);
m_pD3DDevice->SetRenderTarget(0, m_pBackBuffer[index]);
  m_pD3DDevice->BeginScene();

// if (m_Text[index]) {
// if (m_rcSrcFrame[index].right > 500) {
// m_pD3DFontB->DrawTextA(m_Text[index], -1, &m_rcSrcFrame[index], DT_LEFT, COLORW);
// 
// } else {
// m_pD3DFontS->DrawTextA(m_Text[index], -1, &m_rcSrcFrame[index], DT_LEFT, COLORW);
// }
// }
// 
// if (time) {
// m_pD3DFontB->DrawTextA(time, -1, &m_rcSrcFrame[index], DT_BOTTOM | DT_RIGHT | DT_SINGLELINE, COLORT);
// }

m_pD3DDevice->EndScene();

m_pSwapChain[index]->Present(NULL, &m_rcDstFrame[index], NULL, NULL, D3DPRESENT_DONOTWAIT);

LeaveCriticalSection(&m_cs);
} __except(1) {}
}

Direct3DCreate9与Direct3DCreate9Ex相关推荐

  1. DirectX9函数:Direct3DCreate9

    创建一个IDirect3D9 对象实例. IDirect3D9*Direct3DCreate9( UINTSDKVersion ); 参数: SDKVersion 此参数的值应为 D3D_SDK_VE ...

  2. 无法解析的外部符号 Direct3DCreate9@4

    错误 1 error LNK2019: 无法解析的外部符号 _Direct3DCreate9@4,该符号在函数 "void __cdecl InitD3D(struct HWND__ *)& ...

  3. 2007-08-03 16:04 unresolved external symbol Direct3DCreate9

    选择VC的菜单项"Project/Settings...",然后选中"Link"标签,在"Object/library modules"栏输 ...

  4. 游戏编程入门之碰撞检测

    在进行以下内容前我们需先做好准备,明白都要做什么 (1)编写碰撞函数(此时的函数不是完整的下面会对其修改):    我们首先需要创建两个矩形并且调用IntersetRect函数来检查他们是否碰撞的函数 ...

  5. 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8523341 作者:毛星云(浅墨 ...

  6. SDL2源代码分析8:视频显示总结

    SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL2源代码分析2:窗口(SDL_Window) SDL2源代码分析3:渲染器(SDL_Renderer) SD ...

  7. Direct3D初始化代码含义

    // Desc: 初始化Direct3D //----------------------------------------------------------------------------- ...

  8. 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)

    上一篇文章记录了GDI播放视频的技术.打算接下来写两篇文章记录Direct3D(简称D3D)播放视频的技术.Direct3D应该Windows下最常用的播放视频的技术.实际上视频播放只是Direct3 ...

  9. vs2010MFC D3D播放YUV格式视频详细制作全过程

    1.环境配置 1.1 Microsoft Visual Studio 2010安装 先下载Visual Studio 2010,然后双击setup.exe安装,安装时有一步选择vc++安装就可以了,其 ...

最新文章

  1. EF 批量 添加 修改 删除
  2. 在 CentOS 7 中安装并使用自动化工具 Ansible
  3. 如何创建启动界面Splash Screen
  4. Android Memory Management
  5. UITableView的优化原理
  6. vista磁盘使用100%_如何在Windows 7或Vista中创建和使用密码重置磁盘
  7. python 两个数据框合并计算_一文掌握Excel、SQL、Python【数据合并】大法!
  8. emacs shell插件_Windows 下 Emacs 中的 zsh shell 使用方法
  9. Vue学习心得记录之模板语法
  10. python itemgetter函数用法_Python itemgetter函数怎么用?
  11. java数组循环扩容_Java中实现数组动态扩容的两种方法
  12. JavaScript学习(五十二)—继承、call方法和apply方法
  13. 如何在不联网的情况下安装 Silverlight Tools
  14. 阶段3 2.Spring_06.Spring的新注解_3 AnnotationConfigApplicationContext的使用
  15. Visual Studio 201~ Code 格式检查
  16. python itchat模块登录失败_itchat模块的不明错误
  17. 《软件过程管理》 第一章 软件过程规范
  18. 什么是CPA、CPC、CPM、CVR、CTR、PV、UV、GMV定义以及相关计算公式
  19. Postman中文版 !!!!傻瓜教程
  20. win11设置开机自动打开chrome并最大化页面

热门文章

  1. jxTMS--web界面定义
  2. AD学习记录03-规则
  3. 凯撒(caesar)密码加解密方法
  4. PyCharm关闭双击shift全局搜索
  5. 计算机考试照片识别,PS照片JPEGsnoop帮你鉴别
  6. 网络工程师资料-永久有效
  7. 数据结构:链表逆序输出
  8. 设计模式 模版方法模式 展现程序员的一天
  9. Algorithm:数学建模大赛(CUMCM/NPMCM)之数学建模(经验/技巧)、流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价)、论文写作(意义/摘要/关键词/问题重述和模型假设/建
  10. 局域网共享上网IP设置