shaders – OpenGL translation based on “scaled” pixels? (Not physical pixels)

My (2D!) game runs in a “scaling mode” so to speak, and I’ve yet to find anyone asking this question anywhere. Basically, I want to achieve a sort of “scaling algorithm” whether graphics are translated based on some “virtual pixel” multiplier.

Essentially, if the game is running natively at 624×240, then everything is translated exactly 1 physical pixel. But, if the game has been scaled 2 or 3 times, then I need the graphics to be translated by 2 or 3 pixels, respectively, because the graphics are scaled. Basically, each pixel should move 1 pixel multiplied by the scaling factor. In other words, a 64×64 pixel Sprite would move 3 pixels to the right when scaled 3 times. If this sprite starts at 100×50, then it’s new position would be 103×50, not 101×50. This is the issue I cannot overcome. I have tried something like this: model = glam::mat4(<identity>, glm::vec3(pos.x + scale, pos.y + scale, 0.f)); -> everything still moves 1 physical pixel.

I asked on the gamedev subreddit, but no one was able to help me out, primarily because either I probably misunderstood what they were saying, or they were quite vague in what they were saying. One person was talking about scaling the vertex positions in the vertex shader, then mentioned using GL_SHORT when calling glVertexAttribPointer but I was trying for over an hour and couldn’t make GL_SHORT work to save my life.

I tried using glViewport, but everything is still translated by physical pixels. Anyone have any ideas? Any insights? I also tried framebuffers but they ended up being a huge pain for what I want to do, that they didn’t seem worth it to me.