Creation of Switch Node, Fixed Primitives inheritance, and added

Blending to Shader.
This commit is contained in:
brunoherbelin
2020-04-02 00:06:55 +02:00
parent 37a6754de2
commit fc256693dc
13 changed files with 229 additions and 55 deletions

View File

@@ -16,7 +16,7 @@
TexturedRectangle::TexturedRectangle(const std::string& resourcepath) TexturedRectangle::TexturedRectangle(const std::string& resourcepath) : Primitive()
{ {
texturepath_ = resourcepath; texturepath_ = resourcepath;
@@ -48,6 +48,7 @@ TexturedRectangle::TexturedRectangle(const std::string& resourcepath)
// setup shader for textured image // setup shader for textured image
shader_ = new ImageShader(); shader_ = new ImageShader();
drawingPrimitive_ = GL_TRIANGLE_STRIP;
} }
void TexturedRectangle::draw(glm::mat4 modelview, glm::mat4 projection) void TexturedRectangle::draw(glm::mat4 modelview, glm::mat4 projection)
@@ -66,7 +67,7 @@ void TexturedRectangle::accept(Visitor& v)
} }
MediaRectangle::MediaRectangle(const std::string& mediapath) MediaRectangle::MediaRectangle(const std::string& mediapath) : Primitive()
{ {
mediapath_ = mediapath; mediapath_ = mediapath;
@@ -98,6 +99,7 @@ MediaRectangle::MediaRectangle(const std::string& mediapath)
// setup shader for textured image // setup shader for textured image
shader_ = new ImageShader(); shader_ = new ImageShader();
drawingPrimitive_ = GL_TRIANGLE_STRIP;
} }
MediaRectangle::~MediaRectangle() MediaRectangle::~MediaRectangle()
@@ -130,7 +132,7 @@ void MediaRectangle::accept(Visitor& v)
v.visit(*this); v.visit(*this);
} }
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color) LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color) : Primitive()
{ {
for(size_t i = 0; i < points.size(); ++i) for(size_t i = 0; i < points.size(); ++i)
{ {
@@ -140,7 +142,15 @@ LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color)
} }
shader_ = new Shader(); shader_ = new Shader();
drawingPrimitive_ = GL_LINE_STRIP;
drawingPrimitive_ = GL_LINE_LOOP;
linewidth_ = 2;
}
void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
{
glLineWidth(linewidth_);
Primitive::draw(modelview, projection);
} }
void LineStrip::accept(Visitor& v) void LineStrip::accept(Visitor& v)

View File

@@ -46,9 +46,12 @@ public:
// Draw a line strip // Draw a line strip
class LineStrip : public Primitive { class LineStrip : public Primitive {
int linewidth_;
public: public:
LineStrip(std::vector<glm::vec3> points, glm::vec3 color); LineStrip(std::vector<glm::vec3> points, glm::vec3 color);
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override; void accept(Visitor& v) override;
std::vector<glm::vec3> getPoints() { return points_; } std::vector<glm::vec3> getPoints() { return points_; }

View File

@@ -1,4 +1,4 @@
#include "defines.h"
#include "Scene.h" #include "Scene.h"
#include "Shader.h" #include "Shader.h"
#include "Primitives.h" #include "Primitives.h"
@@ -94,7 +94,6 @@ void Primitive::init()
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
drawingPrimitive_ = GL_TRIANGLE_STRIP;
visible_ = true; visible_ = true;
} }
@@ -109,7 +108,7 @@ void Primitive::draw(glm::mat4 modelview, glm::mat4 projection)
} }
// //
// draw // draw vertex array object
// //
glBindVertexArray( vao_ ); glBindVertexArray( vao_ );
glDrawElements( drawingPrimitive_, indices_.size(), GL_UNSIGNED_INT, 0 ); glDrawElements( drawingPrimitive_, indices_.size(), GL_UNSIGNED_INT, 0 );
@@ -138,12 +137,6 @@ Group::~Group()
children_.clear(); children_.clear();
} }
void Group::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
void Group::init() void Group::init()
{ {
visible_ = true; visible_ = true;
@@ -172,10 +165,15 @@ void Group::draw(glm::mat4 modelview, glm::mat4 projection)
node != children_.end(); node++) { node != children_.end(); node++) {
(*node)->draw ( ctm, projection ); (*node)->draw ( ctm, projection );
} }
} }
} }
void Group::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
void Group::addChild(Node *child) void Group::addChild(Node *child)
{ {
@@ -183,7 +181,7 @@ void Group::addChild(Node *child)
child->parent_ = this; child->parent_ = this;
} }
Node *Group::getChild(int i) Node *Group::getChild(uint i)
{ {
if ( i >= 0 && i < children_.size() ) if ( i >= 0 && i < children_.size() )
return children_[i]; return children_[i];
@@ -191,12 +189,50 @@ Node *Group::getChild(int i)
return nullptr; return nullptr;
} }
int Group::numChildren() uint Group::numChildren() const
{ {
return children_.size(); return children_.size();
} }
void Switch::update( float dt )
{
Node::update(dt);
void Scene::accept(Visitor& v) { // update active child node
children_[active_]->update( dt );
}
void Switch::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( visible_ ) {
// append the instance transform to the ctm
glm::mat4 ctm = modelview * transform_;
// draw current child
children_[active_]->draw(ctm, projection);
}
}
void Switch::accept(Visitor& v)
{
Group::accept(v);
v.visit(*this);
}
void Switch::setActiveIndex(uint index)
{
active_ = CLAMP( index, 0, children_.size() - 1);
}
Node* Switch::activeNode()
{
if ( children_.empty() )
return nullptr;
return children_[active_];
}
void Scene::accept(Visitor& v)
{
v.visit(*this); v.visit(*this);
} }

23
Scene.h
View File

