-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.hs
164 lines (137 loc) · 4.73 KB
/
Main.hs
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
{-# LANGUAGE Arrows #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Yage hiding ((</>))
import Yage.Wire hiding (unless, when)
import Yage.Lens
import Yage.Material
import Yage.Scene
import Yage.HDR
import Yage.GL
import Yage.Rendering.Pipeline.Deferred
import Yage.Rendering.Pipeline.Deferred.ScreenPass
import Yage.Rendering.Pipeline.Deferred.BaseGPass
import Yage.Formats.Ygm
import Yage.Resources
import System.FilePath
import Yage.Rendering.Resources.GL
import Foreign.Ptr
import Foreign.Storable
import Data.FileEmbed
import Data.Data
import qualified Data.ByteString.Char8 as Char8
import Quine.Monitor
import Quine.GL
import Quine.GL.Attribute
import Quine.GL.Buffer
import Quine.GL.Error
import Quine.GL.Program
import Quine.GL.Shader
import Quine.GL.Sampler
import Quine.GL.Types
import Quine.GL.Uniform
import Quine.GL.Texture hiding (Texture)
import Quine.GL.VertexArray
import Quine.GL.ProgramPipeline
import Yage.Rendering.GL
import Graphics.GL.Ext.EXT.TextureFilterAnisotropic
appConf :: ApplicationConfig
appConf = defaultAppConfig{ logPriority = WARNING }
winSettings :: WindowConfig
winSettings = WindowConfig
{ windowSize = (800, 600)
, windowHints =
[ WindowHint'ContextVersionMajor 4
, WindowHint'ContextVersionMinor 1
, WindowHint'OpenGLProfile OpenGLProfile'Core
, WindowHint'OpenGLForwardCompat True
, WindowHint'OpenGLDebugContext True
, WindowHint'sRGBCapable True
, WindowHint'RefreshRate 60
]
}
data Configuration = Configuration
{ _mainAppConfig :: ApplicationConfig
, _mainWindowConfig :: WindowConfig
, _mainMonitorOptions :: MonitorOptions
}
makeLenses ''Configuration
configuration :: Configuration
configuration = Configuration appConf winSettings (MonitorOptions "localhost" 8080 True False)
type GameEntity = DeferredEntity
type GameScene = DeferredScene
data Game = Game
{ _mainViewport :: Viewport Int
, _gameScene :: GameScene
, _gameCamera :: HDRCamera
, _sceneRenderer :: RenderSystem Game ()
}
makeLenses ''Game
instance HasCamera Game where
camera = gameCamera.camera
instance HasEntities Game (Seq GameEntity) where
entities = gameScene.entities
simScene :: YageWire t () GameScene
simScene = Scene
<$> fmap singleton (acquireOnce testEntity)
<*> pure emptyEnvironment
testEntity :: YageResource GameEntity
testEntity = Entity
<$> (fromMesh =<< meshRes (loadYGM id ("res/sphere.ygm", mkSelection [])))
<*> gBaseMaterialRes defaultGBaseMaterial
<*> pure idTransformation
sceneWire :: YageWire t () Game
sceneWire = proc () -> do
pipeline <- acquireOnce simplePipeline -< ()
scene <- simScene -< ()
returnA -< Game (defaultViewport 800 600) scene (defaultHDRCamera $ def & position .~ V3 0 0 5) pipeline
simplePipeline :: YageResource (RenderSystem Game ())
simplePipeline = do
-- Convert output linear RGB to SRGB
throwWithStack $ glEnable GL_FRAMEBUFFER_SRGB
throwWithStack $
io (getDir "res/glsl") >>= \ ss -> buildNamedStrings ss ("/res/glsl"</>)
baseSampler <- mkBaseSampler
gBasePass <- drawGBuffers
screenQuadPass <- drawRectangle
return $ do
game <- ask
screenQuadPass .
dimap (,game^.camera, game^.mainViewport)
(\base -> ([(1,baseSampler,base^.aChannel)], game^.mainViewport))
gBasePass
mkBaseSampler :: YageResource Sampler
mkBaseSampler = throwWithStack $ do
sampler <- glResource
samplerParameteri sampler GL_TEXTURE_WRAP_S $= GL_CLAMP_TO_EDGE
samplerParameteri sampler GL_TEXTURE_WRAP_T $= GL_CLAMP_TO_EDGE
samplerParameteri sampler GL_TEXTURE_MIN_FILTER $= GL_LINEAR
samplerParameteri sampler GL_TEXTURE_MAG_FILTER $= GL_LINEAR
when gl_EXT_texture_filter_anisotropic $
samplerParameterf sampler GL_TEXTURE_MAX_ANISOTROPY_EXT $= 16
return sampler
main :: IO ()
main = yageMain "standalone" configuration sceneWire (1/60)
instance HasMonitorOptions Configuration where
monitorOptions = mainMonitorOptions
instance HasWindowConfig Configuration where
windowConfig = mainWindowConfig
instance HasApplicationConfig Configuration where
applicationConfig = mainAppConfig
instance HasViewport Game Int where
viewport = mainViewport
instance LinearInterpolatable Game where
lerp _ _ = id
instance HasRenderSystem Game (ResourceT IO) Game () where
renderSystem = sceneRenderer