zoukankan      html  css  js  c++  java
  • DirectX中利用COM的特性避免重复加载一个纹理

    在DirectX的Mesh文件中,通常一个纹理可能作被几个材质共用。这是因为顶点是以属性分组的,只要材质和纹理不一样,就需要使用不同的属性。 而在一般的建模软件中,纹理常常被当成材质的一部分,导出时每个“材质”都有自己的纹理,这样做也是因为有时Mesh在不同的部分尽管使用相同的纹理,但是有不同的光照特性。DirectX的Mesh也是按照同样的方式组织材质,纹理和网格。
            DirectX提供的案例中,每个材质都分别加载一个纹理,可是,调试程序的时候,你会发现,有时只有几个纹理的物体,加载上来,有十几个材质,这样显然会有纹理被反复加载,那么我们可以使用COM的参照计数来避免这个问题。
            在加载一个材质对应纹理之前,先找一下前面的纹理有没有同名的,如果有,就把那个纹理的指针拷贝到这个材质对应的纹理指针,同时给这个被拷贝指针的纹理加上一个参考。那么以后释放它的时候就不用担心前面一个是否已经被释放了。
            COM是参照计数的,当增加一个参考时,计数器加1,释放一次时,计数器减1,如果计数器减到0,就把它从内存中释放掉。如果是使用了智能的指针,这个问题就更简单了,直接拷贝就可以了:

    m_pMeshTextures[i]=m_pMeshTextures[j];

         
    在DirectX的类型声明中可以看到,LPDIRECT3DTEXTURE9并不是一个智能指针:

    typedef struct IDirect3DTexture9 *LPDIRECT3DTEXTURE9, *PDIRECT3DTEXTURE9;

    所以在拷贝指针后要给这个COM对象的参考加1

    m_pMeshTextures[j]->AddRef();


         

        m_pMeshMaterials = new D3DMATERIAL9[m_dwNumOfMaterials];            //材质指针数组
        m_pMeshTextures  = new LPDIRECT3DTEXTURE9[m_dwNumOfMaterials];        //纹理指针数组
        
        
    for(DWORD i=0; i<m_dwNumOfMaterials; i++ )
        
    {
            m_pMeshMaterials[i] 
    = d3dxMaterials[i].MatD3D;                                //从缓冲区中拷贝材质
            m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;        //设置环境光属性
            m_pMeshTextures[i]  = NULL;                                                                  //初始成空
            
            
    //根据材质中的纹理文件名加载纹理
            DWORD j=0;
            
    while(j<i)
            
    {    //避免重复加载纹理
                if(0==strcmp(d3dxMaterials[j].pTextureFilename, d3dxMaterials[i].pTextureFilename)) //找到同名纹理的序号
                
    {
                    m_pMeshTextures[i]
    =m_pMeshTextures[j];  //直接拷贝指针而不是加载一次
                    m_pMeshTextures[j]
    ->AddRef();                     //参考加1
                    
    break;    
                }
    ;
                j
    ++;
            }


            
    if(! m_pMeshTextures[i])
            
    {
                D3DXCreateTextureFromFile( m_pDevice, 
                    d3dxMaterials[i].pTextureFilename, 
    &m_pMeshTextures[i] );
            }


        }


    在释放时,按照正常的方法释放就可以了

        for(DWORD i=0; i<m_dwNumOfMaterials; i++ )
        
    {
            SAFE_RELEASE(m_pMeshTextures[i]);
        }

        SAFE_DELETE_ARRAY(m_pMeshTextures);
        SAFE_DELETE_ARRAY(m_pMeshMaterials);


  • 相关阅读:
    MongoDB查询语句 (增、删、改、查)
    MongoDB简单查询语句
    jquery Select Change事件
    c# 远程监控(4) 接收端 RTP包重组 分屏显示
    c# 远程监控(3) RTP协议 RTP.NET.DLL
    c# 远程监控(1) 大纲
    c# 远程监控(2) 摄像头调研及模拟
    TortoiseGit记住用户名和密码
    winform ListView和DataGridView实现分页
    制作符合平台的CodeSmith代码生产模版
  • 原文地址:https://www.cnblogs.com/Tue/p/245449.html
Copyright © 2011-2022 走看看