@@ -72,14 +72,31 @@ public:
virtual void draw ( glm::mat4 modelview, glm::mat4 projection) override; virtual void draw ( glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override; virtual void accept(Visitor& v) override;
virtual void addChild ( Node *child ); void addChild ( Node *child );
virtual Node* getChild ( int i ); Node* getChild ( uint i );
virtual int numChildren(); uint numChildren() const;
protected: protected:
std::vector< Node* > children_; std::vector< Node* > children_;
}; };
class Switch : public Group {
public:
Switch() : Group(), active_(0) {}
virtual void update ( float dt ) override;
virtual void draw ( glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override;
void setActiveIndex(uint index);
uint activeIndex() const { return active_; }
Node* activeNode();
protected:
uint active_;
};
// A scene contains a root node and gives a simplified API to add nodes // A scene contains a root node and gives a simplified API to add nodes
class Scene { class Scene {

View File

@@ -12,9 +12,6 @@
#include <tinyxml2.h> #include <tinyxml2.h>
using namespace tinyxml2; using namespace tinyxml2;
#ifndef XMLCheckResult
#define XMLCheckResult(a_eResult) if (a_eResult != XML_SUCCESS) { Log::Warning("XML error %i\n", a_eResult); return; }
#endif
SessionVisitor::SessionVisitor(std::string filename) : filename_(filename) SessionVisitor::SessionVisitor(std::string filename) : filename_(filename)
{ {
@@ -27,7 +24,7 @@ void SessionVisitor::visit(Node &n)
XMLElement *newelement = xmlDoc_->NewElement("Node"); XMLElement *newelement = xmlDoc_->NewElement("Node");
// xmlCurrent_->SetAttribute("type", "Undefined"); // xmlCurrent_->SetAttribute("type", "Undefined");
XMLElement *transform = XMLElementGLM(xmlDoc_, n.transform_); XMLElement *transform = XMLElementFromGLM(xmlDoc_, n.transform_);
newelement->InsertEndChild(transform); newelement->InsertEndChild(transform);
// insert into hierarchy // insert into hierarchy
@@ -46,11 +43,19 @@ void SessionVisitor::visit(Group &n)
{ {
// recursive // recursive
n.getChild(i)->accept(*this); n.getChild(i)->accept(*this);
xmlCurrent_->SetAttribute("index", i);
// revert to group as current // revert to group as current
xmlCurrent_ = group; xmlCurrent_ = group;
} }
} }
void SessionVisitor::visit(Switch &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Switch");
xmlCurrent_->SetAttribute("active", n.activeIndex());
}
void SessionVisitor::visit(Primitive &n) void SessionVisitor::visit(Primitive &n)
{ {
// Node of a different type // Node of a different type
@@ -107,10 +112,14 @@ void SessionVisitor::visit(Shader &n)
// Shader of a simple type // Shader of a simple type
xmlCurrent_->SetAttribute("type", "DefaultShader"); xmlCurrent_->SetAttribute("type", "DefaultShader");
XMLElement *color = XMLElementGLM(xmlDoc_, n.color); XMLElement *color = XMLElementFromGLM(xmlDoc_, n.color);
color->SetAttribute("type", "RGBA"); color->SetAttribute("type", "RGBA");
xmlCurrent_->InsertEndChild(color); xmlCurrent_->InsertEndChild(color);
XMLElement *blend = xmlDoc_->NewElement("blending");
blend->SetAttribute("mode", (int) n.blending);
xmlCurrent_->InsertEndChild(blend);
} }
void SessionVisitor::visit(ImageShader &n) void SessionVisitor::visit(ImageShader &n)
@@ -130,15 +139,15 @@ void SessionVisitor::visit(LineStrip &n)
// Node of a different type // Node of a different type
xmlCurrent_->SetAttribute("type", "LineStrip"); xmlCurrent_->SetAttribute("type", "LineStrip");
XMLElement *color = XMLElementGLM(xmlDoc_, n.getColor()); XMLElement *color = XMLElementFromGLM(xmlDoc_, n.getColor());
color->SetAttribute("type", "RGBA"); color->SetAttribute("type", "RGBA");
xmlCurrent_->InsertEndChild(color); xmlCurrent_->InsertEndChild(color);
std::vector<glm::vec3> points = n.getPoints(); std::vector<glm::vec3> points = n.getPoints();
for(size_t i = 0; i < points.size(); ++i) for(size_t i = 0; i < points.size(); ++i)
{ {
XMLElement *p = XMLElementGLM(xmlDoc_, points[i]); XMLElement *p = XMLElementFromGLM(xmlDoc_, points[i]);
p->SetAttribute("point", (int) i); p->SetAttribute("index", (int) i);
xmlCurrent_->InsertEndChild(p); xmlCurrent_->InsertEndChild(p);
} }
} }
@@ -148,7 +157,7 @@ void SessionVisitor::visit(Scene &n)
XMLDeclaration *pDec = xmlDoc_->NewDeclaration(); XMLDeclaration *pDec = xmlDoc_->NewDeclaration();
xmlDoc_->InsertFirstChild(pDec); xmlDoc_->InsertFirstChild(pDec);
XMLElement *pRoot = xmlDoc_->NewElement("Session"); XMLElement *pRoot = xmlDoc_->NewElement("Scene");
xmlDoc_->InsertEndChild(pRoot); xmlDoc_->InsertEndChild(pRoot);
std::string s = "Saved on " + GstToolkit::date_time_string(); std::string s = "Saved on " + GstToolkit::date_time_string();

View File

@@ -16,6 +16,7 @@ public:
// Elements of Scene // Elements of Scene
void visit(Node& n) override; void visit(Node& n) override;
void visit(Group& n) override; void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override; void visit(Primitive& n) override;
void visit(Scene& n) override; void visit(Scene& n) override;
void visit(TexturedRectangle& n) override; void visit(TexturedRectangle& n) override;

View File

@@ -1,5 +1,5 @@
#include "Settings.h" #include "Settings.h"
#include "Log.h" #include "tinyxml2Toolkit.h"
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@@ -7,10 +7,6 @@ using namespace std;
#include <tinyxml2.h> #include <tinyxml2.h>
using namespace tinyxml2; using namespace tinyxml2;
#ifndef XMLCheckResult
#define XMLCheckResult(a_eResult) if (a_eResult != XML_SUCCESS) { Log::Warning("XML error %i\n", a_eResult); return; }
#endif
Settings::Application Settings::application; Settings::Application Settings::application;
string filename = string("./") + APP_NAME + ".xml"; string filename = string("./") + APP_NAME + ".xml";

View File

@@ -22,6 +22,12 @@
ShadingProgram *ShadingProgram::currentProgram_ = nullptr; ShadingProgram *ShadingProgram::currentProgram_ = nullptr;
ShadingProgram simpleShadingProgram("shaders/simple-shader.vs", "shaders/simple-shader.fs"); ShadingProgram simpleShadingProgram("shaders/simple-shader.vs", "shaders/simple-shader.fs");
// Blending presets for matching with Shader::BlendMode
GLenum blending_equation[6] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD};
GLenum blending_source_function[6] = { GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,};
GLenum blending_destination_function[6] = {GL_ONE, GL_ONE, GL_ONE, GL_DST_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};
ShadingProgram::ShadingProgram(const std::string& vertex_file, const std::string& fragment_file) : vertex_id_(0), fragment_id_(0), id_(0) ShadingProgram::ShadingProgram(const std::string& vertex_file, const std::string& fragment_file) : vertex_id_(0), fragment_id_(0), id_(0)
{ {
@@ -154,7 +160,7 @@ void ShadingProgram::checkLinkingErr()
} }
Shader::Shader() Shader::Shader() : blending(BLEND_OPACITY)
{ {
program_ = &simpleShadingProgram; program_ = &simpleShadingProgram;
reset(); reset();
@@ -177,6 +183,15 @@ void Shader::use()
program_->setUniform("projection", projection); program_->setUniform("projection", projection);
program_->setUniform("modelview", modelview); program_->setUniform("modelview", modelview);
program_->setUniform("color", color); program_->setUniform("color", color);
// Blending Function
if ( blending != BLEND_NONE) {
glEnable(GL_BLEND);
glBlendEquation(blending_equation[blending]);
glBlendFunc(blending_source_function[blending], blending_destination_function[blending]);
}
else
glDisable(GL_BLEND);
} }

