Confusion over images on retina / non-retina devices

Sorry if this has been resolved before but I couldn’t find the answer after searching through the forums.

Basically - I want to create single tpages of (upto) 2048x2048 for my apps and fill them with a mixture of generated images (using the image() / setContext() functions) and imported assets. The plan is to then use this single image as a texture atlas / sprite sheet and render graphics using meshes.

The thinking was that (especially for the coded graphics) on a retina device I’d automatically take advantage of the higher resolution without having to pack in twice as many images and keep final download size low, however I’m a little confused as to what image() will actually do on retina devices.

Say I create an image like so

buffer = image(512,512)

On a non-retina device I’m assuming I’ll get a 512x512 pixel surface and that all will be well.

However on a retina device will I get an image that is actually 1024x1024 but with a scale factor of 2 (ie have double the pixel density of the same image created on a non-retina device, that will still take up the same percentage of the screen) or will it be a “low res” 512x512 that Codea will scale up when it renders it.

I’d be interested to find out - to see if this method actually has any benefit in the long run.

I’m also trying to keep the functionality nice and simple so I can create “universal” apps that respond well at different resolutions.

FWIW - To “fake” the different devices I just set the WIDTH and HEIGHT variables to the different device sizes and then use those values to scale my x & y coords which I keep in the range 0 - 1. It seems to work well at the moment, but is getting a little confusing with different assets using different coordinates.

Any thoughts / comments gratefully received as usual :slight_smile:

@TechDojo If I understand what you’re asking, a 512x512 image will still be 512x512 on a retina display. A retina display uses 1/2 values to double it’s size. So there are pixels at 2, 2.5, 3 , 3.5, 4 screen values, etc.

@dave1707 technically, the image is 1024x1024 on a retina display, but Codea scales it down when you draw it or draw something in it (of course, being able to use 0.5 to take full advantage of the retina).

This is what I mean - in theory a 32bit RGBA 512x512 image should be 1mb (256k pixels) in size regardless of the pixel density, the way I see it on retina devices this could either contain 4 times as many pixels so that operations on the surface are twice as detailed OR it could be the same size and the GPU automatically doubles the size of the image when rendering.

If it’s the former then does this higher detail extend to all of the other rendering functions (so if I draw an ellipse for instance on the surface will the edges be rendered at a higher res).

I guess there is one person who know’s for sure - eh @Simeon :slight_smile:

@TechDojo I know for a fact that images on a retina device are actually 2x the size and not simply scaled @2x for retina displays because you can draw a “half-pixel” (one whole actual pixel on retina) using 0.5 for the width/height parameters of rect()

Another odd thing that also proves the image isn’t scaled to fit retina displays is that 3D in Codea, by default, does not fully use the retina display, it is actually acting as if the screen isn’t retina and scaling the result up to fit the screen if you’re drawing in 3D directly to the screen. If you have a retina display, you can try drawing a 3D scene into an image of the size WIDTH * 2, HEIGHT * 2, and then spriting that image on the screen (with the width and height parameters set to WIDTH and HEIGHT), and you’ll see that it’s actually sharper. Try having a parameter.boolean to toggle whether you’re using the image.

Another thing is that the maximum image size for a retina display is 2048x2048, instead of non-retina’s 4096x4096 (because the retina one is actually 4096x4096, secretly doubled for the retina display)


On iPad, Codea renders to a 1024x768 point buffer. So your logical coordinate system dimensions are 1024x768.

On a retina display each point is represented by four pixels. You end up with a screen buffer that has 2048x1536 pixels.

A 512x512 pixel image will can either render as 512x512 points (which would cause the image to look blurry on retina), or it can render as 256x256 points (which would look sharp on retina).

You can decide whether your image renders at half its dimensions on retina by using the @2x suffix in the file name. If Codea reads an image from disk with an @2x suffix (e.g., myimage@2x.png) then, by default, it will render it at half its resolution in points (usually there would be a myimage.png also on the file-system for non-retina devices to use).

If you create images in Codea (using image()), the size you specify is taken in points (not pixels). So on a retina device you will get an image that is actually double the dimensions of whatever you specify. (Or in the case of iPhone 6 plus, triple the dimensions of whatever you specify.)

All vector graphics (ellipse, lines, mesh, 3D graphics) are rendered at the full retina display resolution, but obviously the graphics themselves are described within a coordinate system specified in points (so as @SkyTheCoder says, 0.5 points is 1 pixel on a retina display).

@Simeon - thanks for clarifying that. As I hoped creating assets directly on the device should give the best output / resolution for that device.

I’lll post some code examples when I get this working.