# Thread: DrawIndexedPrimitive() Failing (DX9)

1. ## 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)))
{...}

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.

2. Code:
```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);
}```
However, I'm getting a crash on the DrawIndexedPrimitive() line again.

I added a safeguard:
Code:
```for(Z = 0; Z < (NumRows-1); Z = Z + 1)
{
for(X = 0; X < (NumCols-1); X = X + 1)
{
if((I + 5) >= NumIndices)
{
free(Indices);
Indices = NULL;
return false;
}

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;
}```
In the blue. A "false" return quits the program. And it doesn't quit. So I know I'm not overwriting any memory I shouldn't. So, I'm back to the problem. Any clues out there as to why that line could bomb like that?

3. I'm a moron:
Code:
`NumIndices  = NumPolygons * 3;`
Is what it should be. I added a "- 1" to the end of it cause the mouse in my room told me to. It works now. Not rendering as hoped, but rendering.

See, sometimes you just gotta talk the problem out to yourself.

4. Why not use D3DXCreateTextureFromFile()? and use the IDirect3DTexture9 interface created in the call to access the texture? You are using Windows API which I don't recommend.

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).
Also I'm not sure what "isn't with a reason" means?
The function DrawIndexedPrimitive is described in the SDK if the w/o reason means you are not sure what's going on in the function.

Also that sounds like a lot of indices if this is for one object. If this is for your entire scene then kudos to you for sticking it all in one buffer. This is something I'm still trying to sort out myself.

5. I'll just say it right now, sorry for another lengthy post

The "isn't for a reason" was me jumping to conclusions about what was actually going wrong in my program without actually knowing

I'll try and explain the program again...

The Bitmap that I'm loading in isn't a texture for my quad here, it's a representation of heights. If you look below, the first picture represent my "Terrain Map". By this, dark squares represent lower altitudes. So RGB(0, 0, 0) is the lowest point possible, while RGB(255, 255, 255) will be the highest point possible. Therefore, each pixel's position in the Terrain Map represents the X, Z coordinate of the vertex, while the colour represents the Y value.

With a lot of searching, I came up with:
Code:
```...
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)))
{
DeleteObject(TerrainFile);
return false;
}

BITMAPINFO TerrainInfo;

TerrainInfo.bmiColors->rgbRed		= NULL;
TerrainInfo.bmiColors->rgbGreen		= NULL;
TerrainInfo.bmiColors->rgbBlue		= NULL;
TerrainInfo.bmiColors->rgbReserved	= NULL;

unsigned long *Pixels = NULL;

Pixels = (unsigned long*)malloc(TerrainInfo.bmiHeader.biHeight * TerrainInfo.bmiHeader.biWidth * sizeof(unsigned long));
if(Pixels == NULL)
{
DeleteObject(TerrainFile);
return false;
}
...```
To open a Bitmap file, and load each Pixel's colour into my array. Currently I'm working with a smaller bitmap for the sake of rendering (38 by 38 pixels = 38 by 38 vertices). You can see that "Map" in the second picture.

Now, the code above for my Index Buffer is working correctly (as far as I can tell) as in wireframe, I'm getting a successful rendering of a grid. Regardless of the Bitmap loaded, the pattern will always be the same for the Index Buffer, which is why I like it so much (it's a slightly edited version of AndyPike's algorithm to match my style) You can see the flatly rendered grid in the third picture. (Perhaps slightly tough to see).

