]> git.tdb.fi Git - libs/gl.git/commitdiff
Refactor winding-based culling
authorMikko Rasa <tdb@tdb.fi>
Tue, 17 Aug 2021 21:39:41 +0000 (00:39 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 17 Aug 2021 21:40:07 +0000 (00:40 +0300)
12 files changed:
source/core/cullface.cpp [new file with mode: 0644]
source/core/cullface.h [new file with mode: 0644]
source/core/mesh.cpp
source/core/mesh.h
source/core/pipelinestate.cpp
source/core/pipelinestate.h
source/core/windingtest.cpp [deleted file]
source/core/windingtest.h [deleted file]
source/materials/renderpass.cpp
source/materials/renderpass.h
source/render/renderer.cpp
source/render/renderer.h

diff --git a/source/core/cullface.cpp b/source/core/cullface.cpp
new file mode 100644 (file)
index 0000000..b183950
--- /dev/null
@@ -0,0 +1,32 @@
+#include <msp/strings/format.h>
+#include "cullface.h"
+
+namespace Msp {
+namespace GL {
+
+void operator>>(const LexicalConverter &conv, FaceWinding &winding)
+{
+       if(conv.get()=="NON_MANIFOLD")
+               winding = NON_MANIFOLD;
+       else if(conv.get()=="CLOCKWISE")
+               winding = CLOCKWISE;
+       else if(conv.get()=="COUNTERCLOCKWISE")
+               winding = COUNTERCLOCKWISE;
+       else
+               throw lexical_error(format("conversion of '%s' to FaceWinding", conv.get()));
+}
+
+void operator>>(const LexicalConverter &conv, CullMode &cull)
+{
+       if(conv.get()=="NO_CULL")
+               cull = NO_CULL;
+       else if(conv.get()=="CULL_FRONT")
+               cull = CULL_FRONT;
+       else if(conv.get()=="CULL_BACK")
+               cull = CULL_BACK;
+       else
+               throw lexical_error(format("conversion of '%s' to CullMode", conv.get()));
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/core/cullface.h b/source/core/cullface.h
new file mode 100644 (file)
index 0000000..fd90ef2
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MSP_GL_CULLFACE_H_
+#define MSP_GL_CULLFACE_H_
+
+#include <msp/strings/lexicalcast.h>
+
+namespace Msp {
+namespace GL {
+
+enum FaceWinding
+{
+       NON_MANIFOLD,
+       CLOCKWISE,
+       COUNTERCLOCKWISE
+};
+
+enum CullMode
+{
+       NO_CULL,
+       CULL_FRONT,
+       CULL_BACK
+};
+
+void operator>>(const LexicalConverter &, FaceWinding &);
+void operator>>(const LexicalConverter &, CullMode &);
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index 492f416d1adeccb28e2abf3febfbe874a679abeb..4414a90e6577910e7881dee65877134e7cd1ba69 100644 (file)
@@ -31,7 +31,7 @@ void Mesh::init(ResourceManager *rm)
        ibuf = 0;
        dirty = 0;
        disallow_rendering = false;
-       winding = 0;
+       face_winding = NON_MANIFOLD;
 
        if(rm)
                set_manager(rm);
@@ -149,9 +149,9 @@ void Mesh::add_batch(const Batch &b)
        check_buffers(INDEX_BUFFER);
 }
 
-void Mesh::set_winding(const WindingTest *w)
+void Mesh::set_winding(FaceWinding w)
 {
-       winding = w;
+       face_winding = w;
 }
 
 void Mesh::draw(Renderer &renderer) const
@@ -183,7 +183,7 @@ void Mesh::draw(Renderer &renderer, const VertexSetup *vs, unsigned count) const
                resize_buffers();
 
        renderer.set_vertex_setup(vs ? vs : &vtx_setup);
-       renderer.set_winding_test(winding);
+       renderer.set_front_face(face_winding);
 
        if(!count)
        {
@@ -256,7 +256,7 @@ Mesh::Loader::Loader(Mesh &m, bool g):
        add("storage",  &Loader::storage);
        add("vertices", &Loader::vertices);
        add("vertices", &Loader::vertices_with_format);
-       add("winding",  &Loader::winding);
+       add("winding",  &Mesh::face_winding);
 }
 
 void Mesh::Loader::storage(const vector<VertexAttribute> &a)
@@ -290,14 +290,6 @@ void Mesh::Loader::batch(PrimitiveType p)
        obj.add_batch(btc);
 }
 
-void Mesh::Loader::winding(FaceWinding w)
-{
-       if(w==CLOCKWISE)
-               obj.winding = &WindingTest::clockwise();
-       else if(w==COUNTERCLOCKWISE)
-               obj.winding = &WindingTest::counterclockwise();
-}
-
 
 Mesh::AsyncLoader::AsyncLoader(Mesh &m, IO::Seekable &i):
        mesh(m),
index 66516267554447968a10912bbc47cdcda9b816de..57ffce4722e30efce84ff588741d9b845f7d108b 100644 (file)
@@ -3,10 +3,10 @@
 
 #include <msp/datafile/objectloader.h>
 #include "batch.h"
+#include "cullface.h"
 #include "resource.h"
 #include "vertexarray.h"
 #include "vertexsetup.h"
-#include "windingtest.h"
 
 namespace Msp {
 namespace GL {
@@ -36,7 +36,6 @@ public:
                void vertices();
                void vertices_with_format(const std::vector<VertexAttribute> &);
                void batch(PrimitiveType);
-               void winding(FaceWinding);
        };
 
 private:
@@ -70,7 +69,7 @@ private:
        VertexSetup vtx_setup;
        mutable unsigned short dirty;
        bool disallow_rendering;
-       const WindingTest *winding;
+       FaceWinding face_winding;
        std::string debug_name;
 
 public:
@@ -97,7 +96,7 @@ public:
        void add_batch(const Batch &b);
        const std::vector<Batch> &get_batches() const { return batches; }
 
-       void set_winding(const WindingTest *);
+       void set_winding(FaceWinding);
 
        void draw(Renderer &) const;
        void draw_instanced(Renderer &, const VertexSetup &, unsigned) const;
index a3b9e640fafee04308a9ed397c84ca3e933bbaed..cfeed9ab26fcd29a1734e225e82a3a33a02a04dc 100644 (file)
@@ -12,7 +12,6 @@
 #include "texture.h"
 #include "uniformblock.h"
 #include "vertexsetup.h"
-#include "windingtest.h"
 
 using namespace std;
 
@@ -25,7 +24,8 @@ vector<int> PipelineState::bound_tex_targets;
 PipelineState::PipelineState():
        shprog(0),
        vertex_setup(0),
-       winding_test(0),
+       front_face(COUNTERCLOCKWISE),
+       face_cull(NO_CULL),
        enabled_clip_planes(0),
        changes(0)
 {
@@ -57,12 +57,21 @@ void PipelineState::set_vertex_setup(const VertexSetup *s)
        }
 }
 
-void PipelineState::set_winding_test(const WindingTest *w)
+void PipelineState::set_front_face(FaceWinding w)
 {
-       if(w!=winding_test)
+       if(w!=front_face)
        {
-               winding_test = w;
-               changes |= WINDING_TEST;
+               front_face = w;
+               changes |= FACE_CULL;
+       }
+}
+
+void PipelineState::set_face_cull(CullMode c)
+{
+       if(c!=face_cull)
+       {
+               face_cull = c;
+               changes |= FACE_CULL;
        }
 }
 
@@ -132,12 +141,14 @@ void PipelineState::apply(unsigned mask) const
                        vertex_setup->refresh();
        }
 
-       if(mask&WINDING_TEST)
+       if(mask&FACE_CULL)
        {
-               if(winding_test)
+               glFrontFace(front_face==CLOCKWISE ? GL_CW : GL_CCW);
+
+               if(face_cull!=NO_CULL)
                {
                        glEnable(GL_CULL_FACE);
-                       glFrontFace(winding_test->get_winding());
+                       glCullFace(face_cull==CULL_FRONT ? GL_FRONT : GL_BACK);
                }
                else
                        glDisable(GL_CULL_FACE);
index 8d1d1aaa974c85f89637bf3bd5df8ccfc9511615..55d96485acbbbac28215369886476857ded52395 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <vector>
 #include <msp/core/noncopyable.h>
+#include "cullface.h"
 
 namespace Msp {
 namespace GL {
@@ -42,7 +43,7 @@ private:
        {
                SHPROG = 1,
                VERTEX_SETUP = 2,
-               WINDING_TEST = 4,
+               FACE_CULL = 4,
                CLIP_PLANES = 8,
                TEXTURES = 16,
                UNIFORMS = 32
@@ -50,7 +51,8 @@ private:
 
        const Program *shprog;
        const VertexSetup *vertex_setup;
-       const WindingTest *winding_test;
+       FaceWinding front_face;
+       CullMode face_cull;
        unsigned enabled_clip_planes;
        std::vector<BoundTexture> textures;
        std::vector<BoundUniformBlock> uniform_blocks;
@@ -65,7 +67,8 @@ public:
 
        void set_shader_program(const Program *);
        void set_vertex_setup(const VertexSetup *);
-       void set_winding_test(const WindingTest *);
+       void set_front_face(FaceWinding);
+       void set_face_cull(CullMode);
        void set_enabled_clip_planes(unsigned);
        void set_texture(unsigned, const Texture *, const Sampler *);
        void set_uniforms(const DefaultUniformBlock *);
@@ -76,7 +79,8 @@ public:
 
        const Program *get_shader_program() const { return shprog; }
        const VertexSetup *get_vertex_setup() const { return vertex_setup; }
-       const WindingTest *get_winding_test() const { return winding_test; }
+       FaceWinding get_front_face() const { return front_face; }
+       CullMode get_face_cull() const { return face_cull; }
 
        void apply() const;
 private:
diff --git a/source/core/windingtest.cpp b/source/core/windingtest.cpp
deleted file mode 100644 (file)
index 0b8218a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <msp/strings/format.h>
-#include "windingtest.h"
-
-namespace Msp {
-namespace GL {
-
-void operator>>(const LexicalConverter &conv, FaceWinding &winding)
-{
-       if(conv.get()=="CLOCKWISE")
-               winding = CLOCKWISE;
-       else if(conv.get()=="COUNTERCLOCKWISE")
-               winding = COUNTERCLOCKWISE;
-       else
-               throw lexical_error(format("conversion of '%s' to FaceWinding", conv.get()));
-}
-
-WindingTest::WindingTest():
-       winding(COUNTERCLOCKWISE)
-{ }
-
-WindingTest::WindingTest(FaceWinding w):
-       winding(w)
-{ }
-
-void WindingTest::bind() const
-{
-       if(set_current(this))
-       {
-               glEnable(GL_CULL_FACE);
-               glFrontFace(winding);
-       }
-}
-
-void WindingTest::unbind()
-{
-       if(set_current(0))
-               glDisable(GL_CULL_FACE);
-}
-
-const WindingTest &WindingTest::get_reverse() const
-{
-       if(winding==CLOCKWISE)
-               return counterclockwise();
-       else
-               return clockwise();
-}
-
-const WindingTest &WindingTest::clockwise()
-{
-       static WindingTest test(CLOCKWISE);
-       return test;
-}
-
-const WindingTest &WindingTest::counterclockwise()
-{
-       static WindingTest test(COUNTERCLOCKWISE);
-       return test;
-}
-
-} // namespace GL
-} // namespace Msp
diff --git a/source/core/windingtest.h b/source/core/windingtest.h
deleted file mode 100644 (file)
index ff5b417..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef MSP_GL_WINDINGTEST_H_
-#define MSP_GL_WINDINGTEST_H_
-
-#include <msp/strings/lexicalcast.h>
-#include "bindable.h"
-#include "gl.h"
-
-namespace Msp {
-namespace GL {
-
-enum FaceWinding
-{
-       CLOCKWISE = GL_CW,
-       COUNTERCLOCKWISE = GL_CCW
-};
-
-void operator>>(const LexicalConverter &, FaceWinding &);
-
-/**
-Tests the winding of polygons.  If the order of vertices on screen does not
-match the winding, the polygon is not rendered.
-*/
-class WindingTest: public Bindable<WindingTest>
-{
-private:
-       FaceWinding winding;
-
-public:
-       WindingTest();
-       WindingTest(FaceWinding);
-
-       FaceWinding get_winding() const { return winding; }
-
-       void bind() const;
-
-       static void unbind();
-
-       const WindingTest &get_reverse() const;
-
-       static const WindingTest &clockwise();
-       static const WindingTest &counterclockwise();
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
index 70143e96a497c7e299f088855c83903c4397fedc..9a7ceef782075ee38821aa5ae9b45f1b6e13c425 100644 (file)
@@ -21,7 +21,7 @@ RenderPass::RenderPass():
        shprog_from_material(false),
        shdata(0),
        material(0),
-       back_faces(false),
+       face_cull(CULL_BACK),
        receive_shadows(false),
        image_based_lighting(false)
 { }
@@ -124,9 +124,9 @@ int RenderPass::get_texture_index(const string &n) const
        return (shprog && i!=textures.end() ? shprog->get_uniform_binding(i->tag) : -1);
 }
 
-void RenderPass::set_back_faces(bool bf)
+void RenderPass::set_face_cull(CullMode fc)
 {
-       back_faces = bf;
+       face_cull = fc;
 }
 
 void RenderPass::set_receive_shadows(bool rs)
@@ -141,7 +141,7 @@ void RenderPass::apply(Renderer &renderer) const
        renderer.set_shader_program(shprog, shdata.get());
        if(material)
                renderer.add_shader_data(material->get_shader_data());
-       renderer.set_reverse_winding(back_faces);
+       renderer.set_face_cull(face_cull);
 }
 
 void RenderPass::set_debug_name(const string &name)
@@ -171,12 +171,12 @@ RenderPass::Loader::Loader(RenderPass &p, Collection &c):
 
 void RenderPass::Loader::init_actions()
 {
+       add("face_cull", &RenderPass::face_cull);
        add("shader",   &Loader::shader);
        add("image_based_lighting", &RenderPass::image_based_lighting);
        add("material", &Loader::material_inline);
        add("material", &Loader::material);
        add("material_slot", &RenderPass::material_slot);
-       add("back_faces",&RenderPass::back_faces);
        add("receive_shadows", &RenderPass::receive_shadows);
        add("texture", &Loader::texture);
        add("uniforms", &Loader::uniforms);
index d5587c25677f140c287e5cfdba75b1d750ef4526..94cc2ed928b328f0f6dc0d16690b058cf75f0a27 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <msp/core/refptr.h>
 #include <msp/datafile/objectloader.h>
+#include "cullface.h"
 #include "material.h"
 
 namespace Msp {
@@ -83,7 +84,7 @@ private:
        const Material *material;
        std::string material_slot;
        std::vector<TextureSlot> textures;
-       bool back_faces;
+       CullMode face_cull;
        bool receive_shadows;
        bool image_based_lighting;
 
@@ -106,8 +107,8 @@ public:
        Tag get_texture_tag(const std::string &) const;
        DEPRECATED void set_texture(unsigned, const Texture *, const Sampler * = 0);
        DEPRECATED int get_texture_index(const std::string &) const;
-       void set_back_faces(bool);
-       bool get_back_faces() const { return back_faces; }
+       void set_face_cull(CullMode);
+       CullMode get_face_cull() const { return face_cull; }
        void set_receive_shadows(bool);
        bool get_receive_shadows() const { return receive_shadows; }
        void set_image_based_lighting(bool);
index 4acf3deda9dded4cabc903e5bfc42d718f0c2f3d..29db99232cd48a8a9e946b12f9326d32fb0e23a8 100644 (file)
@@ -15,7 +15,6 @@
 #include "texture.h"
 #include "vertexarray.h"
 #include "vertexsetup.h"
-#include "windingtest.h"
 
 using namespace std;
 
@@ -152,14 +151,14 @@ void Renderer::set_vertex_setup(const VertexSetup *vs)
        state->vertex_setup = vs;
 }
 
-void Renderer::set_winding_test(const WindingTest *w)
+void Renderer::set_front_face(FaceWinding winding)
 {
-       state->winding_test = w;
+       state->front_face = winding;
 }
 
-void Renderer::set_reverse_winding(bool r)
+void Renderer::set_face_cull(CullMode cull)
 {
-       state->reverse_winding = r;
+       state->face_cull = cull;
 }
 
 void Renderer::set_object_lod_bias(unsigned b)
@@ -252,7 +251,8 @@ void Renderer::apply_state()
        }
        pipeline_state.set_vertex_setup(state->vertex_setup);
 
-       pipeline_state.set_winding_test((state->winding_test && state->reverse_winding) ? &state->winding_test->get_reverse() : state->winding_test);
+       pipeline_state.set_front_face(state->front_face);
+       pipeline_state.set_face_cull(state->face_cull);
        pipeline_state.set_enabled_clip_planes(state->clipping ? (1<<state->clipping->get_n_planes())-1 : 0);
 
        if(state->texture_count<texture_stack.size())
@@ -308,8 +308,8 @@ Renderer::State::State():
        shprog(0),
        shdata_count(0),
        vertex_setup(0),
-       winding_test(0),
-       reverse_winding(false),
+       front_face(NON_MANIFOLD),
+       face_cull(NO_CULL),
        object_lod_bias(0)
 { }
 
index 5f069197453501fa097ccc261cb20b4383c84cb0..ee48b9107cddab64af53442fccb00f10bb4df1ea 100644 (file)
@@ -93,8 +93,8 @@ private:
                const Program *shprog;
                unsigned shdata_count;
                const VertexSetup *vertex_setup;
-               const WindingTest *winding_test;
-               bool reverse_winding;
+               FaceWinding front_face;
+               CullMode face_cull;
                unsigned object_lod_bias;
 
                State();
@@ -157,8 +157,8 @@ private:
 
 public:
        void set_vertex_setup(const VertexSetup *);
-       void set_winding_test(const WindingTest *);
-       void set_reverse_winding(bool);
+       void set_front_face(FaceWinding);
+       void set_face_cull(CullMode);
 
        void set_object_lod_bias(unsigned);
        unsigned get_object_lod_bias() const { return state->object_lod_bias; }