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
|
{- Vivant: Haskell OpenGL game.
Copyright (C) 2020 Yann Herklotz
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-}
module Main where
import Control.Monad
import Foreign.C.Types
import SDL.Vect
import qualified Data.ByteString as BS
import qualified Data.Vector.Storable as V
import System.Exit (exitFailure)
import System.IO
import SDL (($=))
import qualified SDL
import SDL.Time (ticks)
import qualified Graphics.Rendering.OpenGL as GL
import Paths_vivant (getDataDir)
import Vivant.Shader (initShaders)
screenWidth, screenHeight :: CInt
(screenWidth, screenHeight) = (640, 480)
main :: IO ()
main = do
SDL.initialize [SDL.InitVideo]
SDL.HintRenderScaleQuality $= SDL.ScaleLinear
do renderQuality <- SDL.get SDL.HintRenderScaleQuality
when (renderQuality /= SDL.ScaleLinear) $
putStrLn "Warning: Linear texture filtering not enabled!"
window <-
SDL.createWindow
"SDL / OpenGL Example"
SDL.defaultWindow {SDL.windowInitialSize = V2 screenWidth screenHeight,
SDL.windowGraphicsContext = SDL.OpenGLContext SDL.defaultOpenGL}
SDL.showWindow window
_ <- SDL.glCreateContext window
(prog, attrib) <- initShaders
let loop = do
events <- SDL.pollEvents
let quit = elem SDL.QuitEvent $ map SDL.eventPayload events
GL.clear [GL.ColorBuffer]
draw prog attrib
SDL.glSwapWindow window
unless quit loop
loop
SDL.destroyWindow window
SDL.quit
draw :: GL.Program -> GL.AttribLocation -> IO ()
draw program attrib = do
GL.clearColor $= GL.Color4 1 1 1 1
GL.clear [GL.ColorBuffer]
GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral screenWidth) (fromIntegral screenHeight))
GL.currentProgram $= Just program
ourColorLoc <- GL.uniformLocation program "ourColour"
tick <- ticks
GL.uniform ourColorLoc $= (GL.Vector4 (1::Float) (sin (fromIntegral tick / 500) / 2 + 0.5) 1 1)
GL.vertexAttribArray attrib $= GL.Enabled
V.unsafeWith vertices $ \ptr ->
GL.vertexAttribPointer attrib $=
(GL.ToFloat, GL.VertexArrayDescriptor 2 GL.Float 0 ptr)
GL.drawArrays GL.Triangles 0 3 -- 3 is the number of vertices
GL.vertexAttribArray attrib $= GL.Disabled
vertices :: V.Vector Float
vertices = V.fromList [ 0.0, 0.8
, -0.8, -0.8
, 0.8, -0.8
]
texCoords :: V.Vector Float
texCoords = V.fromList [ 0, 0
, 1, 0
, 0.5, 1
]
|