]> git.tdb.fi Git - libs/gl.git/commitdiff
Add Vector3 and Vector4 classes
authorMikko Rasa <tdb@tdb.fi>
Sun, 5 Jul 2009 20:32:00 +0000 (20:32 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 5 Jul 2009 20:32:00 +0000 (20:32 +0000)
Add the rest of Light parameters
Make lighting in PipelinePass const
Reset viewport after each effect
Add load_matrix functions

source/light.cpp
source/light.h
source/matrix.cpp
source/matrix.h
source/pipeline.cpp
source/pipelinepass.h
source/shadowmap.cpp [new file with mode: 0644]
source/shadowmap.h [new file with mode: 0644]
source/vector.h [new file with mode: 0644]

index 899e22c9853d964ed7c0a591d4585cbfb2591c0c..b523fe365124e9c8f52cba0bd4c9edbbaa8e2f07 100644 (file)
@@ -18,11 +18,15 @@ Light::Light():
        ambient(0),
        diffuse(1),
        specular(1),
-       x(0), y(0), z(1), w(0),
-       sdx(0), sdy(0), sdz(-1),
+       position(0, 0, 1, 0),
+       spot_dir(0, 0, -1),
        spot_exp(0),
        spot_cutoff(180)
-{ }
+{
+       attenuation[0]=1;
+       attenuation[1]=0;
+       attenuation[2]=0;
+}
 
 void Light::set_ambient(const Color &c)
 {
@@ -39,12 +43,31 @@ void Light::set_specular(const Color &c)
        specular=c;
 }
 
-void Light::set_position(float x_, float y_, float z_, float w_)
+void Light::set_position(const Vector4 &p)
+{
+       position=p;
+}
+
+void Light::set_spot_direction(const Vector3 &d)
+{
+       spot_dir=d;
+}
+
+void Light::set_spot_exponent(float e)
+{
+       spot_exp=e;
+}
+
+void Light::set_spot_cutoff(float c)
+{
+       spot_cutoff=c;
+}
+
+void Light::set_attenuation(float c, float l, float q)
 {
-       x=x_;
-       y=y_;
-       z=z_;
-       w=w_;
+       attenuation[0]=c;
+       attenuation[1]=l;
+       attenuation[2]=q;
 }
 
 void Light::bind() const
@@ -56,7 +79,13 @@ void Light::bind() const
                glLightfv(l, GL_AMBIENT, &ambient.r);
                glLightfv(l, GL_DIFFUSE, &diffuse.r);
                glLightfv(l, GL_SPECULAR, &specular.r);
-               glLightfv(l, GL_POSITION, &x);
+               glLightfv(l, GL_POSITION, &position.x);
+               glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x);
+               glLightf(l, GL_SPOT_EXPONENT, spot_exp);
+               glLightf(l, GL_SPOT_CUTOFF, spot_cutoff);
+               glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]);
+               glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]);
+               glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]);
                current_lights[current_unit]=this;
        }
 }
index e9b032694565e7e857e32fada5d84a0d70013505..5871ec72d2ea65c3ef3d43721387d47bf86d1a64 100644 (file)
@@ -10,6 +10,7 @@ Distributed under the LGPL
 
 #include <vector>
 #include "color.h"
+#include "vector.h"
 
 namespace Msp {
 namespace GL {
@@ -20,8 +21,8 @@ private:
        Color ambient;
        Color diffuse;
        Color specular;
-       float x, y, z, w;
-       float sdx, sdy, sdz;
+       Vector4 position;
+       Vector3 spot_dir;
        float spot_exp;
        float spot_cutoff;
        float attenuation[3];
@@ -31,13 +32,31 @@ private:
 
 public:
        Light();
+
        void set_ambient(const Color &c);
        void set_diffuse(const Color &c);
        void set_specular(const Color &c);
-       void set_position(float, float, float, float);
+       const Color &get_ambient() const { return ambient; }
+       const Color &get_diffuse() const { return diffuse; }
+       const Color &get_specular() const { return specular; }
+
+       void set_position(const Vector4 &);
+       const Vector4 &get_position() const { return position; }
+       void set_spot_direction(const Vector3 &);
+       void set_spot_exponent(float);
+       void set_spot_cutoff(float);
+       const Vector3 &get_spot_direction() const { return spot_dir; }
+       float get_spot_exponent() const { return spot_exp; }
+       float get_spot_cutoff() const { return spot_cutoff; }
+       void set_attenuation(float, float, float);
+       const float *get_attenuation() const { return attenuation; }
+
        void bind() const;
        void bind_to(unsigned) const;
 
+       // Deprecated
+       void set_position(float x, float y, float z, float w) { set_position(Vector4(x, y, z, w)); }
+
        static void activate(unsigned);
        static void unbind();
 };
index 7841218011935f115c4a7dfbeb7e340ea6ae1a5c..9af850d2dfa68956037be0e4854716813fdc79a6 100644 (file)
@@ -20,6 +20,16 @@ void load_identity()
        glLoadIdentity();
 }
 
+void load_matrix(const float *matrix)
+{
+       glLoadMatrixf(matrix);
+}
+
+void load_matrix(const double *matrix)
+{
+       glLoadMatrixd(matrix);
+}
+
 void mult_matrix(const float *matrix)
 {
        glMultMatrixf(matrix);
index 13de6c8f4542030eb22e35647c443e6e473640fb..79d330a30ca99e3c34348eca271c56f7d7be3404 100644 (file)
@@ -22,6 +22,8 @@ enum MatrixMode
 
 void matrix_mode(MatrixMode);
 void load_identity();
+void load_matrix(const float *);
+void load_matrix(const double *);
 void mult_matrix(const float *);
 void mult_matrix(const double *);
 void push_matrix();
index fcfead76f16c2ea9495801d98f7a9ed2e7bd7801..6a9556a61c5b3fd308cd0e8c0134e30ecec8f78e 100644 (file)
@@ -118,7 +118,10 @@ void Pipeline::render_all() const
                glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        }
        for(vector<Effect *>::const_iterator i=effects.begin(); i!=effects.end(); ++i)
+       {
                (*i)->prepare();
+               glViewport(0, 0, width, height);
+       }
        for(vector<Tag>::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i)
                render(*i);
        for(vector<Effect *>::const_iterator i=effects.end(); i--!=effects.begin();)
index 9f7977294608384c07205ca2ccfae9ae1b15e313..0189c928e187ed0e0f1cd5dc01d0956b94f670e7 100644 (file)
@@ -19,7 +19,7 @@ class Lighting;
 struct PipelinePass
 {
        std::vector<Effect *> effects;
-       Lighting *lighting;
+       const Lighting *lighting;
 
        PipelinePass();
 };
diff --git a/source/shadowmap.cpp b/source/shadowmap.cpp
new file mode 100644 (file)
index 0000000..9b27ba0
--- /dev/null
@@ -0,0 +1,138 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <cmath>
+#include <cstdlib>
+#include "light.h"
+#include "matrix.h"
+#include "misc.h"
+#include "projection.h"
+#include "scene.h"
+#include "shadowmap.h"
+#include "texunit.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+ShadowMap::ShadowMap(unsigned s, const Scene &c, const Light &l):
+       size(s),
+       scene(c),
+       light(l),
+       radius(1)
+{
+       depth_buf.set_min_filter(LINEAR);
+       depth_buf.storage(DEPTH_COMPONENT, size, size, 0);
+       depth_buf.image(0, DEPTH_COMPONENT, UNSIGNED_BYTE, 0);
+       depth_buf.parameter(GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
+       depth_buf.parameter(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+       depth_buf.parameter(GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+       depth_buf.parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       depth_buf.parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+       fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
+       glDrawBuffer(GL_NONE);
+       Framebuffer::unbind();
+       Texture::unbind();
+}
+
+void ShadowMap::set_target(const Vector3 &t, float r)
+{
+       target=t;
+       radius=r;
+}
+
+void ShadowMap::prepare()
+{
+       const Vector4 &lpos=light.get_position();
+       if(lpos.w)
+               throw Exception("Non-directional lights not supported at the moment");
+
+       float matrix[16];
+       if(abs(lpos.z)>=abs(lpos.x) && abs(lpos.z)>=abs(lpos.y))
+       {
+               float d=sqrt(lpos.x*lpos.x+lpos.z*lpos.z);
+               matrix[0]=lpos.z/d;
+               matrix[4]=0;
+               matrix[8]=-lpos.x/d;
+               matrix[1]=-lpos.x*lpos.y/d;
+               matrix[5]=d;
+               matrix[9]=-lpos.z*lpos.y/d;
+       }
+       else
+       {
+               float d=sqrt(lpos.x*lpos.x+lpos.y*lpos.y);
+               matrix[0]=-lpos.y/d;
+               matrix[4]=lpos.x/d;
+               matrix[8]=0;
+               matrix[1]=-lpos.x*lpos.z/d;
+               matrix[5]=-lpos.y*lpos.z/d;
+               matrix[9]=d;
+       }
+
+       matrix[2]=lpos.x;
+       matrix[6]=lpos.y;
+       matrix[10]=lpos.z;
+
+       matrix[12]=-(target.x*matrix[0]+target.y*matrix[4]+target.z*matrix[8]);
+       matrix[13]=-(target.x*matrix[1]+target.y*matrix[5]+target.z*matrix[9]);
+       matrix[14]=-(target.x*matrix[2]+target.y*matrix[6]+target.z*matrix[10]);
+       matrix[3]=0;
+       matrix[7]=0;
+       matrix[11]=0;
+       matrix[15]=1;
+
+       {
+               matrix_mode(PROJECTION);
+               push_matrix();
+               load_identity();
+               ortho(-radius, radius, -radius, radius, -radius, radius);
+               matrix_mode(MODELVIEW);
+               push_matrix();
+               load_matrix(matrix);
+
+               Bind _bind_fbo(fbo);
+               glViewport(0, 0, size, size);
+               glClear(GL_DEPTH_BUFFER_BIT);
+               scene.render();
+
+               matrix_mode(PROJECTION);
+               pop_matrix();
+               matrix_mode(MODELVIEW);
+               pop_matrix();
+       }
+
+       depth_buf.bind_to(3);
+       float diam=radius*2;
+       float s_eq[4]={ matrix[0]/diam, matrix[4]/diam, matrix[8]/diam, matrix[12]/diam+0.5 };
+       float t_eq[4]={ matrix[1]/diam, matrix[5]/diam, matrix[9]/diam, matrix[13]/diam+0.5 };
+       float r_eq[4]={ -matrix[2]/diam, -matrix[6]/diam, -matrix[10]/diam, 0.5-matrix[14]/diam-4.0/size };
+       glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+       glTexGenfv(GL_S, GL_EYE_PLANE, s_eq);
+       enable(GL_TEXTURE_GEN_S);
+       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+       glTexGenfv(GL_T, GL_EYE_PLANE, t_eq);
+       enable(GL_TEXTURE_GEN_T);
+       glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+       glTexGenfv(GL_R, GL_EYE_PLANE, r_eq);
+       enable(GL_TEXTURE_GEN_R);
+
+       TexUnit::activate(0);
+}
+
+void ShadowMap::cleanup()
+{
+       TexUnit::activate(3);
+       Texture::unbind();
+       disable(GL_TEXTURE_GEN_S);
+       disable(GL_TEXTURE_GEN_T);
+       disable(GL_TEXTURE_GEN_R);
+       TexUnit::activate(0);
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/shadowmap.h b/source/shadowmap.h
new file mode 100644 (file)
index 0000000..17e17ca
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef SHADOWMAP_H_
+#define SHADOWMAP_H_
+
+#include "effect.h"
+#include "framebuffer.h"
+#include "texture2d.h"
+#include "vector.h"
+
+namespace Msp {
+namespace GL {
+
+class Light;
+class Scene;
+
+class ShadowMap: public Effect
+{
+private:
+       unsigned size;
+       const Scene &scene;
+       const Light &light;
+       Framebuffer fbo;
+public:
+       Texture2D depth_buf;
+private:
+       Vector3 target;
+       float radius;
+
+public:
+       ShadowMap(unsigned, const Scene &, const Light &);
+       void set_target(const Vector3 &, float);
+       virtual void prepare();
+       virtual void cleanup();
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/vector.h b/source/vector.h
new file mode 100644 (file)
index 0000000..d1693af
--- /dev/null
@@ -0,0 +1,35 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_VECTOR_H_
+#define MSP_GL_VECTOR_H_
+
+namespace Msp {
+namespace GL {
+
+struct Vector3
+{
+       float x, y, z;
+
+       Vector3(): x(0), y(0), z(0) { }
+       Vector3(float x_, float y_, float z_): x(x_), y(y_), z(z_) { }
+};
+
+struct Vector4
+{
+       float x, y, z, w;
+
+       Vector4(): x(0), y(0), z(0), w(1) { }
+       Vector4(float x_, float y_, float z_): x(x_), y(y_), z(z_), w(1) { }
+       Vector4(float x_, float y_, float z_, float w_): x(x_), y(y_), z(z_), w(w_) { }
+       Vector4(const Vector3 &v): x(v.x), y(v.y), z(v.z), w(1) { }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif