/* ====================================================================== $Day: $ (003) $Date: $ $Creator: Emmanuel Vaccaro $ $Notice: (C)Copyright 2014 by Emmanuel Vaccaro. All Rights Reserved. $ ====================================================================== */ Hand made hero Day 003 – Allocating a Backbuffer Step 1). Set up Windows callbacks for Buffer allocation – First, we need to set up a few global variables: global_variable BITMAPINFO BitmapInfo; global_variable void *BitmapMemory; global_variable HBITMAP BitmapHandle; global_variable HDC BitmapDeviceContext; We will need to tell Windows what we want to write onto the buffer that we create. To do this, we need to set up the following code: internal void Win32ResizeDIBSection(int Width, int Height) { if (BitmapHandle) //<-- If BitmapHandle DOES exist { DeleteObject(BitmapHandle); } if (!BitmapDeviceContext) //<-- If BitmapDeviceContext does NOT exist (!) { BitmapDeviceContext = CreateCompatibleDC(0); } BitmapInfo.bmiHeader.biSize = sizeof(BitmapInfo.bmiHeader); //<-- Number of bytes required by ‘bmiHeader’ structure BitmapInfo.bmiHeader.biWidth = Width; //<-- Width of bitmap in pixels BitmapInfo.bmiHeader.biHeight = Height; //<-- Height of bitmap in pixels BitmapInfo.bmiHeader.biPlanes = 1; //<-- Number of planes for device BitmapInfo.bmiHeader.biBitCount = 32; //<-- Number of bits per pixel BitmapInfo.bmiHeader.biCompression = BI_RGB; //<-- Type of bitmap compression //See BitmapInfo: //http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx BitmapHandle = CreateDIBSection( BitmapDeviceContext, //<-- Handle to device context &BitmapInfo, //<-- Pointer to bitmapinfo structure DIB_RGB_COLORS, //<-- The type of data contained in the bmiColors array member of BITMAPINFO structure &BitmapMemory, //<-- A pointer to a variable that receives a pointer to location of DIB bit values 0, 0); //See CreateBigSection(): //http://msdn.microsoft.com/en-us/library/windows/desktop/dd183494%28v=vs.85%29.aspx }
Next, we’re going to call this method from the ‘Win32MainWindowCallback’ under our ‘switch(Message)’ statement and inside of ‘case WM_SIZE’: case WM_SIZE: { RECT ClientRect; GetClientRect(Window, &ClientRect);
//<-- Creates Rectangle //<-- Obtains the Window’s client dimensions int Width = ClientRect.right - ClientRect.left; //<-- Sets Width int Height = ClientRect.bottom - ClientRect.top; //<-- Sets Height Win32ResizeDIBSection(Width, Height); //<-- Calls our prior function to create buffer OutputDebugStringA("WM_SIZE\n");
} break; Step 2). Updating the Window – Next, we need to specify exactly what we want to do when the Window’s ‘WM_SIZE’ message gets called as well as what we want to do when Updating the window: internal void Win32UpdateWindow(HDC DeviceContext, int X, int Y, int Width, int Height) { StretchDIBits( DeviceContext, //<-- Handle of Device Context X, Y, Width, Height, //<-- To RECT (dest) X, Y, Width, Height, //<-- From RECT (src) BitmapMemory, //<-- The memory allocation of the bitmap specified earlier &BitmapInfo, //<-- The bitmap information we specified earlier DIB_RGB_COLORS, //<-- Specifies how to render colours SRCCOPY); //<-- A raster-operation code } Now we’re going to have to replace some code inside of our ‘Win32MainWindowCallback’ function. Inside our ‘switch(Message)’, replace the ‘case WM_PAINT’ with this: case WM_PAINT: { PAINTSTRUCT Paint; HDC DeviceContext; DeviceContext = BeginPaint(Window, &Paint); int X = Paint.rcPaint.left; int Y = Paint.rcPaint.top; int Width = Paint.rcPaint.right - Paint.rcPaint.left; int Height = Paint.rcPaint.bottom - Paint.rcPaint.top; Win32UpdateWindow(DeviceContext, X, Y, Width, Height); //<-- Our call to Update the window EndPaint(Window, &Paint); } break; Done! The above mentioned code is just the ground work needed to cover Allocating Buffers. Stay tuned for the next stream where we get this all up and running!