Extend mechanism of visitor for all important classes that has

attributes of a scene (for saving in XML, or other visitors)
This commit is contained in:
brunoherbelin
2020-04-01 14:41:42 +02:00
parent 178bf45f08
commit 37a6754de2
13 changed files with 176 additions and 101 deletions

View File

@@ -1,4 +1,5 @@
#include "defines.h"
#include "Visitor.h"
#include "ImageShader.h"
ShadingProgram imageShadingProgram("shaders/texture-shader.vs", "shaders/texture-shader.fs");
@@ -25,3 +26,8 @@ void ImageShader::reset()
brightness = 0.f;
contrast = 0.f;
}
void ImageShader::accept(Visitor& v) {
Shader::accept(v);
v.visit(*this);
}

View File

@@ -12,6 +12,7 @@ public:
virtual void use();
virtual void reset();
virtual void accept(Visitor& v);
float brightness;
float contrast;

View File

@@ -6,6 +6,7 @@
#include "Log.h"
#include "RenderingManager.h"
#include "Resource.h"
#include "Visitor.h"
#include "UserInterfaceManager.h"
#include "GstToolkit.h"
@@ -77,6 +78,10 @@ MediaPlayer::~MediaPlayer()
// g_free(v_frame);
}
void MediaPlayer::accept(Visitor& v) {
v.visit(*this);
}
void MediaPlayer::Bind()
{
glBindTexture(GL_TEXTURE_2D, Texture());

View File

@@ -12,6 +12,9 @@
#include <gst/gl/gl.h>
#include <gst/pbutils/pbutils.h>
// Forward declare classes referenced
class Visitor;
#define MAX_PLAY_SPEED 20.0
#define MIN_PLAY_SPEED 0.1
@@ -200,7 +203,10 @@ public:
guint Height() const;
float AspectRatio() const;
/**
* Accept visitors
* */
void accept(Visitor& v);
private:

View File

@@ -2,6 +2,7 @@
#include "ImageShader.h"
#include "Resource.h"
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
#include <glad/glad.h>
@@ -58,6 +59,11 @@ void TexturedRectangle::draw(glm::mat4 modelview, glm::mat4 projection)
glBindTexture(GL_TEXTURE_2D, 0);
}
void TexturedRectangle::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
MediaRectangle::MediaRectangle(const std::string& mediapath)
@@ -118,6 +124,11 @@ void MediaRectangle::update( float dt )
Primitive::update( dt );
}
void MediaRectangle::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color)
{
@@ -132,4 +143,8 @@ LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color)
drawingPrimitive_ = GL_LINE_STRIP;
}
void LineStrip::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}

View File

@@ -15,7 +15,7 @@ public:
TexturedRectangle(const std::string& resourcepath);
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override { v.visit(*this); }
void accept(Visitor& v) override;
std::string getResourcePath() { return texturepath_; }
};
@@ -36,7 +36,7 @@ public:
void update ( float dt ) override;
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override { v.visit(*this); }
void accept(Visitor& v) override;
std::string getMediaPath() { return mediapath_; }
MediaPlayer *getMediaPlayer() { return mediaplayer_; }
@@ -49,7 +49,7 @@ class LineStrip : public Primitive {
public:
LineStrip(std::vector<glm::vec3> points, glm::vec3 color);
void accept(Visitor& v) override { v.visit(*this); }
void accept(Visitor& v) override;
std::vector<glm::vec3> getPoints() { return points_; }
glm::vec3 getColor() { return colors_[0]; }

View File

@@ -1,6 +1,8 @@
#include "Scene.h"
#include "Shader.h"
#include "Primitives.h"
#include "Visitor.h"
#include "Log.h"
#include <glad/glad.h>
@@ -32,6 +34,11 @@ void Node::update( float dt )
}
}
void Node::accept(Visitor& v) {
v.visit(*this);
}
// Primitive
Primitive::~Primitive()
@@ -110,6 +117,13 @@ void Primitive::draw(glm::mat4 modelview, glm::mat4 projection)
}
}
void Primitive::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
void Primitive::deleteGLBuffers_()
{
if ( arrayBuffer_ ) glDeleteBuffers ( 1, &arrayBuffer_);
@@ -124,6 +138,12 @@ Group::~Group()
children_.clear();
}
void Group::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
void Group::init()
{
visible_ = true;
@@ -159,7 +179,7 @@ void Group::draw(glm::mat4 modelview, glm::mat4 projection)
void Group::addChild(Node *child)
{
children_.push_back ( child );
children_.push_back( child );
child->parent_ = this;
}
@@ -176,3 +196,7 @@ int Group::numChildren()
return children_.size();
}
void Scene::accept(Visitor& v) {
v.visit(*this);
}

11
Scene.h
View File

