opengl use mouse to draw lines


i am new to opengl and understand the basics of it (thanks to NeHe).

i would like to draw line on an opengl canvas using

so far:

  • i can get users mouse click (x,y coords) in mouse down method
  • convert then to 3d coords using gluUnproject
  • track users moving cursor (converted to 3d as well) and draw a line between these to points

actual interaction with the program:

  • program starts
  • user clicks (nothing happens)
  • user moves the mouse to a new location (nothing happen)
  • user resizes the opengl form (during the resizing process if the user put the cursor on the form the programs draws the line from the first click to the current mouse position)

don’t understand what is going wrong?

do i need some kind of redraw method, if so where & when would it be called or do i need some kind of refreshing mechanism, refreshing my drawing?

if there some tutorials out there regarding this topic do mention them.

help appreciated.

I suppose you need to hold the variables in memory and on MouseUp check if the button is the proper button (say, left) and then draw the line. I believe the matter goes deeper, as you would need a stack or something to hold all the objects that are drawn on the scene. If you can find it, Edward Angel’s, “Interactive Computer Graphics” has some examples creating lines and basic shapes.

did couple of google searches on the book…there aren’t any example on the web?

the following is a code for drawing a small pixel where the user click.

the problem is that the pixel on displays if i maximize the window!!

any ideas?


Public Class Form1

Inherits System.Windows.Forms.Form

Public Class OurView

Inherits CsGL.OpenGL.OpenGLControl
'global variable declarations
'global x,y,z coords
Public Shared mposWldX As Double = 0
Public Shared mposWldY As Double = 0
Public Shared mposWldZ As Double = 0
'mouse positions
'save the 1st click
Public Shared mposWinX1 As Integer = 0
Public Shared mposWinY1 As Integer = 0
Public Shared mposWinZ1 As Integer = 0
'save the 2nd click
Public Shared mposWinX2 As Integer = 0
Public Shared mposWinY2 As Integer = 0
Public Shared mposWinZ2 As Integer = 0
'save the 1st world coords
Public Shared mposWldFirstX As Single = 0
Public Shared mposWldFirstY As Single = 0
Public Shared mposWldFirstZ As Single = 0
'bool for saving the 1st world coords
Public Shared check As Boolean = True
'bool so as to check user has started drawing
Shared startDrawing As Boolean = False

Protected Overrides Sub InitGLContext()
'// Enable Smooth Shading
'// Black Background
GL.glClearColor(0.0F, 0.0F, 0.0F, 0.5F)
'// Depth Buffer Setup
'// Enables Depth Testing
'// The Type Of Depth Testing To Do
'// Really Nice Perspective Calculations
GL.glHint(Convert.ToUInt32(GLFlags.GL_PERSPECTIVE_CORRECTION_HINT), Convert.ToUInt32(GLFlags.GL_NICEST))
End Sub

Public Overloads Sub glDraw(ByVal _posX As Single, ByVal _posY As Single, ByVal _posZ As Single)

‘MsgBox("_posX: " + _posX.ToString + " _posY: " + _posY.ToString + " _posZ: " + _posZ.ToString)
‘// Clear The Screen And The Depth Buffer
‘// Reset The Current Modelview Matrix
‘set point size
‘green color
GL.glColor3f(1.0F, 1.0F, 1.0F)
‘// Draw A point
‘// a point
GL.glVertex3f(_posX, _posY, _posZ)
End Sub

Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
Dim S As Size = Me.Size

GL.gluPerspective(45.0, S.Width / S.Height, 0.1, 100.0)
End Sub

Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown

'user has started drawing
startDrawing = True

mposWinX1 = e.X
mposWinY1 = e.Y

'pass x & y mouse coords to be converted to 3d x,y,z using gluUnproject()
convert2dTo3d(mposWinX1, mposWinY1, mposWinZ1)

glDraw(CSng(mposWldX), CSng(mposWldY), CSng(mposWldZ))

End Sub

'converts windows x,y to 3d x,y,z
Private Function convert2dTo3d(ByVal _winX As Integer, ByVal _winY As Integer, ByVal _winZ As Integer) As Array

'MsgBox("3d method got x: " + _winX.ToString + " y: " + _winY.ToString)

'declare viewport, modelview, projection
Dim viewport As Integer() = New Integer(4) {}
Dim modelview As Double() = New Double(16) {}
Dim projection As Double() = New Double(16) {}
Dim winX, winY, winZ As Integer

GL.glGetDoublev(Convert.ToUInt32(GLFlags.GL_MODELVIEW_MATRIX), modelview)
GL.glGetDoublev(Convert.ToUInt32(GLFlags.GL_PROJECTION_MATRIX), projection)
GL.glGetIntegerv(Convert.ToUInt32(GLFlags.GL_VIEWPORT), viewport)

'set the x,y,z values
winX = _winX
winY = viewport(3) - _winY
winZ = _winZ
'MsgBox(“x:” + winX.ToString + " y: " + winY.ToString)
'GL.glReadPixels((winX, winY, 1, 1, Convert.ToUInt32(GLFlags.GL_DEPTH_COMPONENT), Convert.ToUInt32(GLFlags.GL_FLOAT), 0)

'actual convertion
GL.gluUnProject(winX, winY, winZ, modelview, projection, viewport, mposWldX, mposWldY, mposWldZ)

'temp array to send 3d x,y,z
Dim tempArray As Double() = New Double(2) {mposWldX, mposWldY, mposWldZ}
'MsgBox("3d method sending x: " + tempArray(0).ToString + " y: " + tempArray(1).ToString + " z: " + tempArray(2).ToString)
Return (tempArray)

End Function

End Class