Run-Time Check Failure #2 - Stack around the varia

2019-08-06 04:22发布

well I think I know what the problem is. I am just having a hard time debugging it. I am working with the directx api and I am trying to generate a plane along the x and z axis according to a book I have. The problem is when I am creating my indices. I think I am setting values out of the bounds of the indices array. I am just having a hard time figuring out what I did wrong. I am unfamiliar with the this method of generating a plane. so its a little difficult for me. below is my code. Take emphasis on the indices loop.

[edit] Ive been reviewing it. This is how the indices works

 int curVertex = x + (z * NUM_VERTSX);

This always gets the beginning vertices. so say we have 17 vertices on the x axis and 17 vertices on the z axis and we are on the first loop of the x and z axis

curVertx = 0 + (0 * 17) curVertx = 0 + 0 = 0

say we are on the first loop of the z axis and second loop of the x axis

curVertx = 1 + (0 * 17) curVertx = 1+ 0 = 1

indices[curIndex] = curVertex;
            indices[curIndex + 1] = curVertex + NUM_VERTSX;
            indices[curIndex + 2] = curVertex + 1;

            indices[curIndex + 3] = curVertex + 1;
            indices[curIndex + 4] = curVertex + NUM_VERTSX;
            indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

if we are on the first

loop indices[curIndex] = curVertex;

this equals the first vertex = 0.

indices[curIndex + 1] = curVertex + NUM_VERTSX;

this equals the second row vertices (its always the vertices below the starting vertices

x x x x

[x] x x x

#include "MyGame.h"
//#include "CubeVector.h"
/* This code sets a projection and shows a turning cube. What has been added is the project, rotation and
a rasterizer to change the rasterization of the cube. The issue that was going on was something with the effect file
which was causing the vertices not to be rendered correctly.*/
typedef struct 
{
    ID3D10Effect* pEffect;
    ID3D10EffectTechnique* pTechnique;

    //vertex information
    ID3D10Buffer* pVertexBuffer;
    ID3D10Buffer* pIndicesBuffer;
    ID3D10InputLayout* pVertexLayout;

    UINT numVertices;
    UINT numIndices;
}ModelObject;

ModelObject modelObject;
// World Matrix
D3DXMATRIX                  WorldMatrix;
// View Matrix
D3DXMATRIX                  ViewMatrix;
// Projection Matrix
D3DXMATRIX                  ProjectionMatrix;
ID3D10EffectMatrixVariable* pProjectionMatrixVariable = NULL;

//grid information
#define NUM_COLS 16
#define NUM_ROWS 16

#define CELL_WIDTH 32
#define CELL_HEIGHT 32

#define NUM_VERTSX (NUM_COLS + 1)
#define NUM_VERTSY (NUM_ROWS + 1)




bool MyGame::InitDirect3D()
{
    if(!DX3dApp::InitDirect3D())
    {
        return false;
    }

    D3D10_RASTERIZER_DESC rastDesc;
    rastDesc.FillMode = D3D10_FILL_WIREFRAME;
    rastDesc.CullMode = D3D10_CULL_FRONT;
    rastDesc.FrontCounterClockwise = true;
    rastDesc.DepthBias = false;
    rastDesc.DepthBiasClamp = 0;
    rastDesc.SlopeScaledDepthBias = 0;
    rastDesc.DepthClipEnable = false;
    rastDesc.ScissorEnable = false;
    rastDesc.MultisampleEnable = false;
    rastDesc.AntialiasedLineEnable = false;

    ID3D10RasterizerState *g_pRasterizerState;
    mpD3DDevice->CreateRasterizerState(&rastDesc, &g_pRasterizerState);
    mpD3DDevice->RSSetState(g_pRasterizerState);

    // Set up the World Matrix
    D3DXMatrixIdentity(&WorldMatrix);
    D3DXMatrixLookAtLH(&ViewMatrix, new D3DXVECTOR3(0.0f, 10.0f, -20.0f), new D3DXVECTOR3(0.0f, 0.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
    // Set up the projection matrix
    D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, (float)D3DX_PI * 0.5f, (float)mWidth/(float)mHeight, 0.1f, 100.0f);

    if(!CreateObject())
    {
        return false;
    }

    return true;
}

//These are actions that take place after the clearing of the buffer and before the present
void MyGame::GameDraw()
{

    static float rotationAngle = 0.0f;

    // create the rotation matrix using the rotation angle
    D3DXMatrixRotationY(&WorldMatrix, rotationAngle);
    rotationAngle += (float)D3DX_PI * 0.0f;

    // Set the input layout
    mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);

    // Set vertex buffer
    UINT stride = sizeof(VertexPos);
    UINT offset = 0;
    mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);
    mpD3DDevice->IASetIndexBuffer(modelObject.pIndicesBuffer, DXGI_FORMAT_R32_UINT, 0);

    // Set primitive topology
    mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Combine and send the final matrix to the shader
    D3DXMATRIX finalMatrix = (WorldMatrix * ViewMatrix * ProjectionMatrix);
    pProjectionMatrixVariable->SetMatrix((float*)&finalMatrix);


    // make sure modelObject is valid


    // Render a model object
    D3D10_TECHNIQUE_DESC techniqueDescription;
    modelObject.pTechnique->GetDesc(&techniqueDescription);

    // Loop through the technique passes
    for(UINT p=0; p < techniqueDescription.Passes; ++p)
    {
        modelObject.pTechnique->GetPassByIndex(p)->Apply(0);

        // draw the cube using all 36 vertices and 12 triangles
        mpD3DDevice->DrawIndexed(modelObject.numIndices,0,0);
    }
}

