Try to improve instancing shadows
This commit is contained in:
@@ -50,7 +50,7 @@ data RenderData = RenderData
|
||||
, _fboColor :: (FBO, TO)
|
||||
, _fboPos :: (FBO, TO)
|
||||
, _fboLighting :: (FBO, TO)
|
||||
, _fboLightingHigh :: (FBO, TO)
|
||||
--, _fboLightingHigh :: (FBO, TO)
|
||||
, _fboShadow :: (FBO, (TO, TO))
|
||||
, _rboBaseBloom :: GLuint -- RenderbufferObject id
|
||||
, _matUBO :: GLuint -- BufferObject id
|
||||
|
||||
@@ -89,6 +89,8 @@ data ObjectShadows = GeoObjShads
|
||||
| InstancingShads
|
||||
| CPUObjShads
|
||||
| NoObjShads
|
||||
| NoShadows
|
||||
| NoLighting
|
||||
deriving (Show, Eq, Ord, Enum, Bounded)
|
||||
|
||||
data RoomClipping = NoRoomClipBoundaries | AllRoomClipBoundaries | IntersectingRoomClipBoundaries
|
||||
|
||||
+28
-39
@@ -3,26 +3,27 @@ module Dodge.Render (
|
||||
doDrawing,
|
||||
) where
|
||||
|
||||
import qualified Data.Map.Strict as M
|
||||
import Picture.Base
|
||||
import qualified SDL
|
||||
import qualified Data.Vector as V
|
||||
import Dodge.Render.Shadow
|
||||
--import qualified Data.Vector as V
|
||||
|
||||
import Control.Lens
|
||||
import Control.Monad
|
||||
import qualified Control.Monad.Parallel as MP
|
||||
import qualified Data.Map.Strict as M
|
||||
import Data.Preload.Render
|
||||
import qualified Data.Vector.Unboxed.Mutable as UMV
|
||||
import Dodge.Data.Universe
|
||||
import Dodge.Render.Lights
|
||||
import Dodge.Render.Picture
|
||||
import Dodge.Render.Shadow
|
||||
import Dodge.Render.ShapePicture
|
||||
import Dodge.Render.Walls
|
||||
import Foreign
|
||||
import Geometry
|
||||
import Graphics.GL.Core45
|
||||
import MatrixHelper
|
||||
import Picture.Base
|
||||
import Render
|
||||
import qualified SDL
|
||||
--import qualified SDL
|
||||
import Shader
|
||||
import Shader.Bind
|
||||
@@ -55,13 +56,11 @@ doDrawing' win pdata u = do
|
||||
lightPoints = lightsToRender cfig (w ^. cWorld . camPos) (w ^. cWorld . lWorld)
|
||||
viewFroms@(V2 vfx vfy) = w ^. cWorld . camPos . camViewFrom
|
||||
shadV = _pictureShaders pdata
|
||||
lwShad = _lightingWallShadShader pdata
|
||||
-- bind as much data into vbos as feasible at this point
|
||||
-- count mutable vectors setup
|
||||
layerCounts <- UMV.replicate (numLayers * 6) 0
|
||||
-- attempt to poke in parallel
|
||||
let (ws, wp) = wallSPics <> worldSPic cfig w
|
||||
--( (nWalls, nWins , nFls),(nShapeVs, nIndices, nSilIndices) )
|
||||
((nWalls, nWins, nFls), (nShapeVs, nIndices, nSilIndices)) <-
|
||||
MP.bindM3
|
||||
(\_ a b -> return (a, b))
|
||||
@@ -109,21 +108,18 @@ doDrawing' win pdata u = do
|
||||
withArray (perspectiveMatrixb rot camzoom trans wins viewFroms) $ \ptr ->
|
||||
glNamedBufferSubData (pdata ^. matUBO) 0 64 ptr
|
||||
setViewportSize (round winx `div` resFact) (round winy `div` resFact)
|
||||
--bindFramebuffer Framebuffer $= fst (_fboBase pdata)
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata)))
|
||||
glDepthMask GL_TRUE
|
||||
glClearColor 0 0 0 1
|
||||
glClear $ sum [GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT]
|
||||
glDepthFunc GL_LESS
|
||||
-- draw wall occlusions from the camera's point of view
|
||||
-- currentProgram $= lwShad ^? shadProg -- Just (_shadProg lwShad)
|
||||
-- uniform (_shadUnis lwShad V.! 0) $= viewFrom3d
|
||||
glUseProgram (lwShad ^. shadProg')
|
||||
glUniform3f (_shadUnis' lwShad V.! 0) vfx vfy 20
|
||||
--bindVertexArrayObject $= lwShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwShad)
|
||||
glBindVertexArray $ lwShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwShad)
|
||||
glUseProgram (pdata ^. lightingWallShadShader . shadProg')
|
||||
glUniform3f (pdata ^?! lightingWallShadShader . shadUnis' . ix 0) vfx vfy 20
|
||||
glBindVertexArray $ pdata ^. lightingWallShadShader . shadVAO' . vaoName
|
||||
unless (debugOn Remove_LOS cfig) $
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode $ _shadPrim' lwShad)
|
||||
(marshalEPrimitiveMode $ pdata ^. lightingWallShadShader . shadPrim')
|
||||
0
|
||||
(fromIntegral nWalls)
|
||||
--draw walls onto base buffer
|
||||
@@ -134,20 +130,16 @@ doDrawing' win pdata u = do
|
||||
renderLayer BottomLayer shadV layerCounts
|
||||
--draw object shapes onto base buffer
|
||||
let fs = _shapeShader pdata
|
||||
--currentProgram $= Just (_shadProg fs)
|
||||
glUseProgram (_shadProg' fs)
|
||||
--bindVertexArrayObject $= fs ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO fs)
|
||||
glBindVertexArray $ fs ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO fs)
|
||||
glBindVertexArray $ fs ^. shadVAO' . vaoName
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' fs)
|
||||
(fromIntegral nIndices)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
--draw floor onto base buffer
|
||||
-- nTextArrayVs <- pokePoint33s (shadVBOptr $ _textureArrayShader pdata) (_floorTiles w)
|
||||
drawShader (_textureArrayShader pdata) nFls
|
||||
--draw lightmap into its own buffer
|
||||
--bindFramebuffer Framebuffer $= fst (_fboLighting pdata)
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
|
||||
createLightMap
|
||||
cfig
|
||||
@@ -156,23 +148,18 @@ doDrawing' win pdata u = do
|
||||
nWalls
|
||||
nSilIndices
|
||||
nIndices
|
||||
--(_graphics_object_shadows $ _uvConfig u)
|
||||
(u ^. uvConfig . graphics_object_shadows)
|
||||
(snd $ snd $ pdata ^. fboBase)
|
||||
(drawCPUShadows pdata ws)
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glClearColor 0 0 0 0
|
||||
--apply lightmap to base buffer
|
||||
--bindFramebuffer Framebuffer $= pdata ^. fboBase . _1 --fst (_fboBase pdata)
|
||||
glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBase . _1 . unFBO)
|
||||
--textureBinding Texture2D $= Just (snd $ _fboLighting pdata)
|
||||
--textureBinding Texture2D $= pdata ^? fboLighting . _2 -- Just (snd $ _fboLighting pdata)
|
||||
glBindTexture GL_TEXTURE_2D (pdata ^. fboLighting . _2 . unTO) -- Just (snd $ _fboLighting pdata)
|
||||
glBindTexture GL_TEXTURE_2D (pdata ^. fboLighting . _2 . unTO)
|
||||
glEnable GL_BLEND
|
||||
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
|
||||
drawShader (_fullscreenShader pdata) 4
|
||||
--draw bloom onto bloom buffer
|
||||
--bindFramebuffer Framebuffer $= pdata ^. fboBloom . _1 --fst (_fboBloom pdata)
|
||||
glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBloom . _1 . unFBO)
|
||||
glClear GL_COLOR_BUFFER_BIT
|
||||
glDepthFunc GL_LESS
|
||||
@@ -233,7 +220,7 @@ doDrawing' win pdata u = do
|
||||
(_graphics_object_shadows $ _uvConfig u)
|
||||
(snd $ snd $ _fboCloud pdata)
|
||||
(drawCPUShadows pdata ws)
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glClearColor 0 0 0 0
|
||||
--apply lightmap to cloud buffer
|
||||
glClearColor 0 0 0 0
|
||||
@@ -307,14 +294,15 @@ doDrawing' win pdata u = do
|
||||
renderFoldable shadV $ fixedCoordPictures u
|
||||
glDepthMask GL_TRUE
|
||||
when (debugOn Show_ms_frame $ _uvConfig u) $
|
||||
renderFoldable
|
||||
(_pictureShaders pdata)
|
||||
( setDepth (-1)
|
||||
. translate (-0.5) (-0.8)
|
||||
. scale 0.0005 0.0005
|
||||
$ fpsText (u ^. uvFrameTicks - u ^. uvLastFrameTicks)
|
||||
)
|
||||
renderFoldable
|
||||
(_pictureShaders pdata)
|
||||
( setDepth (-1)
|
||||
. translate (-0.5) (-0.8)
|
||||
. scale 0.0005 0.0005
|
||||
$ fpsText (u ^. uvFrameTicks - u ^. uvLastFrameTicks)
|
||||
)
|
||||
SDL.glSwapWindow win
|
||||
|
||||
-- eTicks <- SDL.ticks
|
||||
-- return (eTicks - sTicks)
|
||||
|
||||
@@ -328,7 +316,6 @@ fpsText x = color col $ text $ "ms/frame " ++ show x
|
||||
| x < 50 = orange
|
||||
| otherwise = red
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- note: currently assume there is only one UBO, we only bind it once at setup
|
||||
--bufferUBO :: GLuint -> [Float] -> IO ()
|
||||
@@ -350,7 +337,8 @@ renderBlankWalls pdata nWalls = do
|
||||
--cullFace $= Just Back
|
||||
drawShader (_wallBlankShader pdata) nWalls
|
||||
glDisable GL_CULL_FACE
|
||||
--cullFace $= Nothing
|
||||
|
||||
--cullFace $= Nothing
|
||||
|
||||
renderTextureWalls ::
|
||||
RenderData ->
|
||||
@@ -363,11 +351,12 @@ renderTextureWalls pdata nWalls = do
|
||||
glCullFace GL_BACK
|
||||
drawShader (_wallTextureShader pdata) nWalls
|
||||
glDisable GL_CULL_FACE
|
||||
--cullFace $= Nothing
|
||||
|
||||
--cullFace $= Nothing
|
||||
|
||||
checkGLError :: IO ()
|
||||
checkGLError = do
|
||||
err <- glGetError
|
||||
err <- glGetError
|
||||
case err of
|
||||
0 -> return ()
|
||||
i -> error $ "OpenGL error: " ++ show i
|
||||
|
||||
@@ -33,7 +33,8 @@ sizeFBOs xsize ysize xfull yfull rdata = do
|
||||
foldM (updateFBOTO2 xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8 GL_RGBA16F) rdata [fboBase, fboCloud]
|
||||
>>= flip
|
||||
(foldM (updateFBOTO xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8))
|
||||
[fboColor, fboLighting, fboLightingHigh]
|
||||
[fboColor, fboLighting]
|
||||
--[fboColor, fboLighting, fboLightingHigh]
|
||||
rdata'' <-
|
||||
foldM
|
||||
(updateFBOTO xsize ysize GL_LINEAR_MIPMAP_LINEAR GL_LINEAR GL_RGBA16F)
|
||||
|
||||
@@ -213,7 +213,7 @@ preloadRender = do
|
||||
fboColorName <- setupFramebufferGivenStencil rboBaseBloomName
|
||||
fboPosName <- setupFramebufferGivenStencil rboBaseBloomName
|
||||
fboLightingName <- setupFramebufferGivenStencil rboBaseBloomName
|
||||
fboLightingHighName <- setupFramebufferGivenStencil rboBaseBloomName
|
||||
--fboLightingHighName <- setupFramebufferGivenStencil rboBaseBloomName
|
||||
|
||||
fboShadowName <- setupShadowFramebuffer
|
||||
|
||||
@@ -238,7 +238,7 @@ preloadRender = do
|
||||
, aslist
|
||||
, eslist
|
||||
]
|
||||
|
||||
initializeGLState
|
||||
return $
|
||||
RenderData
|
||||
{ _pictureShaders = shadV
|
||||
@@ -270,7 +270,7 @@ preloadRender = do
|
||||
, _fboHalf2 = fboHalf2Name
|
||||
, _fboHalf3 = fboHalf3Name
|
||||
, _fboLighting = fboLightingName
|
||||
, _fboLightingHigh = fboLightingHighName
|
||||
--, _fboLightingHigh = fboLightingHighName
|
||||
, _fboShadow = fboShadowName
|
||||
, _fboBase = fboBaseName
|
||||
, _fboCloud = fboCloudName
|
||||
@@ -301,6 +301,10 @@ cornerList =
|
||||
-- , [1, -1, 1, 0]
|
||||
-- ]
|
||||
|
||||
initializeGLState :: IO ()
|
||||
initializeGLState = do
|
||||
glEnable GL_DEPTH_TEST
|
||||
|
||||
cleanUpRenderPreload :: RenderData -> IO ()
|
||||
cleanUpRenderPreload pd = do
|
||||
-- TODO fix this
|
||||
|
||||
+197
-139
@@ -7,9 +7,8 @@ module Render (
|
||||
bindFBO,
|
||||
) where
|
||||
|
||||
import Control.Monad
|
||||
import Dodge.WindowSize
|
||||
import Control.Lens
|
||||
import Control.Monad
|
||||
import Control.Monad.Primitive
|
||||
import Data.Preload.Render
|
||||
import qualified Data.Vector as V
|
||||
@@ -18,6 +17,7 @@ import qualified Data.Vector.Fusion.Stream.Monadic as VFSM
|
||||
import qualified Data.Vector.Mutable as MV
|
||||
import qualified Data.Vector.Unboxed.Mutable as UMV
|
||||
import Dodge.Data.Config
|
||||
import Dodge.WindowSize
|
||||
import Foreign hiding (rotate)
|
||||
import Geometry.Data
|
||||
import Graphics.GL.Core45
|
||||
@@ -26,13 +26,15 @@ import Shader
|
||||
import Shader.Data
|
||||
import Shader.ExtraPrimitive
|
||||
|
||||
-- | Determine where light is shining in the world.
|
||||
-- think of the produced texture as showing what RGB values should be "taken
|
||||
-- away" from the shape colors.
|
||||
{- | Determine where light is shining in the world.
|
||||
think of the produced texture as showing what RGB values should be "taken
|
||||
away" from the shape colors.
|
||||
-}
|
||||
createLightMap ::
|
||||
Configuration ->
|
||||
RenderData ->
|
||||
[(Point3, Float, Point3)] -> -- Lights
|
||||
|
||||
-- | number of walls
|
||||
Int ->
|
||||
-- | number of silhoutte lines to draw
|
||||
@@ -46,107 +48,159 @@ createLightMap ::
|
||||
(Point3 -> Float -> IO ()) -> -- attempt at drawing shadow not using geo shader
|
||||
IO ()
|
||||
createLightMap cfig pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos drawCPUShadows = case shadsdrawtype of
|
||||
InstancingShads -> instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos
|
||||
_ -> do
|
||||
let llinesShad = _lightingLineShadowShader pdata
|
||||
lcapShad = _lightingCapShader pdata
|
||||
lwallShad = _lightingWallShadShader pdata
|
||||
ltextShad = _lightingTextureShader pdata
|
||||
-- we assume that the renderbuffer's depth has been correctly set elsewhere
|
||||
-- we will not be changing that here
|
||||
glDepthMask GL_FALSE
|
||||
-- clearColor is specified differently in preloadRender
|
||||
-- the colors are inverted
|
||||
glClearColor 1 1 1 1
|
||||
glClear GL_COLOR_BUFFER_BIT
|
||||
-- for each of the lights:
|
||||
-- 1. stencil out the shadows from this light's point of view
|
||||
-- 2. calculate lighting based on each fragment's position
|
||||
-- to consider: adding normals/a "material" for each fragment
|
||||
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
|
||||
glEnable GL_STENCIL_TEST
|
||||
--stencilTest $= Enabled
|
||||
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
|
||||
--stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap)
|
||||
--stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap)
|
||||
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
|
||||
flip VFSM.mapM_ (VFSM.fromList lightPoints) $ \(V3 x y z, rad, V3 r g b) -> do
|
||||
glDepthFunc GL_LESS
|
||||
-- setup stencil
|
||||
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
|
||||
glClear GL_STENCIL_BUFFER_BIT
|
||||
InstancingShads -> instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos
|
||||
NoShadows -> do
|
||||
let ltextShad = _lightingTextureShader pdata
|
||||
-- we assume that the renderbuffer's depth has been correctly set elsewhere
|
||||
-- we will not be changing that here
|
||||
glDepthMask GL_FALSE
|
||||
-- clearColor is specified differently in preloadRender
|
||||
-- the colors are inverted
|
||||
glClearColor 1 1 1 1
|
||||
glClear GL_COLOR_BUFFER_BIT
|
||||
-- for each of the lights:
|
||||
-- 1. stencil out the shadows from this light's point of view
|
||||
-- 2. calculate lighting based on each fragment's position
|
||||
-- to consider: adding normals/a "material" for each fragment
|
||||
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
|
||||
glEnable GL_STENCIL_TEST
|
||||
--stencilTest $= Enabled
|
||||
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
|
||||
--stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap)
|
||||
--stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap)
|
||||
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
|
||||
flip VFSM.mapM_ (VFSM.fromList lightPoints) $ \(V3 x y z, rad, V3 r g b) -> do
|
||||
glDepthFunc GL_LESS
|
||||
-- setup stencil
|
||||
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
|
||||
glClear GL_STENCIL_BUFFER_BIT
|
||||
glDisable GL_CULL_FACE
|
||||
--cullFace $= Nothing
|
||||
glStencilFunc GL_ALWAYS 0 255
|
||||
--draw lightmap itself
|
||||
glDepthFunc GL_ALWAYS
|
||||
-- bind world position texture
|
||||
bindTO toPos
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glStencilFunc GL_EQUAL 0 255
|
||||
glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad)
|
||||
glUniform3f (_shadUnis' ltextShad V.! 0) x y z
|
||||
glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad
|
||||
--bindVertexArrayObject $= ltextShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glBindVertexArray $ ltextShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode (_shadPrim' ltextShad))
|
||||
0
|
||||
(fromIntegral (4 :: Int))
|
||||
--cleanup: may not be necessary, depending on what comes after...
|
||||
glDisable GL_CULL_FACE
|
||||
glDisable GL_STENCIL_TEST
|
||||
NoLighting -> do
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
|
||||
glClearColor 0 0 0 1
|
||||
-- glClearDepth 0
|
||||
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
|
||||
glClear $ GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT
|
||||
-- glClearDepth 1
|
||||
glDisable GL_CULL_FACE
|
||||
--cullFace $= Nothing
|
||||
glStencilFunc GL_ALWAYS 0 255
|
||||
--draw wall shadows
|
||||
--currentProgram $= Just (_shadProg lwallShad)
|
||||
glUseProgram (_shadProg' lwallShad)
|
||||
--uniform (_shadUnis lwallShad V.! 0)
|
||||
-- $= Vector3 x y z
|
||||
glUniform3f (_shadUnis' lwallShad V.! 0) x y z
|
||||
--bindVertexArrayObject $= lwallShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode $ _shadPrim' lwallShad)
|
||||
0
|
||||
(fromIntegral nWalls)
|
||||
case shadsdrawtype of
|
||||
GeoObjShads -> do
|
||||
--draw silhouette shadows
|
||||
glUseProgram (_shadProg' llinesShad)
|
||||
glUniform3f (_shadUnis' llinesShad V.! 0) x y z
|
||||
glUniform1f (_shadUnis' llinesShad V.! 1) rad
|
||||
glBindVertexArray (_vaoName $ _shadVAO' llinesShad)
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' llinesShad)
|
||||
(fromIntegral nSils)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
--draw caps on the near plane as required
|
||||
glEnable GL_CULL_FACE
|
||||
glCullFace GL_BACK
|
||||
glUseProgram (_shadProg' lcapShad)
|
||||
glUniform3f (_shadUnis' lcapShad V.! 0) x y z
|
||||
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad)
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' lcapShad)
|
||||
(fromIntegral nCaps)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
CPUObjShads -> drawCPUShadows (V3 x y z) rad
|
||||
NoObjShads -> return ()
|
||||
--draw lightmap itself
|
||||
glEnable GL_DEPTH_TEST
|
||||
glDepthFunc GL_ALWAYS
|
||||
--depthFunc $= Just Always
|
||||
-- bind world position texture
|
||||
bindTO toPos
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
--stencilOp $= (OpKeep, OpKeep, OpKeep)
|
||||
glStencilFunc GL_EQUAL 0 255
|
||||
--currentProgram $= ltextShad ^? shadProg --Just (_shadProg ltextShad)
|
||||
--uniform (_shadUnis ltextShad V.! 0) $= Vector3 x y z
|
||||
--uniform (_shadUnis ltextShad V.! 1) $= Vector4 r g b rad
|
||||
glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad)
|
||||
glUniform3f (_shadUnis' ltextShad V.! 0) x y z
|
||||
glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad
|
||||
--bindVertexArrayObject $= ltextShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glBindVertexArray $ ltextShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode (_shadPrim' ltextShad))
|
||||
0
|
||||
(fromIntegral (4 :: Int))
|
||||
--cleanup: may not be necessary, depending on what comes after...
|
||||
glDisable GL_CULL_FACE
|
||||
glDisable GL_STENCIL_TEST
|
||||
glDepthFunc GL_ALWAYS
|
||||
glDepthMask GL_FALSE
|
||||
_ -> do
|
||||
let llinesShad = _lightingLineShadowShader pdata
|
||||
lcapShad = _lightingCapShader pdata
|
||||
lwallShad = _lightingWallShadShader pdata
|
||||
ltextShad = _lightingTextureShader pdata
|
||||
-- we assume that the renderbuffer's depth has been correctly set elsewhere
|
||||
-- we will not be changing that here
|
||||
glDepthMask GL_FALSE
|
||||
-- clearColor is specified differently in preloadRender
|
||||
-- the colors are inverted
|
||||
glClearColor 1 1 1 1
|
||||
glClear GL_COLOR_BUFFER_BIT
|
||||
-- for each of the lights:
|
||||
-- 1. stencil out the shadows from this light's point of view
|
||||
-- 2. calculate lighting based on each fragment's position
|
||||
-- to consider: adding normals/a "material" for each fragment
|
||||
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
|
||||
glEnable GL_STENCIL_TEST
|
||||
--stencilTest $= Enabled
|
||||
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
|
||||
--stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap)
|
||||
--stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap)
|
||||
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
|
||||
flip VFSM.mapM_ (VFSM.fromList lightPoints) $ \(V3 x y z, rad, V3 r g b) -> do
|
||||
glDepthFunc GL_LESS
|
||||
-- setup stencil
|
||||
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
|
||||
glClear GL_STENCIL_BUFFER_BIT
|
||||
glDisable GL_CULL_FACE
|
||||
--cullFace $= Nothing
|
||||
glStencilFunc GL_ALWAYS 0 255
|
||||
--draw wall shadows
|
||||
--currentProgram $= Just (_shadProg lwallShad)
|
||||
glUseProgram (_shadProg' lwallShad)
|
||||
--uniform (_shadUnis lwallShad V.! 0)
|
||||
-- $= Vector3 x y z
|
||||
glUniform3f (_shadUnis' lwallShad V.! 0) x y z
|
||||
--bindVertexArrayObject $= lwallShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode $ _shadPrim' lwallShad)
|
||||
0
|
||||
(fromIntegral nWalls)
|
||||
case shadsdrawtype of
|
||||
GeoObjShads -> do
|
||||
--draw silhouette shadows
|
||||
glUseProgram (_shadProg' llinesShad)
|
||||
glUniform3f (_shadUnis' llinesShad V.! 0) x y z
|
||||
glUniform1f (_shadUnis' llinesShad V.! 1) rad
|
||||
glBindVertexArray (_vaoName $ _shadVAO' llinesShad)
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' llinesShad)
|
||||
(fromIntegral nSils)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
--draw caps on the near plane as required
|
||||
glEnable GL_CULL_FACE
|
||||
glCullFace GL_BACK
|
||||
glUseProgram (_shadProg' lcapShad)
|
||||
glUniform3f (_shadUnis' lcapShad V.! 0) x y z
|
||||
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad)
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' lcapShad)
|
||||
(fromIntegral nCaps)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
CPUObjShads -> drawCPUShadows (V3 x y z) rad
|
||||
NoObjShads -> return ()
|
||||
--draw lightmap itself
|
||||
glDepthFunc GL_ALWAYS
|
||||
-- bind world position texture
|
||||
bindTO toPos
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glStencilFunc GL_EQUAL 0 255
|
||||
glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad)
|
||||
glUniform3f (_shadUnis' ltextShad V.! 0) x y z
|
||||
glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad
|
||||
--bindVertexArrayObject $= ltextShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glBindVertexArray $ ltextShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode (_shadPrim' ltextShad))
|
||||
0
|
||||
(fromIntegral (4 :: Int))
|
||||
--cleanup: may not be necessary, depending on what comes after...
|
||||
glDisable GL_CULL_FACE
|
||||
glDisable GL_STENCIL_TEST
|
||||
|
||||
lightsToArray :: [(Point3,Float,Point3)] -> [Float]
|
||||
lightsToArray xs = concat (take 20 $ map t xs ++ repeat [0,0,0,0])
|
||||
++ concat (take 20 $ map s xs ++ repeat [0,0,0,0])
|
||||
lightsToArray :: [(Point3, Float, Point3)] -> [Float]
|
||||
lightsToArray xs =
|
||||
concat (take 20 $ map t xs ++ repeat [0, 0, 0, 0])
|
||||
++ concat (take 20 $ map s xs ++ repeat [0, 0, 0, 0])
|
||||
where
|
||||
t (V3 a b c,_,_) = [a,b,c,1]
|
||||
s (_,d,V3 e f g) = [e,f,g,d]
|
||||
--t (V3 a b c,d,V3 e f g) = [a,b,c,1]
|
||||
t (V3 a b c, _, _) = [a, b, c, 1]
|
||||
s (_, d, V3 e f g) = [e, f, g, d]
|
||||
|
||||
|
||||
instanceLightMap ::
|
||||
Configuration ->
|
||||
@@ -162,52 +216,53 @@ instanceLightMap ::
|
||||
TO ->
|
||||
IO ()
|
||||
instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
|
||||
let llinesShad = _shadowEdgeShader pdata
|
||||
lcapShad = _shadowCapShader pdata
|
||||
lwallShad = _shadowWallShader pdata
|
||||
(xsize,ysize) = getWindowSize cfig
|
||||
let lcapShad = _shadowCapShader pdata
|
||||
(xsize, ysize) = getWindowSize cfig
|
||||
withArray (lightsToArray lightPoints) $ \ptr ->
|
||||
glNamedBufferSubData (pdata ^. lightsUBO) 0 620 ptr
|
||||
|
||||
forM_ [0..19] $ \i -> glCopyImageSubData
|
||||
(pdata ^. rboBaseBloom)
|
||||
GL_RENDERBUFFER
|
||||
0
|
||||
0 0 0
|
||||
(pdata ^. fboShadow . _2 . _2 . unTO)
|
||||
GL_TEXTURE_2D_ARRAY 0 0 0 i (fromIntegral xsize) (fromIntegral ysize)
|
||||
1
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboShadow pdata)))
|
||||
forM_ [0 .. 19] $ \i ->
|
||||
glCopyImageSubData
|
||||
(pdata ^. rboBaseBloom)
|
||||
GL_RENDERBUFFER
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
(pdata ^. fboShadow . _2 . _2 . unTO)
|
||||
GL_TEXTURE_2D_ARRAY
|
||||
0
|
||||
0
|
||||
0
|
||||
i
|
||||
(fromIntegral xsize)
|
||||
(fromIntegral ysize)
|
||||
1
|
||||
glBindFramebuffer GL_FRAMEBUFFER $ pdata ^. fboShadow . _1 . unFBO
|
||||
glDepthMask GL_FALSE
|
||||
-- clearColor is specified differently in preloadRender
|
||||
-- the colors are inverted
|
||||
glClearColor 0 0 0 0
|
||||
glClear $ GL_COLOR_BUFFER_BIT + GL_STENCIL_BUFFER_BIT
|
||||
-- for each of the lights:
|
||||
-- 1. stencil out the shadows from this light's point of view
|
||||
-- 2. calculate lighting based on each fragment's position
|
||||
-- to consider: adding normals/a "material" for each fragment
|
||||
-- stencil out the shadows from each light's point of view
|
||||
-- setup stencil
|
||||
glEnable GL_STENCIL_TEST
|
||||
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
|
||||
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
|
||||
-- this was a loop
|
||||
glDepthFunc GL_LESS
|
||||
-- setup stencil
|
||||
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
|
||||
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
|
||||
glDisable GL_BLEND
|
||||
glDisable GL_CULL_FACE
|
||||
glStencilFunc GL_ALWAYS 0 255
|
||||
--draw wall shadows
|
||||
glUseProgram (_shadProg' lwallShad)
|
||||
glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glUseProgram $ pdata ^. shadowWallShader . shadProg'
|
||||
glBindVertexArray $ pdata ^. shadowWallShader . shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode $ _shadPrim' lwallShad)
|
||||
(marshalEPrimitiveMode $ pdata ^. shadowWallShader . shadPrim')
|
||||
0
|
||||
(fromIntegral nWalls)
|
||||
--draw silhouette shadows
|
||||
glUseProgram (_shadProg' llinesShad)
|
||||
glBindVertexArray (_vaoName $ _shadVAO' llinesShad)
|
||||
glUseProgram $ pdata ^. shadowEdgeShader . shadProg'
|
||||
glBindVertexArray $ pdata ^. shadowEdgeShader . shadVAO' . vaoName
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' llinesShad)
|
||||
(marshalEPrimitiveMode $ pdata ^. shadowEdgeShader . shadPrim')
|
||||
(fromIntegral nSils)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
@@ -215,31 +270,27 @@ instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
|
||||
glEnable GL_CULL_FACE
|
||||
glCullFace GL_BACK
|
||||
glUseProgram (_shadProg' lcapShad)
|
||||
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad)
|
||||
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName
|
||||
glDrawElements
|
||||
(marshalEPrimitiveMode $ _shadPrim' lcapShad)
|
||||
(fromIntegral nCaps)
|
||||
GL_UNSIGNED_SHORT
|
||||
nullPtr
|
||||
--draw lightmap itself
|
||||
glEnable GL_DEPTH_TEST
|
||||
--draw lightmap itself
|
||||
glDepthFunc GL_ALWAYS
|
||||
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
|
||||
glStencilFunc GL_EQUAL 0 255
|
||||
glUseProgram (pdata ^. shadowLightShader . shadProg')
|
||||
-- bind world position texture
|
||||
bindTO toPos
|
||||
glDisable GL_BLEND
|
||||
glBindVertexArray $ pdata ^. shadowLightShader . shadVAO' . vaoName
|
||||
glDrawArrays
|
||||
(marshalEPrimitiveMode $ pdata ^. shadowLightShader . shadPrim')
|
||||
0
|
||||
1
|
||||
|
||||
-- this was the end of the loop
|
||||
glDisable GL_CULL_FACE
|
||||
glDisable GL_STENCIL_TEST
|
||||
|
||||
--draw to the lighting framebuffer here
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
|
||||
glClearColor 1 1 1 1
|
||||
@@ -252,6 +303,11 @@ instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
|
||||
(marshalEPrimitiveMode EPoints)
|
||||
0
|
||||
1
|
||||
withArray [GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT] $ \ptr ->
|
||||
glInvalidateNamedFramebufferData
|
||||
(pdata ^. fboShadow . _1 . unFBO)
|
||||
2
|
||||
ptr
|
||||
|
||||
-- assumes that vertices have already been sent to the shader
|
||||
pingPongBetween ::
|
||||
@@ -294,8 +350,10 @@ renderLayer layer shads counts = do
|
||||
|
||||
bindTO :: TO -> IO ()
|
||||
bindTO t = glBindTexture GL_TEXTURE_2D (_unTO t)
|
||||
--textureBinding Texture2D $= Just t
|
||||
|
||||
--textureBinding Texture2D $= Just t
|
||||
|
||||
bindFBO :: FBO -> IO ()
|
||||
bindFBO fb = --bindFramebuffer Framebuffer $= fb
|
||||
bindFBO fb =
|
||||
--bindFramebuffer Framebuffer $= fb
|
||||
glBindFramebuffer GL_FRAMEBUFFER (_unFBO fb)
|
||||
|
||||
Reference in New Issue
Block a user