TextureSet texman;
SceneSet sceneman;
-unsigned int sdr_ltmap, sdr_ltmap_notex;
-
int fpexcept_enabled;
+unsigned int dbg_key_pending;
+
static Avatar avatar;
static float cam_dist = 0.0;
}
exui_setnode(&exslot_left.node);
- if(!(sdr_ltmap_notex = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-notex.p.glsl"))) {
- return false;
- }
- set_uniform_int(sdr_ltmap_notex, "texmap", MTL_TEX_DIFFUSE);
- set_uniform_int(sdr_ltmap_notex, "lightmap", MTL_TEX_LIGHTMAP);
-
- if(!(sdr_ltmap = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-tex.p.glsl"))) {
- return false;
- }
- set_uniform_int(sdr_ltmap, "texmap", MTL_TEX_DIFFUSE);
- set_uniform_int(sdr_ltmap, "lightmap", MTL_TEX_LIGHTMAP);
-
if(!fb_srgb) {
sdr_post_gamma = create_program_load("sdr/post_gamma.v.glsl", "sdr/post_gamma.p.glsl");
}
case KEY_RIGHT:
exui_change_tab(1);
break;
+
+ case KEY_F5:
+ case KEY_F6:
+ case KEY_F7:
+ case KEY_F8:
+ dbg_key_pending |= 1 << (key - KEY_F5);
+ break;
}
}
extern TextureSet texman;
extern SceneSet sceneman;
-extern unsigned int sdr_ltmap, sdr_ltmap_notex;
-
extern ExSelection exsel_active; // active (info/interact) exhibit
extern ExSelection exsel_grab_left, exsel_grab_right; // grabbed on each hand
extern ExSelection exsel_hover; // hover
+extern unsigned int dbg_key_pending;
+
extern int fpexcept_enabled; // int so that C modules may fwd-delcare and use it
enum {
}
}
+ /*
if(stdtex[MTL_TEX_LIGHTMAP]) {
bind_program(stdtex[MTL_TEX_DIFFUSE] ? sdr_ltmap : sdr_ltmap_notex);
}
+ */
}
void Material::add_texture(Texture *tex, int type)
} else if(strcmp(str, "lightmap") == 0) {
return MTL_TEX_LIGHTMAP;
} else if(strcmp(str, "envmap") == 0) {
- return MTL_TEX_ENVMAP;
+ return MTL_TEX_REFLECT;
}
return MTL_TEX_UNKNOWN;
}
return "normalmap";
case MTL_TEX_LIGHTMAP:
return "lightmap";
- case MTL_TEX_ENVMAP:
+ case MTL_TEX_REFLECT:
return "envmap";
default:
break;
MTL_TEX_SPECULAR,
MTL_TEX_NORMALMAP,
MTL_TEX_LIGHTMAP,
- MTL_TEX_ENVMAP,
+ MTL_TEX_REFLECT,
MTL_TEX_UNKNOWN
};
int MetaScene::calc_mirror_planes()
{
- std::vector<Vec4> world_planes;
+ FlatMirror *planes = 0;
int num_mirrors = 0;
while(mirrors) {
} else {
int plane_idx = obj->mtl.flat_mirror - MTL_MIRROR_AABB_PX;
mir->plane = obj->get_aabox().get_plane(plane_idx);
- debug_log("mirror plane: p(%f %f %f) n(%f %f %f)\n", mir->plane.pt.x, mir->plane.pt.y,
- mir->plane.pt.z, mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z);
}
- float pdist = dot(mir->plane.normal, mir->plane.pt);
- Vec4 plane_eq = Vec4(mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z, pdist);
-
+ mir->wplane = mir->plane;
if(obj->node) {
- plane_eq = obj->node->get_matrix() * plane_eq;
+ const Mat4 &xform = obj->node->get_matrix();
+ mir->wplane.pt = xform * mir->wplane.pt;
+ mir->wplane.normal = normalize(xform.upper3x3() * mir->wplane.normal);
}
// check to see if we have found this mirror plane already
bool found = false;
- int nplanes = world_planes.size();
- for(int k=0; k<nplanes; k++) {
- if(1.0f - dot(plane_eq.xyz(), world_planes[k].xyz()) < 1e-4f &&
- fabs(plane_eq.w - world_planes[k].w) < 1e-4) {
+ FlatMirror *node = planes;
+ while(node) {
+ float d1 = dot(mir->wplane.normal, mir->wplane.pt);
+ float d2 = dot(node->wplane.normal, node->wplane.pt);
+
+ if(1.0f - dot(mir->wplane.normal, node->wplane.normal) < 1e-4f &&
+ fabs(d1 - d2) < 1e-4) {
found = true;
break;
}
+ node = node->next;
}
+ debug_log("[%s@%s] mirror plane: local(%g %g %g %g), world(%g %g %g %g)%s\n",
+ obj->get_name(), obj->node ? obj->node->get_name() : "<no-node>",
+ mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z,
+ dot(mir->plane.normal, mir->plane.pt), mir->wplane.normal.x, mir->wplane.normal.y,
+ mir->wplane.normal.z, dot(mir->wplane.normal, mir->wplane.pt), found ? " duplicate" : "");
+
if(!found) {
mir->next = mirrors;
mirrors = mir;
- world_planes.push_back(plane_eq);
+ node = new FlatMirror;
+ node->wplane = mir->wplane;
+ node->next = planes;
+ planes = node;
mir->objects.push_back(obj);
objmirror[obj] = mir; // associate with object
}
}
+ while(planes) {
+ FlatMirror *tmp = planes;
+ planes = planes->next;
+ delete tmp;
+ }
+
return num_mirrors;
}
struct FlatMirror {
- Plane plane;
+ Plane plane; // plane in local coordinates (original)
+ Plane wplane; // world coords plane (derived, identical to plane if node == 0)
float reflect;
std::vector<Object*> objects;
SceneNode *node;
#include "renderer.h"
#include "rtarg.h"
#include "app.h"
+#include "sdr.h"
+
+enum {
+ USE_TEXMAP = 1,
+ USE_MIRROR = 2,
+};
+static const char *use_flag_str[] = {
+ "#define USE_TEXMAP\n",
+ "#define USE_MIRROR\n"
+};
+#define NUM_USE_FLAGS ((int)(sizeof use_flag_str / sizeof *use_flag_str))
+
static RenderTarget *rtmirror;
{
mscn = 0;
ropt = RENDER_ALL;
+ shaders = 0;
}
Renderer::~Renderer()
{
destroy();
+ delete [] shaders;
}
bool Renderer::init()
}
}
+ int numsdr = 1 << NUM_USE_FLAGS;
+ shaders = new unsigned int[numsdr];
+
+ for(int i=0; i<numsdr; i++) {
+ clear_shader_header(0);
+
+ for(int j=0; j<NUM_USE_FLAGS; j++) {
+ if(i & (1 << j)) {
+ add_shader_header(0, use_flag_str[j]);
+ }
+ }
+
+ if(!(shaders[i] = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap.p.glsl"))) {
+ return false;
+ }
+ set_uniform_int(shaders[i], "texmap", MTL_TEX_DIFFUSE);
+ set_uniform_int(shaders[i], "lightmap", MTL_TEX_LIGHTMAP);
+ set_uniform_int(shaders[i], "mirrortex", MTL_TEX_REFLECT);
+ }
+
return true;
}
}
if(vis) {
+ unsigned int use_mask = 0;
+ if(obj->mtl.stdtex[MTL_TEX_DIFFUSE]) {
+ use_mask |= USE_TEXMAP;
+ }
+ if(obj->mtl.stdtex[MTL_TEX_REFLECT] && obj->mtl.flat_mirror) {
+ use_mask |= USE_MIRROR;
+ }
+
+ unsigned int sdr = shaders[use_mask];
+ if(use_mask & USE_MIRROR) {
+ float sx = 1.0f / rtmirror->texture()->get_width();
+ float sy = 1.0f / rtmirror->texture()->get_height();
+ set_uniform_float2(sdr, "mirtex_scale", sx, sy);
+ set_uniform_float(sdr, "reflectivity", obj->mtl.reflect);
+ }
+ bind_program(sdr);
+
obj->draw();
}
}
void Renderer::draw_mirror(FlatMirror *mir) const
{
push_render_target(rtmirror);
+ glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClearColor(1, 1, 1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- float pdist = dot(mir->plane.normal, mir->plane.pt);
- Vec4 peq = Vec4(mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z, pdist);
-
- if(mir->node) {
- peq = mir->node->get_matrix() * peq;
- }
+ // TODO update mirror plane for movable mirrors?
Mat4 mirmat;
- mirmat.mirror(peq.x, peq.y, peq.z, peq.w);
+ mirmat.mirror(mir->wplane.normal, dot(mir->wplane.normal, mir->wplane.pt));
glMultMatrixf(mirmat[0]);
glFrontFace(GL_CW);
glPopMatrix();
pop_render_target();
- dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm");
+ if(dbg_key_pending & 1) {
+ dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm");
+ dbg_key_pending &= ~1;
+ }
int nobj = mir->objects.size();
for(int i=0; i<nobj; i++) {
+ Object *obj = (Object*)mir->objects[i];
+
+ Texture *prev_refl_tex = obj->mtl.stdtex[MTL_TEX_REFLECT];
+ obj->mtl.stdtex[MTL_TEX_REFLECT] = rtmirror->texture();
+
draw_object(mir->objects[i]);
+
+ obj->mtl.stdtex[MTL_TEX_REFLECT] = prev_refl_tex;
}
}
#ifndef RENDERER_H_
#define RENDERER_H_
+#include <vector>
#include "metascene.h"
enum {
class Renderer {
private:
MetaScene *mscn;
+ unsigned int *shaders;
public:
unsigned int ropt;
std::regex re{qstr};
find_nodes_rec(&res, nodes, re);
}
- return std::move(res);
+ return res;
}
Scene *Scene::extract_nodes(const char *qstr)
case aiTextureType_EMISSIVE:
return MTL_TEX_LIGHTMAP;
case aiTextureType_REFLECTION:
- return MTL_TEX_ENVMAP;
+ return MTL_TEX_REFLECT;
default:
break;
}
Vec3 SceneNode::get_position() const
{
- return xform * Vec3(0, 0, 0);
+ return xform.get_translation();
}
Quat SceneNode::get_rotation() const
{
- return rot; // TODO
+ return xform.get_rotation();
}
Vec3 SceneNode::get_scaling() const
{
- return scale; // TODO
+ return xform.get_scaling();
}
const Mat4 &SceneNode::get_matrix() const
ImGui::NextColumn();
ImGui::Checkbox("##vis", &visible);
+ ImGui::SameLine();
+ if(ImGui::Button("xform")) {
+ ImGui::OpenPopup("xform_popup");
+ }
+ if(ImGui::BeginPopup("xform_popup")) {
+ ImGui::Text("Local transform");
+ Vec3 p = get_node_position();
+ ImGui::BulletText("P: %g %g %g", p.x, p.y, p.z);
+ Quat q = get_node_rotation();
+ ImGui::BulletText("R: %g %g %g %g", q.x, q.y, q.z, q.w);
+ Vec3 s = get_node_scaling();
+ ImGui::BulletText("S: %g %g %g", s.x, s.y, s.z);
+
+ ImGui::Separator();
+ ImGui::Text("Global transform");
+ p = get_position();
+ ImGui::BulletText("P: %g %g %g", p.x, p.y, p.z);
+ q = get_rotation();
+ ImGui::BulletText("R: %g %g %g %g", q.x, q.y, q.z, q.w);
+ s = get_scaling();
+ ImGui::BulletText("S: %g %g %g", s.x, s.y, s.z);
+
+ const Mat4 &mat = get_matrix();
+ ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[0][0], mat[0][1], mat[0][2], mat[0][3]);
+ ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[1][0], mat[1][1], mat[1][2], mat[1][3]);
+ ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[2][0], mat[2][1], mat[2][2], mat[2][3]);
+ ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+
+ ImGui::EndPopup();
+ }
ImGui::NextColumn();
ImGui::PopID();
}