实时阴影绘制技术研究

C++博客 首页 新随笔 联系 聚合 管理
  48 Posts :: 20 Stories :: 57 Comments :: 0 Trackbacks
今天看了书中Basic2的例子,主要在两个方面:
  1. 如何将纹理映射到对象上;
  2. 如何使用框架提供的字体类。

为了贴一张2D纹理要做的事情:

  1. 在顶点结构中使用2个纹理坐标变量,并将其一起填充到顶点缓冲器中;
  2. 在InitDeviceObjects()函数中,使用D3DUtil_CreateTexture()创建纹理;
  3. 在Render()函数中,根据相应的状态使用SetTexture()设置纹理;
  4. 在DeleteDeviceObjects()中,使用SAFE_RELEASE()宏释放纹理。

纹理是一种设备相关的资源,因此要在InitDeviceObject()中创建。纹理经过了:创建->设置->释放,这样一个生存周期。

字体的使用相对比较简单,在应用程序类的构造函数里边创建字体类的对象,然后在对应的函数中调用字体类的函数就可以了。注意的是:在Render()里边调用的是DrawText(),其他都是同名函数。最后在析构函数中删除字体类对象。

下面来看一下代码。
  • 应用程序类的构造函数中创建字体类对象的代码:

m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );

  • InitDeviceObjects()函数

HRESULT CMyD3DApplication::InitDeviceObjects()
{
    m_pFont->InitDeviceObjects( m_pd3dDevice );//
字体的对应函数

    // 载入一张图片来创建纹理
    if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Lake.bmp"),
                                       &m_pBackgroundTexture) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    return S_OK;
}

  • RestoreDeviceObjects()函数基本没有变化,只是添加一个m_pFont->RestoreDeviceObjects();然后把带有纹理坐标的顶点数据拷贝到缓存中,注意纹理坐标全部位于[0,1]之间。
  • Render()函数

HRESULT CMyD3DApplication::Render()
{
    // Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
  // Set up texture stage states for the background
  m_pd3dDevice->SetTexture( 0, m_pBackgroundTexture );
//将纹理指定给设备的某个特定阶段,D3D提供8个纹理阶段,这意味着在一次DrawPrimitive()调用同时设置最多8张纹理;当然也可以多次调用DrawPrimitive(),称之为多遍绘制(multi-pass),SetTexture()的第一个参数就是希望使用的纹理阶段编号,可以为每个阶段指定一个纹理.但程序中指定了当前纹理,在改变之前所有的图元绘制都会采用该纹理,也就是说如果每个图元都有自己的纹理,那么在绘制之前都要设置其相应的纹理
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );//指定第一个参数是SetTexture()设置的纹理颜色
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );//
通过D3DTSS_COLOROP来选择一个颜色操作,D3DTOP_SELECTARG1告知纹理单元使用第一个参数作为输出。这两句的共同作用就是指定输出为所设置纹理的颜色。

//SetTextureStageState()可用于在不同的Materail之间对颜色和alpha做混合,可用于指定D3D纹理引擎和象素引擎的操作和参数。第一个参数给出要使用的纹理,即哪个阶段的问题,第2个参数是系统设置的纹理状态类型。有两种主要类型:D3DTSS_COLORx系列和D3DTSS_ALPHAx系列,分别控制一个RGB向量和一个Alpha标量在通过象素处理流水线中可并行处理部分的操作。

  // Passing an FVF to IDirect3DDevice9::SetFVF specifies a legacy FVF with stream 0.
     m_pd3dDevice->SetFVF(FVF );
  m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) );
     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );

        // Output statistics
        m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );//绘制帧率
        m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );//
绘制设备

      // End the scene.
      m_pd3dDevice->EndScene();
    }

    return S_OK;
}

  • 其他略过,凡是在对应函数中创建的记得在对应的销毁函数中干掉就行了。



转自:http://blog.sina.com.cn/u/40d00f17010001c3

posted on 2005-12-27 22:27 苦行僧 阅读(1085) 评论(2)  编辑 收藏 引用 所属分类: directX

Feedback

# re: 我的directX编程学习(3)-纹理映射与使用字体 2006-03-16 14:09 小银子
不错! 学习  回复  更多评论
  

# re: 我的directX编程学习(3)-纹理映射与使用字体 2006-06-18 00:48 cgdh
图太朦,看不清。  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理