From 131bec9b254f5ba50dcaf7e6192baab9e9ccba6f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 11 Sep 2012 00:35:23 +0300 Subject: [PATCH] Add an EnvironmentMap effect --- source/environmentmap.cpp | 99 +++++++++++++++++++++++++++++++++++++++ source/environmentmap.h | 51 ++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 source/environmentmap.cpp create mode 100644 source/environmentmap.h diff --git a/source/environmentmap.cpp b/source/environmentmap.cpp new file mode 100644 index 00000000..09a9b468 --- /dev/null +++ b/source/environmentmap.cpp @@ -0,0 +1,99 @@ +#include +#include "environmentmap.h" +#include "renderer.h" +#include "texunit.h" + +namespace Msp { +namespace GL { + +EnvironmentMap::EnvironmentMap(unsigned s, Renderable &r, Renderable &e): + Effect(r), + size(s), + environment(e), + rendered(false) +{ + env_tex.storage(RGB, size); + env_tex.set_wrap(CLAMP_TO_EDGE); + env_tex.set_min_filter(LINEAR); + depth_buf.storage(DEPTH_COMPONENT, size, size); + for(unsigned i=0; i<6; ++i) + { + fbo[i].attach(COLOR_ATTACHMENT0, env_tex, TextureCube::enumerate_faces(i), 0); + fbo[i].attach(DEPTH_ATTACHMENT, depth_buf); + } + + // XXX Make the depth range configurable + camera.set_field_of_view(M_PI/2); + camera.set_aspect(1); + camera.set_depth_clip(0.1, 100); + + shdata.uniform("environment", 4); +} + +void EnvironmentMap::setup_frame() const +{ + if(rendered) + return; + + rendered = true; + renderable.setup_frame(); + environment.setup_frame(); + + const Matrix *matrix = renderable.get_matrix(); + Vector3 position = (*matrix)*Vector3(); + camera.set_position(position); + for(unsigned i=0; i<6; ++i) + { + TextureCubeFace face = TextureCube::enumerate_faces(i); + Bind _bind_fbo(fbo[i]); + fbo[i].clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT); + camera.set_look_direction(env_tex.get_face_direction(face)); + camera.set_up_direction(env_tex.get_t_direction(face)); + Renderer env_renderer(&camera); + env_renderer.exclude(renderable); + env_renderer.render(environment); + } +} + +void EnvironmentMap::finish_frame() const +{ + if(rendered) + { + rendered = false; + renderable.finish_frame(); + environment.finish_frame(); + } +} + +void EnvironmentMap::render(Renderer &renderer, const Tag &tag) const +{ + if(!enabled_passes.count(tag)) + return renderer.render(renderable, tag); + + const Matrix &view_matrix = renderer.get_camera()->get_matrix(); + // XXX The camera should maybe have store its own object matrix + float env_mdata[9]; + env_mdata[0] = view_matrix[0]; + env_mdata[1] = view_matrix[4]; + env_mdata[2] = view_matrix[8]; + env_mdata[3] = view_matrix[1]; + env_mdata[4] = view_matrix[5]; + env_mdata[5] = view_matrix[9]; + env_mdata[6] = view_matrix[2]; + env_mdata[7] = view_matrix[6]; + env_mdata[8] = view_matrix[10]; + shdata.uniform_matrix3("env_eye_matrix", env_mdata); + + env_tex.bind_to(4); + TexUnit::activate(0); + + Renderer::Push _push_rend(renderer); + renderer.add_shader_data(shdata); + renderer.render(renderable, tag); + + env_tex.unbind_from(4); + TexUnit::activate(0); +} + +} // namespace GL +} // namespace Msp diff --git a/source/environmentmap.h b/source/environmentmap.h new file mode 100644 index 00000000..9c4c4d15 --- /dev/null +++ b/source/environmentmap.h @@ -0,0 +1,51 @@ +#ifndef MSP_GL_ENVIRONMENTMAP_H_ +#define MSP_GL_ENVIRONMENTMAP_H_ + +#include "camera.h" +#include "effect.h" +#include "framebuffer.h" +#include "matrix.h" +#include "programdata.h" +#include "renderbuffer.h" +#include "texturecube.h" +#include "vector.h" + +namespace Msp { +namespace GL { + +class Renderable; + +/** +Creates a cube map texture of the surroundings of the renderable. This texture +can then be used to implement effects such as reflections or refractions. + +If the EnvironmentMap is used in a Pipeline, it's worth noting that the cube +map will be prepared outside of any rendering pass. It's recommended to use +another Pipeline to define which passes should be used to render the +environment. +*/ +class EnvironmentMap: public Effect +{ +private: + unsigned size; + Renderable &environment; + TextureCube env_tex; + Renderbuffer depth_buf; + mutable Framebuffer fbo[6]; + mutable Camera camera; + mutable ProgramData shdata; + mutable bool rendered; + +public: + EnvironmentMap(unsigned size, Renderable &rend, Renderable &env); + + virtual void setup_frame() const; + virtual void finish_frame() const; + + virtual void render(Renderer &, const Tag &) const; +}; + +} // namespace GL +} // namespace Msp + +#endif -- 2.45.2