Fixed implementation of Visitor in hierarchy of Nodes.

This commit is contained in:
brunoherbelin
2020-04-03 23:10:23 +02:00
parent 91043a0c67
commit f071a49187
12 changed files with 426 additions and 194 deletions

View File

@@ -224,6 +224,7 @@ set(VMIX_SRCS
Resource.cpp
FileDialog.cpp
MediaPlayer.cpp
FrameBuffer.cpp
RenderingManager.cpp
UserInterfaceManager.cpp
ImGuiToolkit.cpp
@@ -243,6 +244,7 @@ set(VMIX_RSC_FILES
./rsc/fonts/fa-regular-400.ttf
./rsc/fonts/fa-solid-900.ttf
./rsc/images/v-mix_256x256.png
./rsc/images/busy.png
./rsc/images/icons.dds
./rsc/images/seed_512.jpg
)

View File

@@ -1,6 +1,112 @@
#include "FrameBuffer.h"
#include "ImageShader.h"
#include "Log.h"
FrameBuffer::FrameBuffer()
#include <glad/glad.h>
FrameBuffer::FrameBuffer(uint width, uint height, bool useDepthBuffer)
{
// create a renderbuffer object to store depth info
GLuint rboId;
if (useDepthBuffer){
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
// create a framebuffer object
glGenFramebuffers(1, &framebufferid_);
bind();
// attach the texture to FBO color attachment point
glGenTextures(1, &textureid_);
glBindTexture(GL_TEXTURE_2D, textureid_);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_, height_, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, textureid_, 0);
// attach the renderbuffer to depth attachment point
if (useDepthBuffer){
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, rboId);
}
checkFramebufferStatus();
}
FrameBuffer::~FrameBuffer()
{
glDeleteFramebuffers(1, &framebufferid_);
}
float FrameBuffer::aspectRatio() const
{
return static_cast<float>(width_) / static_cast<float>(height_);
}
void FrameBuffer::bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
}
void FrameBuffer::release()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
bool FrameBuffer::blit(FrameBuffer *other)
{
if (width_ != other->width() || height_ != other->height())
return false;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
// blit to the frame buffer object
glBlitFramebuffer(0, height_, width_, 0, 0, 0,
other->width(), other->height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
return true;
}
void FrameBuffer::checkFramebufferStatus()
{
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (status){
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT is returned if any of the framebuffer attachment points are framebuffer incomplete.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT is returned if the framebuffer does not have at least one image attached to it.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER is returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for any color attachment point(s) named by GL_DRAWBUFFERi.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER is returned if GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER.");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
Log::Warning("GL_FRAMEBUFFER_UNSUPPORTED is returned if the combination of internal formats of the attached images violates an implementation-dependent set of restrictions.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.\nGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is also returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS is returned if any framebuffer attachment is layered, and any populated attachment is not layered, or if all populated color attachments are not from textures of the same target.");
break;
case GL_FRAMEBUFFER_UNDEFINED:
Log::Warning(" GL_FRAMEBUFFER_UNDEFINED is returned if target is the default framebuffer, but the default framebuffer does not exist.");
break;
case GL_FRAMEBUFFER_COMPLETE:
Log::Warning("Framebuffer complete");
break;
}
}

View File

@@ -1,11 +1,35 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "Scene.h"
class FrameBuffer {
class FrameBuffer
{
public:
FrameBuffer();
FrameBuffer(uint width, uint height, bool useDepthBuffer = false);
~FrameBuffer();
// bind the FrameBuffer as current to draw into
void bind();
// releases the framebuffer object
static void release();
// blit copy to another, returns true on success
bool blit(FrameBuffer *other);
inline uint width() const { return width_; }
inline uint height() const { return height_; }
inline uint texture() const { return textureid_; }
float aspectRatio() const;
private:
void checkFramebufferStatus();
uint width_;
uint height_;
uint textureid_;
uint framebufferid_;
};
#endif // FRAMEBUFFER_H
#endif // FRAMEBUFFER_H

View File

@@ -13,45 +13,60 @@
#include <glm/ext/matrix_float4x4.hpp>
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/constants.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_vector.hpp>
static const std::vector<glm::vec3> square_points { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, 1.f, 0.f ), glm::vec3( 1.f, -1.f, 0.f ) };
static uint square_vao = 0;
static uint circle_vao = 0;
static const std::string default_texture = "images/busy.png";
TexturedRectangle::TexturedRectangle(const std::string& resourcepath) : Primitive()
ImageSurface::ImageSurface(const std::string& path) : Primitive()
{
texturepath_ = resourcepath;
filename_ = path;
float ar = 1.0;
textureindex_ = Resource::getTextureImage(texturepath_, &ar);
textureindex_ = Resource::getTextureImage(filename_, &ar);
transform_ = glm::scale(glm::identity<glm::mat4>(), glm::vec3(ar, 1.f, 1.f));
// point 0
points_.push_back( glm::vec3( -ar, -1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 0.f, 1.f ) );
// point 1
points_.push_back( glm::vec3( -ar, 1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 0.f, 0.f ) );
// point 2
points_.push_back( glm::vec3( ar, -1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 1.f, 1.f ) );
// point 3
points_.push_back( glm::vec3( ar, 1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 1.f, 0.f ) );
// indices
indices_.push_back ( 0 );
indices_.push_back ( 1 );
indices_.push_back ( 2 );
indices_.push_back ( 3 );
// geometry
points_ = std::vector<glm::vec3> { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) };
colors_ = std::vector<glm::vec3> { glm::vec3( 1.f, 1.f, 1.f ), glm::vec3( 1.f, 1.f, 1.f ),
glm::vec3( 1.f, 1.f, 1.f ), glm::vec3( 1.f, 1.f, 1.f ) };
texCoords_ = std::vector<glm::vec2> { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ),
glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) };
indices_ = std::vector<uint> { 0, 1, 2, 3 };
// setup shader for textured image
shader_ = new ImageShader();
drawingPrimitive_ = GL_TRIANGLE_STRIP;
}
void TexturedRectangle::draw(glm::mat4 modelview, glm::mat4 projection)
void ImageSurface::init()
{
// use static global vertex array object
if (square_vao)
// if set, use the global vertex array object
vao_ = square_vao;
else {
// 1. init as usual (only once)
Primitive::init();
// 2. remember global vao
square_vao = vao_;
// 3. vao_ will not be deleted because deleteGLBuffers_() is empty
}
visible_ = true;
}
void ImageSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
glBindTexture(GL_TEXTURE_2D, textureindex_);
@@ -60,79 +75,54 @@ void TexturedRectangle::draw(glm::mat4 modelview, glm::mat4 projection)
glBindTexture(GL_TEXTURE_2D, 0);
}
void TexturedRectangle::accept(Visitor& v)
void ImageSurface::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
MediaRectangle::MediaRectangle(const std::string& mediapath) : Primitive()
MediaSurface::MediaSurface(const std::string& path) : ImageSurface(default_texture)
{
mediapath_ = mediapath;
filename_ = path;
mediaplayer_ = new MediaPlayer;
mediaplayer_->Open(mediapath_);
mediaplayer_->Play(true);
// point 0
points_.push_back( glm::vec3( -1.f, -1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 0.f, 1.f ) );
// point 1
points_.push_back( glm::vec3( -1.f, 1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 0.f, 0.f ) );
// point 2
points_.push_back( glm::vec3( 1.f, -1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 1.f, 1.f ) );
// point 3
points_.push_back( glm::vec3( 1.f, 1.f, 0.f ) );
colors_.push_back( glm::vec3( 1.f, 1.f, 1.f ) );
texCoords_.push_back( glm::vec2( 1.f, 0.f ) );
// indices
indices_.push_back ( 0 );
indices_.push_back ( 1 );
indices_.push_back ( 2 );
indices_.push_back ( 3 );
// setup shader for textured image
shader_ = new ImageShader();
drawingPrimitive_ = GL_TRIANGLE_STRIP;
mediaplayer_->open(filename_);
mediaplayer_->play(true);
}
MediaRectangle::~MediaRectangle()
MediaSurface::~MediaSurface()
{
delete mediaplayer_;
}
void MediaRectangle::draw(glm::mat4 modelview, glm::mat4 projection)
void MediaSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
mediaplayer_->Bind();
if ( mediaplayer_->isOpen() )
mediaplayer_->bind();
else
glBindTexture(GL_TEXTURE_2D, textureindex_);
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
void MediaRectangle::update( float dt )
void MediaSurface::update( float dt )
{
if ( mediaplayer_->isOpen() )
mediaplayer_->Update();
mediaplayer_->update();
transform_ = glm::scale(glm::identity<glm::mat4>(), glm::vec3(mediaplayer_->AspectRatio(), 1.f, 1.f));
transform_ = glm::scale(glm::identity<glm::mat4>(), glm::vec3(mediaplayer_->aspectRatio(), 1.f, 1.f));
Primitive::update( dt );
}
void MediaRectangle::accept(Visitor& v)
void MediaSurface::accept(Visitor& v)
{
Primitive::accept(v);
ImageSurface::accept(v);
v.visit(*this);
}
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color) : Primitive()
LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color, uint linewidth) : Primitive()
{
for(size_t i = 0; i < points.size(); ++i)
{
@@ -144,7 +134,7 @@ LineStrip::LineStrip(std::vector<glm::vec3> points, glm::vec3 color) : Primitive
shader_ = new Shader();
drawingPrimitive_ = GL_LINE_LOOP;
linewidth_ = 2;
linewidth_ = linewidth;
}
void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
@@ -158,3 +148,49 @@ void LineStrip::accept(Visitor& v)
Primitive::accept(v);
v.visit(*this);
}
LineSquare::LineSquare(glm::vec3 color, uint linewidth) : LineStrip(square_points, color, linewidth)
{
}
LineCircle::LineCircle(glm::vec3 color, uint linewidth) : LineStrip(square_points, color, linewidth)
{
points_.clear();
colors_.clear();
indices_.clear();
int N = 72;
float a = glm::two_pi<float>() / static_cast<float>(N);
glm::vec3 P(1.f, 0.f, 0.f);
for (int i = 0; i < N ; i++ ){
points_.push_back( glm::vec3(P) );
colors_.push_back( color );
indices_.push_back ( i );
P = glm::rotateZ(P, a);
}
}
void LineCircle::init()
{
// use static global vertex array object
if (circle_vao)
// if set, use the global vertex array object
vao_ = square_vao;
else {
// 1. init as usual (only once)
Primitive::init();
// 2. remember global vao
circle_vao = vao_;
// 3. vao_ will not be deleted because deleteGLBuffers_() is empty
}
visible_ = true;
}
void LineCircle::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}

