--{-# LANGUAGE TemplateHaskell #-} --{-# OPTIONS_GHC -Wno-unused-top-binds #-} module Preload.Render ( preloadRender, cleanUpRenderPreload, ) where import Shader.AuxAddition import Shape.Data 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.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 orthonormalUBO <- mglCreate glCreateBuffers withArray (isoMatrix 0 1 (V2 0 0) (V2 2 2)) $ \ptr -> glNamedBufferStorage orthonormalUBO 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 <- mglCreate glCreateVertexArrays glBindVertexArray wpVAOname glVertexArrayVertexBuffer wpVAOname 0 wpVBOname 0 (fromIntegral $ floatSize * 8) setupVertexAttribPointer wpVAOname 0 4 0 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} wpColVAO = VAO{_vaoName = wpColVAOname} -- 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 <- 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} -- 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 <- setupVBO nShapeVerxComp shPosVAOname <- mglCreate glCreateVertexArrays glBindVertexArray shPosVAOname glVertexArrayVertexBuffer shPosVAOname 0 (shVBO ^. vboName) 0 (fromIntegral $ floatSize * nShapeVerxComp) setupVertexAttribPointer shPosVAOname 0 4 0 glVertexArrayElementBuffer shPosVAOname shEBOname let shPosVAO = VAO{_vaoName = shPosVAOname} --setup silhouette edge VAO shEdgeVAOname <- mglCreate glCreateVertexArrays glBindVertexArray shEdgeVAOname glVertexArrayVertexBuffer shEdgeVAOname 0 (shVBO ^. vboName) 0 (fromIntegral $ floatSize * nShapeVerxComp) 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} -- 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] shapeVerxSizes nShapeVerxComp 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 -- 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"] 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" -- 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 <- setupFramebuffer3GivenStencil rboBaseBloomName fboCloudName <- setupFramebuffer2GivenStencil rboBaseBloomName fboBloomName <- setupFramebufferGivenStencil rboBaseBloomName fboPosName <- setupFramebufferGivenStencil rboBaseBloomName fboLightingName <- 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 shadV <- MV.new 6 zipWithM_ (MV.write shadV) [0 .. 5] [ bslist -- note the ordering is very important , basicTweakZShad -- ShadNum , bezierQuadShader , cslist , aslist , eslist ] initializeGLState tonormalmap <- initTexture 3 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR "data/normalMaps/verticalRidge.png" 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 , _fboShadow = fboShadowName , _fboBase = fboBaseName , _fboCloud = fboCloudName , _fboBloom = fboBloomName , _fboPos = fboPosName , _rboBaseBloom = rboBaseBloomName , _matUBO = theUBO , _orthonormalMatUBO = orthonormalUBO , _lightsUBO = lightsubo , _vboWalls = wpVBO , _vboWindows = winVBO , _vboShapes = shVBO , _toNormalMaps = tonormalmap } --------------------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