游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3124|回复: 0

请教一下关于DX9程序的“未将对象引用设置到对象的实例

[复制链接]

9

主题

26

帖子

62

积分

注册会员

Rank: 2

积分
62
发表于 2012-8-2 21:01:00 | 显示全部楼层 |阅读模式
我自己写了一个CModeD3D的类(主要就是对ID3DXMesh的封装),里面主要涉及到顶点、索引缓冲区的填充,邻接数组的优化,子集的创建和顶点法线的生成。这个类单独使用创建一个模型的时候没有问题,但是被其他的类组合着来使用的时候就出现问题了,问题就出在所有与邻接数组有关的操作中,比如GenerateAdjacency、OptimizeInplace和D3DXComputeNormals,总要因为空的引用而中断,不知道为什么,单独使用的时候没有问题,被组合着用就出现问题了,但我就是找不出什么地方出现了空的引用,如果是代码问题那单独使用的时候应该也要报错才对。
我把这个类贴出来,希望高手能帮我解决一下,小弟是在不知道什么地方出错了。

头文件:
#ifndef MODE_H
#define MODE_H

#include <d3dx9.h>
#include <vector>
using std::vector;

class CModeD3D
{
private:
        struct SModeMatTex
        {
                D3DMATERIAL9 m_material;
                IDirect3DTexture9* m_pTexture;
        };
private:
        IDirect3DDevice9*         m_pDevice;
        vector<SModeMatTex*> m_vMatTex;
        ID3DXMesh*        m_pMesh;
        DWORD                m_dwFVF;

        ID3DXBuffer* m_pAdjacency;
        ID3DXBuffer* m_pMaterial;
        int                         m_nMatNum;

public:
        CModeD3D(IDirect3DDevice9* pDevice)
                :m_pDevice(pDevice),m_dwFVF(NULL),m_pMesh(NULL),m_pAdjacency(NULL),m_pMaterial(NULL),m_nMatNum(0)
        {};
        ~CModeD3D();
        void InitMode(DWORD, void*, int, DWORD, DWORD, DWORD=D3DXMESH_MANAGED);
        void InitMode(DWORD, void*, int, void*, int, DWORD, DWORD, DWORD=D3DXMESH_MANAGED);
        void InitMode(DWORD, DWORD, DWORD, DWORD=D3DXMESH_MANAGED);
        void InitVertex(void*, int);
        void InitIndex(void*, int);

        void AddSubset(D3DMATERIAL9, TCHAR*, int, int);
        void AddSubset(D3DMATERIAL9, TCHAR*, int*, int);

        void LoadMode(TCHAR*, DWORD=D3DXMESH_MANAGED);
        void OptimizeMesh(DWORD=D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_COMPACT|D3DXMESHOPT_VERTEXCACHE);
        void CreateNormal(bool=false);
        ID3DXMesh* GetMesh(){ return m_pMesh; };

        void DrawVertex();
        void DrawIndex();
        void DrawSubset();
};

#endif


实现文件:
#include "mode.h"

CModeD3D::~CModeD3D()
{
        int nCount = m_vMatTex.size();
        for (int i=0; i<nCount; i++) delete m_vMatTex;
}

void CModeD3D::InitMode(DWORD dwFVF, void* pData, int nBytes, DWORD dwFaceNum, DWORD dwVertexNum, DWORD dwOption)
{
        m_dwFVF = dwFVF;
        if (m_pMesh!=NULL) m_pMesh->Release();
        D3DXCreateMeshFVF(dwFaceNum, dwVertexNum, dwOption, m_dwFVF, m_pDevice, &m_pMesh);

        void* pBuffer;
        m_pMesh->LockVertexBuffer(0, &pBuffer);
        memcpy(pBuffer, pData, nBytes);
        m_pMesh->UnlockVertexBuffer();
}

void CModeD3D::InitMode(DWORD dwFVF, void* pVertex, int nVertexBytes, void* pIndex, int nIndexBytes,
                                                DWORD dwFaceNum, DWORD dwVertexNum, DWORD dwOption)
{
        m_dwFVF = dwFVF;
        if (m_pMesh!=NULL) m_pMesh->Release();
        D3DXCreateMeshFVF(dwFaceNum, dwVertexNum, dwOption, m_dwFVF, m_pDevice, &m_pMesh);

        void* pBuffer;
        m_pMesh->LockVertexBuffer(0, &pBuffer);
        memcpy(pBuffer, pVertex, nVertexBytes);
        m_pMesh->UnlockVertexBuffer();

        m_pMesh->LockIndexBuffer(0, &pBuffer);
        memcpy(pBuffer, pIndex, nIndexBytes);
        m_pMesh->UnlockIndexBuffer();
}

void CModeD3D::InitMode(DWORD dwFVF, DWORD dwFaceNum, DWORD dwVertexNum, DWORD dwOption)
{
        m_dwFVF = dwFVF;
        if (m_pMesh!=NULL) m_pMesh->Release();
        D3DXCreateMeshFVF(dwFaceNum, dwVertexNum, dwOption, m_dwFVF, m_pDevice, &m_pMesh);
}

void CModeD3D::InitVertex(void* pVertex, int nBytes)
{
        void* pBuffer;
        m_pMesh->LockVertexBuffer(0, &pBuffer);
        memcpy(pBuffer, pVertex, nBytes);
        m_pMesh->UnlockVertexBuffer();
}

void CModeD3D::InitIndex(void* pIndex, int nBytes)
{
        void* pBuffer;
        m_pMesh->LockIndexBuffer(0, &pBuffer);
        memcpy(pBuffer, pIndex, nBytes);
        m_pMesh->UnlockIndexBuffer();
}

