Re: Display image BBC BASIC SDL

Discussions related to graphics (2D and 3D), animation and games programming
Hated Moron

Re: Display image BBC BASIC SDL

Post by Hated Moron »

On 11/06/2023 09:30, markbanerji@hotmail.com wrote (cross-posted from the Discussion Group):
I would like to display a image from a list. Is it like in BBBW using the *display keyword
Exactly the same, yes (except that BB4W only accepts BMP images whereas BBCSDL accepts several different formats).

The documentation is (I hope) fairly clear on this point: "In BBC BASIC for Windows the file must be in .BMP format; in BBC BASIC for SDL 2.0 it may alternatively be in .GIF, .JPG, .PNG or .TGA format".

If you are unsure whether something is the same as in BB4W or not, check the differences document.
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Display image BBC BASIC SDL

Post by KenDown »

Displaying a picture in SDL is not quite as easy and straightforward as in BB4W (even though the code for displaying a .jpg image is rather complicated). As a first step you will need to INSTALL the imglib library.

Then you will have to ensure that your window has the hdc (whatever that is). If you only have the one window there will probably not be a problem, but if you have more than one window you will have to set the dc to each window before you attempt to display the picture (which, if I remember correctly, means that you will have to call PROC_imgInit each time).

Then you have to load the image into memory with FN_imgLoad(pic$); this requires both the picture name and the file path to where it is located. This is, of course, similar to the .jpg routine in BB4W. The function returns a handle that refers to that particular image.

However having the image in memory does not display it. For that you need a call to PROC_imgPlot followed by six parameters plus the image handle. The procedure is very versatile, allowing you to specify the position and size of the image and also its angle of rotation. In addition there is PROC_imgMulti which allows you to muck about with the RGB and transparency attributes of the picture before plotting it.

Also be aware that the coordinates used by the imglib library may not be the same as those you are used to with BB4W, so if your picture doesn't appear on the screen, try altering the Y coordinate. The BB4W jpeg routine counts 600 as 600 down from the top whereas imglib counts it as 600 up from the bottom!
Hated Moron

Re: Display image BBC BASIC SDL

Post by Hated Moron »

KenDown wrote: Mon 12 Jun 2023, 07:46 Displaying a picture in SDL is not quite as easy and straightforward as in BB4W
Nonsense. It's exactly the same command (*DISPLAY or OSCLI "DISPLAY..."). As I said, the only difference is that BBCSDL accepts more image formats.
As a first step you will need to INSTALL the imglib library.
Whether or not you choose to use the IMGLIB library is completely unrelated to whether it's BB4W or BBCSDL (both have that library).

The OP was asking whether the process of displaying an image in BBCSDL is different from BB4W. It is not. The most straightforward way of displaying an image is to use *DISPLAY, this works in both BB4W and BBCSDL.

That command provides most of the features that you are likely to want: you can choose the size and position, you can flip the image on either axis, and you can specify a 'key' colour which is treated as transparent.

If you need capabilities not offered by *DISPLAY (for example rotating the image, or using a linear key) then the next most straightforward approach in both BB4W and BBCSDL is to use the IMGLIB library, But that's not what the OP was asking.

Then you will have to ensure that your window has the hdc (whatever that is)....
The rest of your post is specifically about IMGLIB and therefore not relevant to the question at hand.
Also be aware that the coordinates used by the imglib library may not be the same as those you are used to with BB4W
Untrue, they are the same. IMGLIB uses standard BBC BASIC graphics coordinates specifically to avoid this complication.

If you don't know the answer to a question, and especially when I've already answered it accurately, please don't post misleading and unhelpful information.
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Display image BBC BASIC SDL

Post by KenDown »

If the op had been using the routine you provided in the BB4W help to display any jpg images, he would find that my statement was correct. As you point out, "Note that the required display position (xpos%, ypos%) must be specified in pixels, and is measured from the top-left corner of your program's output window to the top-left corner of the image."

So if he already had his coordinates worked out to display the picture at xpos%.ypos%, he would now need xpos%,(screenheight-ypos%)*2

Of course, if he was only using *DISPLAY this problem would not arise, but with BB4W he would have been limited to .bmp pictures.
Hated Moron

Re: Display image BBC BASIC SDL

Post by Hated Moron »

KenDown wrote: Tue 13 Jun 2023, 03:02 If the op had been using the routine you provided in the BB4W help to display any jpg images
That routine is obsolete. To display JPG (GIF, PNG) images in BB4W you should use the IMGLIB library. I considered deleting the reference to the Windows API method but since it still works I decided to leave it; it might also be useful for displaying WMF images.
Of course, if he was only using *DISPLAY this problem would not arise, but with BB4W he would have been limited to .bmp pictures.
Read his original post: "I would like to display a image from a list. Is it like in BBBW using the *display keyword?". He quite specifically asked about *DISPLAY, there was never any mention of other method(s) or any file types other than BMP.

The key thing for me is that you introduced your reply by saying "Displaying a picture in SDL is not quite as easy and straightforward as in BB4W" and that is quite simply untrue. However you analyse the few differences, the only conclusion you can draw is that displaying images in BBCSDL is easier than in BB4W; it's also faster.
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Display image BBC BASIC SDL