The code to initialize the vertex buffer is:
Code:
```...
sVertex *Terrain; //Private Member of my Class
...
Terrain = (sVertex*)malloc(NumVertices * sizeof(sVertex));

unsigned long Colour;
unsigned long I = 0;

for(int ZPos = 0; ZPos < NumRows; ZPos = ZPos + 1)
{
for(int XPos = 0; XPos < NumCols; XPos = XPos + 1)
{
Colour = Pixels[I];
//The X,Z is just based off the Pixel's position on the bitmap
Terrain[I].X		= (float)(XPos * 1.0f);
Terrain[I].Y		= (float)0.0f; //No Height
Terrain[I].Z		= (float)(ZPos * 1.0f);
Terrain[(ZPos * NumCols) + XPos].colour	= 0xFFFFFFFF;
//Terrain[(ZPos * NumCols) + XPos].colour	= Colour;

I = I + 1;
}
}

unsigned char *Vertices;

if(FAILED(VertexBuffer->Lock(0, NumVertices * sizeof(sVertex), (void**)&Vertices, 0)))
{
...
}
else
{
memcpy(Vertices, Terrain, NumVertices * sizeof(sVertex));
VertexBuffer->Unlock();
}

free(Terrain);
Terrain = NULL;
...```
So, in the code above, I'm using the colour 0xFFFFFFFF while ignoring the actual extracted Bitmap pixels (I'm not that far in yet).

My next step was to, instead of using the 0xFFFFFFFF colour, to use the extracted Bitmap colour, by switching to the commented line:
//Terrain[(ZPos * NumCols) + XPos].colour = Colour;
Technically, what I should get in the end, is my "Terrain Map" Bitmap displayed on the screen (since the vertices match colours). I want to get this working before I start interpreting heights.

However, I get what is rendered in my last attached picture. Not the hoped for result. And that's where I am now, trying to find a solution to that.

