2012-12-27 24 views
0

我正在从此链接移植动画代码Loading An MD5 Model,它是线性代码,所以我转向了导向。ifstream w/directX上的堆损坏

问题是,当我读取整个模型(成功完成)时,调试器会在我的代码的另一部分(我加载另一个模型文件 - 静态模型)中指示错误。

stange部分是因为,当我尝试写入一个int或浮点变量的数字,如果我写入字符或字符串它不会导致任何错误导致堆损坏。

在几次测试中,我发现这个错误只出现在两个代码执行时,因为只有一个发生时,程序正常运行。

这里是代码:

负载MD5文件:(它的大)

bool AnimationModelClass::LoadMD5Model(ID3D10Device* device, wstring filename) 
{ 
    ifstream fin; 
    char input=' '; 
    string temp, temp2; 
    int i; 

    // Crear temp2 

    temp2.clear(); 

    // Open the model file. 
    fin.open(filename); 

    // If it could not open the file then exit. 
    if(fin.fail()) 
    { 
     return false; 
    } 

    // Look for MD5 Version 
    temp.clear(); 

    continue_after_string(fin, "MD5Version"); 

    // Store MD5 Version 
    fin >> MD5Model.version; 



    // Look for Command Line 
    temp.clear(); 

    continue_after_string(fin, "commandline"); 

    // Skip line 
    skip_lines(fin, 1); 



    // Look for the number of joints 
    temp.clear(); 

    continue_after_string(fin, "numJoints"); 

    // Store the number of meshes (subsets) 
    fin >> MD5Model.numJoints; 



    // Look for the number of joints 
    temp.clear(); 

    continue_after_string(fin, "numMeshes"); 

    // Store the number of joints 
    fin >> MD5Model.numSubsets; 



    // Look for the joints 
    temp.clear(); 

    continue_after_string(fin, "joints"); 

    continue_after_char(fin, '{'); 

    // Skip the rest of this line 
    skip_lines(fin, 1); 

    // - JOINTS - // 

    // Fill each joint information 
    Joint tempJoint; 

    for(i=0; i < MD5Model.numJoints; i++){ 

     // Jump to name 
     skip_chars(fin, 3, input); 

     temp.clear(); 

     // Find closing brackets 
     while(input!='"') 
     { 
     temp+=input; 
     fin.get(input); 

     } 

     // Store tempJoint name 
     tempJoint.name = temp; 

     // Storte parent ID 
     fin >> tempJoint.parentID; 

     // Find the positions of this joint 
     continue_after_char(fin, '('); 

     // Store the positions 
     fin >> tempJoint.pos.x >> tempJoint.pos.z >> tempJoint.pos.y; 

     // Find the orientation of this joint 
     continue_after_char(fin, ')'); 
     continue_after_char(fin, '('); 

     // Store orientation 
     fin >> tempJoint.orientation.x >> tempJoint.orientation.z >> tempJoint.orientation.y; 

     // Compute the w axis of the quaternion (The MD5 model uses a 3D vector to describe the 
     // direction the bone is facing. However, we need to turn this into a quaternion, and the way 
     // quaternions work, is the xyz values describe the axis of rotation, while the w is a value 
     // between 0 and 1 which describes the angle of rotation) 
     float t = 1.0f - (tempJoint.orientation.x * tempJoint.orientation.x) - (tempJoint.orientation.y * tempJoint.orientation.y) - (tempJoint.orientation.z * tempJoint.orientation.z); 
     if (t < 0.0f) 
     { 
      tempJoint.orientation.w = 0.0f; 
     } 
     else 
     { 
      tempJoint.orientation.w = -sqrtf(t); 
     } 

     // Skip the rest of this line 
     skip_lines(fin, 1); 

     // Store the joint into this models joint vector 
     MD5Model.joints.push_back(tempJoint); 

    } 

    // Skip "}" 
    continue_after_char(fin, '}'); 

    // Find meshes 
    continue_after_string(fin, "mesh"); 

    // Skip "{" 
    continue_after_char(fin, '{'); 

    temp.clear(); 

    // Variables to fill model subsets 
    ModelSubset subset; 
    int numVerts, numTris, numWeights; 

    // End of file controller 
    bool eof = false; 
    int gg=0; 

    // Read until EOF 
    while(!eof){ 


     // Clear the temp string 
     temp.clear(); 

     // Read until "}" 

     while(temp!= "}"){ 

     if(!get_string(fin, temp)){ 

      // Break if we cant read anymore 
      eof = true; 
      break; 
     } 

      // Case we found shader 
      if(temp == "shader"){ 

      // Store it 
      get_string(fin, subset.fileNamePath); 

      // Skip the rest of this line 
      skip_lines(fin, 1); 

      // CHECAR SE A TEXTURA FOI CARREGADA E CARREGA-LA SE NECESSÁRIO 
      } 

      // Case we found tex vertices 
      else if(temp == "numverts"){ 

      // Store the number of tex vertices 
      fin >> numVerts;  

      // Skip the rest of this line 
      skip_lines(fin, 1); 

      // Store stuff for each tex vertice 
      for(int i = 0; i < numVerts; i++) 
       { 

        Vertex tempVert; 

        // Skip "vert # (" 
        continue_after_char(fin, '('); 

        fin >> tempVert.texCoord.x; 
        fin >> tempVert.texCoord.y; 

        // Skip ")" 
        continue_after_char(fin, ')'); 

        fin >> tempVert.StartWeight; 
        fin >> tempVert.WeightCount; 

        // Skip the rest of this line 
        skip_lines(fin, 1); 

        // Push back this vertex into subsets vertex vector 
        subset.vertices.push_back(tempVert);   
       } 


      } 

      // Case we found the triangles 
      else if(temp == "numtris"){ 

      // Store the number of triangles 
      fin >> numTris; 
      subset.numTriangles = numTris; 

      // Skip the rest of this line 
      skip_lines(fin, 1); 

      // Save stuff for each triangle 
      for(int i = 0; i < numTris; i++) 
       { 
        DWORD tempIndex; 

        // Skip "tri" 
        get_string(fin, temp); 

        // Skip tri counter 
        get_string(fin, temp); 

        // Store the 3 indices 
        for(int k = 0; k < 3; k++)     
         { 
          fin >> tempIndex; 
          subset.indices.push_back(tempIndex); 
         } 

        // Skip the rest of this line 
        skip_lines(fin, 1); 
       } 


      } 

      // Case we found the weights 
      else if(temp == "numweights"){ 

      // Store the number of weights 
      fin >> numWeights; 

      // Skip the rest of this line 
      skip_lines(fin, 1); 

      // Save stuff for each weight 
      for(int i = 0; i < numWeights; i++) 
       { 
        Weight tempWeight; 

        // Skip "weight" 
        get_string(fin, temp); 

        // Skip "#" 
        get_string(fin, temp); 

        // Store weight's joint ID 
        fin >> tempWeight.jointID;  

        // Store weight's influence over a vertex 
        fin >> tempWeight.bias; 

        // Skip "(" 
        continue_after_char(fin, '('); 

        // Store weight's pos in joint's local space 
        fin >> tempWeight.pos.x >> tempWeight.pos.z >> tempWeight.pos.y; 

        // Skip the rest of this line 
        skip_lines(fin, 1); 

        // Push back tempWeight into subsets Weight array 
        subset.weights.push_back(tempWeight); 
       } 


      } 
     } 

       //*** find each vertex's position using the joints and weights 
       for (int i = 0; i < subset.vertices.size(); ++i) 
       { 
        Vertex tempVert = subset.vertices[i]; 
        tempVert.pos = D3DXVECTOR3(0, 0, 0); // Make sure the vertex's pos is cleared first 

        // Sum up the joints and weights information to get vertex's position 
        for (int j = 0; j < tempVert.WeightCount; ++j) 
        { 
         Weight tempWeight = subset.weights[tempVert.StartWeight + j]; 
         Joint tempJoint = MD5Model.joints[tempWeight.jointID]; 

         // Convert joint orientation and weight pos to vectors for easier computation 
         // When converting a 3d vector to a quaternion, you should put 0 for "w", and 
         // When converting a quaternion to a 3d vector, you can just ignore the "w" 
         D3DXQUATERNION tempJointOrientation = D3DXQUATERNION(tempJoint.orientation.x, tempJoint.orientation.y, tempJoint.orientation.z, tempJoint.orientation.w); 
         D3DXQUATERNION tempWeightPos = D3DXQUATERNION(tempWeight.pos.x, tempWeight.pos.y, tempWeight.pos.z, 0.0f); 

         // We will need to use the conjugate of the joint orientation quaternion 
         // To get the conjugate of a quaternion, all you have to do is inverse the x, y, and z 
         D3DXQUATERNION tempJointOrientationConjugate = D3DXQUATERNION(-tempJoint.orientation.x, -tempJoint.orientation.y, -tempJoint.orientation.z, tempJoint.orientation.w); 

         // Calculate vertex position (in joint space, eg. rotate the point around (0,0,0)) for this weight using the joint orientation quaternion and its conjugate 
         // We can rotate a point using a quaternion with the equation "rotatedPoint = quaternion * point * quaternionConjugate" 
         D3DXVECTOR3 rotatedPoint; 
         D3DXQUATERNION temp; 

         D3DXQuaternionMultiply(&temp, &tempJointOrientation, &tempWeightPos); 
         D3DXQuaternionMultiply(&temp, &temp, &tempJointOrientationConjugate); 

         rotatedPoint.x = temp.x; 
         rotatedPoint.y = temp.y; 
         rotatedPoint.z = temp.z; 

         // Now move the verices position from joint space (0,0,0) to the joints position in world space, taking the weights bias into account 
         // The weight bias is used because multiple weights might have an effect on the vertices final position. Each weight is attached to one joint. 
         tempVert.pos.x += (tempJoint.pos.x + rotatedPoint.x) * tempWeight.bias; 
         tempVert.pos.y += (tempJoint.pos.y + rotatedPoint.y) * tempWeight.bias; 
         tempVert.pos.z += (tempJoint.pos.z + rotatedPoint.z) * tempWeight.bias; 

         // Basically what has happened above, is we have taken the weights position relative to the joints position 
         // we then rotate the weights position (so that the weight is actually being rotated around (0, 0, 0) in world space) using 
         // the quaternion describing the joints rotation. We have stored this rotated point in rotatedPoint, which we then add to 
         // the joints position (because we rotated the weight's position around (0,0,0) in world space, and now need to translate it 
         // so that it appears to have been rotated around the joints position). Finally we multiply the answer with the weights bias, 
         // or how much control the weight has over the final vertices position. All weight's bias effecting a single vertex's position 
         // must add up to 1. 
        } 

        subset.positions.push_back(tempVert.pos);   // Store the vertices position in the position vector instead of straight into the vertex vector 
        // since we can use the positions vector for certain things like collision detection or picking 
        // without having to work with the entire vertex structure. 
       } 

       // Put the positions into the vertices for this subset 
       for(int i = 0; i < subset.vertices.size(); i++) 
       { 
        subset.vertices[i].pos = subset.positions[i]; 
       } 

       //*** Calculate vertex normals using normal averaging 
       vector<D3DXVECTOR3> tempNormal; 

       //normalized and unnormalized normals 
       D3DXVECTOR3 unnormalized = D3DXVECTOR3(0.0f, 0.0f, 0.0f); 

       //Used to get vectors (sides) from the position of the verts 
       float vecX, vecY, vecZ; 

       //Two edges of our triangle 
       D3DXQUATERNION edge1 = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); 
       D3DXQUATERNION edge2 = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); 

       //Compute face normals 
       for(int i = 0; i < subset.numTriangles; ++i) 
       { 
        //Get the vector describing one edge of our triangle (edge 0,2) 
        vecX = subset.vertices[subset.indices[(i*3)]].pos.x - subset.vertices[subset.indices[(i*3)+2]].pos.x; 
        vecY = subset.vertices[subset.indices[(i*3)]].pos.y - subset.vertices[subset.indices[(i*3)+2]].pos.y; 
        vecZ = subset.vertices[subset.indices[(i*3)]].pos.z - subset.vertices[subset.indices[(i*3)+2]].pos.z;  
        edge1 = D3DXQUATERNION(vecX, vecY, vecZ, 0.0f); //Create our first edge 

        //Get the vector describing another edge of our triangle (edge 2,1) 
        vecX = subset.vertices[subset.indices[(i*3)+2]].pos.x - subset.vertices[subset.indices[(i*3)+1]].pos.x; 
        vecY = subset.vertices[subset.indices[(i*3)+2]].pos.y - subset.vertices[subset.indices[(i*3)+1]].pos.y; 
        vecZ = subset.vertices[subset.indices[(i*3)+2]].pos.z - subset.vertices[subset.indices[(i*3)+1]].pos.z;  
        edge2 = D3DXQUATERNION(vecX, vecY, vecZ, 0.0f); //Create our second edge 

        //Cross multiply the two edge vectors to get the un-normalized face normal 
        unnormalized.x = (edge1.y * edge2.z) - (edge1.z * edge2.y); 
        unnormalized.y = (edge1.z * edge2.x) - (edge1.x * edge2.z); 
        unnormalized.z = (edge1.x * edge2.y) - (edge1.y * edge2.x); 

        tempNormal.push_back(unnormalized); 
       } 

       //Compute vertex normals (normal Averaging) 
       D3DXQUATERNION normalSum = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); 
       int facesUsing = 0; 
       float tX, tY, tZ; //temp axis variables 

       //Go through each vertex 
       for(int i = 0; i < subset.vertices.size(); ++i) 
       { 
        //Check which triangles use this vertex 
        for(int j = 0; j < subset.numTriangles; ++j) 
        { 
         if(subset.indices[j*3] == i || 
          subset.indices[(j*3)+1] == i || 
          subset.indices[(j*3)+2] == i) 
         { 
          tX = normalSum.x + tempNormal[j].x; 
          tY = normalSum.y + tempNormal[j].y; 
          tZ = normalSum.z + tempNormal[j].z; 

          normalSum = D3DXQUATERNION(tX, tY, tZ, 0.0f); //If a face is using the vertex, add the unormalized face normal to the normalSum 

          facesUsing++; 
         } 
        } 

        //Get the actual normal by dividing the normalSum by the number of faces sharing the vertex 
        normalSum = normalSum/facesUsing; 

        //Normalize the normalSum vector 
        D3DXVECTOR3 temp; 
        temp.x = normalSum.x; 
        temp.y = normalSum.y; 
        temp.z = normalSum.z; 

        D3DXVec3Normalize(&temp, &temp); 

        //Store the normal and tangent in our current vertex 
        subset.vertices[i].normal.x = -temp.x; 
        subset.vertices[i].normal.y = -temp.y; 
        subset.vertices[i].normal.z = -temp.z; 

        //Clear normalSum, facesUsing for next vertex 
        normalSum = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); 
        facesUsing = 0; 
       } 

       // Create index buffer 
       D3D10_BUFFER_DESC indexBufferDesc; 
       ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc)); 

       indexBufferDesc.Usage = D3D10_USAGE_DEFAULT; 
       indexBufferDesc.ByteWidth = sizeof(DWORD) * subset.numTriangles * 3; 
       indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER; 
       indexBufferDesc.CPUAccessFlags = 0; 
       indexBufferDesc.MiscFlags = 0; 

       D3D10_SUBRESOURCE_DATA iinitData; 

       iinitData.pSysMem = &subset.indices[0]; 
       device->CreateBuffer(&indexBufferDesc, &iinitData, &subset.indexBuff); 

       //Create Vertex Buffer 
       D3D10_BUFFER_DESC vertexBufferDesc; 
       ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); 

       vertexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;       // We will be updating this buffer, so we must set as dynamic 
       vertexBufferDesc.ByteWidth = sizeof(Vertex) * subset.vertices.size(); 
       vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER; 
       vertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;    // Give CPU power to write to buffer 
       vertexBufferDesc.MiscFlags = 0; 

       D3D10_SUBRESOURCE_DATA vertexBufferData; 

       ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); 
       vertexBufferData.pSysMem = &subset.vertices[0]; 

       HRESULT hr; 

       hr = device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &subset.vertBuff); 

       // Push back the temp subset into the models subset vector 
       MD5Model.subsets.push_back(subset); 

     if(eof == true){ 
      break; 
     } 


    i=i; 

     } 

    fin.clear(); 
    fin.close(); 


    return true; 
} 

