My most amazing error yet! [complicated]
Alright, so for school, we're working with direct x to create a 3D engine that will have heightmaps, cameras, animations, collision, etc...I've been working on it for four weeks now, and of that, over three weeks I've spent stumped without even heightmaps working. The reason for this completely evades me; my code is simply functioning in ways that do not make sense to me.
The initial problem was in my heightMap::init() function. The function takes a few values:
When in debug mode, all of those values were what I expected them to be (a valid pointer, CoastMountain64.raw, 64, 64, 10, 0.5).
bool heightMap::initHeightmap(IDirect3DDevice9 *nDevice, char *fname, int nNumVertsPerRow, int nNumVertsPerCol, int nCellSpacing, float nHeightScale)
However, when I tried to assign those values to members of my class, it would not work. For example:
would result in numVertsPerCol having a value of -1163005939 (copied directly from debug mode). All of the assignments in my init function have had similar results. In order to solve this, I had to use while loops, as follows:
numVertsPerCol = nNumVertsPerCol;
This solved the problem, but I think that somehow that made things worse. All of my assignments worked properly, but my heightmap was crashing my program. I traced it and found that in the computeInds() function, which was supposed to compute the indices, the class was erasing itself. Here's the code from the computeInds() function:
while(numVertsPerCol != nNumVertsPerCol) numVertsPerCol = nNumVertsPerCol;
initially, the class was erasing itself on the WORD* indices... line, but when I commented that line out, the next line erased the class, and if I commented the entire function out until the beggining of the first for loop, it would still erase the class.
HRESULT hr = 0;
hr = device->CreateIndexBuffer(numTriangles * 3 * sizeof(WORD), D3DUSAGE_WRITEONLY,D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib,NULL);
if(hr != D3D_OK) return false;
WORD *indices = new WORD[cellWidth * cellHeight - 1];
if(ib->Lock(0, 0, (void**)&indices, 0) != D3D_OK)
debugger::print("Could not lock index buffer.");
int pos = 0;
for(int i = 0; i < cellWidth; i++)
for(int j = 0; j < cellHeight; j++)
indices[pos] = i * vertsPerRow + j;
indices[pos+1]= i * vertsPerRow + j + 1;
indices[pos+2]= (i+1) * vertsPerRow + j;
indices[pos + 3]= (i+1)*vertsPerRow + j;
indices[pos + 4] = i * vertsPerRow + j + 1;
indices[pos + 5]= (i+1) * vertsPerRow + j + 1;
pos += 6;
}//for(int j = 0; j < cellHeight; j++)
}//for(int i = 0; i < cellWidth; i++)
Eventually, I stopped doing compute inds inside a function, and tried moving it into the init function, but when I did that, the class begin erasing itself on the screwed up while loops, and putting compute inds back into a function didn't fix this.
I gave up and began recoding my 3D engine again. However, I was encountering all the same problems as before, except that this time, the class didn't erase itself in the computeInds function, but in the function that reads a raw file. Frustrated, and worried that perhaps I was corrupting the stack as a friend had suggested, or that my direct x device was doing something silly I hadn't meant ot tell it to do, I ran teh code from the very first line in debug mode, tracing what happened with every line of code.
The only global variable declared before the WinMain function is a
which creates an instance of a game class (which is a class that holds the functionality for my entire application), although the default constructor is empty. The first Line of coding in WinMain is:
game* Glitch = new game();
Stepping into the game->init function, the first two lines create an instance of an inifilereader class that I wrote (it's very basic), and then attempt to open an ini file that controls the size of the window/filename/fullscreen mode. I know that the ini file class works, as I have used it in a previous project, and I had directly copied and pasted it without modifying it. However, in this iteration, it was broken. Here's the code for those lines:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
I entered the ini file load file function, which is as follows:
As you can see, I put the count = 0 in a while loop, because like in my heightmap::init function, unless I put it in the while loop, it was ending up being junk data, although in this case, it's a large positive number instead of a large negative number.
bool iniFileReader::loadFile(char* filename)
count = 0;
fopen_s(&theFile, filename, "r");
if(theFile == NULL)
fread(temp, 1, 1, theFile);
fileText = new char[count];
fread(fileText, 1, count, theFile);
initialised = true;
The interesting thing is that even with the while loop, count ends up being a large file name.
In addition, while running through the while loop, the value of 'filename' (the char* that I pass in) changes. Which makes no sense, as it is not referenced in any way. Additionally, the values it is changing to are not even values stored in the ini file - I do not know where they are comign from, but they seem to be fragments of something, probably code or another file.
Additionally, count++ is actually not incrementing count. Instead, it's giving count random values. The first few digits of count remain the same, but the last three change in values between 200-400.
At this point, I stopped debugging the application. So here's what I know:
1) I have not yet initialised a windows class or direct x, so that's not the problem.
2) the ini reader load file function is essentially the first thing to happen, and it's screwing up pretty badly.
3) I am very confused.
I have been working on this problem for almost four weeks now, and this includes talking with it about several friends who are also good at programming, asking for help from my roommate (who is in the same program), and sitting down with my teacher and trying to figure it out for almost an hour, to no avail.
Any help is greatly appreciated.
EDIT: Formatted code better