From 1d518a54914531d7a4fab3a6835b75de85bd7bc7 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 9 Jul 2014 19:18:31 +0000 Subject: Initial support for multi-layered materials, requires shaders files in the new format. --- src/render/draw.cc | 11 ++-- src/render/state.cc | 133 +++++++++++++++++++++++++------------------------ src/render/state.h | 42 +++++++++++----- src/render/textures.cc | 19 +++---- src/render/textures.h | 4 +- 5 files changed, 113 insertions(+), 96 deletions(-) (limited to 'src/render') diff --git a/src/render/draw.cc b/src/render/draw.cc index b956c18..d932739 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -736,21 +736,24 @@ void draw_model_fragments(model::Model *model, for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) { const model::Fragment *fragment = (*fit); - State::use_material(fragment->material()); - draw_fragment(fragment, detail); + + for (model::Material::Layers::const_iterator lit = fragment->material()->layers().begin(); lit != fragment->material()->layers().end(); ++lit) { + State::use_material_layer(fragment->material(), (*lit)); + draw_fragment(fragment, detail); + State::reset(); + } if (r_normals->value()) { // force reset of material settings for the next fragment State::reset(); gl::color(0.75f, 0.0f, 0.0f); draw_fragment_normals(fragment, detail); + State::reset(); } } gl::pop(); } - - State::reset(); } // draw entity axis diff --git a/src/render/state.cc b/src/render/state.cc index 400a186..7857963 100644 --- a/src/render/state.cc +++ b/src/render/state.cc @@ -24,6 +24,7 @@ bool State::state_has_vbo = false; GLuint State::state_vbo = 0; int State::state_maxlights; int State::state_maxtextureunits; +size_t State::state_logo_texture_id = 0; math::Color State::state_color_primary; @@ -191,8 +192,6 @@ void State::set_normalize(const bool enable) } } - - void State::set_color(const math::Color & color) { state_color_primary.assign(color); @@ -218,24 +217,14 @@ void State::set_power(const bool power) state_power = power; } -void State::use_material(const model::Material * material) { - - math::Color color; - math::Color specular; - - reset(); - - // default specular shininess setting - gl::material(GL_FRONT, GL_SHININESS, 8); - - if (!material) { - color.assign(1.0f, 0.0f, 1.0f); - specular.assign(1.0f, 0.0f, 1.0f); - gl::color(color); - gl::specular(specular); +void State::use_material_layer(const model::Material * material, const model::Layer *layer) +{ + if (!material || !layer) { + gl::color(math::Color(1.0f, 0.0f, 1.0f)); + gl::specular(math::Color(1.0f, 0.0f, 1.0f)); return; } - + // material has the decal flag set if (material->has_flag(model::Material::FlagDecal)) { gl::enable(GL_POLYGON_OFFSET_FILL); @@ -244,32 +233,36 @@ void State::use_material(const model::Material * material) { gl::alphafunc(GL_GEQUAL, 0.5f); } - // assign the opengl drawing color according to material flags - switch (material->colortype()) { - case model::Material::ColorMaterial: - color.assign(material->color()); - specular.assign(material->specular()); + math::Color color(layer->color()); + math::Color specular(layer->color()); + + // apply color generation rules + switch (layer->rgbgen()) { + case model::Layer::RGBGenIdentity: break; - case model::Material::ColorEngine: + case model::Layer::RGBGenColor: + break; + + case model::Layer::RGBGenEngine: // assign current engine color color.assign(state_color_engine); specular.assign(0.0f); break; - case model::Material::ColorPrimary: + case model::Layer::RGBGenPrimary: // assign current primary entity color color.assign(state_color_primary); specular.assign(state_color_primary); break; - case model::Material::ColorSecondary: + case model::Layer::RGBGenSecondary: // assign current secondry entity color color.assign(state_color_secondary); specular.assign(state_color_secondary); break; - case model::Material::ColorTertiary: + case model::Layer::RGBGenTertiary: // assign current tertiary entity color for (size_t i = 0; i < 3; i++) { color[i] = (state_color_primary[i] + state_color_secondary[i]) / 2; @@ -278,66 +271,71 @@ void State::use_material(const model::Material * material) { break; } - // blend color type with material color - if (material->colortype() != model::Material::ColorMaterial) { - color.r *= material->color().r; - color.g *= material->color().g; - color.b *= material->color().b; - specular.r *= material->specular().r; - specular.g *= material->specular().g; - specular.b *= material->specular().b; + // blend current color with layer color + if ((layer->rgbgen() != model::Layer::RGBGenIdentity) && (layer->rgbgen() != model::Layer::RGBGenColor)) { + color.r *= layer->color().r; + color.g *= layer->color().g; + color.b *= layer->color().b; + specular.r *= layer->specular().r; + specular.g *= layer->specular().g; + specular.b *= layer->specular().b; } - + + gl::color(color); + gl::specular(specular); + // lighted or fullbright - if (state_power && (material->has_flag(model::Material::FlagBright))) { + if (state_power && layer->bright()) { gl::disable(GL_LIGHTING); - } else if (state_power && (material->colortype() == model::Material::ColorEngine)) { + } else if (state_power && (layer->rgbgen() == model::Layer::RGBGenEngine)) { gl::disable(GL_LIGHTING); } else { gl::enable(GL_LIGHTING); } - // texture - if (material->has_flag(model::Material::FlagTexture)) { - - Textures::bind(material->texture_id()); + // texture map + if (layer->texmap() == model::Layer::TexMapImage) { + + // map a texture image + Textures::bind(layer->texture_id()); gl::enable(GL_TEXTURE_2D); - if (material->has_flag(model::Material::FlagEnvironment)) { + // texture coordinate generation + if (layer->tcgen() == model::Layer::TCGenEnvironment) { gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); + gl::enable(GL_TEXTURE_GEN_T); } - - } else { - // envmapped without texture: use the skybox as envmap - if (material->has_flag(model::Material::FlagEnvironment)) { - if (core::localplayer()->zone()->sky().size()) { - gl::enable(GL_TEXTURE_CUBE_MAP); + + } else if (layer->texmap() == model::Layer::TexMapEnvironment) { + + // map the current skybox + + if (core::localplayer()->zone()->sky().size()) { + gl::enable(GL_TEXTURE_CUBE_MAP); - gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgen(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); - gl::enable(GL_TEXTURE_GEN_R); - } else { - color.assign(0.0f, 0.0f, 0.0f); - } - gl::material(GL_FRONT, GL_SHININESS, 4); + gl::enable(GL_TEXTURE_GEN_S); + gl::enable(GL_TEXTURE_GEN_T); + gl::enable(GL_TEXTURE_GEN_R); + } else { + color.assign(0.0f, 0.0f, 0.0f); } + gl::material(GL_FRONT, GL_SHININESS, 4); + } - - gl::color(color); - gl::specular(specular); + } -void State::reset() { +void State::reset() +{ gl::disable(GL_POLYGON_OFFSET_FILL); gl::disable(GL_ALPHA_TEST); gl::disable(GL_TEXTURE_GEN_S); @@ -346,7 +344,12 @@ void State::reset() { gl::disable(GL_LIGHTING); gl::disable(GL_TEXTURE_CUBE_MAP); gl::disable(GL_TEXTURE_2D); - gl::color(1.0f, 1.0f, 1.0f, 1.0f); + + // default specular shininess setting + gl::material(GL_FRONT, GL_SHININESS, 8); + + gl::color(math::Color(1.0f)); + gl::specular(math::Color(0.0f)); } } // namespace render diff --git a/src/render/state.h b/src/render/state.h index ea55602..0581c2e 100644 --- a/src/render/state.h +++ b/src/render/state.h @@ -75,36 +75,51 @@ public: static void set_power(const bool power); /** - * @brief Set the material context - * use_material() will alter the current render context according to the settings - * defined by the material. If the material uses primary, secondary or engine color, - * the current material context colors will be used. + * @brief set the material layer context + * use_material_layer() will alter the current render context according to the settings + * defined by the material layer. If the material uses primary, secondary or engine color, + * the current state context colors will be used. **/ - static void use_material(const model::Material * material); + static void use_material_layer(const model::Material * material, const model::Layer *layer); - inline static int width() { + inline static int width() + { return state_width; } - inline static int height() { + + inline static int height() + { return state_height; } - inline static float aspect() { + + inline static float aspect() + { return state_aspect; } - inline static bool has_generate_mipmaps() { + + inline static bool has_generate_mipmaps() + { return state_has_generate_mipmaps; } - inline static bool has_vbo() { + + inline static bool has_vbo() + { return state_has_vbo; } - inline static GLuint vbo() { + + inline static GLuint vbo() + { return state_vbo; } - inline static int max_lights() { + + inline static int max_lights() + { return state_maxlights; } - inline static int max_textureunits() { + + inline static int max_textureunits() + { return state_maxtextureunits; } @@ -120,6 +135,7 @@ private: static GLuint state_vbo; static int state_maxlights; static int state_maxtextureunits; + static size_t state_logo_texture_id; static math::Color state_color_primary; // current primary color static math::Color state_color_secondary; // current secondary color diff --git a/src/render/textures.cc b/src/render/textures.cc index 5a90640..bd75a45 100644 --- a/src/render/textures.cc +++ b/src/render/textures.cc @@ -24,11 +24,6 @@ GLuint Textures::textures_cubemap_id; math::Vector2f Textures::texture_size[MAXTEXTURES]; std::string textures_cubemapname; -void material_loader_func(model::Material *material) -{ - Textures::material_loader(material); -} - void Textures::init() { con_print << "^BLoading textures..." << std::endl; @@ -57,12 +52,12 @@ void Textures::init() load("bitmaps/pointers/control"); load("bitmaps/pointers/target"); - model::Material::set_loader_func(Textures::material_loader); + model::Material::set_imageloader_func(Textures::image_loader); } void Textures::shutdown() { - model::Material::set_loader_func(0); + model::Material::set_imageloader_func(0); clear(); } @@ -416,12 +411,12 @@ size_t Textures::bind(const size_t texture, const bool filter) return id; } -void Textures::material_loader(model::Material *material) +void Textures::image_loader(model::Layer *layer) { - if (material->has_flag(model::Material::FlagTexture) && (material->texture().size() > 0)) { - size_t id = load(material->texture()); - material->set_texture_id(id); - material->set_size(texture_size[id]); + if (layer->texture().size() > 0 ) { + size_t id = load(layer->texture()); + layer->set_texture_id(id); + layer->set_size(texture_size[id]); } } diff --git a/src/render/textures.h b/src/render/textures.h index 69442e8..2341672 100644 --- a/src/render/textures.h +++ b/src/render/textures.h @@ -60,8 +60,8 @@ public: /// list loaded textures static void list(); - /// material loader func - static void material_loader(model::Material *material); + /// material image loader hook + static void image_loader(model::Layer *layer); private: static void clear(); -- cgit v1.2.3