304 lines
12 KiB
Haskell
304 lines
12 KiB
Haskell
--{-# LANGUAGE TemplateHaskell #-}
|
|
--{-# OPTIONS_GHC -Wno-unused-top-binds #-}
|
|
module Preload.Render (
|
|
preloadRender,
|
|
cleanUpRenderPreload,
|
|
) where
|
|
|
|
import Geometry.Data
|
|
import MatrixHelper
|
|
import GLHelp
|
|
import Control.Lens
|
|
import Control.Monad
|
|
import Data.Preload.Render
|
|
import qualified Data.Vector.Mutable as MV
|
|
import Foreign
|
|
import Framebuffer.Setup
|
|
import Shader
|
|
import Shader.AuxAddition
|
|
import Shader.Bind
|
|
import Shader.Compile
|
|
import Shader.Data
|
|
import Shader.Parameters
|
|
import Graphics.GL.Core45
|
|
|
|
numDrawableWalls :: Int
|
|
numDrawableWalls = 5000
|
|
|
|
preloadRender :: IO RenderData
|
|
preloadRender = do
|
|
-- set up uniform buffer object
|
|
theUBO <- mglCreate glCreateBuffers
|
|
glNamedBufferData theUBO 64 nullPtr GL_STREAM_DRAW
|
|
glBindBufferBase GL_UNIFORM_BUFFER 0 theUBO
|
|
|
|
isoUBO <- mglCreate glCreateBuffers
|
|
withArray (isoMatrix 0 1 (V2 0 0) (V2 2 2)) $ \ptr ->
|
|
glNamedBufferStorage isoUBO 64 ptr 0
|
|
|
|
lightsubo <- mglCreate glCreateBuffers
|
|
glNamedBufferData lightsubo 640 nullPtr GL_STREAM_DRAW
|
|
glBindBufferBase GL_UNIFORM_BUFFER 1 lightsubo
|
|
|
|
-- setup wall points VBO, VAOs and shaders
|
|
wpVBOname <- mglCreate glCreateBuffers
|
|
wpVBOptr <- mallocArray (8 * numDrawableWalls)
|
|
glNamedBufferData wpVBOname
|
|
( fromIntegral $ floatSize * numDrawableWalls * 8)
|
|
nullPtr
|
|
GL_STREAM_DRAW
|
|
let wpVBO = VBO{_vboName = wpVBOname, _vboPtr = wpVBOptr, _vboVertexSize = 8}
|
|
-- wpVAOname <- genObjectName
|
|
-- bindVertexArrayObject $= Just wpVAOname
|
|
wpVAOname <- mglCreate glCreateVertexArrays
|
|
glBindVertexArray wpVAOname
|
|
glVertexArrayVertexBuffer wpVAOname 0 wpVBOname 0 (fromIntegral $ floatSize * 8)
|
|
setupVertexAttribPointer wpVAOname 0 4 0
|
|
--wpColVAOname <- genObjectName
|
|
--bindVertexArrayObject $= Just wpColVAOname
|
|
wpColVAOname <- mglCreate glCreateVertexArrays
|
|
glBindVertexArray wpColVAOname
|
|
glVertexArrayVertexBuffer wpColVAOname 0 wpVBOname 0 (fromIntegral $ floatSize * 8)
|
|
setupVertexAttribPointer wpColVAOname 0 4 0
|
|
setupVertexAttribPointer wpColVAOname 1 4 4
|
|
let wpVAO = VAO{_vaoName = wpVAOname, _vaoAttribSizes = [4], _vaoStride = 8}
|
|
wpColVAO = VAO{_vaoName = wpColVAOname, _vaoAttribSizes = [4,4], _vaoStride = 8}
|
|
-- setup window points VBO, VAOs and shaders
|
|
winVBOname <- mglCreate glCreateBuffers
|
|
winVBOptr <- mallocArray (8 * numDrawableWalls)
|
|
glNamedBufferData wpVBOname
|
|
( fromIntegral $ floatSize * numDrawableWalls * 8)
|
|
nullPtr
|
|
GL_STREAM_DRAW
|
|
let winVBO = VBO{_vboName = winVBOname, _vboPtr = winVBOptr, _vboVertexSize = 8}
|
|
--winColVAOname <- genObjectName
|
|
--bindVertexArrayObject $= Just winColVAOname
|
|
winColVAOname <- mglCreate glCreateVertexArrays
|
|
glBindVertexArray winColVAOname
|
|
glVertexArrayVertexBuffer winColVAOname 0 winVBOname 0 (fromIntegral $ floatSize * 8)
|
|
setupVertexAttribPointer winColVAOname 0 4 0
|
|
setupVertexAttribPointer winColVAOname 1 4 4
|
|
let winColVAO = VAO
|
|
{_vaoName = winColVAOname, _vaoAttribSizes = [4,4], _vaoStride = 8}
|
|
-- setup shape geometry/cap VBO and two VAOs
|
|
shEBOptr <- mallocArray numDrawableElements
|
|
shEBOname <- mglCreate glCreateBuffers
|
|
glNamedBufferData
|
|
shEBOname
|
|
( fromIntegral $ glushortSize * numDrawableElements)
|
|
nullPtr
|
|
GL_STREAM_DRAW
|
|
let shEBO = EBO{_eboName = shEBOname, _eboPtr = shEBOptr}
|
|
shVBO <- setupVBO4 8
|
|
shPosVAOname <- mglCreate glCreateVertexArrays
|
|
glBindVertexArray shPosVAOname
|
|
glVertexArrayVertexBuffer shPosVAOname 0 (shVBO ^. vboName) 0 (fromIntegral $ floatSize * 8)
|
|
setupVertexAttribPointer shPosVAOname 0 4 0
|
|
glVertexArrayElementBuffer shPosVAOname shEBOname
|
|
let shPosVAO = VAO{_vaoName = shPosVAOname, _vaoAttribSizes = [4], _vaoStride = 8}
|
|
--setup silhouette edge VAO
|
|
shEdgeVAOname <- mglCreate glCreateVertexArrays
|
|
glBindVertexArray shEdgeVAOname
|
|
glVertexArrayVertexBuffer shEdgeVAOname 0 (shVBO ^. vboName) 0 (fromIntegral $ floatSize * 8)
|
|
setupVertexAttribPointer shEdgeVAOname 0 4 0
|
|
--setup ebo for silhouette edges
|
|
silEBOname <- mglCreate glCreateBuffers
|
|
silEBOptr <- mallocArray numDrawableElements
|
|
glVertexArrayElementBuffer shEdgeVAOname silEBOname
|
|
glNamedBufferData
|
|
silEBOname
|
|
( fromIntegral $ glushortSize * numDrawableElements)
|
|
nullPtr
|
|
GL_STREAM_DRAW
|
|
let silEBO = EBO{_eboName = silEBOname, _eboPtr = silEBOptr}
|
|
shEdgeVAO = VAO{_vaoName = shEdgeVAOname, _vaoAttribSizes = [4], _vaoStride = 8}
|
|
-- shEdgeVAO is unecessary?
|
|
-- lighting shaders
|
|
lightingWallShadShad <-
|
|
makeShaderUsingVAO "lighting/wallShadow" [vert, geom, frag] EPoints wpVAO
|
|
>>= addUniforms ["lightPos","rad"]
|
|
lightingCapShad <-
|
|
makeShaderUsingVAO "lighting/cap" [vert, geom] ETriangles shPosVAO
|
|
>>= addUniforms ["lightPos"]
|
|
lightingLineShadowShad <-
|
|
makeShaderUsingVAO "lighting/lineShadow" [vert, geom] ELinesAdjacency shEdgeVAO
|
|
>>= addUniforms ["lightPos", "radiusUniform"]
|
|
|
|
shadowedgeshader <-
|
|
makeShaderUsingVAO "shadow/edge" [vert, geom] ELinesAdjacency shEdgeVAO
|
|
shadowcapshader <-
|
|
makeShaderUsingVAO "shadow/cap" [vert, geom] ETriangles shPosVAO
|
|
shadowwallshader <-
|
|
makeShaderUsingVAO "shadow/wallShadow" [vert, geom] EPoints wpVAO
|
|
shadowlightshader <- makeShaderSized "shadow/light" [vert, geom, frag]
|
|
[1] 1
|
|
EPoints
|
|
shadowcombineshader <- makeShaderSized "shadow/combine" [vert,geom,frag] [1] 1 EPoints
|
|
poke (shadVBOptr shadowlightshader) 1
|
|
|
|
-- positional shader
|
|
positionalBlankShad <- makeShader "positional/blank" [vert, frag] [3] ETriangles
|
|
-- 2D draw shaders
|
|
bslist <- makeShader "dualTwoD/basic" [vert, frag] [3, 4] ETriangles
|
|
bslista <- makeShader4 "shape/basic" [vert, frag] [4, 4] ETriangles shVBO
|
|
glVertexArrayElementBuffer (bslista ^. shadVAO . vaoName) shEBOname
|
|
aslist <- makeShader "dualTwoD/arc" [vert, frag] [3, 4, 3] ETriangles
|
|
eslist <- makeShader "dualTwoD/ellipse" [vert, geom, frag] [3, 4] ETriangles
|
|
bezierQuadShader <- makeShader "dualTwoD/bezierQuad" [vert, frag] [3, 4, 4] ETriangleStrip
|
|
cslist <-
|
|
makeShader "dualTwoD/character" [vert, frag] [3, 4, 2] ETriangles
|
|
>>= _1 (vaddTextureNoFilter "data/texture/charMap.png")
|
|
-- this should really be a 2d texture array
|
|
basicTweakZShad <- makeShader "dualTwoD/basicTweakZ" [vert, frag] [4, 4] ETriangles
|
|
-- fullscreen shaders
|
|
--fullscreenAlphaHalveShad <- makeShaderSized "fullscreen/alphaHalve" [vert,frag] [2] 4 ETriangleStrip
|
|
--pokeArray (shadVBOptr fullscreenAlphaHalveShad) $ concat cornerListNoCoord
|
|
-- texture shaders, no textures attached
|
|
fsShad <- makeShaderSized "texture/simple" [vert, frag] [2, 2] 4 ETriangleStrip
|
|
-- note we directly poke the shader vertex data here
|
|
-- could possibly use an indirect draw call
|
|
pokeArray (shadVBOptr fsShad) $ concat cornerList
|
|
|
|
let fsshadvao = fsShad ^. _1 . shadVAO
|
|
|
|
bloomBlurShad <- makeShaderUsingVAO "texture/bloomBlur" [vert, frag] ETriangleStrip fsshadvao
|
|
colorBlurShad <- makeShaderUsingVAO "texture/colorBlur" [vert, frag] ETriangleStrip fsshadvao
|
|
grayscaleShad <- makeShaderUsingVAO "texture/grayscale" [vert, frag] ETriangleStrip fsshadvao
|
|
lightingTextureShad <-
|
|
makeShaderUsingVAO "lighting/texture" [vert, frag] ETriangleStrip fsshadvao
|
|
>>= addUniforms ["lightPos", "lumRad"]
|
|
-- >>= addUniforms ["lightPos", "lumRad"]
|
|
-- >>= addUniforms ["lightID"]
|
|
barrelShad <- makeShader "texture/barrel" [vert, geom, frag] [2, 2, 2, 1] EPoints
|
|
-- blank wallShader
|
|
wallBlankShad <- makeShaderUsingVAO "wall/blank" [vert, geom, frag] EPoints wpColVAO
|
|
-- textured wallShader
|
|
wallTextureShad <-
|
|
makeShaderUsingVAO "wall/texture" [vert, geom, frag] EPoints wpColVAO
|
|
>>= addSamplerTexture2D "data/texture/grayscaleDirt.png"
|
|
---- texture array shader
|
|
textArrayShad <-
|
|
makeShader "texture/arrayPos" [vert, frag] [3, 3] ETriangles
|
|
>>= addTextureArray "data/texture/ayene_wooden_floor_transformed.png"
|
|
-- >>= addTextureArray "data/texture/ayene_wooden_floor.png"
|
|
-- bind fixed vertex data
|
|
bufferPokedVBO (snd fsShad) 4
|
|
framebuf2 <- setupTextureFramebuffer 800 600
|
|
framebuf3 <- setupTextureFramebuffer 800 600
|
|
|
|
rboBaseBloomName <- mglCreate glCreateRenderbuffers
|
|
glNamedRenderbufferStorage
|
|
rboBaseBloomName
|
|
GL_DEPTH24_STENCIL8
|
|
800
|
|
600
|
|
|
|
fboBaseName <- setupFramebuffer2GivenStencil rboBaseBloomName
|
|
fboCloudName <- setupFramebuffer2GivenStencil rboBaseBloomName
|
|
fboBloomName <- setupFramebufferGivenStencil rboBaseBloomName
|
|
fboColorName <- setupFramebufferGivenStencil rboBaseBloomName
|
|
fboPosName <- setupFramebufferGivenStencil rboBaseBloomName
|
|
fboLightingName <- setupFramebufferGivenStencil rboBaseBloomName
|
|
--fboLightingHighName <- setupFramebufferGivenStencil rboBaseBloomName
|
|
|
|
fboShadowName <- setupShadowFramebuffer
|
|
|
|
fboHalf1Name <- setupTextureFramebuffer 300 300
|
|
fboHalf2Name <- setupTextureFramebuffer 300 300
|
|
fboHalf3Name <- setupTextureFramebuffer 300 300
|
|
|
|
-- reset to default framebuffer, ready for drawing direct to screen
|
|
glBindFramebuffer GL_FRAMEBUFFER 0
|
|
|
|
-- set the clearColor to have 1 alpha
|
|
glClearColor 0 0 0 1
|
|
|
|
shadV <- MV.new 6
|
|
zipWithM_
|
|
(MV.write shadV)
|
|
[0 .. 5]
|
|
[ bslist -- note the ordering is very important
|
|
, basicTweakZShad -- ShadNum
|
|
, bezierQuadShader
|
|
, cslist
|
|
, aslist
|
|
, eslist
|
|
]
|
|
initializeGLState
|
|
return $
|
|
RenderData
|
|
{ _pictureShaders = shadV
|
|
, _shapeShader = bslista -- & shadVAO' .~ shPosColVAO
|
|
, _shapeEBO = shEBO
|
|
, _silhouetteEBO = silEBO
|
|
, _lightingCapShader = lightingCapShad
|
|
, _lightingLineShadowShader = lightingLineShadowShad
|
|
, _lightingWallShadShader = lightingWallShadShad
|
|
, _shadowEdgeShader = shadowedgeshader
|
|
, _shadowCapShader = shadowcapshader
|
|
, _shadowWallShader = shadowwallshader
|
|
, _shadowLightShader = shadowlightshader
|
|
, _shadowCombineShader = shadowcombineshader
|
|
, _positionalBlankShader = positionalBlankShad
|
|
, _wallBlankShader = wallBlankShad
|
|
, _wallTextureShader = wallTextureShad
|
|
, _windowShader = wallBlankShad{_shadVAO = winColVAO}
|
|
, _textureArrayShader = textArrayShad
|
|
, _fullscreenShader = fsShad
|
|
, _lightingTextureShader = lightingTextureShad
|
|
, _bloomBlurShader = bloomBlurShad
|
|
, _colorBlurShader = colorBlurShad
|
|
, _barrelShader = barrelShad
|
|
, _grayscaleShader = grayscaleShad
|
|
, _fbo2 = framebuf2
|
|
, _fbo3 = framebuf3
|
|
, _fboHalf1 = fboHalf1Name
|
|
, _fboHalf2 = fboHalf2Name
|
|
, _fboHalf3 = fboHalf3Name
|
|
, _fboLighting = fboLightingName
|
|
--, _fboLightingHigh = fboLightingHighName
|
|
, _fboShadow = fboShadowName
|
|
, _fboBase = fboBaseName
|
|
, _fboCloud = fboCloudName
|
|
, _fboBloom = fboBloomName
|
|
, _fboColor = fboColorName
|
|
, _fboPos = fboPosName
|
|
, _rboBaseBloom = rboBaseBloomName
|
|
, _matUBO = theUBO
|
|
, _isoMatUBO = isoUBO
|
|
, _lightsUBO = lightsubo
|
|
, _vboWalls = wpVBO
|
|
, _vboWindows = winVBO
|
|
, _vboShapes = shVBO
|
|
}
|
|
|
|
--------------------end preloadRender
|
|
cornerList :: [[Float]]
|
|
cornerList =
|
|
[ [-1, 1, 0, 1]
|
|
, [-1, -1, 0, 0]
|
|
, [1, 1, 1, 1]
|
|
, [1, -1, 1, 0]
|
|
]
|
|
--cornerListForTriangles :: [[Float]]
|
|
--cornerListForTriangles =
|
|
-- [ [-1, 1, 0, 1]
|
|
-- , [-1, -1, 0, 0]
|
|
-- , [1, 1, 1, 1]
|
|
-- , [-1, -1, 0, 0]
|
|
-- , [1, 1, 1, 1]
|
|
-- , [1, -1, 1, 0]
|
|
-- ]
|
|
|
|
initializeGLState :: IO ()
|
|
initializeGLState = do
|
|
glEnable GL_DEPTH_TEST
|
|
|
|
cleanUpRenderPreload :: RenderData -> IO ()
|
|
cleanUpRenderPreload _ = return ()
|
|
--cleanUpRenderPreload pd = do
|
|
-- TODO fix this
|
|
--mapM_ freeShaderPointers $ _pictureShaders pd
|
|
--freeShaderPointers' $ _lightingWallShadShader pd
|
|
--freeShaderPointers' $ _fullscreenShader pd
|