--- /dev/null
+#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
--- /dev/null
+#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
ibuf = 0;
dirty = 0;
disallow_rendering = false;
- winding = 0;
+ face_winding = NON_MANIFOLD;
if(rm)
set_manager(rm);
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
resize_buffers();
renderer.set_vertex_setup(vs ? vs : &vtx_setup);
- renderer.set_winding_test(winding);
+ renderer.set_front_face(face_winding);
if(!count)
{
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)
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),
#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 {
void vertices();
void vertices_with_format(const std::vector<VertexAttribute> &);
void batch(PrimitiveType);
- void winding(FaceWinding);
};
private:
VertexSetup vtx_setup;
mutable unsigned short dirty;
bool disallow_rendering;
- const WindingTest *winding;
+ FaceWinding face_winding;
std::string debug_name;
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;
#include "texture.h"
#include "uniformblock.h"
#include "vertexsetup.h"
-#include "windingtest.h"
using namespace std;
PipelineState::PipelineState():
shprog(0),
vertex_setup(0),
- winding_test(0),
+ front_face(COUNTERCLOCKWISE),
+ face_cull(NO_CULL),
enabled_clip_planes(0),
changes(0)
{
}
}
-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;
}
}
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);
#include <vector>
#include <msp/core/noncopyable.h>
+#include "cullface.h"
namespace Msp {
namespace GL {
{
SHPROG = 1,
VERTEX_SETUP = 2,
- WINDING_TEST = 4,
+ FACE_CULL = 4,
CLIP_PLANES = 8,
TEXTURES = 16,
UNIFORMS = 32
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;
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 *);
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:
+++ /dev/null
-#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
+++ /dev/null
-#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
shprog_from_material(false),
shdata(0),
material(0),
- back_faces(false),
+ face_cull(CULL_BACK),
receive_shadows(false),
image_based_lighting(false)
{ }
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)
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)
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);
#include <msp/core/refptr.h>
#include <msp/datafile/objectloader.h>
+#include "cullface.h"
#include "material.h"
namespace Msp {
const Material *material;
std::string material_slot;
std::vector<TextureSlot> textures;
- bool back_faces;
+ CullMode face_cull;
bool receive_shadows;
bool image_based_lighting;
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);
#include "texture.h"
#include "vertexarray.h"
#include "vertexsetup.h"
-#include "windingtest.h"
using namespace std;
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)
}
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())
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)
{ }
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();
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; }