10 static const char *use_flag_str[] = {
11 "#define USE_TEXMAP\n",
12 "#define USE_MIRROR\n"
14 #define NUM_USE_FLAGS ((int)(sizeof use_flag_str / sizeof *use_flag_str))
17 static RenderTarget *rtmirror;
18 static int cur_vport[4];
36 if(!rtmirror && !once) {
38 rtmirror = new RenderTarget;
39 if(!rtmirror->create(vp_width, vp_height, GL_SRGB)) {
40 error_log("failed to create mirror render target (%dx%d)\n", vp_width, vp_height);
44 int numsdr = 1 << NUM_USE_FLAGS;
45 shaders = new unsigned int[numsdr];
47 for(int i=0; i<numsdr; i++) {
48 clear_shader_header(0);
50 for(int j=0; j<NUM_USE_FLAGS; j++) {
52 add_shader_header(0, use_flag_str[j]);
56 if(!(shaders[i] = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap.p.glsl"))) {
59 set_uniform_int(shaders[i], "texmap", MTL_TEX_DIFFUSE);
60 set_uniform_int(shaders[i], "lightmap", MTL_TEX_LIGHTMAP);
61 set_uniform_int(shaders[i], "mirrortex", MTL_TEX_REFLECT);
67 void Renderer::destroy()
71 void Renderer::set_scene(MetaScene *mscn)
76 MetaScene *Renderer::get_scene() const
81 // render mirror reflections if ...
83 mscn->mirrors && /* scene contains mirrors */ \
84 (ropt & RENDER_MIRRORS) && /* mirror rendering is enabled */ \
85 rtmirror /* mirror render target succesfully created */
87 void Renderer::draw() const
91 if(DO_MIRRORS && current_render_target() != rtmirror) {
92 // check if the render target needs resizing
93 if(rtmirror->get_width() != vp_width || rtmirror->get_height() != vp_height) {
94 info_log("resizing mirror render target to %dx%d\n", vp_width, vp_height);
95 if(!rtmirror->resize(vp_width, vp_height)) {
96 error_log("failed to resize mirror render target (%dx%d)\n", vp_width, vp_height);
101 glGetIntegerv(GL_VIEWPORT, cur_vport);
103 FlatMirror *mir = mscn->mirrors;
111 int num = (int)mscn->scenes.size();
112 for(int i=0; i<num; i++) {
113 Scene *scn = mscn->scenes[i];
115 int nobj = (int)scn->objects.size();
116 for(int j=0; j<nobj; j++) {
117 // don't draw mirrors, we already did that earlier (if mirror rendering enabled)
118 if((ropt & RENDER_MIRRORS) && scn->objects[j]->mtl.flat_mirror) {
121 draw_object(scn->objects[j]);
126 void Renderer::draw_object(Object *obj) const
129 SceneNode *n = obj->node;
139 unsigned int use_mask = 0;
140 if(obj->mtl.stdtex[MTL_TEX_DIFFUSE]) {
141 use_mask |= USE_TEXMAP;
143 if(obj->mtl.stdtex[MTL_TEX_REFLECT] && obj->mtl.flat_mirror) {
144 use_mask |= USE_MIRROR;
147 unsigned int sdr = shaders[use_mask];
148 if(use_mask & USE_MIRROR) {
149 float sx = 1.0f / rtmirror->texture()->get_width();
150 float sy = 1.0f / rtmirror->texture()->get_height();
151 set_uniform_float2(sdr, "mirtex_offs", -cur_vport[0], -cur_vport[1]);
152 set_uniform_float2(sdr, "mirtex_scale", sx, sy);
153 set_uniform_float(sdr, "reflectivity", obj->mtl.reflect);
161 void Renderer::draw_mirror(FlatMirror *mir) const
163 push_render_target(rtmirror);
164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
166 glMatrixMode(GL_MODELVIEW);
169 // TODO update mirror plane for movable mirrors?
172 mirmat.mirror(mir->wplane.normal, -dot(mir->wplane.normal, mir->wplane.pt));
173 glMultMatrixf(mirmat[0]);
182 if(dbg_key_pending & 1) {
183 dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm");
184 dbg_key_pending &= ~1;
187 int nobj = mir->objects.size();
188 for(int i=0; i<nobj; i++) {
189 Object *obj = (Object*)mir->objects[i];
191 Texture *prev_refl_tex = obj->mtl.stdtex[MTL_TEX_REFLECT];
192 obj->mtl.stdtex[MTL_TEX_REFLECT] = rtmirror->texture();
194 draw_object(mir->objects[i]);
196 obj->mtl.stdtex[MTL_TEX_REFLECT] = prev_refl_tex;