Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/draw.cc216
-rw-r--r--src/render/state.cc175
-rw-r--r--src/render/state.h86
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