View File

@@ -6,58 +6,89 @@
#include "Scene.h"
// Draw a Rectangle (triangle strip) with a texture
class TexturedRectangle : public Primitive {
class ImageSurface : public Primitive {
std::string texturepath_;
unsigned int textureindex_;
void deleteGLBuffers_() {}
public:
TexturedRectangle(const std::string& resourcepath);
ImageSurface(const std::string& path);
void init() override;
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override;
std::string getResourcePath() { return texturepath_; }
std::string getFilename() { return filename_; }
protected:
std::string filename_;
uint textureindex_;
};
// Draw a Rectangle (triangle strip) with a media as animated texture
class MediaPlayer;
class MediaRectangle : public Primitive {
class MediaSurface : public ImageSurface {
MediaPlayer *mediaplayer_;
std::string mediapath_;
unsigned int textureindex_;
public:
MediaRectangle(const std::string& mediapath);
~MediaRectangle();
MediaSurface(const std::string& path);
~MediaSurface();
void update ( float dt ) override;
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override;
void update ( float dt ) override;
std::string getMediaPath() { return mediapath_; }
MediaPlayer *getMediaPlayer() { return mediaplayer_; }
MediaPlayer *getMediaPlayer() { return mediaplayer_; }
};
//// Draw a Frame Buffer
//class FrameBufferSurface : public Primitive {
// void deleteGLBuffers_() {}
//public:
// FrameBufferSurface();
// void init () override;
// void draw(glm::mat4 modelview, glm::mat4 projection) override;
// void accept(Visitor& v) override;
//};
// Draw a line strip
class LineStrip : public Primitive {
int linewidth_;
uint linewidth_;
public:
LineStrip(std::vector<glm::vec3> points, glm::vec3 color);
LineStrip(std::vector<glm::vec3> points, glm::vec3 color, uint linewidth = 1);
void draw(glm::mat4 modelview, glm::mat4 projection) override;
void accept(Visitor& v) override;
virtual void draw(glm::mat4 modelview, glm::mat4 projection) override;
virtual void accept(Visitor& v) override;
std::vector<glm::vec3> getPoints() { return points_; }
glm::vec3 getColor() { return colors_[0]; }
uint getLineWidth() { return linewidth_; }
};
class LineSquare : public LineStrip {
public:
LineSquare(glm::vec3 color, uint linewidth = 1);
};
class LineCircle : public LineStrip {
void deleteGLBuffers_() {}
public:
LineCircle(glm::vec3 color, uint linewidth = 1);
void init() override;
void accept(Visitor& v) override;
};
#endif // PRIMITIVES_H

View File

@@ -25,12 +25,12 @@ Node::Node() : parent_(nullptr), visible_(false)
void Node::update( float dt )
{
if ( parent_ ) {
localToWorld_ = dynamic_cast<Group*>(parent_)->getLocalToWorldMatrix() * transform_;
worldToLocal_ = glm::inverse(transform_) * dynamic_cast<Group*>(parent_)->getWorldToLocalMatrix();
localToWorld_ = dynamic_cast<Group*>(parent_)->getLocalToWorldMatrix() * transform_;
worldToLocal_ = glm::inverse(transform_) * dynamic_cast<Group*>(parent_)->getWorldToLocalMatrix();
}
else {
localToWorld_ = transform_;
worldToLocal_ = glm::inverse(transform_);
localToWorld_ = transform_;
worldToLocal_ = glm::inverse(transform_);
}
}
@@ -49,6 +49,7 @@ Primitive::~Primitive()
colors_.clear();
texCoords_.clear();
indices_.clear();
}
void Primitive::init()
@@ -58,6 +59,8 @@ void Primitive::init()
// Vertex Array
glGenVertexArrays( 1, &vao_ );
// Create and initialize buffer objects
uint arrayBuffer_;
uint elementBuffer_;
glGenBuffers( 1, &arrayBuffer_ );
glGenBuffers( 1, &elementBuffer_);
glBindVertexArray( vao_ );
@@ -77,7 +80,7 @@ void Primitive::init()
// setup the element array for the triangle indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer_);
int sizeofIndices = indices_.size()*sizeof(unsigned int);
int sizeofIndices = indices_.size()*sizeof(uint);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeofIndices, &(indices_[0]), GL_STATIC_DRAW);
// explain how to read attributes 0, 1 and 2 (for point, color and textcoord respectively)
@@ -94,25 +97,30 @@ void Primitive::init()
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// delete temporary buffers
if ( arrayBuffer_ ) glDeleteBuffers ( 1, &arrayBuffer_);
if ( elementBuffer_ ) glDeleteBuffers ( 1, &elementBuffer_);
visible_ = true;
}
void Primitive::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( visible_ ) {
if (shader_) {
shader_->projection = projection;
shader_->modelview = modelview * transform_;
shader_->use();
}
//
// draw vertex array object
//
glBindVertexArray( vao_ );
glDrawElements( drawingPrimitive_, indices_.size(), GL_UNSIGNED_INT, 0 );
glBindVertexArray(0);
//
// prepare and use shader
//
if (shader_) {
shader_->projection = projection;
shader_->modelview = modelview * transform_;
shader_->use();
}
//
// draw vertex array object
//
glBindVertexArray( vao_ );
glDrawElements( drawingPrimitive_, indices_.size(), GL_UNSIGNED_INT, 0 );
glBindVertexArray(0);
}
}
@@ -125,9 +133,8 @@ void Primitive::accept(Visitor& v)
void Primitive::deleteGLBuffers_()
{
if ( arrayBuffer_ ) glDeleteBuffers ( 1, &arrayBuffer_);
if ( elementBuffer_ ) glDeleteBuffers ( 1, &elementBuffer_);
if ( vao_ ) glDeleteVertexArrays ( 1, &vao_);
if ( vao_ )
glDeleteVertexArrays ( 1, &vao_);
}
// Group

12
Scene.h
View File

@@ -37,7 +37,7 @@ public:
class Primitive : public Node {
public:
Primitive() : Node(), shader_(nullptr), vao_(0), arrayBuffer_(0), elementBuffer_(0), drawingPrimitive_(0) {}
Primitive() : Node(), shader_(nullptr), vao_(0), drawingPrimitive_(0) {}
virtual ~Primitive();
virtual void init () override;
@@ -49,15 +49,13 @@ public:
protected:
Shader* shader_;
unsigned int vao_;
unsigned int arrayBuffer_;
unsigned int elementBuffer_;
unsigned int drawingPrimitive_;
uint vao_;
uint drawingPrimitive_;
std::vector<glm::vec3> points_;
std::vector<glm::vec3> colors_;
std::vector<glm::vec2> texCoords_;
std::vector<unsigned int> indices_;
void deleteGLBuffers_();
std::vector<uint> indices_;
virtual void deleteGLBuffers_();
};
// Other Nodes establish hierarchy with a group of nodes

View File

@@ -13,16 +13,18 @@
using namespace tinyxml2;
SessionVisitor::SessionVisitor(std::string filename) : filename_(filename)
SessionVisitor::SessionVisitor()
{
xmlDoc_ = new XMLDocument;
xmlCurrent_ = nullptr;
xmlRoot_ = nullptr;
}
void SessionVisitor::visit(Node &n)
{
XMLElement *newelement = xmlDoc_->NewElement("Node");
// xmlCurrent_->SetAttribute("type", "Undefined");
newelement->SetAttribute("visible", n.visible_);
XMLElement *transform = XMLElementFromGLM(xmlDoc_, n.transform_);
newelement->InsertEndChild(transform);
@@ -47,6 +49,7 @@ void SessionVisitor::visit(Group &n)
// revert to group as current
xmlCurrent_ = group;
}
n.visible_;
}
void SessionVisitor::visit(Switch &n)
@@ -73,37 +76,31 @@ void SessionVisitor::visit(Primitive &n)
}
void SessionVisitor::visit(TexturedRectangle &n)
void SessionVisitor::visit(ImageSurface &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "TexturedRectangle");
xmlCurrent_->SetAttribute("type", "ImageSurface");
XMLText *filename = xmlDoc_->NewText( n.getResourcePath().c_str() );
XMLText *filename = xmlDoc_->NewText( n.getFilename().c_str() );
XMLElement *image = xmlDoc_->NewElement("filename");
image->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(image);
}
void SessionVisitor::visit(MediaRectangle &n)
void SessionVisitor::visit(MediaSurface &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "MediaRectangle");
XMLText *filename = xmlDoc_->NewText( n.getMediaPath().c_str() );
XMLElement *media = xmlDoc_->NewElement("filename");
media->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(media);
xmlCurrent_->SetAttribute("type", "MediaSurface");
n.getMediaPlayer()->accept(*this);
}
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());
newelement->SetAttribute("loop", (int) n.loop());
newelement->SetAttribute("speed", n.playSpeed());
xmlCurrent_->InsertEndChild(newelement);
}
@@ -152,23 +149,48 @@ void SessionVisitor::visit(LineStrip &n)
}
}
void SessionVisitor::visit(LineSquare &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineSquare");
}
void SessionVisitor::visit(LineCircle &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineCircle");
XMLElement *color = XMLElementFromGLM(xmlDoc_, n.getColor());
color->SetAttribute("type", "RGBA");
xmlCurrent_->InsertEndChild(color);
}
void SessionVisitor::visit(Scene &n)
{
std::string s = "Capture time " + GstToolkit::date_time_string();
XMLComment *pComment = xmlDoc_->NewComment(s.c_str());
xmlDoc_->InsertEndChild(pComment);
xmlRoot_ = xmlDoc_->NewElement("Scene");
xmlDoc_->InsertEndChild(xmlRoot_);
// start recursive traverse from root node
xmlCurrent_ = xmlRoot_;
n.getRoot()->accept(*this);
}
void SessionVisitor::save(std::string filename)
{
XMLDeclaration *pDec = xmlDoc_->NewDeclaration();
xmlDoc_->InsertFirstChild(pDec);
XMLElement *pRoot = xmlDoc_->NewElement("Scene");
xmlDoc_->InsertEndChild(pRoot);
std::string s = "Saved on " + GstToolkit::date_time_string();
std::string s = "Save time " + GstToolkit::date_time_string();
XMLComment *pComment = xmlDoc_->NewComment(s.c_str());
pRoot->InsertEndChild(pComment);
xmlDoc_->InsertEndChild(pComment);
// start recursive traverse from root node
xmlCurrent_ = pRoot;
n.getRoot()->accept(*this);
// save scene
XMLError eResult = xmlDoc_->SaveFile(filename_.c_str());
// save session
XMLError eResult = xmlDoc_->SaveFile(filename.c_str());
XMLCheckResult(eResult);
}

