On each computer other positions of pixels

Hello everybody

I want to draw a windows button with opengl because the vb.net program is to slow to interacts user commands with GDI+.
When I draw a button on my machine, the positions are correct. But when a run the program on another machine, the button is not correctly drawed (see attached file). But I don’t know why.
I’ve searched for help in the internet but nothing found.

I would be very grateful if you could help me to solve the problem.

Marco

What is the h/w in each case? You may not have done anything wrong - often your at the mercy of driver quality.

The button should have a width of 17 pixel and a height of 17 pixel.

My project has a reference to the OpenTK-assembly. The main windows-form hosts a glControl where I can draw on it.

To initialize the control, I run the following commands after the control’s loaded (I will only draw 2d objects):
GL.ClearColor(Color.White)
GL.Disable(EnableCap.DepthTest)

GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()

After the commands above and after each resize I setup the viewport :
GL.MatrixMode(MatrixMode.Projection)
GL.LoadIdentity()
GL.Ortho(0, Me.glControl1.Width, Me.glControl1.Height, 0, 0, 128)
GL.Viewport(0, 0, Me.glControl1.Width, Me.glControl1.Height)

When the paint-event is raised, I draw my button with the following commands :
GL.Clear(ClearBufferMask.ColorBufferBit)

GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()

Dim rect AS RectangleF = New RectangleF(2, 2, 17, 17)
’ ############0
#000000000000
#000000000000
#000000000000
’ 0000000000000
GL.Color3(SystemColors.ControlLight)
GL.Begin(BeginMode.LineStrip)
GL.Vertex2(rect.Right - 1, rect.Top + 1)
’ when I here add 1 pixel to the X-position, the corner will not be painted
GL.Vertex2(rect.Left, rect.Top + 1)
GL.Vertex2(rect.Left + 1, rect.Bottom - 1)
GL.End()

' 0000000000000
' 0##########00
' 0#00000000000
' 0#00000000000
' 0000000000000
GL.Color3(SystemColors.ControlLightLight)
GL.Begin(BeginMode.LineStrip)
    GL.Vertex2(rect.Right - 2, rect.Top + 2)
    ' when I here add 2 pixels to the X-position, the corner will not be painted
    GL.Vertex2(rect.Left + 1, rect.Top + 2)
    GL.Vertex2(rect.Left + 2, rect.Bottom - 1)
GL.End()

' 000000000000#
' 000000000000#
' 000000000000#
' 000000000000#
' #############
GL.Color3(SystemColors.ControlDarkDark)
GL.Begin(BeginMode.LineStrip)
    GL.Vertex2(rect.Left, rect.Bottom)
    ' when I here subtract 1 pixel from the X-position, the corner will not be painted
    GL.Vertex2(rect.Right, rect.Bottom)
    GL.Vertex2(rect.Right - 1, rect.Top)
GL.End()

' 0000000000000
' 000000000000#0
' 000000000000#0
' 0###########0
' 0000000000000
GL.Color3(SystemColors.ControlDark)
GL.Begin(BeginMode.LineStrip)
    GL.Vertex2(rect.Left + 1, rect.Bottom - 1)
    ' when I here subtract 2 pixels from the X-position, the corner will not be painted
    GL.Vertex2(rect.Right - 1, rect.Bottom - 1)
    GL.Vertex2(rect.Right - 2, rect.Top + 1)
GL.End()

' 0000000000000
' 0000000000000
' 00#########00
' 0000000000000
' 0000000000000
GL.Color3(SystemColors.Control)
GL.Begin(BeginMode.Quads)
    GL.Vertex2(rect.Left + 2, rect.Top + 2)
    GL.Vertex2(rect.Right - 2, rect.Top + 2)
    GL.Vertex2(rect.Right - 2, rect.Bottom - 2)
    GL.Vertex2(rect.Left + 2, rect.Bottom - 2)
GL.End()
	
Me.glControl1.SwapBuffers()

This code works on my development-machine and draws the button correctly.

The second thing I don’t understand: I have to subtract or add 1 pixel for each corner to draw it. But why?

When I said h/w I meant hardware. I wanted to know what driver versions you are using and the vendor.

The development-machine is a HP Compaq 8100 Elite 64-Bit Computer with a ATI Radeon HD 4650 card. The driver version is 8.670.0.0, dated 2009-10-19. It runs Windows 7.

The second computer is a HP Proliant ML350 G4 with an older onboard ATI Rage XL PCI card. The driver version is 5.10.2600.6204, dated 2004-03-22 and comes from the Microsoft Update-Website. On the ATI-Website is only an older version which cause the same issue. The machine runs Windows 2003 for test purpose.

when drawing widgets with a 3d API, it is recommended to avoid putting the vertices either on the center of the pixel or on the edge of the pixel, in order to avoid issues with rasterization rule.

you seem to hit a difference in rasterization between those two generations of hardware. have you tried on hd5xxx ?

No, I haven’t a hd5xxx card to test.

I have a little played with the program and found out that I have the same problem when I start the program in a remote desktop session. In this case, OpenGL takes GDI Generic for rendering.

have you tried to offset your position to be on 3/4 of the pixel instead of on the edge ?

Many thousand thanks for your help.

I have added 0.2 to the X (when I add more than 0.2 pixels the ATI HD 2600XT doesn’t draw it at the right position) and subtracted 0.25 from the Y coordinate.

Now, I don’t have to correct the positions of the corners and edges any more. The program draws the lines correct on most computers I have testet.

The only exception is a machine with Windows 2000 and a NVIDIA GeForce 4 MX 440 card. When I draw the left outside line from top to bottom, the last pixel is blank. But it works when I begin to draw from bottom to top. After I’ve rewrote the code, I’ve tested the program on other computers with ATI and Intel-cards and it worked.

I will test now my program on any other computers and hope it works too (even if I add some more codes).