minetest
minetest copied to clipboard
Object crosshair misalignment
Minetest version
Minetest 5.5.0-dev-75eb28b95 (Linux)
Using Irrlicht 1.9.0mt0
OS / Hardware
Operating system: Ubuntu (because of the snap build I think it's 18.04) CPU: Intel® Core™ i5-4570
GPU model: Intel® HD Graphics 4600 OpenGL version: 3.0
Summary
The crosshair appears to be misaligned by about 1px since 5.5.0-dev.
Object crosshair in 5.4.0:

Object crosshair in 5.5.0-dev (the box has been added around the crosshair to make the issue stand out more):

Regular crosshair in 5.5.0-dev (fixed)

Steps to reproduce
- Open Minetest 5.5.0-dev
- Join a world
Just measured a screenshot from 2017, the crosshair is indeed 10px in both directions (for a total span of 21px). I sure hope Irrlicht 1.9 hasn't changed all line draw methods to be off-by-one because that'd be hell.
//! Draws a 2d line.
/** In theory both start and end will be included in coloring.
BUG: Currently hardware drivers (d3d/opengl) ignore the last pixel
(they use the so called "diamond exit rule" for drawing lines).
[...] */
virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255)) =0;
uh huh
fixed by minetest/irrlicht@0335a52479b6bd654482ca9d559433aa95b0e00a
The normal crosshair has been fixed but the object crosshair still doesn't look the way it's supposed to, should I open a new issue?

Can't reproduce, looks perfect here:

Also shows correctly here.
I have this issue with the object crosshair in 5.5.0 stable (with IrrlichtMt 1.9.0mt4) as well.
I believe the fix applied in https://github.com/minetest/irrlicht/commit/0335a52479b6bd654482ca9d559433aa95b0e00a should have been extended to the first pixel as well:
// Draw non-drawn last & first pixel (search for "diamond exit rule")
glDrawArrays(GL_POINTS, 0, 0);
glDrawArrays(GL_POINTS, 1, 1);
Drawing these additional pixels may be problematic due to alpha blending.
Alternatively, shifting the positions by 0.5 to the pixel center should work way better (& hopefully make the point drawing hack obsolete):
Note that OpenGL coordinate space has no notion of integers, everything is a float and the "centre" of an OpenGL pixel is really at the 0.5,0.5 instead of its top-left corner. (https://stackoverflow.com/a/10041050/7185318)
The "diamond exit rule" is fine and not equivalent to "the last pixel is exclusive"; this is only the case if rather than to the center of the last pixel, you actually draw to one of the corners of the last pixel, which is obviously not part of the diamond. This only appears at one of the two pixels (which randomly turned out to be "the end" in the case of the normal crosshair) because that's the pixel with the higher coordinate. Here's a quick visualization:

as you can see, the end of the line (the red pixel) is not included because the line only goes up to its top left corner, whereas the line fully crosses the start (the green pixel). Simply drawing the end doesn't fix the issue: It persists for different line directions (if start & end had been swapped).
Edit: Tested the clean solution and it doesn't work; the initial issue reoccurs. A hack of relying on rounding and using 0.375 fails as well. We'll have to go for the hack of drawing points (even though there will be issues with blending; it isn't an issue in practice).
@luk3yx I can't reproduce the issue (this is hardware-dependant); could you try https://github.com/minetest/irrlicht/pull/110?
@luk3yx reminder to test appguru's PR
@luk3yx please test appuguru's PR
@Zughy @luk3yx has fixed my PR, I had wrongly assumed the second argument of gl_DrawArrays to be an (inclusive) end index, but it is a count.
Great! @appgurueu can you please add a "fixes [this issue]" there so it'll be automatically closed once merged?