View File

@@ -6,22 +6,26 @@
class SessionVisitor : public Visitor {
std::string filename_;
tinyxml2::XMLDocument *xmlDoc_;
tinyxml2::XMLElement *xmlCurrent_;
tinyxml2::XMLElement *xmlRoot_;
public:
SessionVisitor(std::string filename);
SessionVisitor();
void save(std::string filename);
tinyxml2::XMLElement *root() {return xmlRoot_;}
// Elements of Scene
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override;
void visit(Scene& n) override;
void visit(TexturedRectangle& n) override;
void visit(MediaRectangle& n) override;
void visit(ImageSurface& n) override;
void visit(MediaSurface& n) override;
void visit(LineStrip& n) override;
void visit(LineSquare& n) override;
void visit(LineCircle& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;

View File

@@ -9,9 +9,11 @@ class Group;
class Switch;
class Primitive;
class Scene;
class TexturedRectangle;
class MediaRectangle;
class ImageSurface;
class MediaSurface;
class LineStrip;
class LineSquare;
class LineCircle;
class MediaPlayer;
class Shader;
class ImageShader;
@@ -21,14 +23,16 @@ class Visitor {
public:
// Declare overloads for each kind of Node to visit
virtual void visit(Scene& n) = 0;
virtual void visit(Node& n) = 0;
virtual void visit(Group& n) = 0;
virtual void visit(Switch& 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(ImageSurface& n) = 0;
virtual void visit(MediaSurface& n) = 0;
virtual void visit(LineStrip& n) = 0;
virtual void visit(LineSquare& n) = 0;
virtual void visit(LineCircle& n) = 0;
virtual void visit(MediaPlayer& n) = 0;
virtual void visit(Shader& n) = 0;
virtual void visit(ImageShader& n) = 0;

View File

@@ -16,8 +16,8 @@
#define EXP100(val) (exp(log(10.0)/50.0*(float)(val))-1.0)
#define EUCLIDEAN(P1, P2) sqrt((P1.x() - P2.x()) * (P1.x() - P2.x()) + (P1.y() - P2.y()) * (P1.y() - P2.y()))
#define SOURCE_UNIT 10.0
#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SOURCE_UNIT * SOURCE_UNIT * CIRCLE_SIZE * CIRCLE_SIZE) )
#define SCENE_UNIT 10.0
#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SCENE_UNIT * SCENE_UNIT * SCENE_UNIT * SCENE_UNIT) )
#define TEXTURE_REQUIRED_MAXIMUM 2048
#define CATALOG_TEXTURE_HEIGHT 96
@@ -54,6 +54,5 @@
#define COLOR_FRAME_MOVE 230, 30, 230
#define COLOR_CURSOR 10, 100, 255
#define XML_PREFERENCE_FILE "vlmixer.xml"
#endif // VMIX_DEFINES_H

View File

@@ -58,14 +58,14 @@ void drawMediaBackgound()
//
// RENDER SOURCE
//
testmedia2.Update();
testmedia2.update();
// use the shader
rendering_shader.projection = Rendering::manager().Projection();
rendering_shader.modelview = glm::identity<glm::mat4>();;
rendering_shader.use();
// use the media
testmedia2.Bind();
testmedia2.bind();
// draw the vertex array
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
@@ -126,12 +126,12 @@ void drawMediaPlayer()
if ( !testmedia.isOpen() )
return;
testmedia.Update();
testmedia.update();
if ( begin == GST_CLOCK_TIME_NONE) {
begin = testmedia.Duration() / 5;
end = testmedia.Duration() / 3;
begin = testmedia.duration() / 5;
end = testmedia.duration() / 3;
// if ( testmedia.addPlaySegment(begin, end) )
// std::cerr << " - first segment " << std::endl;
@@ -146,11 +146,11 @@ void drawMediaPlayer()
float width = ImGui::GetContentRegionAvail().x;
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
ImVec2 imagesize ( width, width / testmedia.AspectRatio());
ImGui::Image((void*)(intptr_t)testmedia.Texture(), imagesize);
ImVec2 imagesize ( width, width / testmedia.aspectRatio());
ImGui::Image((void*)(intptr_t)testmedia.texture(), imagesize);
if (ImGui::Button(ICON_FA_FAST_BACKWARD))
testmedia.Rewind();
testmedia.rewind();
ImGui::SameLine(0, spacing);
// remember playing mode of the GUI
@@ -165,7 +165,7 @@ void drawMediaPlayer()
ImGui::PushButtonRepeat(true);
if (ImGui::Button(ICON_FA_FORWARD))
testmedia.FastForward ();
testmedia.fastForward ();
ImGui::PopButtonRepeat();
}
else {
@@ -176,7 +176,7 @@ void drawMediaPlayer()
ImGui::PushButtonRepeat(true);
if (ImGui::Button(ICON_FA_STEP_FORWARD))
testmedia.SeekNextFrame();
testmedia.seekNextFrame();
ImGui::PopButtonRepeat();
}
@@ -195,23 +195,23 @@ void drawMediaPlayer()
if ( ImGui::SliderInt("", &current_loop, 0, 2, current_loop_name) )
testmedia.setLoop( (MediaPlayer::LoopMode) current_loop );
float speed = static_cast<float>(testmedia.PlaySpeed());
float speed = static_cast<float>(testmedia.playSpeed());
ImGui::SameLine(0, spacing);
ImGui::SetNextItemWidth(270);
// ImGui::SetNextItemWidth(width - 90.0);
if (ImGui::SliderFloat( "Speed", &speed, -10.f, 10.f, "x %.1f", 2.f))
testmedia.SetPlaySpeed( static_cast<double>(speed) );
testmedia.setPlaySpeed( static_cast<double>(speed) );
ImGui::SameLine(0, spacing);
if (ImGuiToolkit::ButtonIcon(19, 15)) {
speed = 1.f;
testmedia.SetPlaySpeed( static_cast<double>(speed) );
testmedia.setPlaySpeed( static_cast<double>(speed) );
}
guint64 current_t = testmedia.Position();
guint64 current_t = testmedia.position();
guint64 seek_t = current_t;
bool slider_pressed = ImGuiToolkit::TimelineSlider( "simpletimeline", &seek_t,
testmedia.Duration(), testmedia.FrameDuration());
testmedia.duration(), testmedia.frameDuration());
// std::list<std::pair<guint64, guint64> > segments = testmedia.getPlaySegments();
// bool slider_pressed = ImGuiToolkit::TimelineSliderEdit( "timeline", &seek_t, testmedia.Duration(),
@@ -231,10 +231,10 @@ void drawMediaPlayer()
// if the seek target time is different from the current position time
// (i.e. the difference is less than one frame)
if ( ABS_DIFF (current_t, seek_t) > testmedia.FrameDuration() ) {
if ( ABS_DIFF (current_t, seek_t) > testmedia.frameDuration() ) {
// request seek (ASYNC)
testmedia.SeekTo(seek_t);
testmedia.seekTo(seek_t);
}
// play/stop command should be following the playing mode (buttons)
@@ -245,12 +245,12 @@ void drawMediaPlayer()
// NB: The seek command performed an ASYNC state change, but
// gst_element_get_state called in isPlaying() will wait for the state change to complete.
if ( testmedia.isPlaying() != media_play ) {
testmedia.Play( media_play );
testmedia.play( media_play );
}
// display info
ImGui::Text("%s %d x %d", testmedia.Codec().c_str(), testmedia.Width(), testmedia.Height());
ImGui::Text("Framerate %.2f / %.2f", testmedia.UpdateFrameRate() , testmedia.FrameRate() );
ImGui::Text("%s %d x %d", testmedia.codec().c_str(), testmedia.width(), testmedia.height());
ImGui::Text("Framerate %.2f / %.2f", testmedia.updateFrameRate() , testmedia.frameRate() );
ImGui::End();
}
@@ -331,27 +331,23 @@ int main(int, char**)
// init the scene
scene.root_.init();
Rendering::manager().AddDrawCallback(drawScene);
Rendering::manager().PushBackDrawCallback(drawScene);
// create and add a elements to the scene
MediaRectangle testnode1("file:///home/bhbn/Videos/iss.mov");
MediaSurface testnode1("file:///home/bhbn/Videos/iss.mov");
testnode1.init();
MediaRectangle testnode2("file:///home/bhbn/Videos/fish.mp4");
MediaSurface testnode2("file:///home/bhbn/Videos/fish.mp4");
testnode2.init();
TexturedRectangle testnode3("images/v-mix_256x256.png");
ImageSurface testnode3("images/v-mix_256x256.png");
testnode3.init();
testnode3.getShader()->blending = Shader::BLEND_SUBSTRACT;
testnode3.getShader()->blending = Shader::BLEND_ADD;
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);
LineCircle border(color);
// LineSquare border(color);
border.init();
Group g1;
@@ -364,11 +360,12 @@ int main(int, char**)
// build tree
g1.addChild(&testnode1);
g1.addChild(&testnode3);
g1.addChild(&border);
scene.root_.addChild(&g1);
g2.addChild(&testnode1);
g2.addChild(&testnode2);
g2.addChild(&border);
g2.setActiveIndex(1);
scene.root_.addChild(&g2);
@@ -380,11 +377,13 @@ int main(int, char**)
Rendering::manager().Draw();
}
testmedia.Close();
testmedia2.Close();
testmedia.close();
testmedia2.close();
SessionVisitor savetoxml("/home/bhbn/test.vmx");
SessionVisitor savetoxml;
scene.accept(savetoxml);
scene.accept(savetoxml);
savetoxml.save("/home/bhbn/test.vmx");
UserInterface::manager().Terminate();
Rendering::manager().Terminate();