My FAQ,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > 综合文章
Direct3D试玩 - 实现一个Image Render
作者:未知 时间:2005-03-23 12:12 出处:Blog 责编:MyFAQ
              摘要:暂无

前些日子写了一个基于DrawDib视频函数库的Render,虽然显示图片速度非常快,但是还是难以满足一些交互式的实时显示.而且在放大缩小的时候,无法设置反锯齿功能(antialias). 本来不想用Directx,看来现在还是逃不过. 我很讨厌用接口经常变动的东西,更讨厌需要安装支持动态链接库的东东, directx就是这样的东西,direct1到现在的directx9,每一次新接口都会变动,当然老的接口还是可以用的,但是出来相应的SDK文档却没有老接口的调用方法。没办法,down了个Directx9硬着头皮学学。

研究了一下午再加一晚上的SDK文档, 脑子里差不多有Render的框架了,大致如下:

class MMD3DRender

{

protected:

    IDirect3D9*             m_pD3D;

    IDirect3DDevice9*       m_pDev;

    IDirect3DSurface9*      m_pSuf;

……

    //作一些Direct3D9的初始化工作

    bool Init( HWND);

    // Buffer里面的东西送到Surface上去(m_pSuf)

    void Draw( BYTE* pBuffer,int iStep, LPRECT lpRc);

    // WM_PAINT 消息处理

    void Paint();

    // 释放资源,退出的善后工作

    void Destroy();

};

按道理调用这个Render很简单,只要在某个Window对象的WM_CREATE消息响应函数里面调用

Init( pWnd->GetSafeHwnd())

然后其WM_PAINT函数里加

          ValidateRect(NULL);

          render.Paint();

OK了。

 

 

 

于是我就建立了一个MFC单视图结构(没有文档(CDocument)),往里面的CChildView

加了OnCreate,OnPaint消息处理函数,并插入了上面的代码,可是运行并没有成功,是Init出了问题:

 

 

 

bool MMD3DRender::Init( HWND hWnd)

{

    ASSERT(::IsWindow(hWnd));

    m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );

    if( !m_pD3D)

        return false;

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory( &d3dpp, sizeof(d3dpp) );

    d3dpp.Windowed = TRUE;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    d3dpp.hDeviceWindow = hWnd;

    HRESULT hr;

    if( FAILED(hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&m_pDev)))

    {

        SAFE_RELEASE(m_pD3D);

        AfxMessageBox( DXGetErrorDescription9(hr));

        return false;

    }

    return true;

}

上面的代码几乎和SDK文档中Tutorial里面的一模一样,可是我的程序每次到CreateDeviceFail掉了,郁闷了半天也找不到原因,运行SDK中的例子程序却好好的,后来再SDK中看到这么一句话:

This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window.

考!我一看晕倒,还有这么bt的限制啊,我就把Init代码移到了View的父窗口CMainFrameOnCreate函数中,再创建View之后紧接着Init

if( !m_wndView.Create(…))

g_render.Init(m_wnd.GetSafeHwnd());

这样总行了吧,考,运行之后还是错误!我又把上面改成

    g_render.Init(this->GetSafeHwnd());

就是把CMainFrame的句柄传入,结果成功运行了,整个窗口被按照期望涂成了黑色,只是顺便把工具条什么的都一块涂掉了,呵呵。

想了半天,不知道什么原因,为什么CMainFrame可以,而且是在其WM_CREATE处理函数中出入句柄的,这个还是是SDK所禁止的。会不会和窗口的初始大小有关呢?我注意到m_wndView的创建函数是把其设成CRect(0,0,0,0)的,把它改成:

    if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,  CRect(0, 0,100, 100), this, AFX_IDW_PANE_FIRST, NULL))

ft,一运行居然OK了~将 Init放回ViewOnCreate处理函数中,也顺利运行了。

看来SDK里面写的东东也不能全信,应该改成:

    Direct3D9 创建Device时依赖的窗口初始大小不能为0

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 myfaq.com.cn All rights reserved. www.myfaq.com.cn 版权所有