From 6eddb531d70d5dad5fb2f037072b9ec4f4e4b5e5 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 1 May 2012 20:46:58 +0000 Subject: Use light environment classes in the model viewer and the main rendering routine. --- src/render/Makefile.am | 4 ++ src/render/draw.cc | 133 ++++++++++++------------------------------------- src/render/draw.h | 6 --- src/ui/modelview.cc | 62 ++++++++++++----------- 4 files changed, 69 insertions(+), 136 deletions(-) diff --git a/src/render/Makefile.am b/src/render/Makefile.am index 31ba73d..7993036 100644 --- a/src/render/Makefile.am +++ b/src/render/Makefile.am @@ -15,6 +15,8 @@ noinst_HEADERS = \ gl.h \ image.h \ jpgfile.h \ + light.h \ + lightenvironment.h \ particles.h \ pngfile.h \ render.h \ @@ -34,6 +36,8 @@ librender_la_SOURCES = \ gl.cc \ image.cc \ jpgfile.cc \ + light.cc \ + lightenvironment.cc \ particles.cc \ pngfile.cc \ render.cc \ diff --git a/src/render/draw.cc b/src/render/draw.cc index 8f9f978..b0d234f 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -10,16 +10,21 @@ #include "core/application.h" #include "core/gameinterface.h" #include "core/range.h" + +#include "math/functions.h" + #include "model/fragment.h" #include "model/material.h" #include "model/model.h" -#include "render/render.h" -#include "render/textures.h" + #include "render/debugdrawer.h" #include "render/draw.h" #include "render/dust.h" +#include "render/light.h" +#include "render/lightenvironment.h" +#include "render/render.h" +#include "render/textures.h" #include "render/gl.h" -#include "math/functions.h" namespace render { @@ -47,81 +52,15 @@ math::Vector3f v7(-1, -1, -1); core::Zone *zone = 0; -math::Vector3f zone_light_location; // location of the zone light -math::Color zone_light_color; // color of the zone light - -bool has_zone_light = false; - bool draw_particles = true; bool draw_lights = true; -size_t max_lights = 8; - -float ambient_light_intensity = 0.1f; -float diffuse_light_intensity = 0.75f; -float specular_light_intensity = 0.75f; - -GLenum zone_gllight = GL_LIGHT0; typedef std::map Globes; Globes globes_list; -/* ---- Prepare the renderer state --------------------------------- */ - -void pass_reset_lights() -{ - // reset light state - has_zone_light = false; - zone_light_color.assign(1.0); - - for (size_t i = 0; i < max_lights; i++) - gl::disable(GL_LIGHT0 + i); -} - -// setup an OpenGL light -int add_light(const math::Vector3f & location, float attenuation, const math::Color & color) -{ - int gllight; - - // check if a light is available - for (size_t i = 0; i < max_lights; i++) { - if (!glIsEnabled(GL_LIGHT0 + i)) { - gllight = GL_LIGHT0 + i; - break; - } else { - gllight = GL_LIGHT0; - return gllight; - } - } - - // set up color and location - GLfloat gllight_location[4]; - GLfloat diffuse_light[4]; - GLfloat ambient_light[4]; - GLfloat specular_light[4]; +LightEnvironment lightenv_zone; - for (size_t i = 0; i < 3; i++) { - gllight_location[i] = location[i]; - ambient_light[i] = color[i] * ambient_light_intensity; - diffuse_light[i] = color[i] * diffuse_light_intensity; - specular_light[i] = color[i] * specular_light_intensity; - } - gllight_location[3] = 1.0f; - ambient_light[3] = 1.0f; - diffuse_light[3] = 1.0f; - specular_light[3] = 1.0f; - - // set up the light - // we use a simple averaging of the color times the specified attenuation value(such as 0.00025f). - // FIXME: use a more standardized and realistic way of doing this. - glLightf(gllight, GL_CONSTANT_ATTENUATION, ((color[0] + color[1] + color[2]) / 3.0f) * attenuation); - glLightf(gllight, GL_LINEAR_ATTENUATION, ((color[0] + color[1] + color[2]) / 3.0f) * attenuation); - - glLightfv(gllight, GL_POSITION, gllight_location); - glLightfv(gllight, GL_AMBIENT, ambient_light); - glLightfv(gllight, GL_DIFFUSE, diffuse_light); - glLightfv(gllight, GL_SPECULAR, specular_light); - return gllight; -} +/* ---- Prepare the renderer state --------------------------------- */ void pass_prepare(float seconds) { @@ -139,7 +78,7 @@ void pass_prepare(float seconds) } // initialize lights - pass_reset_lights(); + lightenv_zone.clear(); // clear current list of globes globes_list.clear(); @@ -152,6 +91,7 @@ void pass_prepare(float seconds) zone_ambient[3] = 1.0f; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, zone_ambient); + // zone light sources for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { core::Entity *entity = (*it); @@ -171,13 +111,9 @@ void pass_prepare(float seconds) // add zone lights if (globe->flag_is_set(core::Entity::Bright)) { - for (size_t i = 0; i < 3; i++) { - zone_light_location[i] = globe->location()[i]; - zone_light_color[i] = globe->color()[i]; - } - GLenum zone_gllight = add_light(zone_light_location, 0.0005f, globe->color()); - gl::enable(zone_gllight); - has_zone_light = true; + Light *zone_light = new Light(globe->location(), globe->color()); + zone_light->set_attenuation(2.0f, 0.0f, 0.0f); + lightenv_zone.add(zone_light); } } else { @@ -187,6 +123,10 @@ void pass_prepare(float seconds) } } } + + // zone lights are draw in world space coordinates + lightenv_zone.draw(); + lightenv_zone.enable(); } /* ----- Skybox ---------------------------------------------------- */ @@ -330,7 +270,6 @@ void draw_pass_globes() // FIXME is this ever reset ? GLfloat globe_specular[] = { 0.25f, 0.25f, 0.25f, 1.0f }; glMaterialfv(GL_FRONT, GL_SPECULAR, globe_specular); - float fake_light_location[4]; // Globes have to be rendered distance sorted, closest last. // Globes behind farplane are rescaled and repositioned. @@ -347,15 +286,7 @@ void draw_pass_globes() gl::depthmask(GL_FALSE); - if (has_zone_light) { - // nudge zone light - // FIXME doesn't work correctly with multiple zone lights - for (size_t i = 0; i < 3; i++) { - fake_light_location[i] = zone_light_location[i] + location[i] - globe->location()[i]; - } - fake_light_location[3] = 1.0f; - glLightfv(zone_gllight, GL_POSITION, fake_light_location); - } + lightenv_zone.draw(location - globe->location()); } gl::push(); @@ -396,17 +327,8 @@ void draw_pass_globes() } if (ext_render(globe)->distance() > (FARPLANE - globe->radius())) { - gl::depthmask(GL_TRUE); - - if (has_zone_light) { - // restore zone light - for (size_t i = 0; i < 3; i++) { - fake_light_location[i] = zone_light_location[i]; - } - fake_light_location[3] = 1.0f; - glLightfv(zone_gllight, GL_POSITION, fake_light_location); - } + lightenv_zone.draw(); } } } @@ -1232,7 +1154,10 @@ void draw(float seconds) draw_pass_spacegrid(); // draw the blue spacegrid if (!core::localplayer()->view()) { - Dust::draw(zone_light_color); // draw spacedust + math::Color dust_color(core::localplayer()->zone()->ambient_color()); + float s = math::max(math::max(dust_color[0], dust_color[1]), dust_color[2]); + dust_color *= 0.8f / s; + Dust::draw(dust_color); // draw spacedust } // draw entity lights, flares and particles @@ -1293,8 +1218,12 @@ void draw(float seconds) // GL_BLEND and GL_COLOR_MATERIAL must be enabled for the GUI //gl::disable(GL_COLOR_MATERIAL); // disable color tracking - // reset light state - pass_reset_lights(); + // clear current zone light environment + lightenv_zone.disable(); + lightenv_zone.clear(); + + // clear current list of globes + globes_list.clear(); } // draw weapon slots diff --git a/src/render/draw.h b/src/render/draw.h index a477d35..71321c5 100644 --- a/src/render/draw.h +++ b/src/render/draw.h @@ -15,9 +15,6 @@ namespace render { -/// reset lighting parameters -void pass_reset_lights(); - /// draw the world void draw(float seconds); @@ -30,9 +27,6 @@ void draw_slots(const core::Entity *entity); /// reset void reset(); -/// add a zone light -int add_light(const math::Vector3f & location, float attenuation, const math::Color & color); - /// draw a sphere void draw_sphere(const math::Color & color, float radius); diff --git a/src/ui/modelview.cc b/src/ui/modelview.cc index d1c5c96..b13b642 100755 --- a/src/ui/modelview.cc +++ b/src/ui/modelview.cc @@ -12,6 +12,8 @@ #include "sys/sys.h" #include "render/camera.h" #include "render/draw.h" +#include "render/light.h" +#include "render/lightenvironment.h" #include "render/render.h" #include #include @@ -20,7 +22,7 @@ namespace ui { const float LIGHT_DISTANCE = -10.0f; -const float LIGHT_ATTENUATION = 0.1f; +const float LIGHT_ATTENUATION = 2.0f; ModelView::ModelView(Widget *parent) : Widget(parent) { @@ -183,9 +185,19 @@ void ModelView::draw_globe() // gl 3d mode render::Camera::frustum_default(modelview_zoom, center.x(), center.y()); - // reset lighting - render::pass_reset_lights(); + // set up light environment + render::Light *light = new render::Light( + math::Vector3f(LIGHT_DISTANCE * reference_radius, 0, 0), + math::Color(1.0f, 1.0f, 1.0f) + ); + light->set_attenuation(0.0f, 1.0f, 0.0f); + render::LightEnvironment lightenv; + lightenv.add(light); + + lightenv.enable(); + lightenv.draw(); + // enable lighting gl::enable(GL_LIGHTING); @@ -204,13 +216,6 @@ void ModelView::draw_globe() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - // we set up the light in camera space - const math::Vector3f light_location(LIGHT_DISTANCE * reference_radius, 0, 0); - const math::Color light_color(1.0f, 1.0f, 1.0f); - GLenum gllight = render::add_light(light_location, LIGHT_ATTENUATION, light_color); - - gl::enable(gllight); - render::State::set_normalize(true); // push transformation matrix to stack @@ -238,7 +243,7 @@ void ModelView::draw_globe() gl::pop(); render::State::set_normalize(false); - gl::disable(gllight); + lightenv.disable(); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); @@ -251,11 +256,9 @@ void ModelView::draw_globe() gl::depthmask(GL_FALSE); // enable depth buffer writing gl::disable(GL_DEPTH_TEST); // disable depth buffer testing gl::disable(GL_LIGHTING); - - // gl 2d mode - render::Camera::ortho(); - + // gl 2d mode + render::Camera::ortho(); } void ModelView::draw_model() @@ -282,8 +285,18 @@ void ModelView::draw_model() // gl 3d mode render::Camera::frustum_default(modelview_zoom, center.x(), center.y()); - // reset lighting - render::pass_reset_lights(); + // set up light environment + render::Light *light = new render::Light( + math::Vector3f(LIGHT_DISTANCE * reference_radius, 0, 0), + math::Color(1.0f, 1.0f, 1.0f) + ); + light->set_attenuation(0.0f, 1.0f, 0.0f); + + render::LightEnvironment lightenv; + lightenv.add(light); + + lightenv.enable(); + lightenv.draw(); // enable lighting gl::enable(GL_LIGHTING); @@ -303,13 +316,6 @@ void ModelView::draw_model() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - // we set up the light in camera space - const math::Vector3f light_location(LIGHT_DISTANCE * reference_radius, 0, 0); - const math::Color light_color(1.0f, 1.0f, 1.0f); - GLenum gllight = render::add_light(light_location, LIGHT_ATTENUATION, light_color); - - gl::enable(gllight); - // push transformation matrix to stack gl::push(); @@ -332,7 +338,7 @@ void ModelView::draw_model() gl::pop(); - gl::disable(gllight); + lightenv.disable(); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); @@ -363,13 +369,13 @@ void ModelView::draw_model() } render::draw_model_lights(model, modelscale, math::Vector3f(), modelview_axis, core::localplayer()->color(), thrust, 0.0f); - + gl::disable(GL_TEXTURE_2D); gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling gl::depthmask(GL_FALSE); // enable depth buffer writing - gl::disable(GL_DEPTH_TEST); // disable depth buffer testing - + gl::disable(GL_DEPTH_TEST); // disable depth buffer testing + // gl 2d mode render::Camera::ortho(); } -- cgit v1.2.3