--{-# LANGUAGE TemplateHaskell #-} --{-# OPTIONS_GHC -Wno-unused-top-binds #-} module Preload.Render ( preloadRender, cleanUpRenderPreload, ) where 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 Graphics.Rendering.OpenGL hiding (Point, imageHeight, scale, translate) 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 <- genObjectName bindBuffer UniformBuffer $= Just theUBO bufferData UniformBuffer $= (64, nullPtr, StreamDraw) bindBufferBase IndexedUniformBuffer 0 $= Just theUBO -- setup wall points VBO, VAOs and shaders wpVBOname <- genObjectName wpVBOptr <- mallocArray (8 * numDrawableWalls) bindBuffer ArrayBuffer $= Just wpVBOname bufferData ArrayBuffer $= ( fromIntegral $ floatSize * numDrawableWalls * 8 , nullPtr , StreamDraw ) let wpVBO = VBO{_vbo = wpVBOname, _vboPtr = wpVBOptr, _vboAttribSizes = [4, 4], _vboStride = 8} -- wpVAOname <- genObjectName -- bindVertexArrayObject $= Just wpVAOname wpVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray wpVAOname bindBuffer ArrayBuffer $= Just wpVBOname setupVertexAttribPointer 0 4 8 0 --wpColVAOname <- genObjectName --bindVertexArrayObject $= Just wpColVAOname wpColVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray wpColVAOname setupVertexAttribPointer 0 4 8 0 setupVertexAttribPointer 1 4 8 4 let wpVAO = VAO{_vaoName = wpVAOname, _vaoVBO = wpVBO} wpColVAO = VAO{_vaoName = wpColVAOname, _vaoVBO = wpVBO} -- setup window points VBO, VAOs and shaders winVBOname <- genObjectName winVBOptr <- mallocArray (8 * numDrawableWalls) bindBuffer ArrayBuffer $= Just winVBOname bufferData ArrayBuffer $= ( fromIntegral $ floatSize * numDrawableWalls * 8 , nullPtr , StreamDraw ) let winVBO = VBO{_vbo = winVBOname, _vboPtr = winVBOptr, _vboAttribSizes = [4, 4], _vboStride = 8} --winColVAOname <- genObjectName --bindVertexArrayObject $= Just winColVAOname winColVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray winColVAOname setupVertexAttribPointer 0 4 8 0 setupVertexAttribPointer 1 4 8 4 let winColVAO = VAO{_vaoName = winColVAOname, _vaoVBO = winVBO} -- setup shape geometry/cap VBO and two VAOs shEBOname <- genObjectName shEBOptr <- mallocArray numDrawableElements bindBuffer ElementArrayBuffer $= Just shEBOname bufferData ElementArrayBuffer $= ( fromIntegral $ glushortSize * numDrawableElements , nullPtr , StreamDraw ) let shEBO = EBO{_ebo = shEBOname, _eboPtr = shEBOptr} shVBOname <- genObjectName shVBOptr <- mallocArray (7 * numDrawableElements) bindBuffer ArrayBuffer $= Just shVBOname bufferData ArrayBuffer $= ( fromIntegral $ floatSize * numDrawableElements * 7 , nullPtr , StreamDraw ) let shVBO = VBO{_vbo = shVBOname, _vboPtr = shVBOptr, _vboAttribSizes = [4, 4], _vboStride = 8} --shPosColVAOname <- genObjectName --bindVertexArrayObject $= Just shPosColVAOname shPosColVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray shPosColVAOname bindBuffer ArrayBuffer $= Just shVBOname setupVertexAttribPointer 0 3 7 0 setupVertexAttribPointer 1 4 7 3 bindBuffer ElementArrayBuffer $= Just shEBOname --shPosVAOname <- genObjectName --bindVertexArrayObject $= Just shPosVAOname shPosVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray shPosVAOname bindBuffer ArrayBuffer $= Just shVBOname setupVertexAttribPointer 0 3 7 0 bindBuffer ElementArrayBuffer $= Just shEBOname let shPosColVAO = VAO{_vaoName = shPosColVAOname, _vaoVBO = shVBO} shPosVAO = VAO{_vaoName = shPosVAOname, _vaoVBO = shVBO} --setup silhouette edge VAO --shEdgeVAOname <- genObjectName --bindVertexArrayObject $= Just shEdgeVAOname shEdgeVAOname <- mglCreateSingle glGenVertexArrays glBindVertexArray shEdgeVAOname bindBuffer ArrayBuffer $= Just shVBOname setupVertexAttribPointer 0 3 7 0 --setup ebo for silhouette edges silEBOname <- genObjectName silEBOptr <- mallocArray numDrawableElements -- it may be important to bind this while the correct VAO is bound bindBuffer ElementArrayBuffer $= Just silEBOname bufferData ElementArrayBuffer $= ( fromIntegral $ glushortSize * numDrawableElements , nullPtr , StreamDraw ) let silEBO = EBO{_ebo = silEBOname, _eboPtr = silEBOptr} shEdgeVAO = VAO{_vaoName = shEdgeVAOname, _vaoVBO = shVBO} -- lighting shaders lightingWallShadShad <- makeShaderUsingVAO "lighting/wallShadow" [vert', geom', frag'] EPoints wpVAO >>= addUniforms ["lightPos"] lightingCapShad <- makeShaderUsingVAO "lighting/cap" [vert', geom', frag'] ETriangles shPosVAO >>= addUniforms ["lightPos"] lightingLineShadowShad <- makeShaderUsingVAO "lighting/lineShadow" [vert', geom', frag'] ELinesAdjacency shEdgeVAO >>= addUniforms ["lightPos", "radiusUniform"] -- positional shader positionalBlankShad <- makeShader "positional/blank" [vert', frag'] [3] ETriangles -- 2D draw shaders bslist <- makeShader "dualTwoD/basic" [vert', frag'] [3, 4] ETriangles bslista <- makeShader "dualTwoD/basic" [vert', frag'] [3, 4] ETriangles 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 >>= 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 ^. 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 >>= addTexture "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 bindShaderBuffers' [fsShad] [4, 4] framebuf2 <- setupTextureFramebuffer 800 600 framebuf3 <- setupTextureFramebuffer 800 600 rboBaseBloomName <- genObjectName bindRenderbuffer Renderbuffer $= rboBaseBloomName renderbufferStorage Renderbuffer Depth24Stencil8 (RenderbufferSize 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 bindFramebuffer Framebuffer $= defaultFramebufferObject -- set the clearColor to have 1 alpha clearColor $= Color4 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 ] return $ RenderData { _pictureShaders = shadV , _shapeShader = bslista{_shadVAO' = shPosColVAO} , _shapeEBO = shEBO , _silhouetteEBO = silEBO , _lightingCapShader = lightingCapShad , _lightingLineShadowShader = lightingLineShadowShad , _positionalBlankShader = positionalBlankShad , _lightingWallShadShader = lightingWallShadShad , _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 } --------------------end preloadRender cornerList :: [[Float]] cornerList = [ [-1, 1, 0, 1] , [-1, -1, 0, 0] , [1, 1, 1, 1] , [1, -1, 1, 0] ] cleanUpRenderPreload :: RenderData -> IO () cleanUpRenderPreload pd = do -- TODO fix this --mapM_ freeShaderPointers $ _pictureShaders pd freeShaderPointers' $ _lightingWallShadShader pd freeShaderPointers' $ _fullscreenShader pd