//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you 
//present data
void MyGame::Render()
{
    DX3dApp::Render();
}

bool MyGame::CreateObject()
{
    VertexPos vertices[NUM_VERTSX * NUM_VERTSY];
    for(int z=0; z < NUM_VERTSY; ++z)
    {
        for(int x = 0; x < NUM_VERTSX; ++x)
        {
            vertices[x + z * NUM_VERTSX].pos.x = (float)x * CELL_WIDTH;
            vertices[x + z * NUM_VERTSX].pos.z = (float)z * CELL_HEIGHT;

            vertices[x + z * NUM_VERTSX].pos.y = 0.0f;

            vertices[x + z * NUM_VERTSX].color = D3DXVECTOR4(1.0, 0.0f, 0.0f, 0.0f);
        }
    }

    DWORD indices[NUM_VERTSX * NUM_VERTSY];
    int curIndex = 0;

    for(int z=0; z < NUM_ROWS; ++z)
    {
        for(int x = 0; x < NUM_COLS; ++x)
        {
            int curVertex = x + (z * NUM_VERTSX);
            indices[curIndex] = curVertex;
            indices[curIndex + 1] = curVertex + NUM_VERTSX;
            indices[curIndex + 2] = curVertex + 1;

            indices[curIndex + 3] = curVertex + 1;
            indices[curIndex + 4] = curVertex + NUM_VERTSX;
            indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

            curIndex += 6;
        }
    }



    //Create Layout
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D10_INPUT_PER_VERTEX_DATA, 0}
    };

    UINT numElements = (sizeof(layout)/sizeof(layout[0]));
    modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);

    //Create buffer desc
    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth = sizeof(VertexPos) * modelObject.numVertices;
    bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA initData;
    initData.pSysMem = vertices;
    //Create the buffer

    HRESULT hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pVertexBuffer);
    if(FAILED(hr))
        return false;

    modelObject.numIndices = sizeof(indices)/sizeof(DWORD);

    bufferDesc.ByteWidth = sizeof(DWORD) * modelObject.numIndices;
    bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;

    initData.pSysMem = indices;

    hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pIndicesBuffer);
    if(FAILED(hr))
        return false;


    /////////////////////////////////////////////////////////////////////////////
    //Set up fx files
    LPCWSTR effectFilename = L"effect.fx";
    modelObject.pEffect = NULL;

     hr = D3DX10CreateEffectFromFile(effectFilename,
        NULL,
        NULL,
        "fx_4_0",
        D3D10_SHADER_ENABLE_STRICTNESS,
        0,
        mpD3DDevice,
        NULL,
        NULL,
        &modelObject.pEffect,
        NULL,
        NULL);

    if(FAILED(hr))
        return false;

    pProjectionMatrixVariable = modelObject.pEffect->GetVariableByName("Projection")->AsMatrix();
    //Dont sweat the technique. Get it!
    LPCSTR effectTechniqueName = "Render";

    modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
    if(modelObject.pTechnique == NULL)
        return false;


    //Create Vertex layout
    D3D10_PASS_DESC passDesc;
    modelObject.pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);

    hr = mpD3DDevice->CreateInputLayout(layout, numElements,
        passDesc.pIAInputSignature,
        passDesc.IAInputSignatureSize,
        &modelObject.pVertexLayout);
    if(FAILED(hr))
        return false;

    return true;
}

2条回答
Rolldiameter
2楼-- · 2019-08-06 04:48

Now let us take the code snippet in question (probable root cause)

Code

 DWORD indices[NUM_VERTSX * NUM_VERTSY];
int curIndex = 0;

for(int z=0; z < NUM_ROWS; ++z)
{
    for(int x = 0; x < NUM_COLS; ++x)
    {
        int curVertex = x + (z * NUM_VERTSX);
        indices[curIndex] = curVertex;
        indices[curIndex + 1] = curVertex + NUM_VERTSX;
        indices[curIndex + 2] = curVertex + 1;

        indices[curIndex + 3] = curVertex + 1;
        indices[curIndex + 4] = curVertex + NUM_VERTSX;
        indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;

        curIndex += 6;
    }
}

Analysis

  1. Here indices have max number of 'cells' = NUM_VERTX * NUM_VERTSY = (16 + 1) * (16+1) = 289. So there are 0...288 'cells'. During the boundary condition - there value of z = 15, x = 15. So curIndex would be 15 * 15 * 6 = 1350. This far exceeds allocated cells.

Suggestion

  1. Since three values determine the size of the target array, all three must be part of the allocation of the array. so if you use DWORD indices[NUM_VERTSX * NUM_VERTSY * UNIT_BLOCK], where UNIT_BLOCK = 6, it should work fine.

  2. Also instead of embedding magic number inside the code, you can use a const variable - it would help a great deal later (if you want to change the value of the index).

HTH

查看更多
forever°为你锁心
3楼-- · 2019-08-06 05:07

Your indices array contains 6 entries per 'cell' (since you're drawing two triangles for each), therefore it should be declared as

DWORD indices[NUM_ROWS * NUM_COLS * 6]

The error you get tells you, that you write outside the boundaries of indices, this is usually either a hint towards a wrong declaration (or a wrong index calculation).

查看更多
登录 后发表回答