Try to improve instancing shadows

This commit is contained in:
2023-03-12 14:06:11 +00:00
parent b88a8d5776
commit 9947979b52
9 changed files with 368 additions and 296 deletions
+1 -1
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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)
+7 -3
View File
@@ -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
View File
@@ -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)