I would like my renderer to act similar to imgui. What ever size imgui application has, imgui widget window size do not change.
that is how imgui looks like when resolution is 1280x720
and that is how it looks when resolution is 1920x1017
primitives are all the time the same size
in my application resizing a window causes different sides to be different thickness or unpleasant phenomena.
my app unfilled rect 1280x720
my app the same rect 1920x1017
as you can see higher resolution causes in this case bottom side of unfilled rect to be different thickness then the other sides (it may not be shown in a photo, but in a screen it is shown and it is very annoying).
imgui has not got this problem. My app renderer is almost the same (without few advanced options).
How could I implement that? Why does it work like this? I asked imgui creator, but he told me it is not about imgui and he cannot help.
In general, one way or another, any primitive you draw will ultimately end up in clip space and then normalized device coordinates. You may apply some matrix transforms to the input positions or whatnot, but the vertex shader, by definition, outputs clip-space coordinates. These clipspace coordinates are then projected to normalized device coordinates.
In normalized device coordinates (NDC), your viewport (your "screen") extends from -1 to 1 in x and y direction (hence the "normalized"). NDC are relative to your viewport. That means if you specify a vertex of your primitive such that it ends up at position (-0.5, 0.25) in NDC, that means it will be 1/4 of the full width of the screen along x and 5/8 along y:
If you want to place primitives at specific pixel locations inside your viewport, then you will have to compute their coordinates such that they end up at the corresponding NDC coordinates. For example, let's say you have an 800×600 viewport and you want to place a vertex at pixel coordinates (50, 40). In this case, you want the vertex coordinates to end up being
x_NDC = 2 * (50 + 0.5) / 800 - 1
y_NDC = 2 * (40 + 0.5) / 600 - 1
The + 0.5
is to account for the fact that sample locations in OpenGL are at the centers of the pixel grid:
In general, to place a vertex at pixel coordinates (x, y) on the near plane, you want your vertex shader to return the coordinates
x_clip = 2.0f * (x + 0.5f) / W - 1
y_clip = 2.0f * (y + 0.5f) / H - 1
z_clip = 0
w_clip = 1
where W
and H
are the width and height of the viewport and assuming the origin of your pixel coordinates is the lower left corner.