Author Topic: My Windows Graphics Tutorial  (Read 32838 times)

Gunther

  • Member
  • *****
  • Posts: 4198
  • Forgive your enemies, but never forget their names
Re: My Windows Graphics Tutorial
« Reply #30 on: November 24, 2013, 10:39:25 PM »
Dave,

the BMP image format includes (contains) a DIB
and - as far as i know, all uncompressed DIB lines are always multiples of 4 bytes
no matter what the bit-depth or image width are

yes. In a certain way, this is a waste of memory space.

Gunther
You have to know the facts before you can distort them.

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: My Windows Graphics Tutorial
« Reply #31 on: November 24, 2013, 11:11:53 PM »
if EAX is non-zero, then GetLastError returns undefined
(i.e., GetLastError is only meaningful if EAX tells you to look at it)
I know, but it's still very irritating to see that particular "not enough memory" error in this context. Plain stupid, dear friends in Richmond :eusa_naughty:

Quote
and - if you want to calc the size, don't forget that DIB lines are always multiples of 4 bytes
as TWell rightly mentioned, see above; however, it works fine without the size.

Working example (plain Masm32) attached. Something's wrong with RGB - it turns out as BGR...

TWell

  • Member
  • ****
  • Posts: 743
Re: My Windows Graphics Tutorial
« Reply #32 on: November 24, 2013, 11:43:48 PM »
yes. In a certain way, this is a waste of memory space.

Gunther
Performance/aligning reasons.
the BMP image format includes (contains) a DIB
and - as far as i know, all uncompressed DIB lines are always multiples of 4 bytes
no matter what the bit-depth or image width are
24-bit DIB biSizeImage ?
Code: [Select]
    // Calculate the image size in bytes
    bmpInfoHeader.biSizeImage = lWidth * lHeight * (wBitsPerPixel/8);

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: My Windows Graphics Tutorial
« Reply #33 on: November 25, 2013, 03:05:17 AM »
the bytes in a DIB data area, as well as in a palette, are ordered B,G,R,(A)

