PDA

View Full Version : On each computer other positions of pixels



MarcoG
09-06-2010, 12:48 PM
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

BionicBytes
09-06-2010, 03:58 PM
What is the h/w in each case? You may not have done anything wrong - often your at the mercy of driver quality.

MarcoG
09-07-2010, 09:24 AM
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?

BionicBytes
09-07-2010, 01:27 PM
When I said h/w I meant hardware. I wanted to know what driver versions you are using and the vendor.

MarcoG
09-08-2010, 01:41 AM
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.

Pierre Boudier
09-08-2010, 02:36 AM
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 ?

MarcoG
09-08-2010, 05:50 AM
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.

Pierre Boudier
09-08-2010, 07:51 AM
have you tried to offset your position to be on 3/4 of the pixel instead of on the edge ?

MarcoG
09-10-2010, 07:30 AM
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).