而且这里的另一个代码:(HEAP问题就在这里!)

bool ModelClass::LoadModel(char* filename) 
{ 
    ifstream fin; 
    char input; 
    int i; 


    // Open the model file. 
    fin.open(filename); 

    // If it could not open the file then exit. 
    if(fin.fail()) 
    { 
     return false; 
    } 

    // Read up to the value of vertex count. 
    fin.get(input); 
    while(input != ':') 
    { 
     fin.get(input); 
    } 

    // Read in the vertex count. 
    fin >> m_vertexCount; 

    // Set the number of indices to be the same as the vertex count. 
    m_indexCount = m_vertexCount; 

    // Create the model using the vertex count that was read in. 
    m_model = new ModelType[m_vertexCount]; 
    if(!m_model) 
    { 
     return false; 
    } 

    // Read up to the beginning of the data. 
    fin.get(input); 
    while(input != ':') 
    { 
     fin.get(input); 
    } 
    fin.get(input); 
    fin.get(input); 

    // Read in the vertex data. 
    for(i=0; i<m_vertexCount; i++) 
    { 

      ///////////// HERE IS THE PROBLEM!! ////////////// 

     fin >> m_model[i].x >> m_model[i].y >> m_model[i].z; 
     fin >> m_model[i].tu >> m_model[i].tv; 
     fin >> m_model[i].nx >> m_model[i].ny >> m_model[i].nz; 
    } 

    // Close the model file. 
    fin.close(); 

    return true; 
} 

我测试配售断点和问题在那里(上面)。

如果我这样做:

// Read in the vertex data. 
for(i=0; i<m_vertexCount; i++) 
{ 
      char a; 

    fin >> a; 
} 

它的工作原理......但我不知道为什么,如果我这样做:

// Read in the vertex data. 
for(i=0; i<m_vertexCount; i++) 
{ 
      float f; // or int, but float is what I want 

    fin >> f; 
} 

爆炸,堆损坏!

如上所述,两个代码都能够正确分离。

对不起,我的英语不好。

如果有人能帮助辩论,因为这很讨厌我...:d


数据:如果我切换顺序都工作(这些代码),无堆损坏occours

回答

0

我发现我的问题在“AnimationModelClass”的声明的原因是:我意识到我没有使用变量“textureNamePath”,并决定将其删除

class AnimationModelClass 
{ 
private: 

    struct Vertex //Overloaded Vertex Structure 
    { 
    Vertex(){} 
    Vertex(float x, float y, float z, 
    float u, float v, 
    float nx, float ny, float nz, 
    float tx, float ty, float tz) 
    : pos(x,y,z), texCoord(u, v), normal(nx, ny, nz), 
    tangent(tx, ty, tz){} 

    D3DXVECTOR3 pos; 
    D3DXVECTOR2 texCoord; 
    D3DXVECTOR3 normal; 
    D3DXVECTOR3 tangent; 
    D3DXVECTOR3 biTangent; 