also, if the biHeight member is positive, the top line of the image is at the higher address
if you assign it as a negative number, the bitmap is "right-side-up"
supposedly, you cannot compress a "right-side-up" image (don't ask me why - lol)

i have been meaning to make some measurements to see if blitting a "right-side-up" image is faster
probably no difference

anyways - all of this was inherited from win1 days (or earlier)
some microsoft guy had his upside-down hat on, that day

caballero

  • Member
  • *****
  • Posts: 2160
  • Matrix - Noah
    • abre ojos ensamblador
Re: My Windows Graphics Tutorial
« Reply #34 on: November 25, 2013, 07:21:53 PM »
Hello, I've missed this debate, ... not much time lately... If what you want is an example of mandelbrot in win32 asm, you can get this one that I developped in nasmx

Don't know if you want to do your work by yourself, but why don't use my examples as a starting point ?... Get the code, modify it on your needs, maybe the better way ?...

Regards

PS. If you want, I can look for it and upload it here
The logic of the error is hidden among the most unexpected lines of the program

Gunther

  • Member
  • *****
  • Posts: 4198
  • Forgive your enemies, but never forget their names
Re: My Windows Graphics Tutorial
« Reply #35 on: November 26, 2013, 05:17:25 AM »
Hi Alfonso,

Hello, I've missed this debate, ... not much time lately... If what you want is an example of mandelbrot in win32 asm, you can get this one that I developped in nasmx

good idea, but the provided link hides your attachment. What about posting it here again?

Gunther
You have to know the facts before you can distort them.

caballero

  • Member
  • *****
  • Posts: 2160
  • Matrix - Noah
    • abre ojos ensamblador
Re: My Windows Graphics Tutorial
« Reply #36 on: November 26, 2013, 07:20:49 PM »
Here it goes, Gunther :icon_cool:

By the way, it is no need to create a bmp buffer, you just need a dib section (this source is dated before the dedndave's tip (thank you dave) ;) :

Quote
     case WM_PAINT :
          {
              hdc = BeginPaint(hWnd, &ps);
              //PintaObjeto ();
              bResult = BitBlt(hdc, 0, 0, cdXSize, cdYSize, bufDIBDC, 0, 0, SRCCOPY);
              EndPaint(hWnd, &ps);
              return 0 ;
          }
« Last Edit: November 26, 2013, 09:37:19 PM by avcaballero »
The logic of the error is hidden among the most unexpected lines of the program

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: My Windows Graphics Tutorial
« Reply #37 on: November 26, 2013, 08:38:49 PM »
works under XP SP3, Alfonso   :t

too bad it's Nasm, though - lol

caballero

  • Member
  • *****
  • Posts: 2160
  • Matrix - Noah
    • abre ojos ensamblador
Re: My Windows Graphics Tutorial
« Reply #38 on: November 26, 2013, 09:39:22 PM »
Thank you Dave, my idea was to do all the tuto in masm, nasm, fasm and tinyc, but time is short...
The logic of the error is hidden among the most unexpected lines of the program

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: My Windows Graphics Tutorial
« Reply #39 on: November 26, 2013, 09:42:22 PM »
looking at the Nasm code - not too hard to understand   :P

FORTRANS

  • Member
  • *****
  • Posts: 1238
Re: My Windows Graphics Tutorial
« Reply #40 on: November 27, 2013, 12:37:39 AM »
Hi,

   Runs on Windows 2000.  The code looks reasonable.  The decent
amount of comments does help.

Cheers,

Steve N.

Gunther

  • Member
  • *****
  • Posts: 4198
  • Forgive your enemies, but never forget their names
Re: My Windows Graphics Tutorial
« Reply #41 on: November 27, 2013, 04:30:26 AM »
Thank you Alfonso. Works fine under Windows 7.

too bad it's Nasm, though - lol

It's not to hard to translate it into MASM syntax.

Gunther
You have to know the facts before you can distort them.

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
SetDIBitsToDevice slower than BitBlt
« Reply #42 on: November 27, 2013, 07:15:22 PM »
Some bits for the graphics tutorial: I've done some testing with the Mandelbrot code. Inter alia, it turns out that BitBlt is about 5% faster than SetDIBitsToDevice:

  CASE WM_PAINT
   invoke BeginPaint, hWnd, addr ps
     NanoTimer() ; MasmBasic macro - any other timer will be fine, too
     if 1      ; 1987 microseconds
      invoke SetDIBitsToDevice, hDC, 0, 0, rc.right, rc.bottom, 0, 0, 0, rc.bottom, ppvBits, offset bmi, DIB_RGB_COLORS
     else      ; 1880 us
      invoke BitBlt, hDC, 0, 0, rc.right, rc.bottom, hDC, 0, 0, SRCCOPY
    endif
    add ntSum, NanoTimer(us)  ; calculate the average
    inc ntCt
    push ntSum
    fild stack
    fidiv ntCt
   deb 4, "Paint", ST(0)  ; show average in microseconds
   fstp st
   invoke EndPaint, hWnd, addr ps


Another observation is that you don't really need a compatible memory DC when working with a DIB:

  CASE WM_SIZE   ; adjust painting rectangle (on resizing problems)
   mov edi, offset rc.right
   movzx eax, word ptr lParam   ; width of client area
   stosd
   push eax
   movzx eax, word ptr lParam+2   ; height
   stosd
   mov edi, offset bmi.bmiHeader.biHeight
   neg eax
   stosd
   pop [edi-8]   ; .biWidth
   mov ecx, oldDib
   jecxz @F
   invoke SelectObject, hDC, ecx   ; de-select,
   ; invoke DeleteDC, hMemDC   ; delete DC,
   invoke DeleteObject, hDib   ; delete old DIB
@@:   ; after a window size change, setup a new bitmap:
   ; mov hMemDC, rv(CreateCompatibleDC, hDC)
   mov hDib, rv(CreateDIBSection, hDC, addr bmi, DIB_RGB_COLORS, addr ppvBits, 0, 0)
   mov oldDib, rv(SelectObject, hDC, eax)


Works fine, but not with BitBlt, only with SetDIBitsToDevice. And it is 5-10% slower than the version with a compatible DC.