Mesh::Mesh():
vertices(VERTEX3),
ibuf(0),
- defer_ibuf(true)
+ defer_ibuf(true),
+ winding(0)
{ }
Mesh::Mesh(const VertexFormat &f):
vertices(f),
ibuf(0),
- defer_ibuf(true)
+ defer_ibuf(true),
+ winding(0)
{ }
Mesh::~Mesh()
}
}
+void Mesh::set_winding(const WindingTest *w)
+{
+ winding = w;
+}
+
void Mesh::draw() const
{
vertices.apply();
if(ibuf)
ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
+ Bind bind_winding(winding);
for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
i->draw();
{
renderer.set_vertex_array(&vertices);
renderer.set_element_buffer(ibuf);
+ renderer.set_winding_test(winding);
for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
renderer.draw(*i);
Mesh::Loader::Loader(Mesh &m):
DataFile::ObjectLoader<Mesh>(m)
{
- add("vertices", &Loader::vertices);
add("batch", &Loader::batch);
+ add("vertices", &Loader::vertices);
+ add("winding", &Loader::winding);
}
void Mesh::Loader::vertices(VertexFormat f)
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();
+}
+
} // namespace GL
} // namespace Msp
#include <msp/datafile/objectloader.h>
#include "batch.h"
#include "vertexarray.h"
+#include "windingtest.h"
namespace Msp {
namespace GL {
private:
void vertices(VertexFormat);
void batch(PrimitiveType);
+ void winding(FaceWinding);
};
private:
std::list<Batch> batches;
Buffer *ibuf;
bool defer_ibuf;
+ const WindingTest *winding;
public:
Mesh();
void add_batch(const Batch &b);
const std::list<Batch> &get_batches() { return batches; }
+ void set_winding(const WindingTest *);
+
void draw() const;
void draw(Renderer &) const;
};
#include "texture.h"
#include "texturing.h"
#include "vertexarray.h"
+#include "windingtest.h"
using namespace std;
state(&state_stack.back()),
vertex_array(0),
vertex_array_changed(false),
- element_buffer(0)
+ element_buffer(0),
+ winding_test(0)
{
MatrixStack::modelview().push();
if(camera)
element_buffer = b;
}
+void Renderer::set_winding_test(const WindingTest *w)
+{
+ winding_test = w;
+}
+
void Renderer::push_state()
{
state_stack.push_back(state_stack.back());
{
apply_state();
Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
+ WindingTest::unbind();
}
void Renderer::draw(const Batch &batch)
else
Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
+ if(winding_test)
+ winding_test->bind();
+ else
+ WindingTest::unbind();
+
batch.draw();
}
class Texture;
class Texturing;
class VertexArray;
+class WindingTest;
/**
A class for supervising the rendering process. While many Renderables (in
const VertexArray *vertex_array;
bool vertex_array_changed;
const Buffer *element_buffer;
+ const WindingTest *winding_test;
public:
Renderer(const Camera *);
void add_shader_data(const ProgramData *);
void set_vertex_array(const VertexArray *);
void set_element_buffer(const Buffer *);
+ void set_winding_test(const WindingTest *);
void push_state();
void pop_state();
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#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 InvalidParameterValue("Invalid FaceWinding");
+}
+
+WindingTest::WindingTest():
+ test(false),
+ winding(COUNTERCLOCKWISE)
+{ }
+
+WindingTest::WindingTest(FaceWinding w):
+ test(true),
+ winding(w)
+{ }
+
+void WindingTest::bind() const
+{
+ if(set_current(this))
+ {
+ if(test)
+ {
+ glEnable(GL_CULL_FACE);
+ glFrontFace(winding);
+ }
+ else
+ glDisable(GL_CULL_FACE);
+ }
+}
+
+void WindingTest::unbind()
+{
+ if(set_current(0))
+ glDisable(GL_CULL_FACE);
+}
+
+WindingTest &WindingTest::clockwise()
+{
+ static WindingTest test(CLOCKWISE);
+ return test;
+}
+
+WindingTest &WindingTest::counterclockwise()
+{
+ static WindingTest test(COUNTERCLOCKWISE);
+ return test;
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef WINDINGTEST_H_
+#define 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:
+ bool test;
+ FaceWinding winding;
+
+public:
+ WindingTest();
+ WindingTest(FaceWinding);
+
+ void bind() const;
+
+ static void unbind();
+
+ static WindingTest &clockwise();
+ static WindingTest &counterclockwise();
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif