1

I'm creating a heightmap in DirectX11 and I'm getting an Access Violation Writing location when I assign the terrain height to be that that is in the bitmapInfoHeader.

bool HMTerrain::LoadHeightMap(char* filename)
{

FILE* filePtr;
int error;
unsigned int count;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bitmapInfoHeader;
int imageSize, i, j, k, index;
unsigned char* bitmapImage;
unsigned char height;

// Open the height map file in binary.
error = fopen_s(&filePtr, filename, "rb");

if (error != 0)
{
    return false;
}

// Read in the file header.
count = fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
if (count != 1)
{
    return false;
}

// Read in the bitmap info header.
count = fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
if (count != 1)
{
    return false;
}
// Save the dimensions of the terrain.
_pTerrainWidth = bitmapInfoHeader.biWidth;     // THIS IS THE BREAK
_pTerrainHeight = bitmapInfoHeader.biHeight;

// Calculate the size of the bitmap image data.
imageSize = _pTerrainWidth * _pTerrainHeight * 3;

// Allocate memory for the bitmap image data.
bitmapImage = new unsigned char[imageSize];
if (!bitmapImage)
{
    return false;
}

// Move to the beginning of the bitmap data.
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

// Read in the bitmap image data.
count = fread(bitmapImage, 1, imageSize, filePtr);
if (count != imageSize)
{
    return false;
}

// Close the file.
error = fclose(filePtr);
if (error != 0)
{
    return false;
}
// Create the structure to hold the height map data.
_pHeightMap = new HeightMapType[_pTerrainWidth * _pTerrainHeight];

if (!_pHeightMap)
{
    return false;
}

// Initialize the position in the image data buffer.
k = 0;

// Read the image data into the height map.
for (j = 0; j<_pTerrainHeight; j++)
{
    for (i = 0; i<_pTerrainWidth; i++)
    {
        height = bitmapImage[k];

        index = (_pTerrainHeight * j) + i;

        _pHeightMap[index].x = (float)i;
        _pHeightMap[index].y = (float)height;
        _pHeightMap[index].z = (float)j;

        k += 3;
    }
}
    // Release the bitmap image data.
    delete[] bitmapImage;
bitmapImage = 0;

return true;
}

///////////////////////// HEADER FILE /////////////////////////
class HMTerrain
{
private:
INT                         _pTerrainWidth, _pTerrainHeight;
int                         _pVertexCount, _pIndexCount;
ID3D11Buffer*       _pVertexBuffer, *_pIndexBuffer;

HeightMapType*  _pHeightMap;


bool                            LoadHeightMap(char*);
bool                            InitialiseBuffers(ID3D11Device*);

void                            NormalizeHeightMap();
void                            ShutdownHeightMap();
void                            ShutdownBuffers();
void                            RenderBuffers(ID3D11DeviceContext*);

public:
HMTerrain();
HMTerrain(const HMTerrain&);
~HMTerrain();

bool                            Initialise(ID3D11Device*, char*);

void                            Shutdown();
void                            Render(ID3D11DeviceContext*);

int                         GetIndexCount();
};

_pTerrainWidth is an int. While biWidth is a DirectX LONG. I believe that is the issue but when I change _pTerrainWidth to a DirectX LONG I still get the same violation error on the same line.

Any ideas would be much appreciated :-))

  • If `_pTerrainWidth` is an `int`, you shouldn't prefix it with `p` - it looks like it's a pointer. – xxbbcc Dec 03 '15 at 21:13
  • From the single line of code you included it's impossible to tell what's wrong. Have you tried debugging your code? – xxbbcc Dec 03 '15 at 21:15
  • 1
    Off topic: sticking underscores on the font of things can lead to unfortunate collisions with reserved terms. Read more here: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – user4581301 Dec 03 '15 at 21:18
  • 2
    Sounds like `_pTerrainWidth` was declared as a member of some object, and the line of code you quoted was inside a member function of that object **and** you called that member function using an uninitialized pointer to that object type. If I estimated any of that incorrectly, consider showing the relevant parts of your code that might prove me incorrect. – JSF Dec 03 '15 at 21:19
  • @xxbbcc I was told that's used for private variables - oops, I've tried debugging from a few lines before hand and it breaks at this line. biWidth actually equals the correct value. Just can't get passed this line. – Ryan Andrew Maverick Dec 03 '15 at 21:25
  • @JSF I'll edit the post for you two to have a look at see if it helps a bit :-)) – Ryan Andrew Maverick Dec 03 '15 at 21:25
  • So you posted enough to confirm parts of my guess: `_pTerrainWidth` is a member of `HMTerrain` and the failure occurs in a member function of `HMTerrain` at exactly the line that would fail if `LoadHeightMap` had been called with an uninitialized `HMTerrain*` But you didn't show anything about the call to `LoadHeightMap` despite my suggestion that the object used for that call is the problem. – JSF Dec 03 '15 at 22:03
  • For a beginner, I'm sure it seems absurd that the failure occurs that far into a member function when the actual bug is way back before the function was called and the function somehow got that far without even having an object to work on. But to an expert, all of that makes sense. If there were no actual object and the function was called for the thing pointed to by an uninitialized pointer, the failure would appear exactly as you described. – JSF Dec 03 '15 at 22:09
  • @JSF I can't tell what is supposed to be initialised. Should I just initialise all the variables? – Ryan Andrew Maverick Dec 03 '15 at 22:19
  • All the instance variables in the header are initialised anyway in the HMTerrain constructor. Just not the ints – Ryan Andrew Maverick Dec 03 '15 at 22:20
  • I'm not talking about any member of that object. I'm talking about the pointer to that type used by the code that calls that function. Until you post the call itself and the code leading up to it, I can only describe that generally, and you don't seem to understand. The problem is **not** in the class or function you posted. It is in the code that calls that function. – JSF Dec 03 '15 at 22:24
  • The LoadHeightMap function is called in another member function called Initialise. Which is called in an Application.cpp file. Application is where all the main DirectX stuff happens and all I'm passing through to Initialise is an instance of ID3D11Device and the filename for the heightmap. The filename is then being passed into the LoadHeightMap function outlined above.. Not sure where else it can go wrong. – Ryan Andrew Maverick Dec 03 '15 at 22:32
  • That sounds like the error is back in the Application.cpp file where initialize is called. But the error might be in initialize (if initialize was declared static). – JSF Dec 04 '15 at 06:13
  • I've not looked through all of your code but note that the bitmap header may have a negative `biHeight` to indicate a bottom-up image. When you debug, make sure that you check the height and use the absolute value if necessary. – Roger Rowland Dec 04 '15 at 11:08
  • Thank you guys. I sat down with my lecturer this afternoon, it turns out I wasn't instantiating the object itself, so it was trying to write to memory that hadn't been allocated. Sorry to waste your with such a rookie error haha – Ryan Andrew Maverick Dec 04 '15 at 18:40

0 Answers0