Why is a pixel missing from my rect outline?
Monkey Targets Forums/Desktop/Why is a pixel missing from my rect outline?
| ||
Check it out, run this and notice the top left pixel is missing in GLFW, but not when in HTML5!Import mojo Function Main:Int() New MyApp Return 1 End Class MyApp Extends App Method OnCreate:Int() 'Set frame rate SetUpdateRate 60 Return 1 End Method Method OnUpdate:Int() Return 1 End Method Method OnRender:Int() Cls(0,0,0) Local x1=100 Local x2=200 Local y1=100 Local y2=200 DrawLine(x1,y1,x2,y1) DrawLine(x2,y1,x2,y2) DrawLine(x2,y2,x1,y2) DrawLine(x1,y2,x1,y1) Return 1 End Method End Class |
| ||
Works fine here Jake, might be a driver issue: Edit: Added zoomed in section, where you can see the missing bottom-left (Ta muddy!) |
| ||
Your bottom left pixel is missing. |
| ||
Oh yeah... I was just checking the top-left :/ |
| ||
I imagine it's the same issue as in Grey Alien's other thread. The OpenGL line renderer doesn't work with pixel boundary positions. Change the values to be floats with half pixel values: [monkeycode] Local x1:Float=100.5 Local x2:Float=200.5 Local y1:Float=100.5 Local y2:Float=200.5 [/monkeycode] ...and see if that works. |
| ||
Yep that did the trick. |
| ||
Mine was on Mac btw, looks like therevills was on PC. Anyway, adding 0.5 fixed it thanks. However, does anyone think that maybe that should be handled inside monkey instead as most users will be expecting it to be drawing on pixel 0 not on the -1/0 boundary...I know I did! I'm going to have to add 0.5 for the GLFW target to all drawing code, or should it also be applied to HTML5 and Flash etc I wonder? e.g. Function ccDrawRectOutline2:Void(x1:Float, y1:Float, x2:Float, y2:Float) #If TARGET="glfw" Then x1+=0.5 x2+=0.5 y1+=0.5 y2+=0.5 #End DrawLine(x1,y1,x2,y1) DrawLine(x2,y1,x2,y2) DrawLine(x2,y2,x1,y2) DrawLine(x1,y2,x1,y1) End Function |
| ||
Seems like a target inconsistency bug that needs ironing out in mojo. |
| ||
Yep, mines on Windows. I think I would raise a bug in the Bug forum. When I tested Flash it worked fine the first time (I doubled checked after Muddy pointed out the bottom-left). |
| ||
OK will probably raise as a bug then. Remind me if I forget. It's late here! Hmm, I'm thinking it also needs to be applied to HTML5 as well because the right hand line at x=640 is visible on HTML5 unless I add 0.5. And the box has better corners with 0.5 added so I think HTML5 is drawing at pixel borders too, not in the centre of pixels. |
| ||
I haven't test Flash yet as I'm still on Mac, but will test in Flash when on my PC tomorrow. |
| ||
This is a known opengl issue rather than a monkey issue. I came across the same thing a few days back. Its also graphics driver dependent as well, as I have the same program running on two machines and the missing pixel is in different places. The solution is as said above to move the object 0.5 before drawing. I have a simple translate at the top of the render routine to move the whole rendering by 0.5. |
| ||
I don't think it's that simple. Firstly this only applies to line rendering, as far as I'm aware, so universally shifting by 0.5 isn't what people should be doing. Secondly, although I've just said "add 0.5" here it's more like "make sure that the line exits the centre of the pixel". In order to resolve the problem more generally you'd have to take into account the direction of the line and create boundary values that ensure the line exits centre points at both ends. Alternatively mojo could avoid using GL_LINES and use different primitives but that's possibly just as involved. I doubt there are many release version uses for the basic line rendering that mojo provides but I still think this is something that needs addressing. Even if the decision is to not make the input consistent there still needs to be clarification on what values are expected. |
| ||
Yeah I was using it to display hitbox rects in debug mode and couldn't understand why they were wrong. I'm wondering if DrawRect has the same issue... |
| ||
Below is some code that tries to ensure that the line exits the pixel centres of both the start and end coordinates. Seems to work okay for me, but I don't know how variable the GL implementations are in this stuff. [monkeycode] Import mojo Function Main:Int() New MyApp Return 1 End Function DrawLineGL:Void( x1:Float, y1:Float, x2:Float, y2:Float) 'Set co-ords to centres x1 += 0.5 y1 += 0.5 x2 += 0.5 y2 += 0.5 'calc line equation Local ydiff:Float = (y2-y1) Local xdiff:Float = (x2-x1) 'calc exit boundary values If ydiff = 0.0 'line is flat x2 += Sgn(xdiff) * 0.5 ElseIf xdiff = 0.0 'line is vertical y2 += Sgn(ydiff) * 0.5 Else 'line is diagonal Local m:Float = ydiff/xdiff Local c:Float = y1 - m*x1 If ydiff > xdiff y2 += Sgn(ydiff) * 0.5 x2 = (y2 - c)/m Else x2 += Sgn(xdiff) * 0.5 y2 = m*x2 + c End End DrawLine(x1,y1,x2,y2) End Class MyApp Extends App Method OnCreate:Int() 'Set frame rate SetUpdateRate 1 Return 1 End Method Method OnUpdate:Int() Return 1 End Method Method OnRender:Int() Cls(0,0,0) Local x1:Float = 100 Local x2:Float = 200 Local y1:Float = 100 Local y2:Float = 200 'should render a pink box surrounded with white 1px border SetColor(255, 255, 255) DrawLineGL(x1, y1, x2, y1) DrawLineGL(x2, y1, x2, y2) DrawLineGL(x2, y2, x1, y2) DrawLineGL(x1, y2, x1, y1) SetColor(255, 64, 64) DrawRect(x1+1, y1+1, x2-x1-1, y2-y1-1) x1 = 300 x2 = 400 y1 = 100 y2 = 200 'should render a pink box crossed with white lines that 'extend 1px out on the corners DrawRect(x1+1, y1+1, x2-x1-1, y2-y1-1) SetColor(255, 255, 255) DrawLineGL(x1, y1, x2, y2) DrawLineGL(x1, y2, x2, y1) Return 1 End Method End Class [/monkeycode] |
| ||
Wow cool. Can I use this in my code please? |
| ||
Sure. I wouldn't post something if it wasn't free for anyone to use. Edit: Turns out I was being optimistic just extending the lines out past the destination point. It was still missing pixels from the source going in certain directions. The code below extends the line both ways and seems to resolve this. |
| ||
Have you tried your new code in V066b? I get a white pixel outside the top right of the box on GLFW. It's fine in Flash and HTML5. |