I recently started working on a side-scroller where the background images fill the entire screen, and there are many background images put together to form the game.

But, I wanted to know how the game scaling should be done? My game is full-screen and obviously there's hundreds of monitors and some with really really odd aspect ratios and sizes. Obviously, if all the monitors had the same aspect ratio the scaling would be fine as there would be no warping.

But I am scaling a smaller image to the size of the screen, if the monitor is shaped oddly, wouldn't the image stretch and warp itself to a point where it will look extremely odd?

Also, I am using Slick, and each background image is an image scaled to the size of the screen, and I'm currently not rendering off-screen images, but for some reason rendering a background images cuts my frame-rate from 4000 fps to 2000 which seems like a bit too large of a performance drop just for rendering one image.

Am I rendering this properly? If not, how should I be rendering these images?

When your application starts, check the resolution of your program's window (not screen size since some users may run the application in windowed mode). Calculate the width/height ratio. Assuming you have a 1920x1080 (16:9) texture to work with and you detect a monitor resolution ratio of 1.77+-10%, then create a 16:9 background image/texture.If the monitor resolution ratio is 1.33+-10%, then create a 4:3 background image using only the central portion of the image. Else check if the resolution ratio is some other popular ratio, else check another ratio, etc...

In other words, for a 4:3 window, only use the central 1440x1080 portion of your texture and create a sprite to match the width and height of the window. If you are using a orthogonal view matrix, create a quad that has corners at -1,-1; -1,1; 1,-1; 1,1; (I don't remember, is [-1,1] standard OpenGL orthogonal matrix corners? I haven't worked with orthogonal matrices lately).

Then just let the graphics card scale the image down to the size of the window it is drawing in. As long as you have the ratio relatively correct and use the right scaling parameters on the texture, the graphic card will do a pretty good job of scaling the image.

As you mentioned, if you are scaling a small image up, you will still have to clip some portion of it, either the top and bottom edges if the window has a much wider aspect ratio than the image, or the left and right edges if the window has a much narrower aspect ratio than the image.

This is the solution I've seen in a number of 2D games when I change the resolution/resize the window. Granted this means that people with older monitors will not see the left and right edges of your beautiful backgrounds, but you can compensate for this by making the left and right edges something unimportant like some shrubbery or the continuation of a castle wall, or some mountains, etc.

In regards to performance, I wouldn't take the drop from 4,000 fps to 2,000 fps too seriously. Most frame rates over 600-800 act very erratically in my experience. A frame rate of 2,000 is once every 0.5 milliseconds! A single frame involves hundreds of thousands to tens of millions of mathematical operations (a 1080p display has 2 million pixels!). Small changes in the type of data being processed, such as a switch from geometry heavy environments to texture heavy environments can make huge changes in GPU memory access patterns, caching, parallelization, etc.

I've seen strange fps gains/loses in my own programs at high (+1,000) fps. However, once you start adding multiple textures, geometry involving thousands of vertices, etc. these types of fluctuations tend to even out around 600-800 fps and adding X percent more objects on screen starts translating to equivalent performance drops.

*note these observations are on my own PC and are not conclusive benchmarks or cited facts of any kind

but for some reason rendering a background images cuts my frame-rate from 4000 fps to 2000 which seems like a bit too large of a performance drop just for rendering one image.

I cant really comment on whether you render these images right without code. However, "FPS drop" is not a useful way to measure performance or performance impact.

Better use the time in ms it takes to render: it went from 0.25ms per frame to 0.5ms per frame, so rendering the background costs 0.25ms for you. To get 60FPS you have about 16ms per frame to spend. 0.25ms for the background does not seem to be that high to me, since it essentially fills the entire screen (which is a couple of million pixels). Rendering smaller images is usually faster, larger images are slower.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org