    int StartWeight; 
    int WeightCount; 

    }; 

    struct Joint 
    { 
     string name; 
     int parentID; 

     D3DXVECTOR3 pos; 
     D3DXVECTOR4 orientation; 
    }; 

    struct Weight 
    { 
     int jointID; 
     float bias; 
     D3DXVECTOR3 pos; 
    }; 

    struct ModelSubset 
    { 
     int texArrayIndex; 
     int numTriangles; 
     int numVertices; 
     int numWeights; 
     string fileNamePath; 

     Vertex* m_vertices; 
     DWORD* m_indices; 
     Weight* m_weights; 

     D3DXVECTOR3* m_positions; 

     ID3D10Buffer* vertBuff; 
     ID3D10Buffer* indexBuff; 
    }; 

    struct Model3D 
    { 
     int version; 
     int numSubsets; 
     int numJoints; 

     Joint* m_joints; 
     ModelSubset* m_subsets; 
    }; 

private: 

    wstring textureNamePath; 

public: 

    AnimationModelClass(); 
    AnimationModelClass(const AnimationModelClass&); 
    ~AnimationModelClass(); 

    bool Initialize(ID3D10Device*); 
    bool LoadModel(ID3D10Device*, wstring); 
    bool render(ID3D10Device*); 

private: 

    bool LoadMD5Model(ID3D10Device*, wstring); 

private: 

    D3DXMATRIX* m_smilesWorld; 
    Model3D* MD5Model; 

    ID3D10Device* m_device; 

}; 

,那么一切都开始工作。

我不知道为什么会发生这种情况,但它已经解决了!