File: Material.hs

package info (click to toggle)
haskell-glut 2.4.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,624 kB
  • ctags: 28
  • sloc: haskell: 10,610; ansic: 121; makefile: 2
file content (149 lines) | stat: -rw-r--r-- 5,684 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{-
   Material.hs (adapted from material.c which is (c) Silicon Graphics, Inc.)
   Copyright (c) Sven Panne 2002-2005 <sven.panne@aedion.de>
   This file is part of HOpenGL and distributed under a BSD-style license
   See the file libraries/GLUT/LICENSE

   This program demonstrates the use of the GL lighting model. Several
   objects are drawn using different material characteristics. A single
   light source illuminates the objects.
-}

import System.Exit ( exitWith, ExitCode(ExitSuccess) )
import Graphics.UI.GLUT

-- Initialize z-buffer, projection matrix, light source, and lighting model.
-- Do not specify a material property here.

myInit :: IO ()
myInit = do
   clearColor $= Color4 0 0.1 0.1 0
   depthFunc $= Just Less
   shadeModel $= Smooth

   ambient (Light 0) $= Color4 0 0 0 1
   diffuse (Light 0) $= Color4 1 1 1 1
   position (Light 0) $= Vertex4 0 3 2 0
   lightModelAmbient $= Color4 0.4 0.4 0.4 1
   lightModelLocalViewer $= Disabled

   lighting $= Enabled
   light (Light 0) $= Enabled

-- Draw twelve spheres in 3 rows with 4 columns.
-- The spheres in the first row have materials with no ambient reflection.
-- The second row has materials with significant ambient reflection.
-- The third row has materials with colored ambient reflection.
--
-- The first column has materials with blue, diffuse reflection only.
-- The second column has blue diffuse reflection, as well as specular
-- reflection with a low shininess exponent.
-- The third column has blue diffuse reflection, as well as specular
-- reflection with a high shininess exponent (a more concentrated highlight).
-- The fourth column has materials which also include an emissive component.
--
-- translate is used to move spheres to their appropriate locations.

display :: DisplayCallback
display = do
   clear [ ColorBuffer, DepthBuffer ]

   let draw :: GLfloat -> GLfloat -> Color4 GLfloat -> Color4 GLfloat -> Color4 GLfloat -> GLfloat -> Color4 GLfloat -> IO ()
       draw row column amb dif spc shi emi =
          preservingMatrix $ do
             translate (Vector3 (2.5 * (column - 2.5)) (3 * (2 - row)) 0)
             materialAmbient   Front $= amb
             materialDiffuse   Front $= dif
             materialSpecular  Front $= spc
             materialShininess Front $= shi
             materialEmission  Front $= emi
             renderObject Solid (Sphere' 1 16 16)

       noMat           = Color4 0 0 0 1
       matAmbient      = Color4 0.7 0.7 0.7 1
       matAmbientColor = Color4 0.8 0.8 0.2 1
       matDiffuse      = Color4 0.1 0.5 0.8 1
       matSpecular     = Color4 1 1 1 1
       noShininess     = 0
       lowShininess    = 5
       highShininess   = 100
       matEmission     = Color4 0.3 0.2 0.2 0

   -- draw sphere in first row, first column
   -- diffuse reflection only; no ambient or specular
   draw 1 1 noMat matDiffuse noMat noShininess noMat

   -- draw sphere in first row, second column
   -- diffuse and specular reflection; low shininess; no ambient
   draw 1 2 noMat matDiffuse matSpecular lowShininess noMat

   -- draw sphere in first row, third column
   -- diffuse and specular reflection; high shininess; no ambient
   draw 1 3 noMat matDiffuse matSpecular highShininess noMat

   -- draw sphere in first row, fourth column
   -- diffuse reflection; emission; no ambient or specular reflection
   draw 1 4 noMat matDiffuse noMat noShininess matEmission

   -- draw sphere in second row, first column
   -- ambient and diffuse reflection; no specular
   draw 2 1 matAmbient matDiffuse noMat noShininess noMat

   -- draw sphere in second row, second column
   -- ambient, diffuse and specular reflection; low shininess
   draw 2 2 matAmbient matDiffuse matSpecular lowShininess noMat

   -- draw sphere in second row, third column
   -- ambient, diffuse and specular reflection; high shininess
   draw 2 3 matAmbient matDiffuse matSpecular highShininess noMat

   -- draw sphere in second row, fourth column
   -- ambient and diffuse reflection; emission; no specular
   draw 2 4 matAmbient matDiffuse noMat noShininess matEmission

   -- draw sphere in third row, first column
   -- colored ambient and diffuse reflection; no specular
   draw 3 1 matAmbientColor matDiffuse noMat noShininess noMat

   -- draw sphere in third row, second column
   -- colored ambient, diffuse and specular reflection; low shininess
   draw 3 2 matAmbientColor matDiffuse matSpecular lowShininess noMat

   -- draw sphere in third row, third column
   -- colored ambient, diffuse and specular reflection; high shininess
   draw 3 3 matAmbientColor matDiffuse matSpecular highShininess noMat

   -- draw sphere in third row, fourth column
   -- colored ambient and diffuse reflection; emission; no specular
   draw 3 4 matAmbientColor matDiffuse noMat noShininess matEmission

   flush

reshape :: ReshapeCallback
reshape size@(Size w h) = do
   viewport $= (Position 0 0, size)
   matrixMode $= Projection
   loadIdentity
   let wf = fromIntegral w
       hf = fromIntegral h
   if w <= h * 2
      then ortho (-6) 6 (-3 * (hf * 2) / wf) (3 * (hf * 2) / wf) (-10) 10
      else ortho (-6 * wf / (hf * 2)) (6 * wf / (hf * 2)) (-3) 3 (-10) 10
   matrixMode $= Modelview 0
   loadIdentity

keyboard :: KeyboardMouseCallback
keyboard (Char '\27') Down _ _ = exitWith ExitSuccess
keyboard _            _    _ _ = return ()

main :: IO ()
main = do
   (progName, _args) <- getArgsAndInitialize
   initialDisplayMode $= [ SingleBuffered, RGBMode, WithDepthBuffer ]
   initialWindowSize $= Size 600 450
   createWindow progName
   myInit
   reshapeCallback $= Just reshape
   displayCallback $= display
   keyboardMouseCallback $= Just keyboard
   mainLoop