View File

@@ -49,10 +49,21 @@ public:
glm::mat4 modelview; glm::mat4 modelview;
glm::vec4 color; glm::vec4 color;
typedef enum {
BLEND_NONE = 0,
BLEND_ADD,
BLEND_SUBSTRACT,
BLEND_LAYER_ADD,
BLEND_LAYER_SUBSTRACT,
BLEND_OPACITY
} BlendMode;
BlendMode blending;
void setModelview(float x, float y, float angle, float scale, float aspect_ratio); void setModelview(float x, float y, float angle, float scale, float aspect_ratio);
protected: protected:
ShadingProgram *program_; ShadingProgram *program_;
}; };
#endif /* __SHADER_H_ */ #endif /* __SHADER_H_ */

View File

@@ -6,6 +6,7 @@
// Forward declare different kind of Node // Forward declare different kind of Node
class Node; class Node;
class Group; class Group;
class Switch;
class Primitive; class Primitive;
class Scene; class Scene;
class TexturedRectangle; class TexturedRectangle;
@@ -22,6 +23,7 @@ public:
// Declare overloads for each kind of Node to visit // Declare overloads for each kind of Node to visit
virtual void visit(Node& n) = 0; virtual void visit(Node& n) = 0;
virtual void visit(Group& n) = 0; virtual void visit(Group& n) = 0;
virtual void visit(Switch& n) = 0;
virtual void visit(Primitive& n) = 0; virtual void visit(Primitive& n) = 0;
virtual void visit(Scene& n) = 0; virtual void visit(Scene& n) = 0;
virtual void visit(TexturedRectangle& n) = 0; virtual void visit(TexturedRectangle& n) = 0;

View File

@@ -341,23 +341,37 @@ int main(int, char**)
MediaRectangle testnode2("file:///home/bhbn/Videos/fish.mp4"); MediaRectangle testnode2("file:///home/bhbn/Videos/fish.mp4");
testnode2.init(); testnode2.init();
TexturedRectangle testnode3("images/v-mix_256x256.png");
testnode3.init();
testnode3.getShader()->blending = Shader::BLEND_SUBSTRACT;
std::vector<glm::vec3> points;
points.push_back( glm::vec3( -1.f, -1.f, 0.f ) );
points.push_back( glm::vec3( -1.f, 1.f, 0.f ) );
points.push_back( glm::vec3( 1.f, 1.f, 0.f ) );
points.push_back( glm::vec3( 1.f, -1.f, 0.f ) );
glm::vec3 color( 1.f, 1.f, 0.f );
LineStrip border(points, color);
border.init();
Group g1; Group g1;
g1.init(); g1.init();
g1.transform_ = glm::translate(glm::identity<glm::mat4>(), glm::vec3(1.f, 1.f, 0.f)); g1.transform_ = glm::translate(glm::identity<glm::mat4>(), glm::vec3(1.f, 1.f, 0.f));
Group g2; Switch g2;
g2.init(); g2.init();
g2.transform_ = glm::translate(glm::identity<glm::mat4>(), glm::vec3(-1.f, -1.f, 0.f)); g2.transform_ = glm::translate(glm::identity<glm::mat4>(), glm::vec3(-1.f, -1.f, 0.f));
// build tree // build tree
g1.addChild(&testnode1); g1.addChild(&testnode1);
g1.addChild(&testnode3);
scene.root_.addChild(&g1); scene.root_.addChild(&g1);
g2.addChild(&testnode2); g2.addChild(&testnode2);
g2.addChild(&border);
g2.setActiveIndex(1);
scene.root_.addChild(&g2); scene.root_.addChild(&g2);
SessionVisitor savetoxml("/home/bhbn/test.vmx");
scene.accept(savetoxml);
/// ///
/// Main LOOP /// Main LOOP
/// ///
@@ -369,6 +383,9 @@ int main(int, char**)
testmedia.Close(); testmedia.Close();
testmedia2.Close(); testmedia2.Close();
SessionVisitor savetoxml("/home/bhbn/test.vmx");
scene.accept(savetoxml);
UserInterface::manager().Terminate(); UserInterface::manager().Terminate();
Rendering::manager().Terminate(); Rendering::manager().Terminate();

View File