void CModeD3D::AddSubset(D3DMATERIAL9 material, TCHAR* szPath, int nStart, int nEnd)
{
        SModeMatTex* pMT = new SModeMatTex;
        pMT->m_material = material;
        if (szPath==NULL) pMT->m_pTexture=NULL;
        else D3DXCreateTextureFromFile(m_pDevice, szPath, &pMT->m_pTexture);

        DWORD* pAttrib = new DWORD[m_pMesh->GetNumFaces()];
        m_pMesh->LockAttributeBuffer(0, &pAttrib);
        int nSubsetID = m_vMatTex.size();
        for (int i=nStart; i<=nEnd; i++) pAttrib=nSubsetID;
        m_pMesh->UnlockAttributeBuffer();

        m_vMatTex.push_back(pMT);
}

void CModeD3D::AddSubset(D3DMATERIAL9 material, TCHAR* szPath, int* pIndex, int nSize)
{
        SModeMatTex* pMT = new SModeMatTex;
        pMT->m_material = material;
        if (szPath==NULL) pMT->m_pTexture=NULL;
        else D3DXCreateTextureFromFile(m_pDevice, szPath, &pMT->m_pTexture);

        DWORD* pAttrib = new DWORD[m_pMesh->GetNumFaces()];
        m_pMesh->LockAttributeBuffer(0, &pAttrib);
        int nSubsetID = m_vMatTex.size();
        for (int i=0; i<nSize; i++) pAttrib[pIndex]=nSubsetID;
        m_pMesh->UnlockAttributeBuffer();

        m_vMatTex.push_back(pMT);
}

void CModeD3D:oadMode(TCHAR* szPath, DWORD dwOption)
{
        if (m_pAdjacency!=NULL) m_pAdjacency->Release();
        if (m_pMaterial!=NULL) m_pMaterial->Release();
        if (m_pMesh!=NULL) m_pMesh->Release();
        D3DXLoadMeshFromX(szPath, dwOption, m_pDevice, &m_pAdjacency, &m_pMaterial, 0, (DWORD*)&m_nMatNum, &m_pMesh);

        if (m_pMaterial==NULL || m_nMatNum==0) return;

        D3DXMATERIAL* pMaterial = (D3DXMATERIAL*)m_pMaterial->GetBufferPointer();
        for (int i=0; i<m_nMatNum; i++)
        {
                SModeMatTex* pMT = new SModeMatTex;
                pMaterial.MatD3D.Ambient = (D3DXCOLOR)pMaterial.MatD3D.Diffuse*0.4f;
                pMT->m_material = pMaterial.MatD3D;
                if (pMaterial.pTextureFilename==NULL) pMT->m_pTexture=NULL;
                else D3DXCreateTextureFromFile(m_pDevice, pMaterial.pTextureFilename, &pMT->m_pTexture);
                m_vMatTex.push_back(pMT);
        }
}

void CModeD3D::OptimizeMesh(DWORD dwOption)
{
        if (m_pAdjacency!=NULL) m_pAdjacency->Release();
        D3DXCreateBuffer(3*m_pMesh->GetNumFaces()*sizeof(DWORD), &m_pAdjacency);
        m_pMesh->GenerateAdjacency(0, (DWORD*)m_pAdjacency->GetBufferPointer());   // 主要就在这个地方出错

        m_pMesh->OptimizeInplace(dwOption, (DWORD*)m_pAdjacency->GetBufferPointer(), 0, 0, 0);  // 如果上面的被注释掉了那这里就出错

        m_pAdjacency->Release();
        D3DXCreateBuffer(3*m_pMesh->GetNumFaces()*sizeof(DWORD), &m_pAdjacency);
        m_pMesh->GenerateAdjacency(0, (DWORD*)m_pAdjacency->GetBufferPointer()); // 如果上面两个都被注释掉了那这里就报错
}

void CModeD3D::CreateNormal(bool bAdj)
{
        if (!(m_pMesh->GetFVF() & D3DFVF_NORMAL))
        {
                ID3DXMesh* pTmpMesh = 0;
                m_pMesh->CloneMeshFVF(D3DXMESH_MANAGED, m_pMesh->GetFVF()|D3DFVF_NORMAL, m_pDevice, &pTmpMesh);

                if(bAdj) D3DXComputeNormals(pTmpMesh, (DWORD*)m_pAdjacency->GetBufferPointer());
                else         D3DXComputeNormals(pTmpMesh, 0);

                m_pMesh->Release();
                m_pMesh = pTmpMesh;
        }
        else
        {
                if(bAdj) D3DXComputeNormals(m_pMesh, (DWORD*)m_pAdjacency->GetBufferPointer());
                else         D3DXComputeNormals(m_pMesh, 0);
        }
} // 如果直接不用OptimizeMesh方法那就直接在这里中断

void CModeD3D:rawVertex()
{
        IDirect3DVertexBuffer9* pVB = 0;
        m_pMesh->GetVertexBuffer(&pVB);
        m_pDevice->SetStreamSource(0, pVB, 0, D3DXGetFVFVertexSize(m_dwFVF));
        m_pDevice->SetFVF(m_dwFVF);
       
        m_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_pMesh->GetNumFaces());
}

void CModeD3D::DrawIndex()
{
        int nCount = m_vMatTex.size();
        for (int i=0; i<nCount; i++) m_pMesh->DrawSubset(i);
}

void CModeD3D::DrawSubset()
{
        int nCount = m_vMatTex.size();
        for (int i=0; i<nCount; i++)
        {
                m_pDevice->SetMaterial(&m_vMatTex->m_material);
                m_pDevice->SetTexture(0, m_vMatTex->m_pTexture);
                m_pMesh->DrawSubset(i);
        }
}


PS:请大大们帮帮忙,小弟感激不尽!!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-10 03:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表