Thread: DrawIndexedPrimitive() Failing (DX9)

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    361

    DrawIndexedPrimitive() Failing (DX9)

    EDIT: SOLVED
    But I posted the next part to the problem below. You can skip this post.

    The For Loops in the InitIndexBuffer() were going one too many rounds. (I.e. while: X < (NumCols -1), should have been the case). After writing it out on paper, it made sense.


    Hullo hullo, (again, if anybody's already read this)

    I'm getting some peculiar Index Buffer problems going on.

    First, I'll blatantly post my code (feel free to skip past it), and below I'll talk about/highlight the key points.

    Code:
    bool cTerrain::InitIndexBuffer(void)
    {
    	unsigned char	*BufferIndices	= NULL;
    	unsigned short	*Indices		= NULL;
    	
    	Indices = (unsigned short*)malloc(NumIndices * sizeof(unsigned short));
    	if(Indices == NULL)
    		return false;
    
    	unsigned short A = 0;
    	unsigned short B = A + 1;
    	unsigned short C = NumCols + 1;
    
    	unsigned short X = 0;
    	unsigned short Z = 0;
    	unsigned long I = 0; //<----This here, this is the guy
    
    	//AndyPike's altered idea to meet my own style
    	for(Z = 0; Z < NumRows; Z = Z + 1)
    	{
    		for(X = 0; X < NumCols; X = X + 1)
    		{
    			Indices[ I ]	= A;
    			Indices[I + 1]	= B;
    			Indices[I + 2]	= C;
    			Indices[I + 3]	= C + 1;
    			Indices[I + 4]	= C;
    			Indices[I + 5]	= B;
    
    			A = A + 1;
    			B = B + 1;
    			C = C + 1;
    			I = I + 6;
    		}
    		A = A + 2;
    		B = B + 2;
    		C = C + 2;
    	}
    
    	IndexBuffer->Lock(0, NumIndices * sizeof(unsigned short), (void**)&BufferIndices, 0);
    
    		memcpy(BufferIndices, Indices, NumIndices * sizeof(unsigned short));
    
    	IndexBuffer->Unlock();
    
    	free(Indices);
    	Indices = NULL;
    
    	return true;
    }
    
    void cTerrain::Draw(void)
    {
    	D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(sVertex));
    	D3DDevice->SetFVF(FVF);
    	D3DDevice->SetIndices(IndexBuffer);
    	D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, NumVertices, 0, NumPolygons);
    }
    
    bool cTerrain::LoadTerrainMap(char *FilePath, HWND *hWnd)
    {
    	//Just so you get an idea of what I'm doing, but the itallic part can be skipped
    	HBITMAP TerrainFile;
    
    	TerrainFile = (HBITMAP)LoadImage(0, FilePath, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
    	if(TerrainFile == NULL)
    		return false;
    
    	BITMAP TerrainMap;
    
    	if(!(GetObject(TerrainFile, sizeof(BITMAP), &TerrainMap)))
    	{...}
    
    	BITMAPINFO TerrainInfo;
    
    	/*FILL TerrainInfo HERE*/
    
    	unsigned long *Pixels = NULL;
    
    	Pixels = (unsigned long*)malloc(TerrainInfo.bmiHeader.biHeight * TerrainInfo.bmiHeader.biWidth * sizeof(unsigned long));
    	if(Pixels == NULL)
    	{...}
    
    	HDC hDC;
    
    	hDC = GetDC(*hWnd);
    	if(hDC == NULL)
    	{...}
    
    	if(!(GetDIBits(hDC, TerrainFile, 0, TerrainInfo.bmiHeader.biHeight, Pixels, &TerrainInfo, DIB_RGB_COLORS)))
    	{...}
    
    	NumCols = (short)TerrainInfo.bmiHeader.biWidth;
    	NumRows = (short)TerrainInfo.bmiHeader.biHeight;
    
    	NumVertices = NumCols * NumRows;
    	NumPolygons = (NumCols - 1) * (NumRows - 1) * 2;
    	NumIndices  = NumPolygons * 3;
    
    	...
    
    	if(FAILED(D3DDevice->CreateIndexBuffer(NumIndices * sizeof(unsigned short), D3DUSAGE_WRITEONLY,
    		D3DFMT_INDEX16, D3DPOOL_MANAGED, &IndexBuffer, NULL)))
    	{...}
    
    	if(InitIndexBuffer() == false)
    	{...}
    
    	...
    }
    The dots represent edited out code, for the sake of nobody going insane from all the useless code. I tried to keep it condensed to only the important parts.

    If you haven't guess it, I'm loading in a Bitmap and creating vertices based on that Bitmap.

    Okay, so here's the thing, it all comes down to the I variable in the InitIndexBuffer() function.

    I used to be an "unsigned short". However, I have 242406 Indeces. Which I wasn't realizing meant that I would wrap back around to 0 when it hit past 65535. Because of this wrapping, I would never fill in information at the very END of Indeces, therefore my IndexBuffer would be incomplete. This caused the program to crash on:
    D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, NumVertices, 0, NumPolygons); //Can be found in Render()
    (Much of this isn't with a reason, this is just what I've seen when trying to figure my problem out).

    When I realized it was wrapping back around, I changed the "unsigned short" to an "unsigned long". This caused my program to crash on the line:
    free(Indices); //Can be found in InitIndexBuffer()

    After thinking my computer was corrupted (I got something like "Block #43 Damaged" popping up in a MessageBox). For no reason, I changed the "unsigned long" back to "unsigned short". And my problem went away. But, back to the Render() crash.

    So, as it stood, my variable was wrapping around, and this wasn't acceptable (either was the crash).

    So, to test it out, I loaded in a different bitmap, one that would only require 8214 Indeces (definitely reachable by an unsigned short, without wrapping back to 0). The result was the return of my "Block #43 Damaged" error.

    So, my only guess here is that I'm not allocating enough space for my IndexBuffer and when I gets too high, it starts writing things to places it shouldn't. But that doesn't explain to me why the free() line is crashing.

    Perhaps if somebody could look over my allocations, check that I didn't miss anything? (I've double and triple-checked and I just can't find anything that could cause this. Hopefully a new set of eyes can.)

    If nothing else, thanks for reading (or scrolling down to the bottom of) this monstrous post.
    Last edited by Epo; 09-11-2005 at 07:47 PM.
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 09-23-2008, 03:32 AM
  2. pointer comparison failing
    By Bleech in forum C Programming
    Replies: 4
    Last Post: 08-11-2007, 06:33 PM
  3. CreateDevice failing
    By MadCow257 in forum Game Programming
    Replies: 6
    Last Post: 03-14-2006, 09:03 PM
  4. initializes all components of failing to false
    By romeoz in forum C++ Programming
    Replies: 21
    Last Post: 08-01-2003, 09:30 PM
  5. DX9 and Dev-C++
    By Ashes999 in forum Windows Programming
    Replies: 5
    Last Post: 06-10-2003, 12:19 AM