Why not use D3DXCreateTextureFromFile()?
Are you saying I can load my Bitmap in with that (well, I know THAT'S doable), but after that, I can extract individual Pixel information from the texture file? Cause if that's what you're saying, that would be swell, and I'll drop the Windows API like a hot, heavy brick.

It's just that when I did all my searching, this was the method I found on extracting pixel information from a bitmap.

6. Yes.

I've used heightmaps quite extensively so I completely understand what you are trying to do.

D3DXCreateTextureFromFile() will create an IDirect3DTexture9 interface pointer for you and return it back to you. Then using that interface you can gain access to IDirect3DSurface9 (or something like that) and then from there you can lock the surface and access it just like you would any other bitmap - either in linear fashion (a little like old 320x200x256 VGA mode) or in 2D using u and v. Your choice.

Try it and see what you come up with. So far I've not used any color bitmaps for heightmaps in my code. What I do is create a 32-bit color map for the terrain and a 256 color greyscale map for the heights. The heightmaps are stored as RAW files with a proprietary header that holds important information pertinent to the engine using the file. The RAW file is loaded using C's I/O library of functions and the bitmap is loaded using my own scaled-down BMP loader. The API has too much crapola to support when it comes to BMPs and most BMPs, if not all by today's standards, can be loaded with a simple BMP loader. The code for a very simple BMP loader can be found at www.brackeen.com - if the guy's site is still up.

I would recommend using 256 color greyscales for your heightmaps. It is cool to attempt to store both color and height in the same file, however it creates more problems than it alleviates.

Just my opinion.

On a side note I've come acrossed a very cool spheres algorithm which generates some very nice terrains - far better than I've ever achieved with the recursive subdivision method(s). Here is one example with texture and fog. There is normal information for each triangle in the terrain, but I've yet to enable the lighting system.

7. And here it is in wireframe so you can see more of the underlying structure.

I do apologize for the complete lack of efficiency displayed here. This is a brute force rendering algorithm.

8. Bubba, thanks alot for the point in the right direction. I've been busy at school for a while, so I haven't gotten to work on this too much. I am getting there though. I like the idea of the RAW file format.

I'll post again when I have something a bit more meaningful. But I just wanted to say thanks.

9. Okay, I've made some progress.

The task I'm working on now is to create a convertor for any BMP file into RAW format (Since I like drawing in MS Paint and learning something new never hurts). I believe I'm pretty close.

To do this, I've opened the BMP file in Binary mode, and found that the pixel information starts after the first 54 bytes. After searching this board (and wotsit.org), I realized that it was the BITMAPFILEHEADER and BITMAPINFOHEADER that take up those 54 bytes.

So, currently I've read in both headers, and then the pixel information.

Now, the buffer for my pixels is of the type unsigned long. My array is dynamically created, and each element represents one Pixel's colour.

I've tried approach after approach to extracting the RGB values from my array. A few include:

Code:
```printf("%d ", (Buffer[I] & 0x00FF0000)); //RED
printf("%d ", (Buffer[I] & 0x0000FF00)); //GREEN
printf("%d ", (Buffer[I] & 0x000000FF)); //BLUE

printf("%d ", (Buffer[I] & 0xFFFF0000)); //RED
printf("%d ", (Buffer[I] & 0xFF00FF00)); //GREEN
printf("%d ", (Buffer[I] & 0xFF0000FF)); //BLUE

printf("%d ", (Buffer[I] & /*Insert Decimal Counterpart Here*/)); //RED
printf("%d ", (Buffer[I] & /*Insert Decimal Counterpart Here*/)); //GREEN
printf("%d ", (Buffer[I] & /*Insert Decimal Counterpart Here*/)); //BLUE```
I've also tried Bitshifting with any appropriate numbers I could think of/read about on these boards.

Still, nothing is getting me the correct outputs. If anybody could lend some idea, I would really appreciate this.

Incase you're wondering, my Pixel Reading function is:
Code:
```unsigned long * CompletePixels(BITMAPINFOHEADER *BitmapInfoHeader, FILE *BinaryIFile)
{
unsigned long *Buffer = (unsigned long *)malloc(BitmapInfoHeader->biSizeImage);

printf("\nReceiving Image Data: ");

if(feof(BinaryIFile) == false)
{
printf("Failed\n");
free(Buffer);
Buffer = NULL;
}
else
{
printf("Succeeded\n");
fclose(BinaryIFile);
BinaryIFile = NULL;
}

return Buffer;
}```
Thanks for any comments

10. The solution to this is actually simpler than you might think.

Since an RGB quad is really RGBX in a BMP file you can do this:

Code:
```struct RGBA
{
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
};```
Now the reason I wrote my own BMP loader is because I thought it was assinine the way MS did it with BitmapInfoHeader and all that crap.

So I put all of the info into one header called BMP. www.brackeen.com has the full BMP header in case you are interested. Now read from the file into the header - the following code is assuming you have a valid file handle.

Code:
```BMP MyHeader;

RGBA *Image=new RGBA[dwImageSize];

if (Image)
{
} else return;

_close(handle);```
Now to access the red green blues simply do:

Code:
```unsigned char red=Image[offset].red;
unsigned char green=Image[offset].green;
unsigned char blue=Image[offset].blue;
unsigned char alpha=Image[offset].alpha;```

This eases the pain of doing all the bitmasking. The reading and loading times should be identical since in theory RGBA is exactly the same size as a DWORD - so you are really just breaking the DWORD up into smaller parts by using a structure instead of an unsigned long or DWORD.

This also makes bi linear interpolation and linear interpolations much easier.

Note that even if you have a RAW format you can still use the RGBA/RGBX structure to load the data. The only diff between the two is that in RGBX the fourth component is discarded and in RGBA it is used as alpha. In your case you could store the actual height data in the alpha channel since the heights in a greyscale image will always fall in range 0 to 255 or 00h to FFh.

So your structure might look like this if you want to store all info in the same file.

Code:
```struct RGBH
{
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char height;
};```
Now you can use PaintShop or PhotoShop or DirectX Texture Tool to create the heightmap, greyscale it, and use it as the alpha channel for the picture.

www.flipcode.com has a very good tutorial on how to blend terrain types using alpha values - you may want to do a search for it there.

Hope this helps.

11. Bubba, you've got this genius way of finding a one-step solution to any problem. I went with your RGBH struct approach (which makes sense to be now, but there's no way I would've thought of it myself), and it works alot better so far, however, I'm having a slight problem...

(I'll post the code/output and outline the problems below, feel free to skip the code for now)

Code:
```#define WIN_32_LEAN_AND_MEAN

#include <Stdlib.h>
#include <Stdio.h>
#include <IO.h>
#include <FCNTL.h>

{
unsigned short	Type;
unsigned long	Size;
unsigned short	Reserved1;
unsigned short	Reserved2;
unsigned long	OffBits;
unsigned long	RemainingSize;
unsigned long	Width;
unsigned long	Height;
unsigned short	Planes;
unsigned short	BitCount;
unsigned long	Compression;
unsigned long	SizeImage;
unsigned long	XPelsPerMeter;
unsigned long	YPelsPerMeter;
unsigned long	ClrUsed;
unsigned long	ClrImportant;
};

struct RGBH
{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char H;
};

void	DisplayPixels(CUSTOMBITMAPHEADER *BitmapHeader, RGBH *Buffer, FILE *Outstream);

int main(void)
{

char	iPath[250];
int	FileHandle	= 0;
RGBH	*Buffer		= NULL;

printf("Enter Input Path: ");
fscanf(stdin, "%s", iPath);
printf("\n");

printf("Opening File:\t");
FileHandle = _open(iPath, _O_TEXT|_O_RDONLY);

if(FileHandle != 0)
{
printf("Succeeded\n");

Buffer = CompletePixels(&BitmapHeader, FileHandle);

if(Buffer != NULL)
{
}
}
else
{
printf("Failed\n");
}

if(Buffer != NULL)
{
free(Buffer);
Buffer = NULL;
}

if(FileHandle != 0)
_close(FileHandle);

printf("\n\n");
return 0;
}

{
}

{
RGBH *Buffer = (RGBH *)malloc(BitmapHeader->SizeImage);

printf("\nReceiving Image Data: ");

if(_eof(FileHandle) == false)
{
printf("Failed\n");
free(Buffer);
Buffer = NULL;
}
else
{
printf("Succeeded\n");
_close(FileHandle);
}

return Buffer;
}

{
fprintf(Outstream, "\n\n");
fprintf(Outstream, "\n\n");
}

void DisplayPixels(CUSTOMBITMAPHEADER *BitmapHeader, RGBH *Buffer, FILE *Outstream)
{
fprintf(Outstream, "Pixel Information:\n");
int I = 0;
for(unsigned int Y = 0; Y < BitmapHeader->Height; Y++)
{
for(unsigned int X = 0; X < BitmapHeader->Width; X++)
{
printf("%ld %ld %ld %ld | ", Buffer[I].R, Buffer[I].G, Buffer[I].B, Buffer[I].H);
I++;
}
printf("\n");
}
}```
With output:
Enter Input Path: c:\2.bmp

Opening File: Succeeded
Requesting: 16 Bytes

Receiving Image Data: Succeeded

Type: 19778
Size: 70
Reserved1: 0
Reserved2: 0
OffBits: 54
Size: 40
Width: 2
Height: 2
Planes: 1
BitCount: 24
Compression: 0
SizeImage: 16
XPelsPerMeter: 0
YPelsPerMeter: 0
ClrUsed: 0
ClrImportant: 0

Pixel Information:
192 192 192 192 | 192 192 0 0 |
192 192 192 192 | 192 192 0 0 |

Press any key to continue
Note: I'm using a 2x2 Bitmap with all RGB(192, 192, 192) pixels.

Firstly, I tried to use a single _read():
However, that gave me some pretty crazy results when it came to displaying the header information. It seems it must be read in variable by variable. Have you gotten your Bitmap Loader working with just _read() line?

I found that _read() and fread() are both accomplishing the same thing, under Binary or just standard ASCII mode.

Using the RGBH struct however HAS significantly improved my output.

This may or may not be a good time to mention I'm using a 24-Bit BMP, could some of the problems be arising from this do you think?

12. Try this:

Code:
```#pragma pack(1)
struct RGBH
{
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char height;
}

struct BMP
{
....
....
};

#pragma```
I think your byte alignment is off which is causing the read to fail. The read just reads bytes - fread is not all that much different - in fact none of the approaches are that much different. Whether you choose to use C I/O or C++ I/O (ala streams) - either way you are basically doing the same thing.

If the byte alignment is off it will cause portions of the DWORDs to be stored in the wrong places - essentially the data is all jumbled up.

Try the pragma pack and see what you get.

If that doesn't work I'll post my loader here.

13. Hey Bubba

I threw the two pragmas in around my structure definitions:
Code:
```#pragma pack(1)

{
unsigned short	Type;
unsigned long	Size;
unsigned short	Reserved1;
unsigned short	Reserved2;
unsigned long	OffBits;
unsigned long	RemainingSize;
unsigned long	Width;
unsigned long	Height;
unsigned short	Planes;
unsigned short	BitCount;
unsigned long	Compression;
unsigned long	SizeImage;
unsigned long	XPelsPerMeter;
unsigned long	YPelsPerMeter;
unsigned long	ClrUsed;
unsigned long	ClrImportant;
};

struct RGBH
{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char H;
};

#pragma```
But I am still getting the same output. Just out of curiosity, what were the pragmas supposed to do? Specify the correct size of a byte? Or similar idea? (I'm shootin' in the dark here)

I did however, come across something that may or may not make sense...

I opened up the Bitmap file with Textpad (image attached), and lo and behold, it is displaying it in the same way as my program. The "C0"s and "00"s match to my display.

Perhaps this IS actually being read in correctly? And I'm just parsing the info incorrectly?

I was thinking that it may be of the form (for, let's say a 2x2 Bitmap, R = Red, G = Green, B = Blue, A = Alpha):
R G B R G B A A R G B R G B A A
Where the Alpha's are stored at the end of each row...

However, when I opened up a larger Bitmap (16x16) I only got "C0"s all the way through the whole file (With Textpad, once the pixel information section starts), and with my program, I get:
Enter Input Path: c:\16.bmp

Opening File: Succeeded
Requesting: 768 Bytes

Receiving Image Data: Succeeded

Type: 19778
Size: 822
Reserved1: 0
Reserved2: 0
OffBits: 54
Size: 40
Width: 16
Height: 16
Planes: 1
BitCount: 24
Compression: 0
SizeImage: 768
XPelsPerMeter: 0
YPelsPerMeter: 0
ClrUsed: 0
ClrImportant: 0

Pixel Information:
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192
192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192
| 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 192 192 192 | 192 19
2 192 192 | 192 192 192 192 | 192 192 192 192 |
253 253 253 253 | 0 0 0 0 | 49 3 0 0 | 65 0 0 0 | 64 29 67 0 | 104 73 50 0 | 200
77 66 0 | 121 0 0 0 | 18 0 0 0 | 2 0 0 0 | 40 0 0 0 | 253 253 253 253 | 95 77 8
3 68 | 69 86 95 66 | 76 68 95 69 | 78 86 95 61 |
49 0 253 253 | 253 253 0 0 | 65 0 0 0 | 161 1 0 0 | 224 30 67 0 | 0 29 67 0 | 20
0 77 66 0 | 121 0 0 0 | 102 1 0 0 | 2 0 0 0 | 39 0 0 0 | 253 253 253 253 | 95 65
67 80 | 95 80 65 84 | 72 61 67 58 | 92 80 114 111 |
103 114 97 109 | 32 70 105 108 | 101 115 92 77 | 105 99 114 111 | 115 111 102 11
6 | 32 68 105 114 | 101 99 116 88 | 32 57 46 48 | 32 83 68 75 | 32 40 79 99 | 11
6 111 98 101 | 114 32 50 48 | 48 52 41 92 | 85 116 105 108 | 105 116 105 101 | 1
15 59 67 58 |
92 80 114 111 | 103 114 97 109 | 32 70 105 108 | 101 115 92 77 | 105 99 114 111
| 115 111 102 116 | 32 86 105 115 | 117 97 108 32 | 83 116 117 100 | 105 111 92
67 | 111 109 109 111 | 110 92 77 83 | 68 101 118 57 | 56 92 66 105 | 110 59 67 5
8 | 92 80 114 111 |
As you can see, it just falls apart towards the end there.

I'm going to keep on trying to figure this out, but right now I just need some sleep. Thanks for the ideas so far though, if you get anymore, I'm always happy to hear them. If I figure anything out, I'll post an update.

14. It should be noted that BMP files are 0 padded to the nearest 4 byte boundary. This means each scanline of pixels is padded and that if your bitmap width is not a factor of 4, your image won't be read into the array correctly and thus it won't be displayed correctly.

To account for this I use a simple modulo operation - or I just ensure when I make the bmp that it's width is a factor of 4.

I suggest attempting to display the bmp on your screen. If it looks garbled, then this is your problem.

15. It's all making sense now

You're right about the padding, however, I don't think there's an Alpha channel. I've been using a 2x2 bitmap until now:
192 192 192 192 | 192 192 0 0 |
192 192 192 192 | 192 192 0 0 |
From above.

Which is making sense for the padding:
R G B R | G B PAD PAD |
R G B R | G B PAD PAD |
Where the PADs are the 0s, and you get the lovely Width multiple of 4 thing.

I switched to a 4x4 bitmap, with R = 100, G = 150, and B = 200, and got the output:
Opening File: Succeeded
File Status: Valid
Creating Pixels: Succeeded

| 200 150 100 | 200 150 100 | 200 150 100 | 200 150 100
| 200 150 100 | 200 150 100 | 200 150 100 | 200 150 100
| 200 150 100 | 200 150 100 | 200 150 100 | 200 150 100
| 200 150 100 | 200 150 100 | 200 150 100 | 200 150 100
Press any key to continue
Integer then Hex printed out

And the larger images aren't going haywire near the end.

Here is the sourcecode for my current loader:
Code:
```#include <Stdlib.h>
#include <Stdio.h>

#define INPUT_PATH "C:\\4.bmp"

{
unsigned short	Type;
unsigned long	Size;
unsigned short	Reserved1;
unsigned short	Reserved2;
unsigned long	OffBits;
unsigned long	RemainingSize;
unsigned long	Width;
unsigned long	Height;
unsigned short	Planes;
unsigned short	BitCount;
unsigned long	Compression;
unsigned long	SizeImage;
unsigned long	XPelsPerMeter;
unsigned long	YPelsPerMeter;
unsigned long	ClrUsed;
unsigned long	ClrImportant;
};

int main(void)
{
unsigned char *Pixels = NULL;

FILE *InputFile = NULL;
unsigned long	FileSize = 0;

printf("Opening File: ");
InputFile = fopen(INPUT_PATH, "rb");
if(InputFile == NULL)
{
printf("Failed\n");
}
else
{
printf("Succeeded\n");

fseek(InputFile, 0, SEEK_END);
FileSize = ftell(InputFile);
rewind(InputFile);

printf("File Status: ");
{
printf("Invalid\n");
}
else
{
printf("Valid\n");

printf("Creating Pixels: ");
Pixels = (unsigned char *)malloc(CustomBitmapHeader.SizeImage);
if(Pixels == NULL)
{
printf("Failed\n");
}
else
{
printf("Succeeded\n");

fread(&(Pixels[0]), sizeof(Pixels[0]), 1, InputFile);
for(int I = 0; feof(InputFile) == false; I++)
{
if(I % (CustomBitmapHeader.Width * 3) == 0)
printf("\n");

if(I % 3 == 0)
printf("| ");

printf("%d ", Pixels[I]);
fread(&(Pixels[I+1]), sizeof(Pixels[I+1]), 1, InputFile);
}
printf("\n");
}
}
}

if(Pixels != NULL)
{
free(Pixels);
Pixels = NULL;
}

if(InputFile != NULL)
{
fclose(InputFile);
InputFile = NULL;
}

return 0;
}

{
}```
Which I believe is working correctly now, and I will move to implementing it in my Terrain Program and hopefully get some nice Terrain's in there.

I would guess that my 24-Bit BMP is the reason for not having an Alpha Channel? 8 Red, 8 Green, 8 Blue?

Popular pages Recent additions