
Originally Posted by
RonHiler
Well, it took a lot more effort than I would have thought, but the movie portion of the AVI player is now working, which is a giant step forward for Milestone 1.
Let me tell you guys, I HATE working with the GDI in general and bitmap files in particular. They are aggravating in the extreme. The functions that open and initialize the AVI files are pretty straightforward. Once you calculate the frame you need and pull it out of the file, it dumps it as a BITMAP field in a memory buffer. You then have to figure out a way to get that bitmap onto a D3D surface. This is where the trouble begins. If the functions you needed to call made any logical sense, this would be possible. However they are completely random and mysterious. In order to do this, you have to:
1) AVITexture->Graphic->GetSurfaceLevel(0, &Surface);
That gets the surface of the texture. It's a D3D call, so it makes perfect sense to me.
2) Surface->GetDC(&SurfaceDC);
That gets something called a Device Context for the D3D surface. No one is really sure what a DC is for, but apparently it is required for access to the GDI functions on a D3D surface.
3) BitmapDC = CreateCompatibleDC(SurfaceDC);
This is the bitmap. Or actually, where the bitmap will go. Or, actually, the DC for where the bitmap will go. Again, no one knows what a DC is, but now we have one, and apparently it is compatable with our D3D DC.
4) HandleBitmap = CreateDIBSection(BitmapDC, lpbi, DIB_RGB_COLORS, (LPVOID*)&BitmapColorInfo, NULL, 0);
NOW we have a place to put our bitmap. There is nothing there yet, mind you, but we have a place for it.
5) memcpy(BitmapColorInfo, ImageData, lpbi->bmiHeader.biSizeImage);
And this copies the data that was dumped to the buffer from the AVI file over to a brand new buffer that we just created. What's the difference? Why could we not simply have used the original buffer in the first place?The new buffer has our D3D compatable DC (which again, no one really knows what that is), and we also have a handle to this buffer which we didn't have before. Why do we need a handle? Who knows! I certainly don't. But goddammit, we have one! (to paraphrase my favorite comedian Lewis Black)
6) OldObject = SelectObject(BitmapDC, HandleBitmap);
It's not enough that we have a mysterious handle and DC to our recently moved buffer, now we need to select it. Select it for what? The bowling team? Beats the hell out of me.
7) BitBlt(SurfaceDC, 0, 0, lpbi->bmiHeader.biWidth, lpbi->bmiHeader.biHeight, BitmapDC, 0, 0, SRCCOPY);
This is the part that does the actual copying from our recently moved buffer onto our D3D surface. The reason I used this function is because the bitmap and the D3D surface may not be compatable in terms of how they hold the color data. BitBlt does those conversions for us, which is a big relief (because, for one thing, I don't even know what the format of the D3D surface is, it depends on the particular video card in the user's machine. For another, the bitmap format is also variable, depending on how the AVI is set up, so writing a lot of conversion routines would be a nightmare).
Then there is a lot of cleanup crap that no one cares about involving deselecting the object we just got finished selecting and releasing all those DCs and surfaces and stuff.
And after all that, the texture is FINALLY ready to be displayed.
I didn't mean to turn this into a rant. I just really HATE bitmaps and dealing with the GDI in any form. Anyway, it's pretty cool to see the movie play when you run the program. Now I just have to get the sound working. The logo avi doesn't have sound, so I picked up a short avi that does just for testing purposes so I can at least get the sound ready for when the logo movie actually does have a sound track (or any of the other movies we might add later on).