@@ -1,4 +1,5 @@
#include "tinyxml2Toolkit.h" #include "tinyxml2Toolkit.h"
#include "Log.h"
#include <tinyxml2.h> #include <tinyxml2.h>
using namespace tinyxml2; using namespace tinyxml2;
@@ -8,35 +9,85 @@ using namespace tinyxml2;
#include <glm/ext/matrix_float4x4.hpp> #include <glm/ext/matrix_float4x4.hpp>
#include <glm/gtc/matrix_access.hpp> #include <glm/gtc/matrix_access.hpp>
#include <string>
XMLElement *tinyxml2::XMLElementGLM(XMLDocument *doc, glm::vec3 vector) XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::vec3 vector)
{ {
XMLElement *newelement = doc->NewElement( "vec3" ); XMLElement *newelement = doc->NewElement( "vec3" );
newelement->SetAttribute("x", vector[0]); newelement->SetAttribute("x", vector.x);
newelement->SetAttribute("y", vector[1]); newelement->SetAttribute("y", vector.y);
newelement->SetAttribute("z", vector[2]); newelement->SetAttribute("z", vector.z);
return newelement; return newelement;
} }
XMLElement *tinyxml2::XMLElementGLM(XMLDocument *doc, glm::vec4 vector) XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::vec4 vector)
{ {
XMLElement *newelement = doc->NewElement( "vec4" ); XMLElement *newelement = doc->NewElement( "vec4" );
newelement->SetAttribute("x", vector[0]); newelement->SetAttribute("x", vector.x);
newelement->SetAttribute("y", vector[1]); newelement->SetAttribute("y", vector.y);
newelement->SetAttribute("z", vector[2]); newelement->SetAttribute("z", vector.z);
newelement->SetAttribute("w", vector[3]); newelement->SetAttribute("w", vector.w);
return newelement; return newelement;
} }
XMLElement *tinyxml2::XMLElementGLM(XMLDocument *doc, glm::mat4 matrix) XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::mat4 matrix)
{ {
XMLElement *newelement = doc->NewElement( "mat4" ); XMLElement *newelement = doc->NewElement( "mat4" );
for (int r = 0 ; r < 4 ; r ++) for (int r = 0 ; r < 4 ; r ++)
{ {
glm::vec4 row = glm::row(matrix, r); glm::vec4 row = glm::row(matrix, r);
XMLElement *rowxml = XMLElementGLM(doc, row); XMLElement *rowxml = XMLElementFromGLM(doc, row);
rowxml->SetAttribute("row", r); rowxml->SetAttribute("row", r);
newelement->InsertEndChild(rowxml); newelement->InsertEndChild(rowxml);
} }
return newelement; return newelement;
} }
void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::vec3 &vector)
{
if ( std::string(elem->Name()).find("vec3") == std::string::npos )
return;
elem->QueryFloatAttribute("x", &vector.x); // If this fails, original value is left as-is
elem->QueryFloatAttribute("y", &vector.y);
elem->QueryFloatAttribute("z", &vector.z);
}
void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::vec4 &vector)
{
if ( std::string(elem->Name()).find("vec4") == std::string::npos )
return;
elem->QueryFloatAttribute("x", &vector.x); // If this fails, original value is left as-is
elem->QueryFloatAttribute("y", &vector.y);
elem->QueryFloatAttribute("z", &vector.z);
elem->QueryFloatAttribute("w", &vector.w);
}
void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix)
{
if ( std::string(elem->Name()).find("mat4") == std::string::npos )
return;
// loop over rows of vec4
XMLElement* row = elem->FirstChildElement("vec4");
for( ; row ; row = row->NextSiblingElement())
{
int r = 0;
row->QueryIntAttribute("row", &r); // which row index are we reading?
glm::vec4 vector = glm::row(matrix, r); // use matrix row as default
XMLElementToGLM(row, vector); // read vec4 values
matrix[0][r] = vector[0];
matrix[1][r] = vector[1];
matrix[2][r] = vector[2];
matrix[3][r] = vector[3];
}
}
void tinyxml2::XMLCheckResult(uint r)
{
XMLError result = (XMLError) r;
if ( result != XML_SUCCESS)
{
Log::Error("XML error %i: %s", r, tinyxml2::XMLDocument::ErrorIDToName(result));
}
}

View File

@@ -8,9 +8,15 @@ namespace tinyxml2 {
class XMLDocument; class XMLDocument;
class XMLElement; class XMLElement;
XMLElement *XMLElementGLM(XMLDocument *doc, glm::vec3 vector); XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::vec3 vector);
XMLElement *XMLElementGLM(XMLDocument *doc, glm::vec4 vector); XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::vec4 vector);
XMLElement *XMLElementGLM(XMLDocument *doc, glm::mat4 matrix); XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::mat4 matrix);
void XMLElementToGLM(XMLElement *elem, glm::vec3 &vector);
void XMLElementToGLM(XMLElement *elem, glm::vec4 &vector);
void XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix);
void XMLCheckResult(uint r);
} }