Author Topic: C++ Win32 - Draw directly into memory and show Bitmap  (Read 5191 times)

0 Members and 2 Guests are viewing this topic.

Offline va!n

  • Pentium
  • *****
  • Posts: 1398
  • Karma: 108
    • View Profile
    • http://www.secretly.de
My following code uses the very slow Win32 API SetPixel and draws the image
directly on the window.

Code: [Select]
       hdc = BeginPaint(hWnd, &ps);
hBrush = CreateSolidBrush(g_Color);
hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0));
holdPen = (HPEN)SelectObject(hdc, hPen);
holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

int color;

for (int y = 0; y < 255; y++)
{
for (int x = 0; x < 255; x++)
{
color = x & y;
SetPixel(hdc, x + 460, y + 180, RGB(color, color, color));
}
}

SelectObject(hdc, holdBrush);
SelectObject(hdc, holdPen);
DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(hWnd, &ps);


How to create a bitmap in memory, drawing directly into this bitmap (1d array)
and display the bitmap on the window? Thanks in advance.


- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline Knurz

  • Atari ST
  • ***
  • Posts: 100
  • Karma: 24
    • View Profile
Have a look at this article on Codeproject: http://www.codeproject.com/Articles/224754/Guide-to-Win-Memory-DC

pDC = def. dev. Context
Code: [Select]
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, r.right, r.bottom);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&bmp); 
Remember what the dormouse said: Feed your head

Offline va!n

  • Pentium
  • *****
  • Posts: 1398
  • Karma: 108
    • View Profile
    • http://www.secretly.de
I have following code and it creates an empty (black) bitmap. How to use the array of the generated bitmap? Seems i am doing someting wrong.

Code: [Select]

int pBits[ (256*256*4) ];

static HBITMAP CreateBitmapFromPixels(HDC hDC, UINT uWidth, UINT uHeight, UINT uBitsPerPixel, LPVOID pBits)
{
int mySize = uWidth * uHeight * (uBitsPerPixel / 8);

int *xBits[(256 * 256 * 4)];

for (size_t i = 0; i < (256 * 256); i=+4)
{
pBits[i] = 128;
}

       /* ============= */

if (uBitsPerPixel < 8) // NOT IMPLEMENTED YET
return NULL;

if (uBitsPerPixel == 8)
return Create8bppBitmap(hDC, uWidth, uHeight, pBits);

HBITMAP hBitmap = 0;
if (!uWidth || !uHeight || !uBitsPerPixel)
return hBitmap;
LONG lBmpSize = uWidth * uHeight * (uBitsPerPixel / 8);
BITMAPINFO bmpInfo = { 0 };
bmpInfo.bmiHeader.biBitCount = uBitsPerPixel;
bmpInfo.bmiHeader.biHeight = uHeight;
bmpInfo.bmiHeader.biWidth = uWidth;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// Pointer to access the pixels of bitmap
UINT * pPixels = 0;
hBitmap = CreateDIBSection(hDC, (BITMAPINFO *)&
bmpInfo, DIB_RGB_COLORS, (void **)&
pPixels, NULL, 0);

if (!hBitmap)
return hBitmap; // return if invalid bitmaps

//SetBitmapBits( hBitmap, lBmpSize, pBits);
// Directly Write
//memcpy(pPixels, *xBits, lBmpSize);

return hBitmap;
}

HBITMAP hTest = CreateBitmapFromPixels(hdc, 256, 256, 32, NULL);
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Offline Knurz

  • Atari ST
  • ***
  • Posts: 100
  • Karma: 24
    • View Profile
If you want to use an existing array of data for a new bitmap(Object) you have to use CreateBitmap.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd183485%28v=vs.85%29.aspx
Remember what the dormouse said: Feed your head

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Something like this should work, I haven't compiled it but this set of calls is what I use to push pixels with pure GDI.

Code: [Select]
#define ResX 256
#define ResY 192

int main(void) {
    // required data
    static int pixel[ResX*ResY];
    static BITMAPINFO bmi = {sizeof(BITMAPINFOHEADER),ResX,ResY,1,32};

    // window creation
    HWND hWnd = CreateWindowExA(0,"edit",0,WS_POPUP|WS_VISIBLE|WS_MAXIMIZE,0,0,0,0,0,0,0,0);
    HDC hDC = GetDC(hWnd);
    ShowCursor(FALSE);

    // main loop
    for (MSG msg; msg.message != WM_KEYDOWN; PeekMessage(&msg,0,0,0,PM_REMOVE)) {
        // screen blitting
        int ScreenX = GetSystemMetrics(SM_CXSCREEN);
        int ScreenY = GetSystemMetrics(SM_CYSCREEN);
        StretchDIBits(hDC,0,0,ScreenX,ScreenY,0,0,ResX,ResY,pixel,&bmi,0,SRCCOPY);
        SwapBuffers(hDC);

        // pixel pushing
        int t = GetTickCount();
        for (int i = 0; i < ResX*ResY; i++) pixel[i] = i + t;
    }

    ExitProcess(0);
    return 0;
}

Challenge Trophies Won: