From 9480e20f4de41693ebd1f22e63d3bcecde878f70 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 18 Mar 2018 14:42:28 +0200 Subject: [PATCH] simple ubershader system, reflection debugging --- src/app.cc | 23 +++++++---------- src/app.h | 4 +-- src/material.cc | 6 +++-- src/material.h | 2 +- src/metascene.cc | 41 +++++++++++++++++++++--------- src/metascene.h | 3 ++- src/renderer.cc | 74 ++++++++++++++++++++++++++++++++++++++++++++++++------ src/renderer.h | 2 ++ src/scene.cc | 2 +- src/sceneload.cc | 2 +- src/snode.cc | 36 +++++++++++++++++++++++--- 11 files changed, 150 insertions(+), 45 deletions(-) diff --git a/src/app.cc b/src/app.cc index 30222f9..fcf5fe0 100644 --- a/src/app.cc +++ b/src/app.cc @@ -41,10 +41,10 @@ bool opt_gear_wireframe; 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; @@ -175,18 +175,6 @@ bool app_init(int argc, char **argv) } 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"); } @@ -671,6 +659,13 @@ void app_keyboard(int key, bool pressed) 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; } } diff --git a/src/app.h b/src/app.h index 0e41312..8f40515 100644 --- a/src/app.h +++ b/src/app.h @@ -15,12 +15,12 @@ extern bool fb_srgb; 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 { diff --git a/src/material.cc b/src/material.cc index 26ab63d..a079c83 100644 --- a/src/material.cc +++ b/src/material.cc @@ -37,9 +37,11 @@ void Material::setup() const } } + /* if(stdtex[MTL_TEX_LIGHTMAP]) { bind_program(stdtex[MTL_TEX_DIFFUSE] ? sdr_ltmap : sdr_ltmap_notex); } + */ } void Material::add_texture(Texture *tex, int type) @@ -78,7 +80,7 @@ int mtl_parse_type(const char *str) } 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; } @@ -94,7 +96,7 @@ const char *mtl_type_string(int type) return "normalmap"; case MTL_TEX_LIGHTMAP: return "lightmap"; - case MTL_TEX_ENVMAP: + case MTL_TEX_REFLECT: return "envmap"; default: break; diff --git a/src/material.h b/src/material.h index a1244d4..4ca5c7d 100644 --- a/src/material.h +++ b/src/material.h @@ -11,7 +11,7 @@ enum { MTL_TEX_SPECULAR, MTL_TEX_NORMALMAP, MTL_TEX_LIGHTMAP, - MTL_TEX_ENVMAP, + MTL_TEX_REFLECT, MTL_TEX_UNKNOWN }; diff --git a/src/metascene.cc b/src/metascene.cc index a85b65e..a45bfec 100644 --- a/src/metascene.cc +++ b/src/metascene.cc @@ -203,7 +203,7 @@ Scene *MetaScene::extract_nodes(const char *qstr) int MetaScene::calc_mirror_planes() { - std::vector world_planes; + FlatMirror *planes = 0; int num_mirrors = 0; while(mirrors) { @@ -241,33 +241,44 @@ int MetaScene::calc_mirror_planes() } 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; kwplane.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() : "", + 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 @@ -279,6 +290,12 @@ int MetaScene::calc_mirror_planes() } } + while(planes) { + FlatMirror *tmp = planes; + planes = planes->next; + delete tmp; + } + return num_mirrors; } diff --git a/src/metascene.h b/src/metascene.h index 6987f00..0565f3d 100644 --- a/src/metascene.h +++ b/src/metascene.h @@ -11,7 +11,8 @@ 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 objects; SceneNode *node; diff --git a/src/renderer.cc b/src/renderer.cc index 43a96db..deff1b9 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -1,6 +1,18 @@ #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; @@ -8,11 +20,13 @@ Renderer::Renderer() { mscn = 0; ropt = RENDER_ALL; + shaders = 0; } Renderer::~Renderer() { destroy(); + delete [] shaders; } bool Renderer::init() @@ -26,6 +40,26 @@ bool Renderer::init() } } + int numsdr = 1 << NUM_USE_FLAGS; + shaders = new unsigned int[numsdr]; + + for(int i=0; imtl.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(); } } @@ -105,20 +156,17 @@ void Renderer::draw_object(Object *obj) const 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); @@ -128,10 +176,20 @@ void Renderer::draw_mirror(FlatMirror *mir) const 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; iobjects[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; } } diff --git a/src/renderer.h b/src/renderer.h index e6aa8d5..01fc5fd 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -1,6 +1,7 @@ #ifndef RENDERER_H_ #define RENDERER_H_ +#include #include "metascene.h" enum { @@ -12,6 +13,7 @@ enum { class Renderer { private: MetaScene *mscn; + unsigned int *shaders; public: unsigned int ropt; diff --git a/src/scene.cc b/src/scene.cc index b439286..10304f6 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -245,7 +245,7 @@ std::list Scene::match_nodes(const char *qstr) const std::regex re{qstr}; find_nodes_rec(&res, nodes, re); } - return std::move(res); + return res; } Scene *Scene::extract_nodes(const char *qstr) diff --git a/src/sceneload.cc b/src/sceneload.cc index 4c0d324..28f5877 100644 --- a/src/sceneload.cc +++ b/src/sceneload.cc @@ -335,7 +335,7 @@ static int assimp_textype(aiTextureType type) case aiTextureType_EMISSIVE: return MTL_TEX_LIGHTMAP; case aiTextureType_REFLECTION: - return MTL_TEX_ENVMAP; + return MTL_TEX_REFLECT; default: break; } diff --git a/src/snode.cc b/src/snode.cc index b171f35..fb2877d 100644 --- a/src/snode.cc +++ b/src/snode.cc @@ -164,17 +164,17 @@ const Vec3 &SceneNode::get_node_scaling() const 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 @@ -220,6 +220,36 @@ void SceneNode::update(float dt) 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(); } -- 1.7.10.4