@@ -2,13 +2,12 @@
#define SCENE_H
#include <vector>
#include <glm/glm.hpp>
#include "Visitor.h"
// Forward declare classes referenced
class Shader;
class Visitor;
// Base virtual class for all Node types
// Manages modelview transformations and culling
@@ -20,7 +19,7 @@ public:
virtual void init() = 0;
virtual void draw( glm::mat4 modelview, glm::mat4 projection) = 0;
virtual void accept(Visitor& v) = 0;
virtual void accept(Visitor& v);
virtual void update( float dt );
virtual glm::mat4 getWorldToLocalMatrix() {return worldToLocal_;}
@@ -43,7 +42,7 @@ public:
virtual void init () override;
virtual void draw ( glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override { v.visit(*this); }
virtual void accept(Visitor& v) override;
Shader *getShader() { return shader_; }
void setShader( Shader* e ) { shader_ = e; }
@@ -71,7 +70,7 @@ public:
virtual void init () override;
virtual void update ( float dt ) override;
virtual void draw ( glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override { v.visit(*this); }
virtual void accept(Visitor& v) override;
virtual void addChild ( Node *child );
virtual Node* getChild ( int i );
@@ -89,7 +88,7 @@ public:
Group *getRoot() { return &root_; }
void accept(Visitor& v) { v.visit(*this); }
void accept(Visitor& v);
Group root_;

View File

@@ -3,6 +3,7 @@
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "ImageShader.h"
#include "MediaPlayer.h"
#include "GstToolkit.h"
@@ -21,110 +22,113 @@ SessionVisitor::SessionVisitor(std::string filename) : filename_(filename)
xmlCurrent_ = nullptr;
}
void SessionVisitor::visit(Group &n)
{
XMLElement *xmlParent = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("Group");
visit( (Node&) n);
for (int node = 0; node < n.numChildren(); ++node)
{
Node *child = n.getChild(node);
Group *g = dynamic_cast<Group *>(child);
if (g != nullptr) {
g->accept(*this);
continue;
}
TexturedRectangle *tr = dynamic_cast<TexturedRectangle *>(child);
if (tr != nullptr) {
tr->accept(*this);
continue;
}
MediaRectangle *mr = dynamic_cast<MediaRectangle *>(child);
if (mr != nullptr) {
mr->accept(*this);
continue;
}
LineStrip *ls = dynamic_cast<LineStrip *>(child);
if (ls != nullptr) {
ls->accept(*this);
continue;
}
Primitive *p = dynamic_cast<Primitive *>(child);
if (p != nullptr) {
p->accept(*this);
continue;
}
}
// recursive
xmlParent->InsertEndChild(xmlCurrent_);
xmlCurrent_ = xmlParent;
}
void SessionVisitor::visit(Node &n)
{
XMLElement *newelement = xmlDoc_->NewElement("Node");
// xmlCurrent_->SetAttribute("type", "Undefined");
XMLElement *transform = XMLElementGLM(xmlDoc_, n.transform_);
xmlCurrent_->InsertEndChild(transform);
newelement->InsertEndChild(transform);
// insert into hierarchy
xmlCurrent_->InsertEndChild(newelement);
xmlCurrent_ = newelement; // parent for next visits
}
void SessionVisitor::visit(Group &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Group");
// loop over members of a group
XMLElement *group = xmlCurrent_;
for (int i = 0; i < n.numChildren(); ++i)
{
// recursive
n.getChild(i)->accept(*this);
// revert to group as current
xmlCurrent_ = group;
}
}
void SessionVisitor::visit(Primitive &n)
{
visit( (Node&) n);
// Node of a different type
xmlCurrent_->SetAttribute("type", "Primitive");
// go over members of a primitive
XMLElement *Primitive = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("Shader");
n.getShader()->accept(*this);
Primitive->InsertEndChild(xmlCurrent_);
// revert to primitive as current
xmlCurrent_ = Primitive;
}
void SessionVisitor::visit(TexturedRectangle &n)
{
// type specific
XMLElement *xmlParent = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("TexturedRectangle");
// Node of a different type
xmlCurrent_->SetAttribute("type", "TexturedRectangle");
XMLElement *image = xmlDoc_->NewElement("filename");
xmlCurrent_->InsertEndChild(image);
XMLText *filename = xmlDoc_->NewText( n.getResourcePath().c_str() );
XMLElement *image = xmlDoc_->NewElement("filename");
image->InsertEndChild(filename);
// inherited from Primitive
visit( (Primitive&) n);
// recursive
xmlParent->InsertEndChild(xmlCurrent_);
xmlCurrent_ = xmlParent;
xmlCurrent_->InsertEndChild(image);
}
void SessionVisitor::visit(MediaRectangle &n)
{
// type specific
XMLElement *xmlParent = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("MediaRectangle");
// Node of a different type
xmlCurrent_->SetAttribute("type", "MediaRectangle");
XMLElement *media = xmlDoc_->NewElement("filename");
xmlCurrent_->InsertEndChild(media);
XMLText *filename = xmlDoc_->NewText( n.getMediaPath().c_str() );
XMLElement *media = xmlDoc_->NewElement("filename");
media->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(media);
// TODO : visit MediaPlayer
n.getMediaPlayer()->accept(*this);
// inherited from Primitive
visit( (Primitive&) n);
}
void SessionVisitor::visit(MediaPlayer &n)
{
XMLElement *newelement = xmlDoc_->NewElement("MediaPlayer");
newelement->SetAttribute("play", n.isPlaying());
newelement->SetAttribute("loop", (int) n.Loop());
newelement->SetAttribute("speed", n.PlaySpeed());
xmlCurrent_->InsertEndChild(newelement);
}
void SessionVisitor::visit(Shader &n)
{
// Shader of a simple type
xmlCurrent_->SetAttribute("type", "DefaultShader");
XMLElement *color = XMLElementGLM(xmlDoc_, n.color);
color->SetAttribute("type", "RGBA");
xmlCurrent_->InsertEndChild(color);
}
void SessionVisitor::visit(ImageShader &n)
{
// Shader of a textured type
xmlCurrent_->SetAttribute("type", "ImageShader");
XMLElement *filter = xmlDoc_->NewElement("filter");
filter->SetAttribute("brightness", n.brightness);
filter->SetAttribute("contrast", n.contrast);
xmlCurrent_->InsertEndChild(filter);
// recursive
xmlParent->InsertEndChild(xmlCurrent_);
xmlCurrent_ = xmlParent;
}
void SessionVisitor::visit(LineStrip &n)
{
// type specific
XMLElement *xmlParent = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("LineStrip");
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineStrip");
XMLElement *color = XMLElementGLM(xmlDoc_, n.getColor());
color->SetAttribute("type", "RGBA");
@@ -137,13 +141,6 @@ void SessionVisitor::visit(LineStrip &n)
p->SetAttribute("point", (int) i);
xmlCurrent_->InsertEndChild(p);
}
// inherited from Primitive
visit( (Primitive&) n);
// recursive
xmlParent->InsertEndChild(xmlCurrent_);
xmlCurrent_ = xmlParent;
}
void SessionVisitor::visit(Scene &n)
@@ -158,10 +155,11 @@ void SessionVisitor::visit(Scene &n)
XMLComment *pComment = xmlDoc_->NewComment(s.c_str());
pRoot->InsertEndChild(pComment);
// save scene
// start recursive traverse from root node
xmlCurrent_ = pRoot;
n.getRoot()->accept(*this);
// save scene
XMLError eResult = xmlDoc_->SaveFile(filename_.c_str());
XMLCheckResult(eResult);
}

