Try to improve instancing shadows
This commit is contained in:
@@ -10,7 +10,7 @@ layout (std140, binding = 1) uniform LightsBlock
|
||||
} ;
|
||||
vec3 lightPos = posBool[gl_InvocationID].xyz ;
|
||||
float theBool = posBool[gl_InvocationID].w;
|
||||
// this code is duplicated in lineShadow.geom, should not be changed on its own
|
||||
// this code is duplicated in shadow/edge.geom, should not be changed on its own
|
||||
vec4 projNear (vec4 pos)
|
||||
{
|
||||
// note we project to a specific height
|
||||
|
||||
+74
-67
@@ -1,78 +1,85 @@
|
||||
#version 450 core
|
||||
layout (lines_adjacency) in;
|
||||
layout (invocations = 20) in;
|
||||
layout (triangle_strip, max_vertices = 4) out;
|
||||
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
|
||||
layout (std140, binding = 1) uniform LightsBlock
|
||||
{
|
||||
vec4 posBool[20];
|
||||
vec4 colRad[20];
|
||||
} ;
|
||||
vec3 lightPos1 = posBool[gl_InvocationID].xyz;
|
||||
layout(lines_adjacency) in;
|
||||
layout(invocations = 20) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
layout(std140, binding = 0) uniform TheMat { mat4 theMat; };
|
||||
layout(std140, binding = 1) uniform LightsBlock {
|
||||
vec4 posBool[20];
|
||||
vec4 colRad[20];
|
||||
};
|
||||
vec3 lightPos = posBool[gl_InvocationID].xyz;
|
||||
float theBool = posBool[gl_InvocationID].w;
|
||||
vec4 shift (vec4 p) { return (vec4 (p.xyz + (100000*(p.xyz-lightPos1)), 1));} ;
|
||||
vec4 shiftBy (float x,vec4 p) { return (vec4 (lightPos1 + (x*normalize(p.xyz-lightPos1)), 1));} ;
|
||||
// copied from lighting/cap.geom, should not be changed on its own
|
||||
vec4 projNear (vec4 pos)
|
||||
{
|
||||
// note we project to a specific height
|
||||
// this is quite brittle, not ideal
|
||||
vec3 dir = pos.xyz - lightPos1 ;
|
||||
float a = (140 - pos.z) / dir.z ;
|
||||
vec2 xy = (pos.xyz + a * dir).xy ;
|
||||
return vec4 ( xy, 140 , 1) ;
|
||||
} ;
|
||||
vec4 shiftNear (vec4 pos)
|
||||
{ vec4 sp = shift(pos);
|
||||
if (sp.z > 140)
|
||||
{ return projNear(pos) ; }
|
||||
else
|
||||
{ return sp ; }
|
||||
} ;
|
||||
vec4 f (vec4 p) {return (theMat * p);} ;
|
||||
void main()
|
||||
{
|
||||
if (theBool == 1){
|
||||
// float ru2 = radiusUniform * radiusUniform ;
|
||||
float ru = colRad[gl_InvocationID].w ;
|
||||
float ru2 = ru * ru;
|
||||
float rad = colRad[gl_InvocationID].w;
|
||||
vec4 shift(vec4 p) { return (vec4(p.xyz + (100000 * (p.xyz - lightPos)), 1)); };
|
||||
vec4 shiftBy(float x, vec4 p) {
|
||||
return (vec4(lightPos + (x * normalize(p.xyz - lightPos)), 1));
|
||||
};
|
||||
vec4 shift1(vec4 p) {
|
||||
return (vec4(lightPos + (rad * normalize(p.xyz - lightPos)), 1));
|
||||
};
|
||||
// copied from shadow/cap.geom, should not be changed on its own
|
||||
vec4 projNear(vec4 pos) {
|
||||
// note we project to a specific height
|
||||
// this is quite brittle, not ideal
|
||||
vec3 dir = pos.xyz - lightPos;
|
||||
float a = (140 - pos.z) / dir.z;
|
||||
vec2 xy = (pos.xyz + a * dir).xy;
|
||||
return vec4(xy, 140, 1);
|
||||
};
|
||||
vec4 shiftNear(vec4 pos) {
|
||||
vec4 sp = shift(pos);
|
||||
if (sp.z > 140) {
|
||||
return projNear(pos);
|
||||
} else {
|
||||
return sp;
|
||||
}
|
||||
};
|
||||
void main() {
|
||||
if (theBool == 1) {
|
||||
vec4 p0 = gl_in[0].gl_Position;
|
||||
vec4 p1 = gl_in[1].gl_Position;
|
||||
vec4 mid = 0.5*(p0 + p1);
|
||||
vec4 mid = 0.5 * (p0 + p1);
|
||||
vec3 n0a = gl_in[2].gl_Position.xyz;
|
||||
vec3 n1a = gl_in[3].gl_Position.xyz;
|
||||
vec3 n0 = cross(p1.xyz - p0.xyz, n0a - p0.xyz) ;
|
||||
vec3 n1 = cross(p0.xyz - p1.xyz, n1a - p1.xyz) ;
|
||||
|
||||
//vec3 n2 = n0 + n1; // assumes the summands are normalized
|
||||
vec3 lightDir = p0.xyz - lightPos1.xyz;
|
||||
vec3 lightDir2 = p1.xyz - lightPos1.xyz;
|
||||
// first test if the edge is part of the silhouette
|
||||
vec3 n0 = cross(p1.xyz - p0.xyz, n0a - p0.xyz);
|
||||
vec3 n1 = cross(p0.xyz - p1.xyz, n1a - p1.xyz);
|
||||
vec3 lightDir = p0.xyz - lightPos.xyz;
|
||||
vec3 lightDir2 = p1.xyz - lightPos.xyz;
|
||||
// test if the edge is part of the silhouette
|
||||
// that is, if the normals of the faces connected by the edge point are in
|
||||
// "different directions" wrt the light direction
|
||||
if ( dot(n0 , lightDir) * dot(n1 , lightDir) <= 0 &&
|
||||
(dot(lightDir,lightDir) < ru2 || dot(lightDir2,lightDir2) < ru2) )
|
||||
// using <= rather than < seems to get rid of overlapping shadow
|
||||
// artefacts
|
||||
if (dot(n0, lightDir) * dot(n1, lightDir) <= 0 &&
|
||||
(dot(lightDir, lightDir) < rad * rad ||
|
||||
dot(lightDir2, lightDir2) < rad * rad))
|
||||
// using <= rather than < seems to get rid of overlapping shadow
|
||||
// artefacts
|
||||
{
|
||||
vec4 p2 = shiftNear(p0);
|
||||
vec4 p3 = shiftNear(p1);
|
||||
if ( dot(n0 , lightDir) > 0)
|
||||
{
|
||||
gl_Position = f(p0); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p1); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p2); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p3); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_Position = f(p1); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p0); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p3); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = f(p2); gl_Layer = gl_InvocationID; EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
vec4 p2 = shiftNear(p0);
|
||||
vec4 p3 = shiftNear(p1);
|
||||
gl_Position = theMat * p0;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
if (dot(n0, lightDir) > 0) {
|
||||
gl_Position = theMat * p1;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = theMat * p2;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
} else {
|
||||
gl_Position = theMat * p2;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = theMat * p1;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
}
|
||||
gl_Position = theMat * p3;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
} else {
|
||||
}
|
||||
else { }
|
||||
}else {}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,65 @@
|
||||
#version 450 core
|
||||
layout (points) in;
|
||||
layout (invocations = 20) in;
|
||||
layout (triangle_strip, max_vertices = 8) out;
|
||||
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
|
||||
layout (std140, binding = 1) uniform LightsBlock
|
||||
{
|
||||
vec4 posBool[20];
|
||||
vec4 colRad[20];
|
||||
} ;
|
||||
layout(points) in;
|
||||
layout(invocations = 20) in;
|
||||
layout(triangle_strip, max_vertices = 8) out;
|
||||
layout(std140, binding = 0) uniform TheMat { mat4 theMat; };
|
||||
layout(std140, binding = 1) uniform LightsBlock {
|
||||
vec4 posBool[20];
|
||||
vec4 colRad[20];
|
||||
};
|
||||
vec3 lightPos = posBool[gl_InvocationID].xyz;
|
||||
float theBool = posBool[gl_InvocationID].w;
|
||||
vec4 shift (vec4 p)
|
||||
{ return vec4 (p.xy + (200 * (p.xy-lightPos.xy)), 0 , 1);
|
||||
}
|
||||
float isLHS (vec2 startV, vec2 testV)
|
||||
{
|
||||
return sign( -startV.x * testV.y + startV.y * testV.x);
|
||||
vec4 shift(vec4 p) { return vec4(p.xy + (200 * (p.xy - lightPos.xy)), 0, 1); }
|
||||
float isLHS(vec2 startV, vec2 testV) {
|
||||
return sign(-startV.x * testV.y + startV.y * testV.x);
|
||||
}
|
||||
// construct a box with openings on bottom face and face away from wall
|
||||
void main()
|
||||
{
|
||||
vec4 p1 = vec4 (gl_in[0].gl_Position.xy,0,1);
|
||||
vec4 p2 = vec4 (gl_in[0].gl_Position.zw,0,1);
|
||||
if (theBool==1 && isLHS (p1.xy - lightPos.xy, p2.xy - lightPos.xy) < 0)
|
||||
{
|
||||
vec4 p3 = vec4 (p1.xy,100,1);
|
||||
vec4 p4 = vec4 (p2.xy,100,1);
|
||||
vec4 p5 = shift(p1);
|
||||
vec4 p6 = shift(p2);
|
||||
vec4 p7 = vec4 (p6.xy,100,1);
|
||||
vec4 p8 = vec4 (p5.xy,100,1);
|
||||
void main() {
|
||||
vec4 p1 = vec4(gl_in[0].gl_Position.xy, 0, 1);
|
||||
vec4 p2 = vec4(gl_in[0].gl_Position.zw, 0, 1);
|
||||
if (theBool == 1 && isLHS(p1.xy - lightPos.xy, p2.xy - lightPos.xy) < 0) {
|
||||
vec4 p3 = vec4(p1.xy, 100, 1);
|
||||
vec4 p4 = vec4(p2.xy, 100, 1);
|
||||
vec4 p5 = shift(p1);
|
||||
vec4 p6 = shift(p2);
|
||||
vec4 p7 = vec4(p6.xy, 100, 1);
|
||||
vec4 p8 = vec4(p5.xy, 100, 1);
|
||||
|
||||
vec4 a1 = theMat * p1;
|
||||
vec4 a2 = theMat * p2;
|
||||
vec4 a3 = theMat * p3;
|
||||
vec4 a4 = theMat * p4;
|
||||
vec4 a5 = theMat * p5;
|
||||
vec4 a6 = theMat * p6;
|
||||
vec4 a7 = theMat * p7;
|
||||
vec4 a8 = theMat * p8;
|
||||
vec4 a1 = theMat * p1;
|
||||
vec4 a2 = theMat * p2;
|
||||
vec4 a3 = theMat * p3;
|
||||
vec4 a4 = theMat * p4;
|
||||
vec4 a5 = theMat * p5;
|
||||
vec4 a6 = theMat * p6;
|
||||
vec4 a7 = theMat * p7;
|
||||
vec4 a8 = theMat * p8;
|
||||
|
||||
gl_Position = a1; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a5; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a3; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a8; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a4; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a7; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a2; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a6; gl_Layer = gl_InvocationID; EmitVertex();
|
||||
gl_Position = a1;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a5;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a3;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a8;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a4;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a7;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a2;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
gl_Position = a6;
|
||||
gl_Layer = gl_InvocationID;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
} else {}
|
||||
EndPrimitive();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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