--{-# 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.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 shVBO <- setupVBO nShapeVerxComp shPosVAOname <- mglCreate glCreateVertexArrays glBindVertexArray shPosVAOname glVertexArrayVertexBuffer shPosVAOname 0 (shVBO ^. vboName) 0 (fromIntegral $ floatSize * nShapeVerxComp) setupVertexAttribPointer shPosVAOname 0 4 0 let shPosVAO = VAO{_vaoName = shPosVAOname} --setup silhouette edge VAO shEBO' <- setupEBO shPosVAO 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] pmPoints wpVAO lightingCapShad <- makeShaderUsingVAO "lighting/cap" [vert, geom] pmTriangles shPosVAO lightingLineShadowShad <- makeShaderUsingVAO "lighting/lineShadow" [vert, geom] pmLinesAdjacency shEdgeVAO shadowedgeshader <- makeShaderUsingVAO "shadow/edge" [vert, geom] pmLinesAdjacency shEdgeVAO shadowcapshader <- makeShaderUsingVAO "shadow/cap" [vert, geom] pmTriangles shPosVAO shadowwallshader <- makeShaderUsingVAO "shadow/wallShadow" [vert, geom] pmPoints wpVAO shadowlightshader <- makeShaderSized "shadow/light" [vert, geom, frag] [1] 1 pmPoints shadowcombineshader <- makeShaderSized "shadow/combine" [vert,geom,frag] [1] 1 pmPoints poke (shadVBOptr shadowlightshader) 1 -- positional shader positionalBlankShad <- makeShader "positional/blank" [vert, frag] [3] pmTriangles -- 2D draw shaders bslist <- makeShader "dualTwoD/basic" [vert, frag] [3, 4] pmTriangles bslista <- makeShader4 "shape/basic" [vert, frag] shapeVerxSizes nShapeVerxComp pmTriangles shVBO glVertexArrayElementBuffer (bslista ^. shaderVAO . vaoName) (shEBO' ^. eboName) --glVertexArrayElementBuffer (bslista ^. shaderVAO . vaoName) shEBOname aslist <- makeShader "dualTwoD/arc" [vert, frag] [3, 4, 3] pmTriangles eslist <- makeShader "dualTwoD/ellipse" [vert, geom, frag] [3, 4] pmTriangles bezierQuadShader <- makeShader "dualTwoD/bezierQuad" [vert, frag] [3, 4, 4] pmTriangleStrip cslist <- makeShader "dualTwoD/character" [vert, frag] [3, 4, 2] pmTriangles >>= _1 (vaddTextureNoFilter "data/texture/charMap.png") -- this should really be a 2d texture array screentexturevbo <- mglCreate glCreateBuffers withArray (concat cornerList) $ \ptr -> glNamedBufferStorage screentexturevbo (fromIntegral $ floatSize * length (concat cornerList)) ptr 0 screentexturevao <- setupVAOvbo' [2,2] 4 screentexturevbo alphadivideshader <- makeShader4UsingVAO "texture2D/alphaDivide" [vert,frag] pmTriangleStrip screentexturevao fsShad <- makeShader4UsingVAO "texture/simple" [vert, frag] pmTriangleStrip screentexturevao bloomBlurShad <- makeShaderUsingVAO "texture/bloomBlur" [vert, frag] pmTriangleStrip screentexturevao colorBlurShad <- makeShaderUsingVAO "texture/colorBlur" [vert, frag] pmTriangleStrip screentexturevao grayscaleShad <- makeShaderUsingVAO "texture/grayscale" [vert, frag] pmTriangleStrip screentexturevao lightingTextureShad <- makeShaderUsingVAO "lighting/texture" [vert, frag] pmTriangleStrip screentexturevao barrelShad <- makeShader "texture/barrel" [vert, geom, frag] [2, 2, 2, 1] pmPoints -- blank wallShader wallBlankShad <- makeShaderUsingVAO "wall/blank" [vert, geom, frag] pmPoints wpColVAO -- textured wallShader wallTextureShad <- makeShaderUsingVAO "wall/texture" [vert, geom, frag] pmPoints wpColVAO let wallverxstrd = 8 wallvbo <- setupVBO wallverxstrd wallshader <- makeShader4 "wall/basic" [vert,geom,frag] [4,4] wallverxstrd pmPoints wallvbo let floorverxstrd = 8 floorvbo <- setupVBOStatic floorverxstrd floorshader <- makeShader4 "floor/arrayPos" [vert, frag] [4,4] floorverxstrd pmTriangles floorvbo tonormalmap <- initTexture2DArray 3 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR "data/normalMaps/normalArray.png" todiffusemap <- initTexture2DArray 3 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR "data/normalMaps/diffuseArray.png" let cloudverxsizes = [4,4,4,4] cloudvbo <- setupVBO (sum cloudverxsizes) (cloudshader, cloudebo) <- makeShaderEBO "cloud/basic" [vert, frag] cloudverxsizes (sum cloudverxsizes) pmTriangles cloudvbo framebuf2 <- setupTextureFramebuffer 800 600 framebuf3 <- setupTextureFramebuffer 800 600 rboBaseBloomName <- mglCreate glCreateRenderbuffers glNamedRenderbufferStorage rboBaseBloomName GL_DEPTH24_STENCIL8 800 600 fboBaseName <- setupFramebuffer3GivenStencil rboBaseBloomName fboCloudName <- setupFramebuffer3GivenStencil 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 5 zipWithM_ (MV.write shadV) [0 .. 4] [ bslist -- note the ordering is very important , bezierQuadShader , cslist , aslist , eslist ] initializeGLState return $ RenderData { _pictureShaders = shadV , _shapeShader = bslista -- & shaderVAO' .~ 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{_shaderVAO = winColVAO} -- , _textureArrayShader = textArrayShad , _fullscreenShader = fsShad , _alphaDivideShader = alphadivideshader , _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 , _floorVBO = floorvbo , _floorShader = floorshader , _toNormalMaps = tonormalmap , _toDiffuse = todiffusemap , _wallVBO = wallvbo , _wallShader = wallshader , _cloudVBO = cloudvbo , _cloudShader = cloudshader , _cloudEBO = cloudebo , _screenTextureVAO = screentexturevao } --------------------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