02-01-2023, 10:56 AM
Thanks for your input. I think we might be getting somewhere... maybe... I got some more ideas.
To be clear, I haven't been constantly resizing every little thing on the fly, I've been drawing all elements at source size, then once the screen is fully assembled, resizing that once to produce the final result, so one resizing per game state update. Prescaling doesn't just mean resizing some source image ahead of time, it means updating how every single piece is drawn, from the ground up, and adjusting the source and destination coordinates everywhere flexibly depending on the player's window size option.
I had already drawn up the changes I would need to make to pre-scale everything, I'll provide the checklist here so you can get an idea of the work involved and why I wanted to scout a simpler solution first:
I ran ten tests based on your suggestion. The first five tests, I took a 640x360 image and drew it 100 times to the screen, scaled up to 1280x720. In the latter five tests, I took a prescaled 1280x720 image, and drew it 100 times to the screen without any scaling. Here are the results in seconds:
1.92578125
1.8671875
1.8125
1.8671875
1.8125
0.60546875
0.55078125
0.546875
0.55078125
0.60546875
So yes, scaling is increasing the expense of the operation by about a factor of 3.
I wonder, is there a command that will let me resize the program window, like a user would with $RESIZE turned on, but to a new size I determine? Allowing user resize would not be a good idea here, as people who have worked with pixelart can confirm - it makes things look very jagged and distorted, and switching to $RESIZE:SMOOTH does not help. So the window size option in my game requires strict singling, doubling, or tripling of pixels. With smart choice of base resolution, the resulting options will yield at least one favorable size for anyone's hardware - typically people would probably choose the x2 option, or 1280x720, but 640x360 will work if someone's on a small notebook, and x3 would fit people with enormous monitors. Adding a x4 would take very little extra work, too.
So I ran another set of ten tests, this time all of them drawing 640x360 without any scaling. I added $RESIZE:STRETCH to the header, and after five of the tests, I used my mouse to resize the window to about double width and height. There was no significant difference, as you can see:
0.21875
0.1640625
0.109375
0.1640625
0.11328125
0.11328125
0.109375
0.1640625
0.109375
0.109375
So far, I've been unable to find commands to set the window stretch size in QB64, but as $RESIZE is capable of letting the user do it themselves, I'm sure even if it doesn't exist, it could exist? If it does, it's a silver bullet. The whole scaling thing gets boiled down to a single line of code, and rather than adding more data management to make it faster, I can remove the stuff I already put in, and it gets even faster for free.
To be clear, I haven't been constantly resizing every little thing on the fly, I've been drawing all elements at source size, then once the screen is fully assembled, resizing that once to produce the final result, so one resizing per game state update. Prescaling doesn't just mean resizing some source image ahead of time, it means updating how every single piece is drawn, from the ground up, and adjusting the source and destination coordinates everywhere flexibly depending on the player's window size option.
I had already drawn up the changes I would need to make to pre-scale everything, I'll provide the checklist here so you can get an idea of the work involved and why I wanted to scout a simpler solution first:
Quote:- Replace every PUTIMAGE with a new subroutine call that automatically scales the coordinates provided. I can't just scale up the base images to x2 and x3 versions, I have to be able to scale up the coordinates involved too.
- Split the sprite sheet image handle references into three branches, and update every usage of them in the code. Object specs have attached sprite references.
- The sprite sheet parser routine needs to be passed three image handles instead of one, and scale up the first one to produce the other two. This is the one easy part.
- Manual draws need to be branched to several versions, to account for the scaling option.
- Slanted resource meter slicing needs to be branched as well, so the slicing will be accurate at all scalings.
- Font routine library may need to be imported and branched to account for scaling - on font load, scale up the source files as done with the sprite sheets, and update every call accordingly. This one may be the biggest headache; I don't use the font support QB64 provides, because the way I'm using "fonts" is rather pixelart-drawn words, with shading, coloring, etc.
I ran ten tests based on your suggestion. The first five tests, I took a 640x360 image and drew it 100 times to the screen, scaled up to 1280x720. In the latter five tests, I took a prescaled 1280x720 image, and drew it 100 times to the screen without any scaling. Here are the results in seconds:
1.92578125
1.8671875
1.8125
1.8671875
1.8125
0.60546875
0.55078125
0.546875
0.55078125
0.60546875
So yes, scaling is increasing the expense of the operation by about a factor of 3.
I wonder, is there a command that will let me resize the program window, like a user would with $RESIZE turned on, but to a new size I determine? Allowing user resize would not be a good idea here, as people who have worked with pixelart can confirm - it makes things look very jagged and distorted, and switching to $RESIZE:SMOOTH does not help. So the window size option in my game requires strict singling, doubling, or tripling of pixels. With smart choice of base resolution, the resulting options will yield at least one favorable size for anyone's hardware - typically people would probably choose the x2 option, or 1280x720, but 640x360 will work if someone's on a small notebook, and x3 would fit people with enormous monitors. Adding a x4 would take very little extra work, too.
So I ran another set of ten tests, this time all of them drawing 640x360 without any scaling. I added $RESIZE:STRETCH to the header, and after five of the tests, I used my mouse to resize the window to about double width and height. There was no significant difference, as you can see:
0.21875
0.1640625
0.109375
0.1640625
0.11328125
0.11328125
0.109375
0.1640625
0.109375
0.109375
So far, I've been unable to find commands to set the window stretch size in QB64, but as $RESIZE is capable of letting the user do it themselves, I'm sure even if it doesn't exist, it could exist? If it does, it's a silver bullet. The whole scaling thing gets boiled down to a single line of code, and rather than adding more data management to make it faster, I can remove the stuff I already put in, and it gets even faster for free.