Pixel perfect

Discussions related to graphics (2D and 3D), animation and games programming
User avatar
hellomike
Posts: 192
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Pixel perfect

Post by hellomike »

Hi,

It has been covered before in some threads but I still don't seem to fully understand it.
With BB4W 6.13a I want a rectangle exactly 50x50 pixels in size.

In theory one would assume the following does the trick.

Code: Select all

      MODE 8
      GCOL 11 : REM Yellow
      RECTANGLEFILL 100, 100, 100, 100
      OSCLI("GSAVE temp.bmp 100, 100, 100, 100")
      END
I save it as BMP to check the outcome.
The resulting BMP measures exactly 50 by 50 pixels and it is a yellow square.... Almost. Only the bottom row pixels is black.

This would be explained by the help Pixel Perfect.
I.e. the right and bottom are exclusive.
But then I also expect the right pixel column to be black which it isn't.

So what am I missing here and also what, in theory, would be the correct statement to draw a 50x50 pixel yellow square, from graphic units 100, 100 (inclusive)?
Thanks

Mike
RichardRussell

Re: Pixel perfect

Post by RichardRussell »

hellomike wrote: Mon 08 Jun 2020, 10:12So what am I missing here and also what, in theory, would be the correct statement to draw a 50x50 pixel yellow square, from graphic units 100, 100 (inclusive)?
In theory, in generic BBC BASIC, the correct way is:

Code: Select all

      GCOL 3
      RECTANGLE FILL 100, 100, 98, 98
That's because RECTANGLE FILL x,y,w,h is equivalent to MOVE x,y : PLOT 97,w,h and the rectangle is drawn inclusive of the supplied coordinates.

That's what happens in Acorn's ARM BASIC V, Matrix Brandy BASIC and BBC BASIC for SDL 2.0 and can be considered definitive. It's not what happens in BBC BASIC for Windows; to get the same size and position square in BB4W you would need to do:

Code: Select all

      GCOL 3
      RECTANGLE FILL 100, 98, 100, 100
The width and height values need to be increased by one pixel (2 graphics units) because of the way Windows defines the rectangle exclusive of the right and bottom edges, and the Y-coordinate needs to be reduced by one pixel because graphics coordinates are measured with respect to the bottom of the window rather than the top.

This is an example of when BBC BASIC for SDL 2.0 is a better choice than BBC BASIC for Windows!
User avatar
hellomike
Posts: 192
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Pixel perfect

Post by hellomike »

Thanks for the fast reply.

I still struggled a bit so I trimmed the problem down to:

Code: Select all

      MODE 8
      GCOL 11
      RECTANGLEFILL 0, 0, 8, 8
      OSCLI("GSAVE temp.bmp 0, 0, 12, 12")
      END
So I want 4 pixels wide and 4 pixels high. From the help I (wrongly) understood that I get 3 pixels wide and 3 pixels high because it (windows) doesn't paint row #0 and column #3.

Studying the BMP I now indeed see that I do get 4x4 pixels but it starts at row #1 and not row #0.

Regards,

Mike
User avatar
hellomike
Posts: 192
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Pixel perfect

Post by hellomike »

Wait.........
Running the same program WITHOUT the FILL (I still want a rectangle 4 pixels wide and 4 pixels high) now, row#0 is included and column#4 as well!
I get a rectangle 5x5 pixels!

So now that fits with the previous assumption. I.e. with RECTANGLEFILL I also get a 5x5 square but row#0 and column#4 are excluded.

By the way, I'm dealing with several hundred K's of BB4W source. For the moment fully switching to BBC BASIC for SDL 2.0 is not an option.

I have to let this sink in........
RichardRussell

Re: Pixel perfect

Post by RichardRussell »

hellomike wrote: Mon 08 Jun 2020, 14:08 From the help I (wrongly) understood that I get 3 pixels wide and 3 pixels high because it (windows) doesn't paint row #0 and column #3.
RECTANGLE FILL 0,0,8,8 should produce a 5 x 5 square (inclusive coordinates) and will on versions of BBC BASIC that work 'properly'. As you say, Windows doesn't paint the bottom row and the right column, so in BB4W you end up with a 4 x 4 square instead.
Studying the BMP I now indeed see that I do get 4x4 pixels but it starts at row #1 and not row #0.
*GSAVE isn't affected by the Windows 'anomaly' (it's got nothing to do with drawing) and should always create a BMP with the position and dimensions you specify in the command, in both BB4W and BBCSDL.
Running the same program WITHOUT the FILL (I still want a rectangle 4 pixels wide and 4 pixels high) now, row#0 is included and column#4 as well! I get a rectangle 5x5 pixels!
I hope that doesn't surprise you, it shouldn't. Without the FILL it's simply a statement which draws four straight lines, so of course it's now 'inclusive' of the edges. It's best if you think not in terms of the 'shorthand' statements like RECTANGLE but rather the lower-level graphics commands that they generate:

Code: Select all

RECTANGLE FILL x,y,w,h equivalent to MOVE x,y : PLOT 97,w,h
RECTANGLE x,y,w,h equivalent to MOVE x,y : PLOT 9,w,0 : PLOT 9,0,h : PLOT 9,-w,0 : PLOT 9,0,-h
By the way, I'm dealing with several hundred K's of BB4W source. For the moment fully switching to BBC BASIC for SDL 2.0 is not an option.
Fair enough, but if 'pixel perfect' results are important to you (and that's relatively unusual given how small pixels are on modern displays, compared with the BBC Micro etc.) you will need to make adjustments to compensate for BB4W being 'different'. It might be a good idea to include REMs to remind you about these adjustments in case you ever want to port it to BBCSDL or Brandy.
RichardRussell

Re: Pixel perfect

Post by RichardRussell »

Have you considered switching to antialiased graphics (using the GDIPLIB library in BB4W or the aagfxlib library in BBCSDL)? If speed is not an issue - antialiasing is necessarily rather slow - all these inclusive/exclusive anomalies disappear. Coordinates are floats, not integers, so edges of objects should be unambiguously where you want them to be.
User avatar
hellomike
Posts: 192
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Pixel perfect

Post by hellomike »

All solid advise Richard!

Thanks again.

Mike