Post by KenDown »

I'm glad you left it; it is still useful - to me, at any rate.

And certainly using imglib is easy and straight-forward, *when* you know what you are doing. When I started to play with imglib, I had to ask on this forum, where someone kindly explained about the need to set the dc before a picture can be displayed. (Yes, I know I'm thick, but there is a possibility that others may be as well, hence my post.)

Using the routine you characterise as "obsolete" I was able to display pictures in multiple windows without any problems. However using imglib it is not possible to display in multiple windows and my appeal in this forum for advice was basically that what I wanted was impossible. It is *not* impossible, but it did require a slight rewriting of imglib. To avoid the problems of updated img libraries, I have incorporated the rewritten imglib in my program and can now display pics in five windows as required. (Incidentally, you recently asked why anyone would incorporate a library in their programs; well, here is an instance.)

I also have a MULTIWINMOD.BBC in my library which incorporates a slight change someone here suggested to me. It was so long ago I can't even remember what it was for, but my program wouldn't work without it, so many thanks to whoever it was.
Hated Moron

Re: Display image BBC BASIC SDL

Post by Hated Moron »

KenDown wrote: Tue 13 Jun 2023, 10:53 I'm glad you left it; it is still useful - to me, at any rate.
It's only useful for displaying obscure Windows-only image formats like WMF. You shouldn't use it for anything else, and I will delete it from any future BB4W releases to emphasise that.
I had to ask on this forum, where someone kindly explained about the need to set the dc before a picture can be displayed.
I'm sorry, but that's not (generally) correct. You are talking about a very specific and untypical usage: displaying images in multiple windows (that is, in conjunction with the MULTIWIN library). Apart from that there is no requirement to "set the DC" (whatever that means).

I fully appreciate that your understanding of the internals of Windows, SDL2 and OpenGL is very limited. Once you move outside of the confines of native BBC BASIC things are complicated, which is why there are libraries to try to hide this complication within a 'black box' that you don't have to understand.

Unfortunately you have wanted to do things that are not supported by any existing libraries, which either means you have to accept that they are 'impossible' or find your own solutions. It seems that in this particular case you have found some ad-hoc solutions which seem to work (have you tested them in MacOS and Linux though?).

So because of this I would earnestly ask you to refrain from passing on this 'ad hoc' knowledge, especially when the OP is not faced with the same unsupported challenges. It is likely to be misleading and unhelpful, and that has been the case in this thread.

On a more general note I would advise against using the MULTIWIN library if possible. It is supported only on desktop platforms; neither mobile platforms (Android, iOS) nor the in-browser edition have any support for multiple 'windows'. When a single-window solution is practical, perhaps with a change of UI, that's the way to go to ensure maximum cross-platform compatibility.
Hated Moron

Re: Display image BBC BASIC SDL

Post by Hated Moron »

Remarkably, it turns out that Kendall's comments, purporting to support his assertion that displaying an image is harder in BBCSDL than in BB4W (it isn't), were actually about BBC BASIC for Windows all along, and therefore completely irrelevant and off-topic! :shock:

I must admit I was puzzled by his reference to having to "set the DC" because a DC (Device Context) is a purely Windows concept, with no direct equivalent in SDL2. I put that down to confusion on his part since he claimed to be talking about BBCSDL. But he wasn't! :?

So I can only apologise that this thread drifted so far off-topic. To bring it to a conclusion I will repeat here a summary of ways to display 2D images, in both BB4W and BBCSDL, which I have published elsewhere:
  1. Use the built-in *DISPLAY command (or OSCLI "DISPLAY..." statement) which will cater for most requirements. The image's position and size can be set, it can be flipped on either axis (or both) and a 'key colour' (which is treated as transparent) can be defined.

  2. Use the IMGLIB library, which is available in both BB4W and BBCSDL. This can additionally rotate the image, scale and position it with sub-pixel accuracy, and supports a 'linear' (anti-aliased) key. Another advantage is that it separates 'loading' the image from 'displaying' the image, so is more efficient if the image is displayed multiple times.

  3. In the special case of displaying images which represent objects in a Box2D physics simulation, use the BOX2DGFX library. This automatically positions and orientates the image according to the current state of the simulation.

  4. If you want the ultimate in speed, for example in a video game when you are displaying the image every frame, use the GFXLIB library. This bypasses some overheads, for example by using pixel coordinates rather than BBC BASIC graphics coordinates, but is harder to use.
Methods 1, 2 and 3 are almost 100% compatible between BB4W and BBCSDL, the only significant difference being that in BB4W *DISPLAY will accept only .BMP images (in BBCSDL it will also accept several other formats such as JPG, GIF and PNG). Methods 1-3 are likely to be much faster in BBCSDL than in BB4W because of the hardware (GPU) acceleration.

Method 4 (the GFXLIB library) is significantly different between BB4W and BBCSDL because it works at a lower-level to get the best performance. In BB4W it uses assembly-language routines (written by David Williams) and in BBCSDL direct calls to SDL 2.0. Attempting to write high-performance video games that run in both BB4W and BBCSDL is not recommended.