🔒 Locked
Sub-pixel accuracy
Advertisement
Original Post
Hello, I have tried to obtain an ultra smooth scrolling into a 2D opengl application but the polygon I created seems to "jump" rather than slide. It does use double-buffering and the screen renders as much as possible. I got told to use sub-pixel accuracy as it lets you translate to a value inferior to 1 pixel. I have defined my polygon to move at a speed of 0.25 pixel/second, so every 4 seconds, I see it jump 1 pixel.. are sub-pixel movements really possible? Anyway, I could not find a lot of theory about it on google and even less samples of applications using that. Could you guys hint me as to how sub-pixel accuracy can be illustrated in a 2D opengl application? Thanks a lot.
Good ol' Wikipedia has a pretty good article on subpixel rendering:
http://en.wikipedia.org/wiki/Subpixel_rendering
It probably isn't going to do what you want. The only reason to consider using subpixel rendering is if you're coding for one target device and you know the display will ALWAYS be the same. For example, many homebrew Nintendo DS games use subpixel fonts because you know the screen is constant. Also, this type of rendering is only useful on LCDs.
Are you using time constant movement, as opposed to movement based on FPS? Also, you might try enabling VSync to see if you like how that looks better. If you still don't like the movement, you might have to resort to some kind of blurring.
http://en.wikipedia.org/wiki/Subpixel_rendering
It probably isn't going to do what you want. The only reason to consider using subpixel rendering is if you're coding for one target device and you know the display will ALWAYS be the same. For example, many homebrew Nintendo DS games use subpixel fonts because you know the screen is constant. Also, this type of rendering is only useful on LCDs.
Are you using time constant movement, as opposed to movement based on FPS? Also, you might try enabling VSync to see if you like how that looks better. If you still don't like the movement, you might have to resort to some kind of blurring.
Quote:
Original post by sinoth
Are you using time constant movement, as opposed to movement based on FPS?
My game logic function is called at a constant speed of 20 times per second. Rendering, on the other hand, is done as much as possible.
Quote:
Original post by sinoth
Also, you might try enabling VSync to see if you like how that looks better. If you still don't like the movement, you might have to resort to some kind of blurring.
Ok, but how can I enable Vsync?
Unless you've got a really good reason then I think you really should be running your logic at a much higher frequency. Since pretty much everyone is running on an LCD these days I find it best to run your logic at 60Hz (and as already mentioned, run your framerate locked to vsync (which will probably end up being 60Hz as well)).
20Hz is really far too low for smooth movement in a 2d game IMHO.
20Hz is really far too low for smooth movement in a 2d game IMHO.
Quote:
Original post by OrangyTang
Unless you've got a really good reason then I think you really should be running your logic at a much higher frequency. Since pretty much everyone is running on an LCD these days I find it best to run your logic at 60Hz (and as already mentioned, run your framerate locked to vsync (which will probably end up being 60Hz as well)).
20Hz is really far too low for smooth movement in a 2d game IMHO.
Ok gotcha.
Also, I found this really interesting article earlier today on Vsync and how it effects FPS: http://www.hardforum.com/showthread.php?t=928593
Although, I could not find how to enable it on opengl.
Are you seeing the edge of the polygon jump from pixel to pixel? If so, then it's nothing to do with vsync or game logic - all of that is probably working fine. It's because you need good quality antialiasing to be able to draw the edge of a polygon at a sub-pixel location. This is not something that is supported in a standard way, and can generally only be turned on by driver extensions or the vendor's control panel application.
If you draw a texture across your polygon, you will see that the texture moves smoothly across the screen, effectively jumping relative to the polygon.
Don't worry about it. Once you have a screen full of fast moving objects and a bunch of colorful textures, you wont notice the edge of the polygon jumping. If you do, just use your quad SLI rig to render 16x FSAA or something and I'm sure it will be fine.
If you draw a texture across your polygon, you will see that the texture moves smoothly across the screen, effectively jumping relative to the polygon.
Don't worry about it. Once you have a screen full of fast moving objects and a bunch of colorful textures, you wont notice the edge of the polygon jumping. If you do, just use your quad SLI rig to render 16x FSAA or something and I'm sure it will be fine.
Quote:Unfortunately, there is no portable way to enable vsync in SDL. I would advocate moving to GLFW or SFML instead.
Original post by Lodis
Although, I could not find how to enable it on opengl.
Why toy with the output hardware to get ugly 0.5px subpixels?
Do it yourself, with regular OpenGL code, blending, 1px-wider/higher quads, some simple math and textures with borders (or sprites in the textures, that have a transparent border, thus do not touch another sprite).
To get the idea how to use all above, imagine you need to draw a 16x16 sprite at position 10:10, from tu:tv=100:100 (expressed as integer tex-coords). Now, move the sprite 0.1px to the left. At 10:10 you get the texture coords tu:tv=101:100, but your eyes expect tu:tv=100.1:100 . And you expect pixels to be set at the vertical line starting from 25:10. (thus we draw the sprite with extra 1px horizontally and vertically, space which should be transparent).
Do it yourself, with regular OpenGL code, blending, 1px-wider/higher quads, some simple math and textures with borders (or sprites in the textures, that have a transparent border, thus do not touch another sprite).
To get the idea how to use all above, imagine you need to draw a 16x16 sprite at position 10:10, from tu:tv=100:100 (expressed as integer tex-coords). Now, move the sprite 0.1px to the left. At 10:10 you get the texture coords tu:tv=101:100, but your eyes expect tu:tv=100.1:100 . And you expect pixels to be set at the vertical line starting from 25:10. (thus we draw the sprite with extra 1px horizontally and vertically, space which should be transparent).
Quote:
Original post by swiftcoder Quote:Unfortunately, there is no portable way to enable vsync in SDL. I would advocate moving to GLFW or SFML instead.
Original post by Lodis
Although, I could not find how to enable it on opengl.
Ok noted, that's what I will do :)
Quote:
Original post by idinev
Why toy with the output hardware to get ugly 0.5px subpixels?
Do it yourself, with regular OpenGL code, blending, 1px-wider/higher quads, some simple math and textures with borders (or sprites in the textures, that have a transparent border, thus do not touch another sprite).
To get the idea how to use all above, imagine you need to draw a 16x16 sprite at position 10:10, from tu:tv=100:100 (expressed as integer tex-coords). Now, move the sprite 0.1px to the left. At 10:10 you get the texture coords tu:tv=101:100, but your eyes expect tu:tv=100.1:100 . And you expect pixels to be set at the vertical line starting from 25:10. (thus we draw the sprite with extra 1px horizontally and vertically, space which should be transparent).
That is really interesting, thanks.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement
