]> git.tdb.fi Git - libs/gl.git/commitdiff
Add object-oriented interfaces for the various tests and blending
authorMikko Rasa <tdb@tdb.fi>
Wed, 3 Mar 2010 12:39:59 +0000 (12:39 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 3 Mar 2010 12:39:59 +0000 (12:39 +0000)
Add DepthTest and Blend pointers to PipelinePass
Move the Bind RAII class from misc.h to bindable.h

source/bindable.h [new file with mode: 0644]
source/blend.cpp
source/blend.h
source/misc.h
source/object.h
source/pipeline.cpp
source/pipelinepass.cpp
source/pipelinepass.h
source/tests.cpp
source/tests.h

diff --git a/source/bindable.h b/source/bindable.h
new file mode 100644 (file)
index 0000000..cd012fb
--- /dev/null
@@ -0,0 +1,81 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_BINDABLE_H_
+#define MSP_GL_BINDABLE_H_
+
+namespace Msp {
+namespace GL {
+
+template<typename T>
+class Bindable
+{
+protected:
+       static const T *cur_obj;
+
+       Bindable() { }
+
+       static bool set_current(const T *obj)
+       {
+               if(obj==cur_obj)
+                       return false;
+
+               cur_obj=obj;
+               return true;
+       }
+
+public:
+       const T *current() const { return cur_obj; }
+};
+
+template<typename T>
+const T *Bindable<T>::cur_obj;
+
+
+/**
+RAII class for binding things.  Binds the thing upon construction and unbinds
+it upon destruction.  If a null pointer is given, unbinds upon construction and
+does nothing upon destruction.
+*/
+class Bind
+{
+private:
+       struct Base
+       {
+               virtual ~Base() { }
+       };
+
+       template<typename T>
+       struct Binder: Base
+       {
+               const T &obj;
+
+               Binder(const T &o): obj(o) { obj.bind(); }
+               ~Binder() { obj.unbind(); }
+       };
+
+       Base *binder;
+
+public:
+       template<typename T>
+       Bind(const T &o): binder(new Binder<T>(o)) { }
+
+       template<typename T>
+       Bind(const T *o): binder(o ? new Binder<T>(*o) : 0) { if(!o) T::unbind(); }
+
+private:
+       Bind(const Bind &);
+       Bind &operator=(const Bind &);
+
+public:
+       ~Bind() { delete binder; }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index 854b2032d4e26ea31168beaf141790d6ffdb536f..8b82772fded1e7fc6acc755c312964ac867a0b3b 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Copyright © 2008, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -12,6 +12,51 @@ Distributed under the LGPL
 namespace Msp {
 namespace GL {
 
+Blend::Blend():
+       eq(ADD),
+       src_factor(ONE),
+       dst_factor(ZERO)
+{ }
+
+Blend::Blend(BlendFactor sf, BlendFactor df):
+       eq(ADD),
+       src_factor(sf),
+       dst_factor(df)
+{ }
+
+Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df):
+       eq(e),
+       src_factor(sf),
+       dst_factor(df)
+{
+       if(eq!=ADD)
+               static RequireVersion _ver(1, 2);
+}
+
+void Blend::bind() const
+{
+       if(set_current(this))
+       {
+               glEnable(GL_BLEND);
+               // XXX Don't try to set equation if version < 1.2
+               glBlendEquation(eq);
+               glBlendFunc(src_factor, dst_factor);
+       }
+}
+
+const Blend &Blend::alpha()
+{
+       static Blend blend(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
+       return blend;
+}
+
+void Blend::unbind()
+{
+       if(set_current(0))
+               glDisable(GL_BLEND);
+}
+
+
 void blend_equation(BlendEquation eq)
 {
        static RequireVersion _ver(1, 2);
index 27e76d6469ccb7ea6ab52aee8cb00e29dcdef5a5..c4c78d7d51e516fe9e7278c0983dad6446cf6f12 100644 (file)
@@ -1,13 +1,14 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Copyright © 2008, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
 #ifndef MSP_GL_BLEND_H_
 #define MSP_GL_BLEND_H_
 
+#include "bindable.h"
 #include "gl.h"
 
 namespace Msp {
@@ -45,6 +46,27 @@ enum BlendFactor
        ONE_MINUS_CONSTANT_ALPHA = GL_ONE_MINUS_CONSTANT_ALPHA
 };
 
+/**
+Blends incoming fragments with those already in the framebuffer.
+*/
+class Blend: public Bindable<Blend>
+{
+private:
+       BlendEquation eq;
+       BlendFactor src_factor;
+       BlendFactor dst_factor;
+
+public:
+       Blend();
+       Blend(BlendFactor, BlendFactor);
+       Blend(BlendEquation, BlendFactor, BlendFactor);
+
+       void bind() const;
+
+       static const Blend &alpha();
+       static void unbind();
+};
+
 void blend_equation(BlendEquation eq);
 void blend_func(BlendFactor src, BlendFactor dst);
 
index 11cb3a60fdc24f9d94e713f89f17cdd9bd351ca6..b8540bd61e7ec1fef504ec9c6c94dbdb6b2c164b 100644 (file)
@@ -23,31 +23,6 @@ void get(GLenum, int &);
 void get(GLenum, int *);
 int get_i(GLenum);
 
-class Bind
-{
-private:
-       struct Base
-       {
-               virtual ~Base() { }
-       };
-
-       template<typename T>
-       struct Binder: Base
-       {
-               const T &obj;
-
-               Binder(const T &o): obj(o) { obj.bind(); }
-               ~Binder() { obj.unbind(); }
-       };
-
-       Base *binder;
-
-public:
-       template<typename T>
-       Bind(const T &o): binder(new Binder<T>(o)) { }
-       ~Bind() { delete binder; }
-};
-
 } // namespace GL
 } // namespace Msp
 
index ad856323d732e6356d6708c123f688c1061b66c8..0b53d63c6cb6871a58735668fcfca29418caa87f 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -9,7 +9,7 @@ Distributed under the LGPL
 #define MSP_GL_OBJECT_H_
 
 #include <vector>
-#include "misc.h"
+#include "bindable.h"
 #include "renderable.h"
 #include "renderpass.h"
 
index 0256850844fef66ebd3d32fb117d73d6be7d6dd0..97c452658153acb8c7561652ee22dcc0fc928961 100644 (file)
@@ -1,10 +1,11 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include "blend.h"
 #include "camera.h"
 #include "effect.h"
 #include "except.h"
@@ -13,6 +14,7 @@ Distributed under the LGPL
 #include "pipeline.h"
 #include "postprocessor.h"
 #include "renderbuffer.h"
+#include "tests.h"
 #include "texture2d.h"
 
 using namespace std;
@@ -100,16 +102,19 @@ void Pipeline::add_postprocessor(PostProcessor &pp)
 void Pipeline::render(const Tag &tag) const
 {
        const PipelinePass &pass=get_pass(tag);
-       if(pass.lighting)
-               pass.lighting->bind();
+
+       Bind bind_depth_test(pass.depth_test);
+       Bind bind_blend(pass.blend);
+       Bind bind_lighting(pass.lighting);
+
        for(vector<Effect *>::const_iterator i=pass.effects.begin(); i!=pass.effects.end(); ++i)
                (*i)->prepare();
+
        for(vector<const Renderable *>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
                (*i)->render(tag);
-       for(vector<Effect *>::const_iterator i=pass.effects.end(); i--!=pass.effects.begin();)
-               (*i)->cleanup();
-       if(pass.lighting)
-               Lighting::unbind();
+
+       for(vector<Effect *>::const_iterator i=pass.effects.end(); i!=pass.effects.begin();)
+               (*--i)->cleanup();
 }
 
 void Pipeline::render_all() const
@@ -125,10 +130,12 @@ void Pipeline::render_all() const
 
        for(vector<Effect *>::const_iterator i=effects.begin(); i!=effects.end(); ++i)
                (*i)->prepare();
+
        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();)
-               (*i)->cleanup();
+
+       for(vector<Effect *>::const_iterator i=effects.end(); i!=effects.begin();)
+               (*--i)->cleanup();
 
        if(fbo)
                Framebuffer::unbind();
index e49db7e2b50f99bc5ac326f322c1ffd4024d2d04..f566f7ac4fecb40f0ce217097cb40ebc2476a980 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -11,7 +11,9 @@ namespace Msp {
 namespace GL {
 
 PipelinePass::PipelinePass():
-       lighting(0)
+       lighting(0),
+       depth_test(0),
+       blend(0)
 { }
 
 } // namespace GL
index 0189c928e187ed0e0f1cd5dc01d0956b94f670e7..7e824082d2bdaae412fdbac6b0ab09dc646c1f08 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2009  Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -13,6 +13,8 @@ Distributed under the LGPL
 namespace Msp {
 namespace GL {
 
+class Blend;
+class DepthTest;
 class Effect;
 class Lighting;
 
@@ -20,6 +22,8 @@ struct PipelinePass
 {
        std::vector<Effect *> effects;
        const Lighting *lighting;
+       const DepthTest *depth_test;
+       const Blend *blend;
 
        PipelinePass();
 };
index 5b34bf69d9d37fc732c4f45c5ea1c55a41394be1..a741b268a998dd31aa425f7df2f647a3095ab2b2 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -10,9 +10,29 @@ Distributed under the LGPL
 namespace Msp {
 namespace GL {
 
-void scissor(int left, int bottom, unsigned width, unsigned height)
+AlphaTest::AlphaTest():
+       pred(ALWAYS),
+       ref(0)
+{ }
+
+AlphaTest::AlphaTest(Predicate p, float r):
+       pred(p),
+       ref(r)
+{ }
+
+void AlphaTest::bind() const
 {
-       glScissor(left, bottom, width, height);
+       if(set_current(this))
+       {
+               glEnable(GL_ALPHA_TEST);
+               glAlphaFunc(pred, ref);
+       }
+}
+
+void AlphaTest::unbind()
+{
+       if(set_current(0))
+               glDisable(GL_ALPHA_TEST);
 }
 
 void alpha_func(Predicate func, float ref)
@@ -20,10 +40,78 @@ void alpha_func(Predicate func, float ref)
        glAlphaFunc(func, ref);
 }
 
+
+DepthTest::DepthTest():
+       write(true),
+       pred(LESS)
+{ }
+
+DepthTest::DepthTest(Predicate p, bool w):
+       write(w),
+       pred(p)
+{ }
+
+void DepthTest::bind() const
+{
+       if(set_current(this))
+       {
+               glEnable(GL_DEPTH_TEST);
+               glDepthFunc(pred);
+               glDepthMask(write);
+       }
+}
+
+const DepthTest &DepthTest::lequal()
+{
+       static DepthTest test(LEQUAL);
+       return test;
+}
+
+void DepthTest::unbind()
+{
+       if(set_current(0))
+               glDisable(GL_DEPTH_TEST);
+}
+
 void depth_func(Predicate func)
 {
        glDepthFunc(func);
 }
 
+
+ScissorTest::ScissorTest():
+       left(0),
+       bottom(0),
+       width(1),
+       height(1)
+{ }
+
+ScissorTest::ScissorTest(int l, int b, unsigned w, unsigned h):
+       left(l),
+       bottom(b),
+       width(w),
+       height(h)
+{ }
+
+void ScissorTest::bind() const
+{
+       if(set_current(this))
+       {
+               glEnable(GL_SCISSOR_TEST);
+               glScissor(left, bottom, width, height);
+       }
+}
+
+void ScissorTest::unbind()
+{
+       if(set_current(0))
+               glDisable(GL_SCISSOR_TEST);
+}
+
+void scissor(int left, int bottom, unsigned width, unsigned height)
+{
+       glScissor(left, bottom, width, height);
+}
+
 } // namespace GL
 } // namespace Msp
index b906c0cec2afada2ba5ebb36adcf7ef53ede89a8..622834dcf888db6abb982abf1721a3291d8cc439 100644 (file)
@@ -1,13 +1,14 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
 #ifndef MSP_GL_TESTS_H_
 #define MSP_GL_TESTS_H_
 
+#include "bindable.h"
 #include "gl.h"
 #include "predicate.h"
 
@@ -21,12 +22,76 @@ enum
        DEPTH_TEST   = GL_DEPTH_TEST
 };
 
-void scissor(int left, int bottom, unsigned width, unsigned height);
+/**
+Tests incoming fragment alpha values against a reference.  If the test fails,
+the fragment is discarded.
+*/
+class AlphaTest: public Bindable<AlphaTest>
+{
+private:
+       Predicate pred;
+       float ref;
+
+public:
+       AlphaTest();
+       AlphaTest(Predicate, float);
+
+       void bind() const;
+
+       static void unbind();
+};
 
 void alpha_func(Predicate func, float ref);
 
+
+/**
+Tests incoming fragment depth values against the depth buffer.  If the test
+fails, the fragment is discarded.
+*/
+class DepthTest: public Bindable<DepthTest>
+{
+private:
+       bool write;
+       Predicate pred;
+
+       static const DepthTest *current; 
+
+public:
+       DepthTest();
+       DepthTest(Predicate, bool = true);
+
+       void bind() const;
+
+       static const DepthTest &lequal();
+       static void unbind();
+};
+
 void depth_func(Predicate func);
 
+
+/**
+Tests fragment coordinates against a rectangle.  Any fragments outside the
+rectangle are discarded.
+*/
+class ScissorTest: public Bindable<ScissorTest>
+{
+private:
+       int left;
+       int bottom;
+       unsigned width;
+       unsigned height;
+
+public:
+       ScissorTest();
+       ScissorTest(int, int, unsigned, unsigned);
+
+       void bind() const;
+
+       static void unbind();
+};
+
+void scissor(int left, int bottom, unsigned width, unsigned height);
+
 } // namespace GL
 } // namespace Msp