/*--------------------------------------------------------------------------- Tests the selected input texture and changes configuration if the resolutions do not match. The function does nothing for identical configurations. ---------------------------------------------------------------------------*/ void Filter::Change(Buffers &Buffer) { vector2u Res[2]; Texture::TexType Type[2]; switch (Select) { case Filter::SelectVideo : Res[0] = Buffer.GetVideoResolution(); Res[1] = Video.Resolution(); Type[0] = Buffer.GetVideoDataType(); Type[1] = Video.DataType(); break; case Filter::SelectDepth : Res[0] = Buffer.GetDepthResolution(); Res[1] = Depth.Resolution(); Type[0] = Buffer.GetDepthDataType(); Type[1] = Depth.DataType(); break; default : throw dexception("Invalid Select enumeration."); } if (Res[0].U < 1 || Res[0].V < 1) {return;} if (Res[0].U != Res[1].U || Res[0].V != Res[1].V || Type[0] != Type[1]) { Setup(Buffer); Assets(Buffer); } }
/*--------------------------------------------------------------------------- Class specific setup function for the effects assets. ---------------------------------------------------------------------------*/ void Filter::Assets(Buffers &Buffer) { if (!Ready()) {return;} Video.Create(Buffer.GetVideoResolution(), Buffer.GetVideoDataType()); Video.ClearData(); Video.Buffer(false); Model.Plane(1, Mesh::ModeSolid); Model.Buffer(false); File::Text Text; std::string CodeVert, CodeFrag; Text.Load(CodeVert, File::Path::Shader(File::FilterVert)); Text.Load(CodeFrag, File::Path::Shader(File::FilterFrag)); Program.Attach(CodeVert, Shader::ShaderVert); Program.Attach(CodeFrag, Shader::ShaderFrag); Program.Buffer(false); GLenum Error = glGetError(); if (Error != GL_NO_ERROR) {throw dexception("OpenGL generated an error: %s", Debug::ErrorGL(Error));} }
/*--------------------------------------------------------------------------- Setup function that a intialises assets, matrices and other OpenGL related structure for rendering. NOTE: This must be called within a valid OpenGL context. ---------------------------------------------------------------------------*/ void Filter::Setup(Buffers &Buffer) { Destroy(); if (!GLEW_ARB_framebuffer_object) {throw dexception("Current OpenGL context does not support frame buffer objects.");} vector2u Res; switch (Select) { case Filter::SelectVideo : Res = Buffer.GetVideoResolution(); break; case Filter::SelectDepth : Res = Buffer.GetDepthResolution(); break; default : throw dexception("Invalid Select enumeration.");; } if (Res.X < 1 || Res.Y < 1) {return;} //Create a new frame buffer object glGenFramebuffers(1, &FBOID); glBindFramebuffer(GL_FRAMEBUFFER, FBOID); //Create a new depth buffer object, then associate a // storage space for it, and attach it to the FBO glGenRenderbuffers(1, &DBOID); glBindRenderbuffer(GL_RENDERBUFFER, DBOID); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, Res.X, Res.Y); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DBOID); //Create a colour buffer in form of a texture and attach it to the FBO glGenTextures(1, &CBOID); glBindTexture(GL_TEXTURE_2D, CBOID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Res.X, Res.Y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CBOID, 0); //FBO texture scaling glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); //Setup view port size ViewPort.Set4(0, 0, Res.X, Res.Y); //Compute frustum aspect ratio from viewport size Ratio.Set((float)ViewPort.C2, (float)ViewPort.C3); Ratio /= (float)Math::Min(ViewPort.C2, ViewPort.C3); //Default projection matrix MP = MP.Identity(); MP = MP.Ortho(-Ratio.X, Ratio.X, -Ratio.Y, Ratio.Y, Near, Far); //Default model view matrix MV = MV.Identity(); MV = MV.Scale(Ratio.X, Ratio.Y, 1.0f); //Default texture matrix MT = MT.Identity(); //MT = MT.Scale(1.0f, -1.0f, 1.0f); //MT = MT.Translate(0.0f, -1.0f, 0.0f); MC = MC.Identity(); //Error checking GLenum Error = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (Error != GL_FRAMEBUFFER_COMPLETE) {throw dexception("Failed to setup frame buffer object: %s.", Debug::StatusFBO(Error));} Error = glGetError(); if (Error != GL_NO_ERROR) {throw dexception("OpenGL generated an error: %s", Debug::ErrorGL(Error));} }
/*--------------------------------------------------------------------------- Class specific setup function for the effects assets. ---------------------------------------------------------------------------*/ void FilterSolids::Assets(Buffers &Buffer) { if (!Ready()) {return;} vector2u Res = Buffer.GetDepthResolution(); Depth.Create(Res, Buffer.GetDepthDataType()); Depth.ClearData(); Depth.Buffer(false); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); Light.SetPosition(vector4f(0.5f, -0.5f, Near + 1.0f, 0.0f)); Light.Buffer(0); glPopMatrix(); Grid = Res / GridDiv; Grid = Grid.Clamp(GridMin, GridMax); GridNorm = cast_vector2(float, Grid); GridNorm = GridNorm.Rcp(); uint GridSmallest = Math::Min(Grid.U, Grid.V); Offset = cast_vector2(float, Grid); Offset = (Offset - 1.0f) * 0.5f; //Geometry subdivisions for curved solids uint PolyDiv = (Math::Min(Res.U, Res.V) / GridSmallest) / PolyDivPixels; PolyDiv = Math::Clamp(PolyDiv, PolyDivMin, PolyDivMax); File::Text Text; std::string CodeVert, CodeFrag; switch (Type) { case FilterSolids::Cubes : Model.Cube(1, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsDepthVert)); EnableVideo = false; EnableDepth = true; EnableCal = false; Mat.SetShininess(0.0f); break; case FilterSolids::Spheres : Model.Sphere(PolyDiv, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsDepthVert)); EnableVideo = false; EnableDepth = true; EnableCal = false; break; case FilterSolids::CubesTinted : Model.Cube(1, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsVideoVert)); Video.Create(Buffer.GetVideoResolution(), Buffer.GetVideoDataType()); Video.ClearData(); Video.Buffer(false); EnableVideo = true; EnableDepth = true; EnableCal = true; Mat.SetShininess(0.0f); break; case FilterSolids::SpheresTinted : Model.Sphere(PolyDiv, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsVideoVert)); Video.Create(Buffer.GetVideoResolution(), Buffer.GetVideoDataType()); Video.ClearData(); Video.Buffer(false); EnableVideo = true; EnableDepth = true; EnableCal = true; break; case FilterSolids::CubesFar : Model.Cube(1, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsDepthVert)); EnableVideo = false; EnableDepth = true; EnableCal = false; Mat.SetShininess(0.0f); Far = -1000.0f; break; case FilterSolids::SpheresFar : Model.Sphere(PolyDiv, Mesh::ModeSolid); Text.Load(CodeVert, File::Path::Shader(File::FilterSolidsDepthVert)); EnableVideo = false; EnableDepth = true; EnableCal = false; Far = -1000.0f; break; default : dexception("Unknown filter enumeration type."); } Range = Math::Abs(Far - Near); Model.Buffer(false); Text.Load(CodeFrag, File::Path::Shader(File::FilterSolidsFrag)); Program.Attach(CodeVert, Shader::ShaderVert); Program.Attach(CodeFrag, Shader::ShaderFrag); Program.Buffer(false); Program.Bind(); glUniform1f(glGetUniformLocation(Program.ID(), "Range"), Math::Abs(Range)); glUniform1i(glGetUniformLocation(Program.ID(), "Depth"), 0); //Texture unit 0 glUniform1i(glGetUniformLocation(Program.ID(), "Video"), 1); //Texture unit 1 UID = glGetUniformLocation(Program.ID(), "TexCoord"); glUniform2f(UID, 0.0f, 0.0f); Program.Unbind(); //Projection matrix MP = MP.Identity(); MP = MP.Frustum(-Ratio.X, Ratio.X, -Ratio.Y, Ratio.Y, Math::Abs(Near), Math::Abs(Far)); //Modelview matrix float Scale = 1.0f / (float)GridSmallest; MV = MV.Identity(); MV = MV.Scale(Scale, Scale, Scale); MV = MV.Translate(0.0f, 0.0f, (Near - Scale - 0.01f) / Scale); GLenum Error = glGetError(); if (Error != GL_NO_ERROR) {throw dexception("OpenGL generated an error: %s", Debug::ErrorGL(Error));} }