Drawing Primitives and Modifying Colors
(updated in 17/05/2001)

Previous | Index | Next

To draw some HOpenGL primitives, such as lines, points and triangles, you'll need to use the function beginEnd. It is defined in module GL_BeginEnd, which is automatically imported if your program already imports module GL.

The following example draws a blue triangle whose vertices, using the (x,y,z) axis notation, are (0.20,0.20,0.0), (0.50,0.20,0.0) and (0.35,0.40,0.0):

	blueTriangle :: IO ()
	blueTriangle = do
		color (Color3 0.0 0.0 1.0 :: Color3 GLfloat)
		beginEnd Triangles $ mapM_ vertex [
			Vertex3 0.20 0.20 0.0,
			Vertex3 0.50 0.20 0.0,
			Vertex3 0.35 0.40 (0.0 :: GLfloat)]
Notes:
  • If you wish to work with 2D rather than 3D, it is possible to use Vertex2 instead of Vertex3, to make things simpler.
  • The cast to GLfloat is necessary. Although it must be applied only to the last element of the last Vertex, all elements of all Vertex will be "casted to" GLfloat.
  • The color function is very simple and is used to modify the current color. The values of the parameters (just after Color3) follows the RGB notation. In the example above, we have: RED = 0%, GREEN = 0% and BLUE = 100%.
  • The type of the function beginEnd is VertexMode -> IO a -> IO a.

Now we are going to show all possible values for VertexMode, and a brief explanation of what each one draws (obs.: let n be the number of vertices (Vertex3 or Vertex2) received by beginEnd):

  • Points - Draws a group of n points.

  • Lines - Draws (n/2) lines. Given 2 vertices, one line is drawn; given 4 vertices, two lines are drawn: the first line with the first two vertices and the second line with the two last vertices. And so on...

  • LineStrip - Draws a line strip: the first two vertices are used to draw the first line, the next vertex v[n] draws a new line whose extremities are the vertices (v[n],v[n-1]).

  • LineLoop - It behaves the same way as as LineStrip, but this time the first and the last vertices are connected together, in order to draw one more line.

  • Polygon - Draws a (filled) polygon with n vertices (n >= 3), with the last vertex connected to the first one. Concavous polygons need special attention (the result obtained may not be the one you would like to have).

  • Triangles - Draws (n/3) triangles: given 3 vertices, one triangle is drawn; given 6 vertices, two triangles are drawn: one with the first three vertices and the other one with the three last last vertices. And so on...

  • TriangleStrip - Draws a triangle strip (n >= 3): the first three vertices are used to draw the first triangle, the next vertex v[n] draws a new triangle whose vertices are (v[n],v[n-1],v[n-2]).

  • TriangleFan - Draws a fan made of several triangles (n >= 3): the first three vertices are used to draw the first triangle, the next vertex v[n] draws a new triangle whose vertices are (v[n],v[n-1],v[1]).

  • Quads - Draws (n/4) quadrilaterals: given 4 vertices, one quadrilateral is drawn; given 8 vertices, two quadrilaterals are drawn: one with the first four vertices and the other one with the four last last vertices. And so on...

  • QuadStrip - Draws a quadrilateral strip (n>=4): the first four vertices are used to draw the first quadrilateral; the next two vertices v[n] and v[n+1] draw a new quadrilateral whose vertices are (v[n+1],v[n],v[n-1],v[n-2]).

Check out the following picture to understand how the primitives are drawn:



Let the bottom left corner and the top right corner of the window be the coordinates (0.0,0.0,0.0) and (1.0,1.0,1.0) respectively. Now observe some examples

  • Example 1 - two red points are drawn, one in the middle of the window and other next to its top left corner:
    	ex1 :: IO ()
    	ex1 = do
    		color (Color3 1.0 0.0 0.0 :: Color3 GLfloat)
    		beginEnd Points $ mapM_ vertex [
    			Vertex3 0.50 0.50 0.0,
    			Vertex3 0.10 0.90 (0.0 :: GLfloat)]
    

  • Example 2 - draws a non-filled green star:
    	ex2 :: IO ()
    	ex2 = do
    		color (Color3 0.0 1.0 0.0 :: Color3 GLfloat)
    		beginEnd LineLoop $ mapM_ vertex [
    			Vertex3 0.20 0.10 0.0,
    			Vertex3 0.50 0.90 0.0,
    			Vertex3 0.80 0.10 0.0,
    			Vertex3 0.10 0.60 0.0,
    			Vertex3 0.90 0.60 (0.0 :: GLfloat)]
    

  • Exemplo 3 - draws a yellow square and a red triangle inside it:
    	ex3 :: IO ()
    	ex3 = do
    		color (Color3 1.0 1.0 0.0 :: Color3 GLfloat)
    		beginEnd Quads $ mapM_ vertex [
    			Vertex3 0.20 0.20 0.0,
    			Vertex3 0.80 0.20 0.0,
    			Vertex3 0.80 0.80 0.0,
    			Vertex3 0.20 0.80 (0.0 :: GLfloat)]
    
    		color (Color3 1.0 0.0 0.0 :: Color3 GLfloat)
    		beginEnd Triangles $ mapM_ vertex [
    			Vertex3 0.30 0.30 0.0,
    			Vertex3 0.70 0.30 0.0,
    			Vertex3 0.50 0.70 (0.0 :: GLfloat)]
    

    Notice that, in this last example, the order in which the primitives are drawn is important. The triangle won't appear if you draw the square before it.

    In the display function introduced to you in our "first (and simple) program" (previous module), try to make a call to one of these examples (ex1, ex2 or ex3). Obviously, do not forget to include their respesctive code. Compile again and watch the results by yourself.



    Hints and Tips:
    • Use Strips as often as you can. They are a great way to boost your program performance (a less number of vertices are needed in order to draw them).
    • If you wish to draw non-filled polygons, use LineLoop to trace their contour.
    • You can create a Vertex3 (or Vertex2) list and call the function beginEnd using this list. This may be helpful to create animations, in which the values of the vertices are updated in the list and a new call to beginEnd will draw the primitive with new coordinates.
    • Pay attention to problems related to bad identation: the declaration of the vertices and the declaration of BeginEnd must not be done in the same column. For example, the following code will have problems during compilation:
      		beginEnd Points $ mapM_ vertex [
      		Vertex3 0.50 0.50 0.0,
      		Vertex3 0.10 0.90 (0.0 :: GLfloat)]	
      


    Downloads:
    • Source code of the first example (primitives drawing) you've learned in this lesson.
    • Source code of the second example (primitives drawing) you've learned in this lesson.
    • Source code of the third example (primitives drawing) you've learned in this lesson.


    HOpenGL Tutorial - Andre W B Furtado
    Drawing Primitives and Modifying Colors
    www.cin.ufpe.br/~haskell/hopengl/primitives.html
    Last updated in 17/05/2001
    Informatics Center (CIn) - UFPE
    Recife - PE - Brazil