RenderTarget::RenderTarget ( int _width, int _height ) : RenderTargetBase(_width, _height, true) , m_positionTexture(_width, _height, GL_RGBA16F, GL_NEAREST, GL_NEAREST) , m_colorTexture(_width, _height, GL_RGBA16F) , m_colorPostTransparencyTexture(_width, _height, GL_RGBA16F) { AttachTexture(FRAME_BUFFER_ATTACHMENT_POSITION, m_positionTexture); AttachTexture(FRAME_BUFFER_ATTACHMENT_COLOR, m_colorTexture); AttachTexture(FRAME_BUFFER_ATTACHMENT_COLOR_POST_TRANSPARENCY, m_colorPostTransparencyTexture); }
FBTexThread(FBTexExample& example) : gl() , prog(make_prog(example)) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , shape(List("Position")("Normal")("TexCoord").Get(), shapes::TwistedTorus(), prog) , tex_side(512) , parent_ready(example.parent_ready) { example.thread_ready = &thread_ready; Uniform<Vec3f>(prog, "LightPos").Set(20.0f, 30.0f, 40.0f); Texture::Active(0); { auto bound_tex = Bind(example.tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind(fbo, Framebuffer::Target::Draw); auto bound_rbo = Bind(rbo, Renderbuffer::Target::Renderbuffer); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture(FramebufferAttachment::Color, example.tex, 0); bound_fbo.AttachRenderbuffer(FramebufferAttachment::Depth, rbo); } Use(); }
bool TextureOverlay::Initialize(RenderManagerPtr pRenderManager, const std::string& name, const math::RectI& rect, TexturePtr pTex) { m_pRenderManager = pRenderManager; m_name = name; m_rect = rect; m_pMaterial = m_pRenderManager->CreateMaterialFromFile("./assets/standard/material/texture_overlay.material"); if(m_pMaterial == nullptr) { return false; } m_pParamImage = m_pMaterial->GetParameterByName("overlay_image");; m_pParamTrans = m_pMaterial->GetParameterByName("trans");; m_pParamScreenSize = m_pMaterial->GetParameterByName("screen_size");; if(CreateGeometry() == false) { return false; } m_pRenderData = alloc_object<RenderData>(); m_pRenderData->geometry = m_pGeometry; m_pRenderData->material = m_pMaterial; m_pRenderData->world_matrix.MakeIdentity(); m_pRenderData->base_vertex = 0; m_pRenderData->index_count = 0; m_pRenderData->start_index = 0; m_pRenderData->vertex_count = 6; AttachTexture(pTex); return true; }
ReflectionExample(void) : make_plane( Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15 ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , make_shape() , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , plane_vs(ObjectDesc("Plane vertex")) , shape_vs(ObjectDesc("Shape vertex")) , plane_fs(ObjectDesc("Plane fragment")) , shape_fs(ObjectDesc("Shape fragment")) , plane_projection_matrix(plane_prog, "ProjectionMatrix") , plane_camera_matrix(plane_prog, "CameraMatrix") , plane_model_matrix(plane_prog, "ModelMatrix") , shape_projection_matrix(shape_prog, "ProjectionMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , shape_model_matrix(shape_prog, "ModelMatrix") , width(800) , height(600) , tex_size_div(2) { plane_vs.Source( "#version 330\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertLightDir;" "out vec4 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix*Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertTexCoord = gl_Position;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "uniform sampler2DRect ReflectTex;" "uniform vec3 Normal;" "in vec3 vertLightDir;" "in vec4 vertTexCoord;" "out vec3 fragColor;" "const int n = 5;" "const int ns = (n*n);" "const float blur = 0.15/n;" "void main(void)" "{" " float d = dot(Normal, normalize(vertLightDir));" " float intensity = 0.5 + pow(1.4*d, 2.0);" " vec3 color = vec3(0.0, 0.0, 0.0);" " int n = 2;" " float pct = 0.5/vertTexCoord.w;" " for(int y=-n; y!=(n+1); ++y)" " for(int x=-n; x!=(n+1); ++x)" " {" " vec2 coord = vertTexCoord.xy;" " coord += vec2(blur*x, blur*y);" " coord *= pct;" " coord += vec2(0.5, 0.5);" " coord *= textureSize(ReflectTex);" " color += texture(ReflectTex, coord).rgb/ns;" " }" " fragColor = color*intensity;" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Vec3f lightPos(3.0f, 0.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal()); plane.Bind(); plane_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(plane_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // Texture::Active(1); { auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } Texture::Active(0); ProgramUniformSampler(plane_prog, "ReflectTex").Set(0); { auto bound_tex = Bind(reflect_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Color, reflect_tex, 0 ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } shape_vs.Source( "#version 330\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;" " vertColor = vec3(1, 1, 1) - vertNormal;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertColor;" "out vec3 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " fragColor = " " vertColor * 0.4 + " " (lt + vertColor)*pow(max(2.5*d, 0.0), 3) + " " lt * pow(max(s, 0.0), 64);" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); shape.Bind(); shape_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(shape_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(shape_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); }
FBTexExample(void) : make_cube() , cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , cube_fs(ObjectDesc("Cube fragment")) , torus_fs(ObjectDesc("Torus fragment")) , torus_projection_matrix(torus_prog, "ProjectionMatrix") , torus_camera_matrix(torus_prog, "CameraMatrix") , torus_model_matrix(torus_prog, "ModelMatrix") , cube_projection_matrix(cube_prog, "ProjectionMatrix") , cube_camera_matrix(cube_prog, "CameraMatrix") , cube_model_matrix(cube_prog, "ModelMatrix") , tex_side(512) , width(tex_side) , height(tex_side) { vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos-gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); cube_fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = sqrt(length(vertLight));" " float d = l > 0? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.6 + max(d, 0.0);" " fragColor = texture(TexUnit, vertTexCoord)*i;" "}" ); cube_fs.Compile(); cube_prog.AttachShader(vs); cube_prog.AttachShader(cube_fs); cube_prog.Link(); cube_prog.Use(); cube.Bind(); cube_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } UniformSampler(cube_prog, "TexUnit").Set(0); Uniform<Vec3f>(cube_prog, "LightPos").Set(4.0f, 4.0f, -8.0f); torus_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float d = dot(" " vertNormal, " " normalize(vertLight)" " );" " float i = (" " int(vertTexCoord.x*18) % 2+" " int(vertTexCoord.y*14) % 2" " ) % 2;" " float c = (0.4 + max(d, 0.0))*(1-i/2);" " fragColor = vec4(c, c, c, 1.0);" "}" ); torus_fs.Compile(); torus_prog.AttachShader(vs); torus_prog.AttachShader(torus_fs); torus_prog.Link(); torus_prog.Use(); torus.Bind(); torus_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(torus_prog, "LightPos").Set(2.0f, 3.0f, 4.0f); { auto bound_tex = Bind(tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); auto bound_rbo = Bind( rbo, Renderbuffer::Target::Renderbuffer ); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture( FramebufferAttachment::Color, tex, 0 ); bound_fbo.AttachRenderbuffer( FramebufferAttachment::Depth, rbo ); } gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); }
DOFExample(const ExampleParams& params) : face_instr(make_cube.Instructions()) , edge_instr(make_cube.EdgeInstructions()) , face_indices(make_cube.Indices()) , edge_indices(make_cube.EdgeIndices()) , cube_matrices(MakeCubeMatrices(100, 10.0)) , viewport_width(dof_prog, "ViewportWidth") , viewport_height(dof_prog, "ViewportHeight") , projection_matrix(main_prog, "ProjectionMatrix") , camera_matrix(main_prog, "CameraMatrix") , model_matrix(main_prog, "ModelMatrix") , ambient_color(main_prog, "AmbientColor") , diffuse_color(main_prog, "DiffuseColor") , focus_depth(dof_prog, "FocusDepth") , color_tex(Texture::Target::Rectangle) , depth_tex(Texture::Target::Rectangle) , width(800) , height(600) { main_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertLightDir;" "out vec3 vertNormal;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = normalize(LightPos - gl_Position.xyz);" " vertNormal = normalize(mat3(ModelMatrix)*Normal);" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it main_vs.Compile(); // set the fragment shader source main_fs.Source( "#version 330\n" "uniform vec3 AmbientColor, DiffuseColor;" "in vec3 vertLightDir;" "in vec3 vertNormal;" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(vertLightDir,vertNormal),0.0);" " float e = sin(" " 10.0*vertLightDir.x + " " 20.0*vertLightDir.y + " " 25.0*vertLightDir.z " " )*0.9;" " fragColor = vec4(" " mix(AmbientColor, DiffuseColor, d+e)," " 1.0" " );" "}" ); // compile it main_fs.Compile(); // attach the shaders to the program main_prog.AttachShader(main_vs); main_prog.AttachShader(main_fs); // link and use it main_prog.Link(); main_prog.Use(); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertices positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(main_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the cube normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(main_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(main_prog, "LightPos").Set(30.0, 50.0, 20.0); dof_vs.Source( "#version 330\n" "uniform uint ViewportWidth, ViewportHeight;" "in vec4 Position;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = Position;" " vertTexCoord = vec2(" " (Position.x*0.5 + 0.5)*ViewportWidth," " (Position.y*0.5 + 0.5)*ViewportHeight" " );" "}" ); dof_vs.Compile(); dof_fs.Source( "#version 330\n" "uniform sampler2DRect ColorTex;" "uniform sampler2DRect DepthTex;" "uniform float FocusDepth;" "uniform uint SampleMult;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "const float strength = 16.0;" "void main(void)" "{" " float fragDepth = texture(DepthTex, vertTexCoord).r;" " vec3 color = texture(ColorTex, vertTexCoord).rgb;" " float of = abs(fragDepth - FocusDepth);" " int nsam = int(of*SampleMult);" " float inv_nsam = 1.0 / (1.0 + nsam);" " float astep = (3.14151*4.0)/nsam;" " for(int i=0; i!=nsam; ++i)" " {" " float a = i*astep;" " float d = sqrt(i*inv_nsam);" " float sx = cos(a)*of*strength*d;" " float sy = sin(a)*of*strength*d;" " vec2 samTexCoord = vertTexCoord + vec2(sx, sy) + noise2(vec2(sx, sy));" " color += texture(ColorTex, samTexCoord).rgb;" " }" " fragColor = vec4(color * inv_nsam , 1.0);" "}" ); dof_fs.Compile(); dof_prog.AttachShader(dof_vs); dof_prog.AttachShader(dof_fs); dof_prog.Link(); dof_prog.Use(); GLuint sample_mult = params.HighQuality()?512:128; Uniform<GLuint>(dof_prog, "SampleMult") = sample_mult; // bind the VAO for the screen screen.Bind(); corners.Bind(Buffer::Target::Array); { GLfloat screen_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; Buffer::Data(Buffer::Target::Array, 8, screen_verts); VertexAttribArray attr(dof_prog, "Position"); attr.Setup<Vec2f>(); attr.Enable(); } Texture::Active(0); UniformSampler(dof_prog, "ColorTex").Set(0); { auto bound_tex = Bind(color_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::RGB, width, height, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); } Texture::Active(1); UniformSampler(dof_prog, "DepthTex").Set(1); { auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::DepthComponent, width, height, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Color, color_tex, 0 ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::LEqual); gl.Enable(Capability::LineSmooth); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
ShadowVolExample(const ExampleParams& params) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , shape_vs(ShaderType::Vertex, ObjectDesc("Shape vertex")) , depth_vs(ShaderType::Vertex, ObjectDesc("Depth vertex")) , light_vs(ShaderType::Vertex, ObjectDesc("Light vertex")) , depth_gs(ShaderType::Geometry, ObjectDesc("Depth geometry")) , light_gs(ShaderType::Geometry, ObjectDesc("Light geometry")) , shape_fs(ShaderType::Fragment, ObjectDesc("Shape fragment")) , depth_fs(ShaderType::Fragment, ObjectDesc("Depthfragment")) , light_fs(ShaderType::Fragment, ObjectDesc("Light fragment")) , shape_prog(ObjectDesc("Shape")) , depth_prog(ObjectDesc("Depth")) , light_prog(ObjectDesc("Light")) , tex_side(128) , sample_count(params.HighQuality()?1024:128) { shape_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)* CameraMatrix).xyz;" " vertViewRefl = reflect(" " normalize(vertViewDir)," " normalize(vertNormal)" " );" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 ambi = vec3(0.6, 0.3, 0.5);" " vec3 diff = vec3(0.9, 0.7, 0.8);" " vec3 spec = vec3(1.0, 0.9, 0.95);" " fragColor = vec4(" " ambi * 0.3 + " " diff * 0.7 * max(d, 0.0) + " " spec * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); depth_vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "void main(void)" "{" " gl_Position = " " mat4(" " 1.0, 0.0, 0.0, -LightPos.x," " 0.0, 1.0, 0.0, -LightPos.y," " 0.0, 0.0, 1.0, -LightPos.z," " 0.0, 0.0, 0.0, 1.0" " )*" " ModelMatrix *" " mat4(" " 10.0, 0.0, 0.0, 0.0," " 0.0, 10.0, 0.0, 0.0," " 0.0, 0.0, 10.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " )*" " Position;" "}" ); depth_vs.Compile(); depth_gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 18) out;" "uniform mat4 ProjectionMatrix;" "const mat4 CubeFaceMatrix[6] = mat4[6](" " mat4(" " 0.0, 0.0, -1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " -1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, -1.0, 0.0," " 0.0, 1.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, -1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " -1.0, 0.0, 0.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " )" ");" "void main(void)" "{" " for(gl_Layer=0; gl_Layer!=6; ++gl_Layer)" " {" " for(int i=0; i!=3; ++i)" " {" " gl_Position = " " ProjectionMatrix *" " CubeFaceMatrix[gl_Layer]*" " gl_in[i].gl_Position;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); depth_gs.Compile(); depth_fs.Source( "#version 330\n" "void main(void)" "{" " gl_FragDepth = gl_FragCoord.z;" "}" ); depth_fs.Compile(); depth_prog.AttachShader(depth_vs); depth_prog.AttachShader(depth_gs); depth_prog.AttachShader(depth_fs); depth_prog.Link(); depth_prog.Use(); Uniform<Mat4f>(depth_prog, "ProjectionMatrix").Set( CamMatrixf::PerspectiveX( RightAngles(1.0), 1.0, 0.1, 10.0 ) ); // bind the VAO for the shape shape.Bind(); shape_positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribSlot location; if(VertexAttribArray::QueryCommonLocation( "Position", location, shape_prog, depth_prog )) { VertexAttribArray shape_attr(location); shape_attr.Setup(n_per_vertex, DataType::Float); shape_attr.Enable(); } else assert(!"Inconsistent 'Position' location"); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); shape_prog.Use(); VertexAttribArray attr(shape_prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } light_vs.Source( "#version 330\n" "in vec3 Position;" "out float vertZOffs;" "uniform vec3 LightPos;" "uniform int SampleCount;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " gl_Position = vec4(Position + LightPos, 1.0);" "}" ); light_vs.Compile(); light_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "out vec4 geomPosition;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 ViewX, ViewY, ViewZ;" "uniform float LightVolSize;" "void main(void)" "{" " float zo = vertZOffs[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " geomPosition = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX * xo[i] * LightVolSize+" " ViewY * yo[j] * LightVolSize+" " ViewZ * zo * LightVolSize," " 1.0" " );" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " geomPosition;" " EmitVertex();" " }" " EndPrimitive();" "}" ); light_gs.Compile(); light_fs.Source( "#version 330\n" "in vec4 geomPosition;" "out vec4 fragColor;" "uniform samplerCubeShadow ShadowMap;" "uniform int SampleCount;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 LightDir = geomPosition.xyz - LightPos;" " vec4 ShadowCoord = vec4(" " normalize(LightDir)," " length(LightDir)" " );" " float s = texture(ShadowMap, ShadowCoord);" " float alpha = s / (SampleCount * pow(length(LightDir), 2));" " fragColor = vec4(1.0, 1.0, 1.0, alpha);" "}" ); light_fs.Compile(); light_prog.AttachShader(light_vs); light_prog.AttachShader(light_gs); light_prog.AttachShader(light_fs); light_prog.Link(); light_prog.Use(); // bind the VAO for the light volume light.Bind(); // bind the VBO for the light volume plane positions light_positions.Bind(Buffer::Target::Array); { GLfloat position[3] = {0.0, 0.0, 0.0}; Buffer::Data(Buffer::Target::Array, 3, position); VertexAttribArray attr(light_prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } Uniform<GLint>(light_prog, "SampleCount").Set(sample_count); Uniform<GLfloat>(light_prog, "LightVolSize").Set(4); UniformSampler(light_prog, "ShadowMap").Set(0); // Setup the texture and the offscreen FBO Texture::Active(0); { auto bound_tex = Bind(depth_tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); bound_tex.CompareFunc(CompareFunction::LEqual); bound_tex.CompareMode( TextureCompareMode::CompareRefToTexture ); for(int i=0; i!=6; ++i) { Texture::Image2D( Texture::CubeMapFace(i), 0, PixelDataInternalFormat::DepthComponent, tex_side, tex_side, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } auto bound_fbo = Bind( depth_fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.2f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); gl.BlendFunc(BlendFunction::SrcAlpha, BlendFunction::One); }