diff options
author | Stijn Buys <ingar@osirion.org> | 2011-07-29 23:38:07 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2011-07-29 23:38:07 +0000 |
commit | 044d0183e254d89dd12d0799be6aa8f8f0f979f2 (patch) | |
tree | 285ec77a8cf5ac57fb17f4168272e1a600e13917 | |
parent | 8924c07280cdd96b01c501b3b820711f89039edd (diff) |
Moved material context functions into the State class.
-rw-r--r-- | src/render/draw.cc | 216 | ||||
-rw-r--r-- | src/render/state.cc | 175 | ||||
-rw-r--r-- | src/render/state.h | 86 |
3 files changed, 237 insertions, 240 deletions
diff --git a/src/render/draw.cc b/src/render/draw.cc index 84015e3..64ac4c1 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -644,23 +644,10 @@ void draw_model_fragments(model::Model *model, const math::Color & color_primary, const math::Color & color_secondary, const float enginetime, const bool detail, const bool power, const float thrust) { - // default material, lighted and geometry color - const model::Material *material = 0; - math::Color color(1.0f, 1.0f, 1.0f); // current drawing color - bool use_light = true; // gl::disable(GL_LIGHTING) is set - bool use_texture = false; // texturing - bool use_env = false; // environment mapping - - // TODO this should probably be initialized somewhere else - gl::texgeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - gl::texgeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - - /* - gl::texgeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - */ - + State::set_color(color_primary); + State::set_color_second(color_secondary); + State::set_color_engine(model->enginecolor() * thrust); + for (model::Model::Groups::const_iterator git = model->groups().begin(); git != model->groups().end(); git++) { const model::FragmentGroup *group = (*git); @@ -684,201 +671,24 @@ void draw_model_fragments(model::Model *model, gl::translate(translation); } - for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) { const model::Fragment *fragment = (*fit); - - if (fragment->material() != material) { - material = fragment->material(); - - if (material) { - if (material->flags() & model::Material::Engine) { - - color.assign(model->enginecolor() * thrust); - - } else if (material->flags() & model::Material::Tertiary) { - - if ((material->flags() & model::Material::Tertiary) == model::Material::Tertiary) { - for (size_t i = 0; i < 3; i++) - color[i] = (color_primary[i] + color_secondary[i]) / 2; - - } else if ((material->flags() & model::Material::Secondary) == model::Material::Secondary) { - color.assign(color_secondary); - - } - if ((material->flags() & model::Material::Primary) == model::Material::Primary) { - color.assign(color_primary); - } - - color.r *= material->color().r; - color.g *= material->color().g; - color.b *= material->color().b; - } else { - - color.assign(material->color()); - } - - if (power && (material->flags() & model::Material::Bright)) { - if (use_light) { - gl::disable(GL_LIGHTING); - use_light = false; - } - } else if (power && (material->flags() & model::Material::Engine)) { - if (use_light) { - gl::disable(GL_LIGHTING); - use_light = false; - } - } else { - if (!use_light) { - gl::enable(GL_LIGHTING); - use_light = true; - } - } - - if (material->flags() & model::Material::Texture) { - - Textures::bind(material->texture_id()); - - if (!use_texture) { - gl::enable(GL_TEXTURE_2D); - use_texture = true; - } - - } - - if (material->flags() & model::Material::Environment) { - - if (!(material->flags() & model::Material::Texture)) { - - if (use_texture) { - gl::disable(GL_TEXTURE_2D); - use_texture = false; - } - - // use sky as envmap if the material doesn't define a texture - if (core::localplayer()->zone()->sky().size()) { - gl::enable(GL_TEXTURE_CUBE_MAP); - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(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); - use_env = true; - } - - } else { - gl::disable(GL_TEXTURE_CUBE_MAP); - - gl::texgeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - gl::texgeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - - gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); - use_env = true; - - if (!use_texture) { - gl::enable(GL_TEXTURE_2D); - use_texture = true; - } - } - } else { - if (use_env) { - // disable env mapping - gl::disable(GL_TEXTURE_GEN_S); - gl::disable(GL_TEXTURE_GEN_T); - gl::disable(GL_TEXTURE_GEN_R); - gl::disable(GL_TEXTURE_CUBE_MAP); - use_env = false; - } - } - - if (!(material->flags() & (model::Material::Texture + model::Material::Environment))) { - if (use_texture) { - gl::disable(GL_TEXTURE_2D); - use_texture = false; - } - } - - } else { - // material not found - if (use_light) { - // disable lighting - gl::disable(GL_LIGHTING); - use_light = false; - } - - if (use_env) { - // disable env mapping - gl::disable(GL_TEXTURE_GEN_S); - gl::disable(GL_TEXTURE_GEN_T); - gl::disable(GL_TEXTURE_GEN_R); - gl::disable(GL_TEXTURE_CUBE_MAP); - use_env = false; - } - - if (use_texture) { - gl::disable(GL_TEXTURE_2D); - use_texture = false; - } - - color.assign(1.0f, 0.0f, 1.0f); - } - } - - gl::color(color); + State::use_material(fragment->material()); draw_fragment(fragment, detail); if (r_normals->value()) { // force reset of material settings for the next fragment - material = 0; - if (use_light) { - // disable lighting - gl::disable(GL_LIGHTING); - use_light = false; - } - - if (use_env) { - // disable env mapping - gl::disable(GL_TEXTURE_GEN_S); - gl::disable(GL_TEXTURE_GEN_T); - gl::disable(GL_TEXTURE_GEN_R); - gl::disable(GL_TEXTURE_CUBE_MAP); - use_env = false; - } - - if (use_texture) { - gl::disable(GL_TEXTURE_2D); - use_texture = false; - } - - color.assign(0.75f, 0.0f, 0.0f); + State::reset(); + gl::color(0.75f, 0.0f, 0.0f); draw_fragment_normals(fragment, detail); } } gl::pop(); } - - if (!use_light) { - gl::enable(GL_LIGHTING); - } - - if (use_env) { - // disable env mapping - gl::disable(GL_TEXTURE_GEN_S); - gl::disable(GL_TEXTURE_GEN_T); - gl::disable(GL_TEXTURE_GEN_R); - gl::disable(GL_TEXTURE_CUBE_MAP); - } - - if (use_texture) { - gl::disable(GL_TEXTURE_2D); - } - + + State::reset(); } // draw bounding box @@ -1433,13 +1243,11 @@ void draw(float seconds) } gl::depthmask(GL_TRUE); // enable depth buffer writing - gl::disable(GL_DEPTH_TEST); // disable depth buffer testing - - gl::disable(GL_COLOR_MATERIAL); // disable color tracking + gl::disable(GL_DEPTH_TEST); // disable depth buffer testing gl::disable(GL_CULL_FACE); // disable culling - - // GL_BLEND must be enabled for the GUI + // GL_BLEND and GL_COLOR_MATERIAL must be enabled for the GUI + //gl::disable(GL_COLOR_MATERIAL); // disable color tracking } // draw HUD target world space geometry, like dock indicators diff --git a/src/render/state.cc b/src/render/state.cc index fb64319..21a142f 100644 --- a/src/render/state.cc +++ b/src/render/state.cc @@ -16,18 +16,23 @@ namespace render { -int State::render_width = 0; -int State::render_height = 0; -float State::render_aspect = 0; -bool State::render_has_generate_mipmaps = false; -bool State::render_has_vbo = false; -GLuint State::render_vbo = 0; +int State::state_width = 0; +int State::state_height = 0; +float State::state_aspect = 0; +bool State::state_has_generate_mipmaps = false; +bool State::state_has_vbo = false; +GLuint State::state_vbo = 0; + + +math::Color State::state_color_primary; +math::Color State::state_color_secondary; +math::Color State::state_color_engine; void State::init(int width, int height) { resize(width, height); - render_has_generate_mipmaps = false; + state_has_generate_mipmaps = false; std::string version(gl::version()); for (size_t i = 0; i < version.size(); i++) { @@ -40,10 +45,10 @@ void State::init(int width, int height) if (versionstream >> major >> minor) { if (major > 1) { - render_has_generate_mipmaps = true; + state_has_generate_mipmaps = true; } else if (major == 1) { if (minor > 3) - render_has_generate_mipmaps = true; + state_has_generate_mipmaps = true; } } else { @@ -51,61 +56,61 @@ void State::init(int width, int height) } con_print << " hardware generated mipmaps "; - if (render_has_generate_mipmaps) + if (state_has_generate_mipmaps) con_print << "available" << std::endl; else con_print << "not available" << std::endl; // initialize gl functions - render_has_vbo = true; + state_has_vbo = true; gl::genbuffers = (gl::genbuffers_func) SDL_GL_GetProcAddress("glGenBuffers"); if (!gl::genbuffers) { con_debug << " glGenBuffers not available" << std::endl; - render_has_vbo = false; + state_has_vbo = false; } gl::deletebuffers = (gl::deletebuffers_func) SDL_GL_GetProcAddress("glDeleteBuffers"); if (!gl::deletebuffers) { con_debug << " glDeleteBuffers not available" << std::endl; - render_has_vbo = false; + state_has_vbo = false; } gl::bindbuffer = (gl::bindbuffer_func) SDL_GL_GetProcAddress("glBindBuffer"); if (!gl::bindbuffer) { con_debug << " glBindBuffer not available" << std::endl; - render_has_vbo = false; + state_has_vbo = false; } gl::bufferdata = (gl::bufferdata_func) SDL_GL_GetProcAddress("glBufferData"); if (!gl::bufferdata) { con_debug << " glBufferData not available" << std::endl; - render_has_vbo = false; + state_has_vbo = false; } con_print << " vertex bufer objects "; - if (render_has_vbo) + if (state_has_vbo) con_print << "enabled" << std::endl; else con_print << "disabled" << std::endl; // Generate VBO - if (render_has_vbo) - gl::genbuffers(1, &render_vbo); + if (state_has_vbo) + gl::genbuffers(1, &state_vbo); } void State::shutdown() { // Delete VBO - if (render_has_vbo) - gl::deletebuffers(1, &render_vbo); + if (state_has_vbo) + gl::deletebuffers(1, &state_vbo); } void State::resize(int width, int height) { - render_width = width; - render_height = height; + state_width = width; + state_height = height; - render_aspect = (float) width / (float) height; + state_aspect = (float) width / (float) height; clear(); } @@ -113,7 +118,7 @@ void State::resize(int width, int height) void State::clear() { // set viewport - gl::viewport(0, 0, render_width, render_height); + gl::viewport(0, 0, state_width, state_height); // set clear color gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f); @@ -171,4 +176,126 @@ void State::set_normalize(const bool enable) } } + + +void State::set_color(const math::Color & color) +{ + state_color_primary.assign(color); +} + +void State::set_color_second(const math::Color & color) +{ + state_color_secondary.assign(color); +} + +void State::set_color_engine(const math::Color & color) { + state_color_engine.assign(color); +} + +void State::set_color(const core::Entity *entity) +{ + state_color_primary.assign(entity->color()); + state_color_secondary.assign(entity->color_second()); +} + +void State::use_material(const model::Material * material) { + + math::Color color; + + reset(); + + if (!material) { + color.assign(1.0f, 0.0f, 1.0f); + gl::color(color); + return; + } + + // assign the opengl drawing color according to material flags + if (material->flags() & model::Material::Engine) { + + // use current engine color + color.assign(state_color_engine); + + } else if (material->flags() & model::Material::Tertiary) { + + // use entity colors + if ((material->flags() & model::Material::Tertiary) == model::Material::Tertiary) { + for (size_t i = 0; i < 3; i++) + color[i] = (state_color_primary[i] + state_color_secondary[i]) / 2; + + } else if ((material->flags() & model::Material::Secondary) == model::Material::Secondary) { + color.assign(state_color_secondary); + + } else if ((material->flags() & model::Material::Primary) == model::Material::Primary) { + color.assign(state_color_primary); + } + + color.r *= material->color().r; + color.g *= material->color().g; + color.b *= material->color().b; + + } else { + // use material color + color.assign(material->color()); + } + + // lighted or fullbright + // FIXME entity power + if (material->flags() & model::Material::Bright) { + gl::disable(GL_LIGHTING); + + } else if (material->flags() & model::Material::Engine) { + gl::disable(GL_LIGHTING); + + } else { + gl::enable(GL_LIGHTING); + } + + // texture + if (material->flags() & model::Material::Texture) { + + Textures::bind(material->texture_id()); + gl::enable(GL_TEXTURE_2D); + + if (material->flags() & model::Material::Environment) { + + gl::texgeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + gl::texgeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + gl::enable(GL_TEXTURE_GEN_S); + gl::enable(GL_TEXTURE_GEN_T); + } + + } else { + // envmapped without texture: use the skybox as envmap + if (material->flags() & model::Material::Environment) { + + if (core::localplayer()->zone()->sky().size()) { + gl::enable(GL_TEXTURE_CUBE_MAP); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(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); + } + } + } + + + gl::color(color); +} + +void State::reset() { + gl::disable(GL_TEXTURE_GEN_S); + gl::disable(GL_TEXTURE_GEN_T); + gl::disable(GL_TEXTURE_GEN_R); + 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); +} + } // namespace render diff --git a/src/render/state.h b/src/render/state.h index 6387be8..b614c1b 100644 --- a/src/render/state.h +++ b/src/render/state.h @@ -7,6 +7,7 @@ #ifndef __INCLUDED_RENDER_STATE_H__ #define __INCLUDED_RENDER_STATE_H__ +#include "core/entity.h" #include "render/gl.h" namespace render @@ -15,41 +16,102 @@ namespace render class State { public: + /* ---- render context ------------------------------------- */ + + /** + * @brief Initialize the render state + **/ static void init(int width, int height); + + /** + * @brief Initialize the render state + **/ static void shutdown(); + /** + * @brief Resize the render context + **/ static void resize(int width, int height); + + /** + * @brief Clear the render context state + **/ static void clear(); + + /* ---- material context ----------------------------------- */ + + /** + * @brief Reset the material context + **/ + static void reset(); + /** + * @brief Set the primary color of the material context + * set_color() should be used before calling set_material(). + **/ + static void set_color(const math::Color & color); + + /** + * @brief Set the secondary color of the material context + * set_color_second() should be used before calling set_material(). + **/ + static void set_color_second(const math::Color & color); + + /** + * @brief Set the engine color of the material context + * set_color_engine() should be used before calling set_material(). + **/ + static void set_color_engine(const math::Color & color); + + /** + * @brief Copy primary, secondary and engine color from an entity + * set_color() should be used before calling set_material(). + **/ + static void set_color(const core::Entity *entity); + + /** + * @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. + **/ + static void use_material(const model::Material * material); + + inline static int width() { - return render_width; + return state_width; } inline static int height() { - return render_height; + return state_height; } inline static float aspect() { - return render_aspect; + return state_aspect; } inline static bool has_generate_mipmaps() { - return render_has_generate_mipmaps; + return state_has_generate_mipmaps; } inline static bool has_vbo() { - return render_has_vbo; + return state_has_vbo; } inline static GLuint vbo() { - return render_vbo; + return state_vbo; } static void set_normalize(const bool enable=true); private: - static int render_width; - static int render_height; + static int state_width; + static int state_height; - static float render_aspect; - static bool render_has_generate_mipmaps; - static bool render_has_vbo; - static GLuint render_vbo; + static float state_aspect; + static bool state_has_generate_mipmaps; + static bool state_has_vbo; + static GLuint state_vbo; + + static math::Color state_color_primary; // current primary color + static math::Color state_color_secondary; // current secondary color + static math::Color state_color_engine; // current secondary color + }; } // namespace render |