View File

@@ -13,14 +13,19 @@ class SessionVisitor : public Visitor {
public:
SessionVisitor(std::string filename);
// Elements of Scene
void visit(Node& n) override;
void visit(Primitive& n) override;
void visit(Group& n) override;
void visit(Primitive& n) override;
void visit(Scene& n) override;
void visit(TexturedRectangle& n) override;
void visit(MediaRectangle& n) override;
void visit(LineStrip& n) override;
void visit(Scene& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;
void visit(Shader& n) override;
void visit(ImageShader& n) override;
};
#endif // XMLVISITOR_H

View File

@@ -1,6 +1,7 @@
#include "Shader.h"
#include "Resource.h"
#include "Log.h"
#include "Visitor.h"
#include "RenderingManager.h"
#include <fstream>
@@ -159,6 +160,10 @@ Shader::Shader()
reset();
}
void Shader::accept(Visitor& v) {
v.visit(*this);
}
void Shader::use()
{
// initialization on first use

View File

@@ -5,6 +5,9 @@
#include <vector>
#include <glm/glm.hpp>
// Forward declare classes referenced
class Visitor;
class ShadingProgram
{
public:
@@ -40,6 +43,7 @@ public:
virtual void use();
virtual void reset();
virtual void accept(Visitor& v);
glm::mat4 projection;
glm::mat4 modelview;

View File

@@ -5,12 +5,15 @@
// Forward declare different kind of Node
class Node;
class Primitive;
class Group;
class Primitive;
class Scene;
class TexturedRectangle;
class MediaRectangle;
class LineStrip;
class MediaPlayer;
class Shader;
class ImageShader;
// Declares the interface for the visitors
class Visitor {
@@ -18,12 +21,16 @@ class Visitor {
public:
// Declare overloads for each kind of Node to visit
virtual void visit(Node& n) = 0;
virtual void visit(Primitive& n) = 0;
virtual void visit(Group& n) = 0;
virtual void visit(Primitive& n) = 0;
virtual void visit(Scene& n) = 0;
virtual void visit(TexturedRectangle& n) = 0;
virtual void visit(MediaRectangle& n) = 0;
virtual void visit(LineStrip& n) = 0;
virtual void visit(Scene& n) = 0;
virtual void visit(MediaPlayer& n) = 0;
virtual void visit(Shader& n) = 0;
virtual void visit(ImageShader& n) = 0;
};