From: Mikko Rasa Date: Wed, 3 Mar 2010 12:39:59 +0000 (+0000) Subject: Add object-oriented interfaces for the various tests and blending X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=f17794d55923d4fb4f63e9d082d8d84a735a04e8 Add object-oriented interfaces for the various tests and blending Add DepthTest and Blend pointers to PipelinePass Move the Bind RAII class from misc.h to bindable.h --- diff --git a/source/bindable.h b/source/bindable.h new file mode 100644 index 00000000..cd012fbb --- /dev/null +++ b/source/bindable.h @@ -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 +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 +const T *Bindable::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 + struct Binder: Base + { + const T &obj; + + Binder(const T &o): obj(o) { obj.bind(); } + ~Binder() { obj.unbind(); } + }; + + Base *binder; + +public: + template + Bind(const T &o): binder(new Binder(o)) { } + + template + Bind(const T *o): binder(o ? new Binder(*o) : 0) { if(!o) T::unbind(); } + +private: + Bind(const Bind &); + Bind &operator=(const Bind &); + +public: + ~Bind() { delete binder; } +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/blend.cpp b/source/blend.cpp index 854b2032..8b82772f 100644 --- a/source/blend.cpp +++ b/source/blend.cpp @@ -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); diff --git a/source/blend.h b/source/blend.h index 27e76d64..c4c78d7d 100644 --- a/source/blend.h +++ b/source/blend.h @@ -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 +{ +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); diff --git a/source/misc.h b/source/misc.h index 11cb3a60..b8540bd6 100644 --- a/source/misc.h +++ b/source/misc.h @@ -23,31 +23,6 @@ void get(GLenum, int &); void get(GLenum, int *); int get_i(GLenum); -class Bind -{ -private: - struct Base - { - virtual ~Base() { } - }; - - template - struct Binder: Base - { - const T &obj; - - Binder(const T &o): obj(o) { obj.bind(); } - ~Binder() { obj.unbind(); } - }; - - Base *binder; - -public: - template - Bind(const T &o): binder(new Binder(o)) { } - ~Bind() { delete binder; } -}; - } // namespace GL } // namespace Msp diff --git a/source/object.h b/source/object.h index ad856323..0b53d63c 100644 --- a/source/object.h +++ b/source/object.h @@ -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 -#include "misc.h" +#include "bindable.h" #include "renderable.h" #include "renderpass.h" diff --git a/source/pipeline.cpp b/source/pipeline.cpp index 02568508..97c45265 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -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::const_iterator i=pass.effects.begin(); i!=pass.effects.end(); ++i) (*i)->prepare(); + for(vector::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) (*i)->render(tag); - for(vector::const_iterator i=pass.effects.end(); i--!=pass.effects.begin();) - (*i)->cleanup(); - if(pass.lighting) - Lighting::unbind(); + + for(vector::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::const_iterator i=effects.begin(); i!=effects.end(); ++i) (*i)->prepare(); + for(vector::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i) render(*i); - for(vector::const_iterator i=effects.end(); i--!=effects.begin();) - (*i)->cleanup(); + + for(vector::const_iterator i=effects.end(); i!=effects.begin();) + (*--i)->cleanup(); if(fbo) Framebuffer::unbind(); diff --git a/source/pipelinepass.cpp b/source/pipelinepass.cpp index e49db7e2..f566f7ac 100644 --- a/source/pipelinepass.cpp +++ b/source/pipelinepass.cpp @@ -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 diff --git a/source/pipelinepass.h b/source/pipelinepass.h index 0189c928..7e824082 100644 --- a/source/pipelinepass.h +++ b/source/pipelinepass.h @@ -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 effects; const Lighting *lighting; + const DepthTest *depth_test; + const Blend *blend; PipelinePass(); }; diff --git a/source/tests.cpp b/source/tests.cpp index 5b34bf69..a741b268 100644 --- a/source/tests.cpp +++ b/source/tests.cpp @@ -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 diff --git a/source/tests.h b/source/tests.h index b906c0ce..622834dc 100644 --- a/source/tests.h +++ b/source/tests.h @@ -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 +{ +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 +{ +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 +{ +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