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):
Now we are going to show all possible values for 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
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
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:
Vertex2
instead of Vertex3
, to make things simpler.
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
.
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%.
beginEnd
is VertexMode -> IO a -> IO a
.
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 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
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)]
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)]
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)]
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:
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).
LineLoop
to trace their contour.
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.
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:
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