summaryrefslogtreecommitdiff
path: root/src/player
diff options
context:
space:
mode:
authorDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 16:10:52 +0000
committerDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 19:15:57 +0000
commitd20f4a64eba38690337ac914a04a113de7caf125 (patch)
tree6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/player
parent28161e9209f21be1a600f637565ecede94855a36 (diff)
New upstream release. Closes: #721047debian/1.8.0-1
Drop all patches, none are needed with this new upstream release. Port to dh. Specify foreign in configure.ac.
Diffstat (limited to 'src/player')
-rw-r--r--src/player/AVGNode.cpp15
-rw-r--r--src/player/AVGNode.h4
-rw-r--r--src/player/AppleTrackpadInputDevice.cpp28
-rw-r--r--src/player/AreaNode.cpp193
-rw-r--r--src/player/AreaNode.h78
-rw-r--r--src/player/Arg.cpp19
-rw-r--r--src/player/Arg.h27
-rw-r--r--src/player/ArgBase.cpp2
-rw-r--r--src/player/ArgBase.h6
-rw-r--r--src/player/ArgList.cpp154
-rw-r--r--src/player/ArgList.h12
-rw-r--r--src/player/BitmapManager.cpp147
-rw-r--r--src/player/BitmapManager.h66
-rw-r--r--src/player/BitmapManagerMsg.cpp121
-rw-r--r--src/player/BitmapManagerMsg.h76
-rw-r--r--src/player/BitmapManagerThread.cpp78
-rw-r--r--src/player/BitmapManagerThread.h55
-rw-r--r--src/player/BlurFXNode.cpp22
-rw-r--r--src/player/BlurFXNode.h11
-rw-r--r--src/player/BoostPython.h4
-rw-r--r--src/player/CameraNode.cpp48
-rw-r--r--src/player/CameraNode.h17
-rw-r--r--src/player/Canvas.cpp141
-rw-r--r--src/player/Canvas.h38
-rw-r--r--src/player/CanvasNode.cpp13
-rw-r--r--src/player/CanvasNode.h5
-rw-r--r--src/player/ChromaKeyFXNode.cpp27
-rw-r--r--src/player/ChromaKeyFXNode.h32
-rw-r--r--src/player/CircleNode.cpp230
-rw-r--r--src/player/CircleNode.h50
-rw-r--r--src/player/Contact.cpp88
-rw-r--r--src/player/Contact.h25
-rw-r--r--src/player/CursorEvent.cpp21
-rw-r--r--src/player/CursorEvent.h16
-rw-r--r--src/player/CursorState.cpp8
-rw-r--r--src/player/CursorState.h12
-rw-r--r--src/player/CurveNode.cpp101
-rw-r--r--src/player/CurveNode.h54
-rw-r--r--src/player/DisplayEngine.cpp68
-rw-r--r--src/player/DisplayEngine.h18
-rw-r--r--src/player/DisplayParams.cpp16
-rw-r--r--src/player/DisplayParams.h9
-rw-r--r--src/player/DivNode.cpp133
-rw-r--r--src/player/DivNode.h25
-rw-r--r--src/player/Event.cpp38
-rw-r--r--src/player/Event.h20
-rw-r--r--src/player/EventDispatcher.cpp59
-rw-r--r--src/player/EventDispatcher.h7
-rw-r--r--src/player/ExportedObject.cpp105
-rw-r--r--src/player/ExportedObject.h73
-rw-r--r--src/player/FXNode.cpp17
-rw-r--r--src/player/FXNode.h8
-rw-r--r--src/player/FilledVectorNode.cpp75
-rw-r--r--src/player/FilledVectorNode.h42
-rw-r--r--src/player/FontStyle.cpp315
-rw-r--r--src/player/FontStyle.h114
-rw-r--r--src/player/HueSatFXNode.cpp34
-rw-r--r--src/player/HueSatFXNode.h7
-rw-r--r--src/player/IBitmapLoadedListener.h44
-rw-r--r--src/player/IInputDevice.h2
-rw-r--r--src/player/Image.cpp65
-rw-r--r--src/player/Image.h5
-rw-r--r--src/player/ImageNode.cpp49
-rw-r--r--src/player/ImageNode.h11
-rw-r--r--src/player/InvertFXNode.cpp15
-rw-r--r--src/player/InvertFXNode.h2
-rw-r--r--src/player/KeyEvent.cpp6
-rw-r--r--src/player/KeyEvent.h2
-rw-r--r--src/player/LibMTDevInputDevice.cpp19
-rw-r--r--src/player/LibMTDevInputDevice.h2
-rw-r--r--src/player/LineNode.cpp39
-rw-r--r--src/player/LineNode.h30
-rw-r--r--src/player/MainCanvas.cpp15
-rw-r--r--src/player/MainCanvas.h4
-rw-r--r--src/player/Makefile.am71
-rw-r--r--src/player/Makefile.in307
-rw-r--r--src/player/MaterialInfo.cpp2
-rw-r--r--src/player/MaterialInfo.h4
-rw-r--r--src/player/MeshNode.cpp74
-rw-r--r--src/player/MeshNode.h37
-rw-r--r--src/player/MessageID.cpp62
-rw-r--r--src/player/MessageID.h48
-rw-r--r--src/player/MouseEvent.cpp6
-rw-r--r--src/player/MouseEvent.h4
-rw-r--r--src/player/MultitouchInputDevice.cpp32
-rw-r--r--src/player/MultitouchInputDevice.h13
-rw-r--r--src/player/Node.cpp255
-rw-r--r--src/player/Node.h93
-rw-r--r--src/player/NodeRegistry.cpp126
-rw-r--r--src/player/NullFXNode.cpp3
-rw-r--r--src/player/NullFXNode.h2
-rw-r--r--src/player/OGLSurface.cpp281
-rw-r--r--src/player/OGLSurface.h33
-rw-r--r--src/player/OffscreenCanvas.cpp75
-rw-r--r--src/player/OffscreenCanvas.h11
-rw-r--r--src/player/OffscreenCanvasNode.cpp11
-rw-r--r--src/player/OffscreenCanvasNode.h4
-rw-r--r--src/player/PanoImageNode.cpp351
-rw-r--r--src/player/PanoImageNode.h95
-rw-r--r--src/player/Player.cpp959
-rw-r--r--src/player/Player.h106
-rw-r--r--src/player/PluginManager.cpp28
-rw-r--r--src/player/PluginManager.h4
-rw-r--r--src/player/PolyLineNode.cpp38
-rw-r--r--src/player/PolyLineNode.h22
-rw-r--r--src/player/PolygonNode.cpp105
-rw-r--r--src/player/PolygonNode.h32
-rw-r--r--src/player/Publisher.cpp248
-rw-r--r--src/player/Publisher.h113
-rw-r--r--src/player/PublisherDefinition.cpp90
-rw-r--r--src/player/PublisherDefinition.h62
-rw-r--r--src/player/PublisherDefinitionRegistry.cpp90
-rw-r--r--src/player/PublisherDefinitionRegistry.h63
-rw-r--r--src/player/PythonLogSink.cpp90
-rw-r--r--src/player/PythonLogSink.h46
-rw-r--r--src/player/RasterNode.cpp315
-rw-r--r--src/player/RasterNode.h78
-rw-r--r--src/player/RectNode.cpp137
-rw-r--r--src/player/RectNode.h34
-rw-r--r--src/player/SDLDisplayEngine.cpp577
-rw-r--r--src/player/SDLDisplayEngine.h45
-rw-r--r--src/player/SVG.cpp62
-rw-r--r--src/player/SVG.h21
-rw-r--r--src/player/SVGElement.cpp23
-rw-r--r--src/player/SVGElement.h12
-rw-r--r--src/player/ShadowFXNode.cpp47
-rw-r--r--src/player/ShadowFXNode.h26
-rw-r--r--src/player/Shape.cpp50
-rw-r--r--src/player/Shape.h14
-rw-r--r--src/player/SoundNode.cpp113
-rw-r--r--src/player/SoundNode.h22
-rw-r--r--src/player/SubscriberInfo.cpp85
-rw-r--r--src/player/SubscriberInfo.h58
-rw-r--r--src/player/TUIOInputDevice.cpp44
-rw-r--r--src/player/TUIOInputDevice.h4
-rw-r--r--src/player/TestHelper.cpp21
-rw-r--r--src/player/TestHelper.h6
-rw-r--r--src/player/TextEngine.cpp40
-rw-r--r--src/player/TextEngine.h2
-rw-r--r--src/player/Timeout.cpp20
-rw-r--r--src/player/Timeout.h10
-rw-r--r--src/player/TouchEvent.cpp44
-rw-r--r--src/player/TouchEvent.h40
-rw-r--r--src/player/TouchStatus.cpp6
-rw-r--r--src/player/TouchStatus.h4
-rw-r--r--src/player/TrackerCalibrator.cpp29
-rw-r--r--src/player/TrackerCalibrator.h12
-rw-r--r--src/player/TrackerInputDevice.cpp66
-rw-r--r--src/player/TrackerInputDevice.h10
-rw-r--r--src/player/TrackerTouchStatus.cpp22
-rw-r--r--src/player/TrackerTouchStatus.h12
-rw-r--r--src/player/TypeDefinition.cpp (renamed from src/player/NodeDefinition.cpp)50
-rw-r--r--src/player/TypeDefinition.h (renamed from src/player/NodeDefinition.h)41
-rw-r--r--src/player/TypeRegistry.cpp159
-rw-r--r--src/player/TypeRegistry.h (renamed from src/player/NodeRegistry.h)33
-rw-r--r--src/player/VectorNode.cpp229
-rw-r--r--src/player/VectorNode.h47
-rw-r--r--src/player/VersionInfo.cpp72
-rw-r--r--src/player/VersionInfo.h47
-rw-r--r--src/player/VideoNode.cpp240
-rw-r--r--src/player/VideoNode.h33
-rw-r--r--src/player/VideoWriter.cpp45
-rw-r--r--src/player/VideoWriter.h9
-rw-r--r--src/player/VideoWriterThread.cpp52
-rw-r--r--src/player/VideoWriterThread.h8
-rw-r--r--src/player/WordsNode.cpp523
-rw-r--r--src/player/WordsNode.h72
-rw-r--r--src/player/WrapPython.cpp72
-rw-r--r--src/player/WrapPython.h23
-rw-r--r--src/player/XInputMTInputDevice.cpp26
-rw-r--r--src/player/XInputMTInputDevice.h7
-rw-r--r--src/player/testcalibrator.cpp39
-rw-r--r--src/player/testplayer.cpp19
173 files changed, 6858 insertions, 4732 deletions
diff --git a/src/player/AVGNode.cpp b/src/player/AVGNode.cpp
index 524bab5..e7c94bc 100644
--- a/src/player/AVGNode.cpp
+++ b/src/player/AVGNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
#include "AVGNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "KeyEvent.h"
#include "../base/FileHelper.h"
@@ -33,20 +33,17 @@ using namespace std;
namespace avg {
-NodeDefinition AVGNode::createDefinition()
+void AVGNode::registerType()
{
- return NodeDefinition("avg", Node::buildNode<AVGNode>)
- .extendDefinition(CanvasNode::createDefinition())
- .addArg(Arg<string>("onkeyup", ""))
- .addArg(Arg<string>("onkeydown", ""));
+ TypeDefinition def = TypeDefinition("avg", "canvasbase",
+ ExportedObject::buildObject<AVGNode>);
+ TypeRegistry::get()->registerType(def);
}
AVGNode::AVGNode(const ArgList& args)
: CanvasNode(args)
{
args.setMembers(this);
- addArgEventHandler(Event::KEYUP, Event::NONE, args.getArgVal<string>("onkeyup"));
- addArgEventHandler(Event::KEYDOWN, Event::NONE, args.getArgVal<string>("onkeydown"));
}
AVGNode::~AVGNode()
diff --git a/src/player/AVGNode.h b/src/player/AVGNode.h
index ade1f79..fead377 100644
--- a/src/player/AVGNode.h
+++ b/src/player/AVGNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ namespace avg {
class AVG_API AVGNode : public CanvasNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
AVGNode(const ArgList& args);
virtual ~AVGNode();
diff --git a/src/player/AppleTrackpadInputDevice.cpp b/src/player/AppleTrackpadInputDevice.cpp
index d78e946..63059ae 100644
--- a/src/player/AppleTrackpadInputDevice.cpp
+++ b/src/player/AppleTrackpadInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -57,27 +57,28 @@ void AppleTrackpadInputDevice::start()
m_Device = MTDeviceCreateDefault();
MTRegisterContactFrameCallback(m_Device, callback);
MTDeviceStart(m_Device, 0);
- AVG_TRACE(Logger::CONFIG, "Apple Trackpad Multitouch event source created.");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Apple Trackpad Multitouch event source created.");
}
void AppleTrackpadInputDevice::onData(int device, Finger* pFingers, int numFingers,
- double timestamp, int frame)
+ float timestamp, int frame)
{
- boost::mutex::scoped_lock lock(getMutex());
+ lock_guard lock(getMutex());
for (int i = 0; i < numFingers; i++) {
Finger* pFinger = &pFingers[i];
TouchStatusPtr pTouchStatus = getTouchStatus(pFinger->identifier);
if (!pTouchStatus) {
m_LastID++;
- TouchEventPtr pEvent = createEvent(m_LastID, pFinger, Event::CURSORDOWN);
+ TouchEventPtr pEvent = createEvent(m_LastID, pFinger, Event::CURSOR_DOWN);
addTouchStatus(pFinger->identifier, pEvent);
} else {
Event::Type eventType;
if (pFinger->state == 7) {
- eventType = Event::CURSORUP;
+ eventType = Event::CURSOR_UP;
removeTouchStatus(pFinger->identifier);
} else {
- eventType = Event::CURSORMOTION;
+ eventType = Event::CURSOR_MOTION;
}
TouchEventPtr pEvent = createEvent(0, pFinger, eventType);
pTouchStatus->pushEvent(pEvent);
@@ -96,13 +97,14 @@ int AppleTrackpadInputDevice::callback(int device, Finger *data, int nFingers,
TouchEventPtr AppleTrackpadInputDevice::createEvent(int avgID, Finger* pFinger,
Event::Type eventType)
{
- DPoint size = getWindowSize();
- IntPoint pos(pFinger->normalized.pos.x*size.x, (1-pFinger->normalized.pos.y)*size.y);
- DPoint speed(pFinger->normalized.vel.x*size.x, pFinger->normalized.vel.y*size.y);
- double eccentricity = pFinger->majorAxis/pFinger->minorAxis;
- DPoint majorAxis = DPoint::fromPolar(pFinger->angle, pFinger->majorAxis);
+ glm::vec2 size = getTouchArea();
+ IntPoint pos = getScreenPos(glm::vec2(pFinger->normalized.pos.x,
+ 1-pFinger->normalized.pos.y));
+ glm::vec2 speed(pFinger->normalized.vel.x*size.x, pFinger->normalized.vel.y*size.y);
+ float eccentricity = pFinger->majorAxis/pFinger->minorAxis;
+ glm::vec2 majorAxis = fromPolar(pFinger->angle, pFinger->majorAxis);
majorAxis.y = -majorAxis.y;
- DPoint minorAxis = DPoint::fromPolar(pFinger->angle+1.57, pFinger->minorAxis);
+ glm::vec2 minorAxis = fromPolar(pFinger->angle+1.57, pFinger->minorAxis);
minorAxis.y = -minorAxis.y;
TouchEventPtr pEvent(new TouchEvent(avgID, eventType, pos, Event::TOUCH,
diff --git a/src/player/AreaNode.cpp b/src/player/AreaNode.cpp
index 64e2ae8..b09f4a6 100644
--- a/src/player/AreaNode.cpp
+++ b/src/player/AreaNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,8 @@
#include "MouseEvent.h"
#include "DivNode.h"
#include "ArgList.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
+#include "TypeRegistry.h"
#include "BoostPython.h"
#include "../base/MathHelper.h"
@@ -43,29 +44,32 @@
#include <iostream>
using namespace boost;
-using namespace boost::python;
using namespace std;
namespace avg {
-NodeDefinition AreaNode::createDefinition()
+void AreaNode::registerType()
{
- return NodeDefinition("areanode")
- .extendDefinition(Node::createDefinition())
- .addArg(Arg<double>("x", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.x)))
- .addArg(Arg<double>("y", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.y)))
- .addArg(Arg<DPoint>("pos", DPoint(0.0, 0.0)))
- .addArg(Arg<double>("width", 0.0, false, offsetof(AreaNode, m_UserSize.x)))
- .addArg(Arg<double>("height", 0.0, false, offsetof(AreaNode, m_UserSize.y)))
- .addArg(Arg<DPoint>("size", DPoint(0.0, 0.0)))
- .addArg(Arg<double>("angle", 0.0, false, offsetof(AreaNode, m_Angle)))
- .addArg(Arg<DPoint>("pivot", DPoint(-32767, -32767), false,
- offsetof(AreaNode, m_Pivot)));
+ TypeDefinition def = TypeDefinition("areanode", "node")
+ .addArg(Arg<float>("x", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.x)))
+ .addArg(Arg<float>("y", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.y)))
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("width", 0.0, false, offsetof(AreaNode, m_UserSize.x)))
+ .addArg(Arg<float>("height", 0.0, false, offsetof(AreaNode, m_UserSize.y)))
+ .addArg(Arg<glm::vec2>("size", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("angle", 0.0, false, offsetof(AreaNode, m_Angle)))
+ .addArg(Arg<glm::vec2>("pivot", glm::vec2(-32767, -32767), false,
+ offsetof(AreaNode, m_Pivot)))
+ .addArg(Arg<string>("elementoutlinecolor", "", false,
+ offsetof(AreaNode, m_sElementOutlineColor)));
+ TypeRegistry::get()->registerType(def);
}
AreaNode::AreaNode()
- : m_RelViewport(0,0,0,0)
+ : m_RelViewport(0,0,0,0),
+ m_Transform(glm::mat4(0)),
+ m_bTransformChanged(true)
{
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -83,170 +87,202 @@ void AreaNode::setArgs(const ArgList& args)
m_RelViewport.setWidth(m_UserSize.x);
m_RelViewport.setHeight(m_UserSize.y);
m_bHasCustomPivot = ((m_Pivot.x != -32767) && (m_Pivot.y != -32767));
+ setElementOutlineColor(m_sElementOutlineColor);
}
void AreaNode::connectDisplay()
{
IntPoint MediaSize = getMediaSize();
if (m_UserSize.x == 0.0) {
- m_RelViewport.setWidth(MediaSize.x);
+ m_RelViewport.setWidth(float(MediaSize.x));
} else {
- m_RelViewport.setWidth(m_UserSize.x);
+ m_RelViewport.setWidth(float(m_UserSize.x));
}
if (m_UserSize.y == 0.0) {
- m_RelViewport.setHeight(MediaSize.y);
+ m_RelViewport.setHeight(float(MediaSize.y));
} else {
- m_RelViewport.setHeight(m_UserSize.y);
+ m_RelViewport.setHeight(float(m_UserSize.y));
}
+ if (m_UserSize.x == 0.0 || m_UserSize.y == 0) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
Node::connectDisplay();
}
-double AreaNode::getX() const
+float AreaNode::getX() const
{
return m_RelViewport.tl.x;
}
-void AreaNode::setX(double x)
+void AreaNode::setX(float x)
{
setViewport(x, -32767, -32767, -32767);
}
-double AreaNode::getY() const
+float AreaNode::getY() const
{
return m_RelViewport.tl.y;
}
-void AreaNode::setY(double y)
+void AreaNode::setY(float y)
{
setViewport(-32767, y, -32767, -32767);
}
-const DPoint& AreaNode::getPos() const
+const glm::vec2& AreaNode::getPos() const
{
return m_RelViewport.tl;
}
-void AreaNode::setPos(const DPoint& pt)
+void AreaNode::setPos(const glm::vec2& pt)
{
setViewport(pt.x, pt.y, -32767, -32767);
}
-double AreaNode::getWidth() const
+float AreaNode::getWidth() const
{
return getRelViewport().width();
}
-void AreaNode::setWidth(double width)
+void AreaNode::setWidth(float width)
{
m_UserSize.x = width;
setViewport(-32767, -32767, -32767, -32767);
}
-double AreaNode::getHeight() const
+float AreaNode::getHeight() const
{
return getRelViewport().height();
}
-void AreaNode::setHeight(double height)
+void AreaNode::setHeight(float height)
{
m_UserSize.y = height;
setViewport(-32767, -32767, -32767, -32767);
}
-DPoint AreaNode::getSize() const
+glm::vec2 AreaNode::getSize() const
{
return getRelViewport().size();
}
-void AreaNode::setSize(const DPoint& pt)
+void AreaNode::setSize(const glm::vec2& pt)
{
m_UserSize = pt;
setViewport(-32767, -32767, -32767, -32767);
}
-double AreaNode::getAngle() const
+float AreaNode::getAngle() const
{
return m_Angle;
}
-void AreaNode::setAngle(double angle)
+void AreaNode::setAngle(float angle)
{
- m_Angle = fmod(angle, 2*M_PI);
+ m_Angle = fmod(angle, 2*PI);
+ m_bTransformChanged = true;
}
-DPoint AreaNode::getPivot() const
+glm::vec2 AreaNode::getPivot() const
{
if (m_bHasCustomPivot) {
return m_Pivot;
} else {
- return getSize()/2;
+ return getSize()/2.f;
}
}
-void AreaNode::setPivot(const DPoint& pt)
+void AreaNode::setPivot(const glm::vec2& pt)
{
m_Pivot.x = pt.x;
m_Pivot.y = pt.y;
m_bHasCustomPivot = true;
+ m_bTransformChanged = true;
+}
+
+const std::string& AreaNode::getElementOutlineColor() const
+{
+ return m_sElementOutlineColor;
+}
+
+void AreaNode::setElementOutlineColor(const std::string& sColor)
+{
+ m_sElementOutlineColor = sColor;
+ if (sColor == "") {
+ m_ElementOutlineColor = Pixel32(0,0,0,0);
+ } else {
+ m_ElementOutlineColor = colorStringToColor(m_sElementOutlineColor);
+ }
}
-DPoint AreaNode::toLocal(const DPoint& globalPos) const
+glm::vec2 AreaNode::toLocal(const glm::vec2& globalPos) const
{
- DPoint localPos = globalPos-m_RelViewport.tl;
- return localPos.getRotatedPivot(-getAngle(), getPivot());
+ glm::vec2 localPos = globalPos-m_RelViewport.tl;
+ return getRotatedPivot(localPos, -getAngle(), getPivot());
}
-DPoint AreaNode::toGlobal(const DPoint& localPos) const
+glm::vec2 AreaNode::toGlobal(const glm::vec2& localPos) const
{
- DPoint globalPos = localPos.getRotatedPivot(getAngle(), getPivot());
+ glm::vec2 globalPos = getRotatedPivot(localPos, getAngle(), getPivot());
return globalPos+m_RelViewport.tl;
}
-void AreaNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void AreaNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
if (pos.x >= 0 && pos.y >= 0 && pos.x < getSize().x && pos.y < getSize().y &&
reactsToMouseEvents())
{
- pElements.push_back(shared_from_this());
+ pElements.push_back(getSharedThis());
}
}
-void AreaNode::maybeRender(const DRect& rect)
+void AreaNode::maybeRender(const glm::mat4& parentTransform)
{
AVG_ASSERT(getState() == NS_CANRENDER);
if (isVisible()) {
- if (getID() != "") {
- AVG_TRACE(Logger::BLTS, "Rendering " << getTypeStr() <<
- " with ID " << getID());
- } else {
- AVG_TRACE(Logger::BLTS, "Rendering " << getTypeStr());
- }
- GLContext * pContext = GLContext::getCurrent();
- pContext->pushTransform(getRelViewport().tl, getAngle(), getPivot());
- render(rect);
- pContext->popTransform();
+ calcTransform();
+ m_Transform = parentTransform*m_LocalTransform;
+ render();
+ }
+}
+
+void AreaNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor)
+{
+ Pixel32 effColor = getEffectiveOutlineColor(parentColor);
+ if (effColor != Pixel32(0,0,0,0)) {
+ glm::vec2 size = getSize();
+ glm::vec2 p0 = getAbsPos(glm::vec2(0.5, 0.5));
+ glm::vec2 p1 = getAbsPos(glm::vec2(size.x+0.5,0.5));
+ glm::vec2 p2 = getAbsPos(glm::vec2(size.x+0.5,size.y+0.5));
+ glm::vec2 p3 = getAbsPos(glm::vec2(0.5,size.y+0.5));
+ pVA->addLineData(effColor, p0, p1, 1);
+ pVA->addLineData(effColor, p1, p2, 1);
+ pVA->addLineData(effColor, p2, p3, 1);
+ pVA->addLineData(effColor, p3, p0, 1);
}
}
-void AreaNode::setViewport(double x, double y, double width, double height)
+void AreaNode::setViewport(float x, float y, float width, float height)
{
+ glm::vec2 oldSize = getRelViewport().size();
if (x == -32767) {
x = getRelViewport().tl.x;
}
if (y == -32767) {
y = getRelViewport().tl.y;
}
- IntPoint MediaSize = getMediaSize();
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
if (width == -32767) {
if (m_UserSize.x == 0.0) {
- width = MediaSize.x;
+ width = mediaSize.x;
} else {
width = m_UserSize.x;
}
}
if (height == -32767) {
if (m_UserSize.y == 0.0) {
- height = MediaSize.y;
+ height = mediaSize.y;
} else {
height = m_UserSize.y;
}
@@ -254,10 +290,14 @@ void AreaNode::setViewport(double x, double y, double width, double height)
if (width < 0 || height < 0) {
throw Exception(AVG_ERR_OUT_OF_RANGE, "Negative size for a node.");
}
- m_RelViewport = DRect (x, y, x+width, y+height);
+ m_RelViewport = FRect(x, y, x+width, y+height);
+ if (oldSize != m_RelViewport.size()) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
}
-const DRect& AreaNode::getRelViewport() const
+const FRect& AreaNode::getRelViewport() const
{
// cerr << "Node " << getID() << ": " << m_RelViewport << endl;
return m_RelViewport;
@@ -275,9 +315,36 @@ string AreaNode::dump(int indent)
return dumpStr;
}
-DPoint AreaNode::getUserSize() const
+const glm::mat4& AreaNode::getTransform() const
+{
+ return m_Transform;
+}
+
+glm::vec2 AreaNode::getUserSize() const
{
return m_UserSize;
}
+Pixel32 AreaNode::getEffectiveOutlineColor(Pixel32 parentColor) const
+{
+ if (m_ElementOutlineColor == Pixel32(0,0,0,0)) {
+ return parentColor;
+ } else {
+ return m_ElementOutlineColor;
+ }
+}
+
+void AreaNode::calcTransform()
+{
+ if (m_bTransformChanged) {
+ glm::vec3 pos(m_RelViewport.tl.x, m_RelViewport.tl.y, 0);
+ glm::vec3 pivot(getPivot().x, getPivot().y, 0);
+ glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
+ transform = glm::translate(transform, pivot);
+ transform = glm::rotate(transform, (180.f/PI)*m_Angle, glm::vec3(0,0,1));
+ m_LocalTransform = glm::translate(transform, -pivot);
+ m_bTransformChanged = false;
+ }
+}
+
}
diff --git a/src/player/AreaNode.h b/src/player/AreaNode.h
index 65bb3bf..7a65c52 100644
--- a/src/player/AreaNode.h
+++ b/src/player/AreaNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,7 @@
#include "Node.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../base/Rect.h"
#include "../graphics/OGLShader.h"
@@ -44,9 +44,6 @@ class DivNode;
class ArgList;
typedef boost::shared_ptr<AreaNode> AreaNodePtr;
-typedef boost::weak_ptr<AreaNode> AreaNodeWeakPtr;
-typedef boost::shared_ptr<DivNode> DivNodePtr;
-typedef boost::weak_ptr<DivNode> DivNodeWeakPtr;
class AVG_API AreaNode: public Node
{
@@ -56,45 +53,49 @@ class AVG_API AreaNode: public Node
{
return NodePtr(new NodeType(args));
}
- static NodeDefinition createDefinition();
+ static void registerType();
virtual ~AreaNode() = 0;
virtual void setArgs(const ArgList& args);
virtual void connectDisplay();
- double getX() const;
- void setX(double x);
+ float getX() const;
+ void setX(float x);
- double getY() const;
- void setY(double Y);
+ float getY() const;
+ void setY(float Y);
- const DPoint& getPos() const;
- void setPos(const DPoint& pt);
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
- virtual double getWidth() const;
- virtual void setWidth(double width);
+ virtual float getWidth() const;
+ virtual void setWidth(float width);
- virtual double getHeight() const;
- virtual void setHeight(double height);
+ virtual float getHeight() const;
+ virtual void setHeight(float height);
- virtual DPoint getSize() const;
- virtual void setSize(const DPoint& pt);
+ virtual glm::vec2 getSize() const;
+ virtual void setSize(const glm::vec2& pt);
- double getAngle() const;
- void setAngle(double angle);
+ float getAngle() const;
+ void setAngle(float angle);
- virtual DPoint getPivot() const;
- void setPivot(const DPoint& pt);
+ virtual glm::vec2 getPivot() const;
+ void setPivot(const glm::vec2& pt);
- virtual DPoint toLocal(const DPoint& globalPos) const;
- virtual DPoint toGlobal(const DPoint& localPos) const;
+ const std::string& getElementOutlineColor() const;
+ void setElementOutlineColor(const std::string& sColor);
+
+ virtual glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ virtual glm::vec2 toGlobal(const glm::vec2& localPos) const;
- virtual void getElementsByPos(const DPoint& pos,
- std::vector<NodeWeakPtr>& pElements);
+ virtual void getElementsByPos(const glm::vec2& pos,
+ std::vector<NodePtr>& pElements);
- virtual void maybeRender(const DRect& rect);
- virtual void setViewport(double x, double y, double width, double height);
- virtual const DRect& getRelViewport() const;
+ virtual void maybeRender(const glm::mat4& parentTransform);
+ virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor);
+ virtual void setViewport(float x, float y, float width, float height);
+ virtual const FRect& getRelViewport() const;
virtual std::string dump(int indent = 0);
@@ -102,18 +103,27 @@ class AVG_API AreaNode: public Node
virtual IntPoint getMediaSize()
{ return IntPoint(0,0); };
+ const glm::mat4& getTransform() const;
protected:
AreaNode();
- DPoint getUserSize() const;
+ glm::vec2 getUserSize() const;
+ Pixel32 getEffectiveOutlineColor(Pixel32 parentColor) const;
private:
- DRect m_RelViewport; // In coordinates relative to the parent.
- double m_Angle;
- DPoint m_Pivot;
+ void calcTransform();
+
+ FRect m_RelViewport; // In coordinates relative to the parent.
+ float m_Angle;
+ glm::vec2 m_Pivot;
bool m_bHasCustomPivot;
+ std::string m_sElementOutlineColor;
+ Pixel32 m_ElementOutlineColor;
- DPoint m_UserSize;
+ glm::vec2 m_UserSize;
+ glm::mat4 m_Transform;
+ glm::mat4 m_LocalTransform;
+ bool m_bTransformChanged;
};
}
diff --git a/src/player/Arg.cpp b/src/player/Arg.cpp
index 6bb7fbb..1518164 100644
--- a/src/player/Arg.cpp
+++ b/src/player/Arg.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,8 @@
//
#include "Arg.h"
+#include "FontStyle.h"
+
#include <string>
using namespace std;
@@ -31,14 +33,15 @@ namespace avg {
#ifndef _WIN32
template class Arg<int>;
template class Arg<bool>;
-template class Arg<double>;
template class Arg<float>;
template class Arg<string>;
-template class Arg<DPoint>;
-template class Arg<IntTriple>;
-template class Arg<DTriple>;
-template class Arg<vector<double> >;
-template class Arg<vector<DPoint> >;
-template class Arg<vector<IntTriple> >;
+template class Arg<glm::vec2>;
+template class Arg<glm::vec3>;
+template class Arg<glm::ivec3>;
+template class Arg<std::vector<float> >;
+template class Arg<std::vector<int> >;
+template class Arg<vector<glm::vec2> >;
+template class Arg<vector<glm::ivec3> >;
+template class Arg<FontStyle>;
#endif
}
diff --git a/src/player/Arg.h b/src/player/Arg.h
index a48e86f..be441e3 100644
--- a/src/player/Arg.h
+++ b/src/player/Arg.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,7 @@
#define _Arg_H_
#include "../api.h"
-#include "../base/Point.h"
-#include "../base/Triple.h"
+#include "../base/GLMHelper.h"
#include "ArgBase.h"
@@ -35,7 +34,7 @@
namespace avg {
-class Node;
+class ExportedObject;
template<class T>
class AVG_TEMPLATE_API Arg: public ArgBase
@@ -47,7 +46,7 @@ public:
void setValue(const T& Value);
const T& getValue() const;
- virtual void setMember(Node * pNode) const;
+ virtual void setMember(ExportedObject * pObj) const;
virtual ArgBase* createCopy() const;
private:
@@ -81,10 +80,10 @@ void Arg<T>::setValue(const T& Value)
}
template<class T>
-void Arg<T>::setMember(Node * pNode) const
+void Arg<T>::setMember(ExportedObject * pObj) const
{
if (getMemberOffset() != -1) {
- T* pMember = (T*)((char*)pNode+getMemberOffset());
+ T* pMember = (T*)((char*)pObj+getMemberOffset());
*pMember = m_Value;
}
}
@@ -103,14 +102,14 @@ ArgBase* Arg<T>::createCopy() const
extern template class Arg<int>;
extern template class Arg<bool>;
extern template class Arg<float>;
-extern template class Arg<double>;
extern template class Arg<std::string>;
-extern template class Arg<DPoint>;
-extern template class Arg<IntTriple>;
-extern template class Arg<DTriple>;
-extern template class Arg<std::vector<double> >;
-extern template class Arg<std::vector<DPoint> >;
-extern template class Arg<std::vector<IntTriple> >;
+extern template class Arg<glm::vec2>;
+extern template class Arg<glm::vec3>;
+extern template class Arg<glm::ivec3>;
+extern template class Arg<std::vector<float> >;
+extern template class Arg<std::vector<int> >;
+extern template class Arg<std::vector<glm::vec2> >;
+extern template class Arg<std::vector<glm::ivec2> >;
#endif
#endif
diff --git a/src/player/ArgBase.cpp b/src/player/ArgBase.cpp
index 1c4882d..9409f45 100644
--- a/src/player/ArgBase.cpp
+++ b/src/player/ArgBase.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/ArgBase.h b/src/player/ArgBase.h
index c6017f2..fff8969 100644
--- a/src/player/ArgBase.h
+++ b/src/player/ArgBase.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@
namespace avg {
-class Node;
+class ExportedObject;
class AVG_API ArgBase
{
@@ -44,7 +44,7 @@ public:
bool isDefault() const;
bool isRequired() const;
- virtual void setMember(Node * pNode) const = 0;
+ virtual void setMember(ExportedObject * pObj) const = 0;
virtual ArgBase* createCopy() const = 0;
diff --git a/src/player/ArgList.cpp b/src/player/ArgList.cpp
index 15b5ce3..5abe78c 100644
--- a/src/player/ArgList.cpp
+++ b/src/player/ArgList.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,8 @@
#include "ArgList.h"
-#include "Node.h"
+#include "ExportedObject.h"
+#include "FontStyle.h"
#include "../base/Logger.h"
#include "../base/Exception.h"
@@ -36,6 +37,8 @@ using namespace std;
namespace avg {
+typedef std::vector<std::vector<glm::vec2> > CollVec2Vector;
+
ArgList::ArgList()
{
}
@@ -52,18 +55,18 @@ ArgList::ArgList(const ArgList& argTemplates, const xmlNodePtr xmlNode)
}
}
-ArgList::ArgList(const ArgList& argTemplates, const boost::python::dict& PyDict)
+ArgList::ArgList(const ArgList& argTemplates, const py::dict& PyDict)
{
// TODO: Check if all required args are being set.
copyArgsFrom(argTemplates);
- boost::python::list keys = PyDict.keys();
- int nKeys = boost::python::len(keys);
+ py::list keys = PyDict.keys();
+ int nKeys = py::len(keys);
for (int i = 0; i < nKeys; i++)
{
- boost::python::object keyObj = keys[i];
- boost::python::object valObj = PyDict[keyObj];
+ py::object keyObj = keys[i];
+ py::object valObj = PyDict[keyObj];
- boost::python::extract<string> keyStrProxy(keyObj);
+ py::extract<string> keyStrProxy(keyObj);
if (!keyStrProxy.check()) {
throw Exception(AVG_ERR_INVALID_ARGS, "Argument name must be a string.");
}
@@ -93,7 +96,7 @@ const ArgBasePtr ArgList::getArg(const string& sName) const
return valIt->second;
}
-void ArgList::getOverlayedArgVal(DPoint* pResult, const string& sName,
+void ArgList::getOverlayedArgVal(glm::vec2* pResult, const string& sName,
const string& sOverlay1, const string& sOverlay2, const string& sID) const
{
if (hasArg(sName)) {
@@ -102,7 +105,7 @@ void ArgList::getOverlayedArgVal(DPoint* pResult, const string& sName,
string("Duplicate node arguments (")+sName+" and "+
sOverlay1+","+sOverlay2+") for node '"+sID+"'"));
}
- *pResult = getArgVal<DPoint>(sName);
+ *pResult = getArgVal<glm::vec2>(sName);
}
}
@@ -113,7 +116,7 @@ const ArgMap& ArgList::getArgMap() const
void ArgList::setArg(const ArgBase& newArg)
{
- m_Args.insert(ArgMap::value_type(newArg.getName(), ArgBasePtr(newArg.createCopy())));
+ m_Args[newArg.getName()] = ArgBasePtr(newArg.createCopy());
}
void ArgList::setArgs(const ArgList& args)
@@ -123,20 +126,19 @@ void ArgList::setArgs(const ArgList& args)
}
}
-void ArgList::setMembers(Node * pNode) const
+void ArgList::setMembers(ExportedObject * pObj) const
{
for (ArgMap::const_iterator it = m_Args.begin(); it != m_Args.end(); it++) {
const ArgBasePtr pCurArg = it->second;
- pCurArg->setMember(pNode);
+ pCurArg->setMember(pObj);
}
- pNode->setArgs(*this);
+ pObj->setArgs(*this);
}
template<class T>
-void setArgValue(Arg<T>* pArg, const std::string & sName,
- const boost::python::object& value)
+void setArgValue(Arg<T>* pArg, const std::string & sName, const py::object& value)
{
- boost::python::extract<T> valProxy(value);
+ py::extract<T> valProxy(value);
if (!valProxy.check()) {
string sTypeName = getFriendlyTypeName(pArg->getValue());
throw Exception(AVG_ERR_INVALID_ARGS, "Type error in argument "+sName+": "
@@ -145,47 +147,57 @@ void setArgValue(Arg<T>* pArg, const std::string & sName,
pArg->setValue(valProxy());
}
-void ArgList::setArgValue(const std::string & sName, const boost::python::object& value)
+void ArgList::setArgValue(const std::string & sName, const py::object& value)
{
ArgBasePtr pArg = getArg(sName);
Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg);
Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg);
Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg);
- Arg<double>* pDoubleArg = dynamic_cast<Arg<double>* >(&*pArg);
Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg);
Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg);
- Arg<DPoint>* pDPointArg = dynamic_cast<Arg<DPoint>* >(&*pArg);
- Arg<IntTriple>* pIntTripleArg = dynamic_cast<Arg<IntTriple>* >(&*pArg);
- Arg<DTriple>* pDTripleArg = dynamic_cast<Arg<DTriple>* >(&*pArg);
- Arg<vector<double> >* pDVectorArg = dynamic_cast<Arg<vector<double> >* >(&*pArg);
- Arg<vector<DPoint> >* pDPointVectorArg =
- dynamic_cast<Arg<vector<DPoint> >* >(&*pArg);
- Arg<vector<IntTriple> >* pIntTripleVectorArg =
- dynamic_cast<Arg<vector<IntTriple> >* >(&*pArg);
+ Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg);
+ Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg);
+ Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg);
+ Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg);
+ Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg);
+ Arg<vector<glm::vec2> >* pVec2VectorArg =
+ dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg);
+ Arg<vector<glm::ivec3> >* pIVec3VectorArg =
+ dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg);
+ Arg<CollVec2Vector>* pCollVec2VectorArg =
+ dynamic_cast<Arg<CollVec2Vector>* >(&*pArg);
+ Arg<FontStyle>* pFontStyleArg = dynamic_cast<Arg<FontStyle>* >(&*pArg);
+ Arg<FontStylePtr>* pFontStylePtrArg = dynamic_cast<Arg<FontStylePtr>* >(&*pArg);
if(pStringArg) {
avg::setArgValue(pStringArg, sName, value);
} else if (pUTF8StringArg) {
avg::setArgValue(pUTF8StringArg, sName, value);
} else if (pIntArg) {
avg::setArgValue(pIntArg, sName, value);
- } else if (pDoubleArg) {
- avg::setArgValue(pDoubleArg, sName, value);
} else if (pFloatArg) {
avg::setArgValue(pFloatArg, sName, value);
} else if (pBoolArg) {
avg::setArgValue(pBoolArg, sName, value);
- } else if (pDPointArg) {
- avg::setArgValue(pDPointArg, sName, value);
- } else if (pDVectorArg) {
- avg::setArgValue(pDVectorArg, sName, value);
- } else if (pDPointVectorArg) {
- avg::setArgValue(pDPointVectorArg, sName, value);
- } else if (pIntTripleArg) {
- avg::setArgValue(pIntTripleArg, sName, value);
- } else if (pDTripleArg) {
- avg::setArgValue(pDTripleArg, sName, value);
- } else if (pIntTripleVectorArg) {
- avg::setArgValue(pIntTripleVectorArg, sName, value);
+ } else if (pVec2Arg) {
+ avg::setArgValue(pVec2Arg, sName, value);
+ } else if (pVec3Arg) {
+ avg::setArgValue(pVec3Arg, sName, value);
+ } else if (pIVec3Arg) {
+ avg::setArgValue(pIVec3Arg, sName, value);
+ } else if (pFVectorArg) {
+ avg::setArgValue(pFVectorArg, sName, value);
+ } else if (pIVectorArg) {
+ avg::setArgValue(pIVectorArg, sName, value);
+ } else if (pVec2VectorArg) {
+ avg::setArgValue(pVec2VectorArg, sName, value);
+ } else if (pIVec3VectorArg) {
+ avg::setArgValue(pIVec3VectorArg, sName, value);
+ } else if (pCollVec2VectorArg) {
+ avg::setArgValue(pCollVec2VectorArg, sName, value);
+ } else if (pFontStyleArg) {
+ avg::setArgValue(pFontStyleArg, sName, value);
+ } else if (pFontStylePtrArg) {
+ avg::setArgValue(pFontStylePtrArg, sName, value);
} else {
AVG_ASSERT(false);
}
@@ -197,45 +209,55 @@ void ArgList::setArgValue(const std::string & sName, const std::string & sValue)
Arg<string>* pStringArg = dynamic_cast<Arg<string>* >(&*pArg);
Arg<UTF8String>* pUTF8StringArg = dynamic_cast<Arg<UTF8String>* >(&*pArg);
Arg<int>* pIntArg = dynamic_cast<Arg<int>* >(&*pArg);
- Arg<double>* pDoubleArg = dynamic_cast<Arg<double>* >(&*pArg);
Arg<float>* pFloatArg = dynamic_cast<Arg<float>* >(&*pArg);
Arg<bool>* pBoolArg = dynamic_cast<Arg<bool>* >(&*pArg);
- Arg<DPoint>* pDPointArg = dynamic_cast<Arg<DPoint>* >(&*pArg);
- Arg<IntTriple>* pIntTripleArg = dynamic_cast<Arg<IntTriple>* >(&*pArg);
- Arg<vector<double> >* pDVectorArg = dynamic_cast<Arg<vector<double> >* >(&*pArg);
- Arg<vector<DPoint> >* pDPointVectorArg =
- dynamic_cast<Arg<vector<DPoint> >* >(&*pArg);
- Arg<vector<IntTriple> >* pIntTripleVectorArg =
- dynamic_cast<Arg<vector<IntTriple> >* >(&*pArg);
-
+ Arg<glm::vec2>* pVec2Arg = dynamic_cast<Arg<glm::vec2>* >(&*pArg);
+ Arg<glm::vec3>* pVec3Arg = dynamic_cast<Arg<glm::vec3>* >(&*pArg);
+ Arg<glm::ivec3>* pIVec3Arg = dynamic_cast<Arg<glm::ivec3>* >(&*pArg);
+ Arg<vector<float> >* pFVectorArg = dynamic_cast<Arg<vector<float> >* >(&*pArg);
+ Arg<vector<int> >* pIVectorArg = dynamic_cast<Arg<vector<int> >* >(&*pArg);
+ Arg<vector<glm::vec2> >* pVec2VectorArg =
+ dynamic_cast<Arg<vector<glm::vec2> >* >(&*pArg);
+ Arg<vector<glm::ivec3> >* pIVec3VectorArg =
+ dynamic_cast<Arg<vector<glm::ivec3> >* >(&*pArg);
+ Arg<CollVec2Vector>* pCollVec2VectorArg =
+ dynamic_cast<Arg<CollVec2Vector>* >(&*pArg);
if (pStringArg) {
pStringArg->setValue(sValue);
} else if (pUTF8StringArg) {
pUTF8StringArg->setValue(sValue);
} else if (pIntArg) {
pIntArg->setValue(stringToInt(sValue));
- } else if (pDoubleArg) {
- pDoubleArg->setValue(stringToDouble(sValue));
} else if (pFloatArg) {
- pFloatArg->setValue(float(stringToDouble(sValue)));
+ pFloatArg->setValue(stringToFloat(sValue));
} else if (pBoolArg) {
pBoolArg->setValue(stringToBool(sValue));
- } else if (pDPointArg) {
- pDPointArg->setValue(stringToDPoint(sValue));
- } else if (pIntTripleArg) {
- pIntTripleArg->setValue(stringToIntTriple(sValue));
- } else if (pDVectorArg) {
- vector<double> v;
+ } else if (pVec2Arg) {
+ pVec2Arg->setValue(stringToVec2(sValue));
+ } else if (pVec3Arg) {
+ pVec3Arg->setValue(stringToVec3(sValue));
+ } else if (pIVec3Arg) {
+ pIVec3Arg->setValue(stringToIVec3(sValue));
+ } else if (pFVectorArg) {
+ vector<float> v;
+ fromString(sValue, v);
+ pFVectorArg->setValue(v);
+ } else if (pIVectorArg) {
+ vector<int> v;
+ fromString(sValue, v);
+ pIVectorArg->setValue(v);
+ } else if (pVec2VectorArg) {
+ vector<glm::vec2> v;
fromString(sValue, v);
- pDVectorArg->setValue(v);
- } else if (pDPointVectorArg) {
- vector<DPoint> v;
+ pVec2VectorArg->setValue(v);
+ } else if (pIVec3VectorArg) {
+ vector<glm::ivec3> v;
fromString(sValue, v);
- pDPointVectorArg->setValue(v);
- } else if (pIntTripleVectorArg) {
- vector<IntTriple> v;
+ pIVec3VectorArg->setValue(v);
+ } else if (pCollVec2VectorArg) {
+ CollVec2Vector v;
fromString(sValue, v);
- pIntTripleVectorArg->setValue(v);
+ pCollVec2VectorArg->setValue(v);
} else {
AVG_ASSERT(false);
}
diff --git a/src/player/ArgList.h b/src/player/ArgList.h
index d04b1d4..5f78114 100644
--- a/src/player/ArgList.h
+++ b/src/player/ArgList.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -38,14 +38,14 @@ namespace avg {
typedef std::map<std::string, ArgBasePtr> ArgMap;
-class Node;
+class ExportedObject;
class AVG_API ArgList
{
public:
ArgList();
ArgList(const ArgList& argTemplates, const xmlNodePtr xmlNode);
- ArgList(const ArgList& argTemplates, const boost::python::dict& PyDict);
+ ArgList(const ArgList& argTemplates, const py::dict& PyDict);
virtual ~ArgList();
bool hasArg(const std::string& sName) const;
@@ -54,7 +54,7 @@ public:
template<class T>
const T& getArgVal(const std::string& sName) const;
- void getOverlayedArgVal(DPoint* pResult, const std::string& sName,
+ void getOverlayedArgVal(glm::vec2* pResult, const std::string& sName,
const std::string& sOverlay1, const std::string& sOverlay2,
const std::string& sID) const;
@@ -62,12 +62,12 @@ public:
void setArg(const ArgBase& newArg);
void setArgs(const ArgList& args);
- void setMembers(Node * pNode) const;
+ void setMembers(ExportedObject * pObj) const;
void copyArgsFrom(const ArgList& argTemplates);
private:
- void setArgValue(const std::string & sName, const boost::python::object& value);
+ void setArgValue(const std::string & sName, const py::object& value);
void setArgValue(const std::string & sName, const std::string & sValue);
ArgMap m_Args;
};
diff --git a/src/player/BitmapManager.cpp b/src/player/BitmapManager.cpp
new file mode 100644
index 0000000..6151f1e
--- /dev/null
+++ b/src/player/BitmapManager.cpp
@@ -0,0 +1,147 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManager.h"
+#include "IBitmapLoadedListener.h"
+
+#ifdef WIN32
+#include <io.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../base/OSHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+BitmapManager * BitmapManager::s_pBitmapManager=0;
+
+BitmapManager::BitmapManager()
+{
+ if (s_pBitmapManager) {
+ throw Exception(AVG_ERR_UNKNOWN, "BitmapMananger has already been instantiated.");
+ }
+
+ m_pCmdQueue = BitmapManagerThread::CQueuePtr(new BitmapManagerThread::CQueue);
+ m_pMsgQueue = BitmapManagerMsgQueuePtr(new BitmapManagerMsgQueue(8));
+
+ startThreads(1);
+
+ s_pBitmapManager = this;
+}
+
+BitmapManager::~BitmapManager()
+{
+ while (!m_pCmdQueue->empty()) {
+ m_pCmdQueue->pop();
+ }
+ while (!m_pMsgQueue->empty()) {
+ m_pMsgQueue->pop();
+ }
+ stopThreads();
+ s_pBitmapManager = 0;
+}
+
+BitmapManager* BitmapManager::get()
+{
+ if (!s_pBitmapManager) {
+ s_pBitmapManager = new BitmapManager();
+ }
+ return s_pBitmapManager;
+}
+
+void BitmapManager::loadBitmapPy(const UTF8String& sUtf8FileName,
+ const boost::python::object& pyFunc, PixelFormat pf)
+{
+ std::string sFileName = convertUTF8ToFilename(sUtf8FileName);
+ BitmapManagerMsgPtr pMsg = BitmapManagerMsgPtr(
+ new BitmapManagerMsg(sUtf8FileName, pyFunc, pf));
+ internalLoadBitmap(pMsg);
+}
+
+void BitmapManager::loadBitmap(const UTF8String& sUtf8FileName,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf)
+{
+ std::string sFileName = convertUTF8ToFilename(sUtf8FileName);
+ BitmapManagerMsgPtr pMsg = BitmapManagerMsgPtr(
+ new BitmapManagerMsg(sUtf8FileName, pLoadedListener, pf));
+ internalLoadBitmap(pMsg);
+}
+
+void BitmapManager::setNumThreads(int numThreads)
+{
+ stopThreads();
+ startThreads(numThreads);
+}
+
+void BitmapManager::onFrameEnd()
+{
+ while (!m_pMsgQueue->empty()) {
+ BitmapManagerMsgPtr pMsg = m_pMsgQueue->pop();
+ pMsg->executeCallback();
+ }
+}
+
+void BitmapManager::internalLoadBitmap(BitmapManagerMsgPtr pMsg)
+{
+#ifdef WIN32
+ int rc = _access(pMsg->getFilename().c_str(), 04);
+#else
+ int rc = access(pMsg->getFilename().c_str(), R_OK);
+#endif
+
+ if (rc != 0) {
+ pMsg->setError(Exception(AVG_ERR_FILEIO,
+ std::string("BitmapManager can't open output file '") +
+ pMsg->getFilename() + "'. Reason: " +
+ strerror(errno)));
+ m_pMsgQueue->push(pMsg);
+ } else {
+ m_pCmdQueue->pushCmd(boost::bind(&BitmapManagerThread::loadBitmap, _1, pMsg));
+ }
+}
+
+void BitmapManager::startThreads(int numThreads)
+{
+ for (int i=0; i<numThreads; ++i) {
+ boost::thread* pThread = new boost::thread(
+ BitmapManagerThread(*m_pCmdQueue, *m_pMsgQueue));
+ m_pBitmapManagerThreads.push_back(pThread);
+ }
+}
+
+void BitmapManager::stopThreads()
+{
+ int numThreads = m_pBitmapManagerThreads.size();
+ for (int i=0; i<numThreads; ++i) {
+ m_pCmdQueue->pushCmd(boost::bind(&BitmapManagerThread::stop, _1));
+ }
+ for (int i=0; i<numThreads; ++i) {
+ boost::thread* pThread = m_pBitmapManagerThreads[i];
+ pThread->join();
+ delete pThread;
+ }
+ m_pBitmapManagerThreads.clear();
+}
+
+}
diff --git a/src/player/BitmapManager.h b/src/player/BitmapManager.h
new file mode 100644
index 0000000..64f8ba5
--- /dev/null
+++ b/src/player/BitmapManager.h
@@ -0,0 +1,66 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManager_H_
+#define _BitmapManager_H_
+
+#include "BitmapManagerThread.h"
+#include "BitmapManagerMsg.h"
+
+#include "../api.h"
+#include "../base/Queue.h"
+#include "../base/IFrameEndListener.h"
+
+#include <boost/thread.hpp>
+
+#include <vector>
+
+namespace avg {
+
+class AVG_API BitmapManager : public IFrameEndListener
+{
+ public:
+ BitmapManager();
+ ~BitmapManager();
+ static BitmapManager* get();
+ void loadBitmapPy(const UTF8String& sUtf8FileName,
+ const boost::python::object& pyFunc, PixelFormat pf=NO_PIXELFORMAT);
+ void loadBitmap(const UTF8String& sUtf8FileName,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf=NO_PIXELFORMAT);
+ void setNumThreads(int numThreads);
+
+ virtual void onFrameEnd();
+
+ private:
+ void internalLoadBitmap(BitmapManagerMsgPtr pMsg);
+ void startThreads(int numThreads);
+ void stopThreads();
+
+ static BitmapManager * s_pBitmapManager;
+
+ std::vector<boost::thread*> m_pBitmapManagerThreads;
+ BitmapManagerThread::CQueuePtr m_pCmdQueue;
+ BitmapManagerMsgQueuePtr m_pMsgQueue;
+};
+
+}
+
+#endif
diff --git a/src/player/BitmapManagerMsg.cpp b/src/player/BitmapManagerMsg.cpp
new file mode 100644
index 0000000..f9dfc53
--- /dev/null
+++ b/src/player/BitmapManagerMsg.cpp
@@ -0,0 +1,121 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManagerMsg.h"
+#include "IBitmapLoadedListener.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+#include "../base/TimeSource.h"
+
+
+namespace avg {
+
+BitmapManagerMsg::BitmapManagerMsg(const UTF8String& sFilename,
+ const boost::python::object& onLoadedCb, PixelFormat pf)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ init(sFilename, pf);
+ m_OnLoadedCb = onLoadedCb;
+ m_pLoadedListener = 0;
+}
+
+BitmapManagerMsg::BitmapManagerMsg(const UTF8String& sFilename,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ init(sFilename, pf);
+ m_OnLoadedCb = boost::python::object();
+ m_pLoadedListener = pLoadedListener;
+}
+
+BitmapManagerMsg::~BitmapManagerMsg()
+{
+ if (m_pEx) {
+ delete m_pEx;
+ }
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void BitmapManagerMsg::init(const UTF8String& sFilename, PixelFormat pf)
+{
+ m_sFilename = sFilename;
+ m_StartTime = TimeSource::get()->getCurrentMicrosecs()/1000.0f;
+ m_PF = pf;
+ m_MsgType = REQUEST;
+ m_pEx = 0;
+}
+
+void BitmapManagerMsg::executeCallback()
+{
+ switch (m_MsgType) {
+ case BITMAP:
+ if (m_pLoadedListener) {
+ m_pLoadedListener->onBitmapLoaded(m_pBmp);
+ } else {
+ boost::python::call<void>(m_OnLoadedCb.ptr(), m_pBmp);
+ }
+ break;
+ case ERROR:
+ if (m_pLoadedListener) {
+ m_pLoadedListener->onBitmapLoadError(m_pEx);
+ } else {
+ boost::python::call<void>(m_OnLoadedCb.ptr(), m_pEx);
+ }
+ break;
+
+ default:
+ AVG_ASSERT(false);
+ }
+}
+
+const UTF8String BitmapManagerMsg::getFilename()
+{
+ return m_sFilename;
+}
+
+float BitmapManagerMsg::getStartTime()
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ return m_StartTime;
+}
+
+PixelFormat BitmapManagerMsg::getPixelFormat()
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ return m_PF;
+}
+
+void BitmapManagerMsg::setBitmap(BitmapPtr pBmp)
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ m_pBmp = pBmp;
+ m_MsgType = BITMAP;
+}
+
+void BitmapManagerMsg::setError(const Exception& ex)
+{
+ AVG_ASSERT(m_MsgType == REQUEST);
+ m_MsgType = ERROR;
+ m_pEx = new Exception(ex);
+}
+
+}
diff --git a/src/player/BitmapManagerMsg.h b/src/player/BitmapManagerMsg.h
new file mode 100644
index 0000000..47ba785
--- /dev/null
+++ b/src/player/BitmapManagerMsg.h
@@ -0,0 +1,76 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManagerMsg_H_
+#define _BitmapManagerMsg_H_
+
+#include "WrapPython.h"
+
+#include "../api.h"
+#include "../base/Queue.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/python.hpp>
+
+
+namespace avg {
+
+class IBitmapLoadedListener;
+
+class AVG_API BitmapManagerMsg
+{
+public:
+ enum MsgType {REQUEST, BITMAP, ERROR};
+
+ BitmapManagerMsg(const UTF8String& sFilename,
+ const boost::python::object& onLoadedCb, PixelFormat pf);
+ BitmapManagerMsg(const UTF8String& sFilename,
+ IBitmapLoadedListener* pLoadedListener, PixelFormat pf);
+ virtual ~BitmapManagerMsg();
+ void init(const UTF8String& sFilename, PixelFormat pf);
+
+ void executeCallback();
+ const UTF8String getFilename();
+ float getStartTime();
+ PixelFormat getPixelFormat();
+ void setBitmap(BitmapPtr pBmp);
+ void setError(const Exception& ex);
+
+ MsgType getType() { return m_MsgType; };
+
+private:
+ UTF8String m_sFilename;
+ float m_StartTime;
+ BitmapPtr m_pBmp;
+ boost::python::object m_OnLoadedCb;
+ IBitmapLoadedListener* m_pLoadedListener;
+ PixelFormat m_PF;
+ MsgType m_MsgType;
+ Exception* m_pEx;
+};
+
+typedef boost::shared_ptr<BitmapManagerMsg> BitmapManagerMsgPtr;
+typedef Queue<BitmapManagerMsg> BitmapManagerMsgQueue;
+typedef boost::shared_ptr<BitmapManagerMsgQueue> BitmapManagerMsgQueuePtr;
+}
+
+#endif
diff --git a/src/player/BitmapManagerThread.cpp b/src/player/BitmapManagerThread.cpp
new file mode 100644
index 0000000..42372a6
--- /dev/null
+++ b/src/player/BitmapManagerThread.cpp
@@ -0,0 +1,78 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "BitmapManagerThread.h"
+
+#include "../base/Exception.h"
+#include "../base/ScopeTimer.h"
+#include "../base/TimeSource.h"
+
+#include "../graphics/BitmapLoader.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace avg {
+
+BitmapManagerThread::BitmapManagerThread(CQueue& cmdQ, BitmapManagerMsgQueue& MsgQueue)
+ : WorkerThread<BitmapManagerThread>("BitmapManager", cmdQ),
+ m_MsgQueue(MsgQueue),
+ m_TotalLatency(0),
+ m_NumBmpsLoaded(0)
+{
+}
+
+bool BitmapManagerThread::work()
+{
+ waitForCommand();
+ return true;
+}
+
+void BitmapManagerThread::deinit()
+{
+ if (m_NumBmpsLoaded > 0) {
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Average latency for async bitmap loads: " << m_TotalLatency/m_NumBmpsLoaded
+ << " ms");
+ }
+}
+
+static ProfilingZoneID LoaderProfilingZone("loadBitmap", true);
+
+void BitmapManagerThread::loadBitmap(BitmapManagerMsgPtr pRequest)
+{
+ BitmapPtr pBmp;
+ ScopeTimer timer(LoaderProfilingZone);
+ float startTime = pRequest->getStartTime();
+ try {
+ pBmp = avg::loadBitmap(pRequest->getFilename(), pRequest->getPixelFormat());
+ pRequest->setBitmap(pBmp);
+ } catch (const Exception& ex) {
+ pRequest->setError(ex);
+ }
+ m_MsgQueue.push(pRequest);
+ m_NumBmpsLoaded++;
+ float curLatency = TimeSource::get()->getCurrentMicrosecs()/1000 - startTime;
+ m_TotalLatency += curLatency;
+ ThreadProfiler::get()->reset();
+}
+
+}
diff --git a/src/player/BitmapManagerThread.h b/src/player/BitmapManagerThread.h
new file mode 100644
index 0000000..fbc5c56
--- /dev/null
+++ b/src/player/BitmapManagerThread.h
@@ -0,0 +1,55 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _BitmapManagerThread_H_
+#define _BitmapManagerThread_H_
+
+#include "../api.h"
+
+#include "BitmapManagerMsg.h"
+
+#include "../base/WorkerThread.h"
+#include "../graphics/Bitmap.h"
+
+#include <boost/thread.hpp>
+
+
+namespace avg {
+
+class AVG_API BitmapManagerThread : public WorkerThread<BitmapManagerThread>
+{
+ public:
+ BitmapManagerThread(CQueue& cmdQ, BitmapManagerMsgQueue& MsgQueue);
+
+ void loadBitmap(BitmapManagerMsgPtr pRequest);
+
+ private:
+ virtual bool work();
+ virtual void deinit();
+ BitmapManagerMsgQueue& m_MsgQueue;
+
+ float m_TotalLatency;
+ int m_NumBmpsLoaded;
+};
+
+}
+
+#endif
diff --git a/src/player/BlurFXNode.cpp b/src/player/BlurFXNode.cpp
index 3a0ad19..16583a8 100644
--- a/src/player/BlurFXNode.cpp
+++ b/src/player/BlurFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"
-#include "../graphics/ShaderRegistry.h"
#include <string>
@@ -31,9 +30,9 @@ using namespace std;
namespace avg {
-BlurFXNode::BlurFXNode()
- : FXNode(),
- m_StdDev(1)
+BlurFXNode::BlurFXNode(float radius)
+ : FXNode(false),
+ m_StdDev(radius)
{
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -45,10 +44,6 @@ BlurFXNode::~BlurFXNode()
void BlurFXNode::connect()
{
- if (!GLTexture::isFloatFormatSupported()) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "Cannot create BlurFX: OpenGL configuration doesn't support Blur (no float textures).");
- }
setDirty();
FXNode::connect();
}
@@ -59,12 +54,7 @@ void BlurFXNode::disconnect()
FXNode::disconnect();
}
-void BlurFXNode::setParam(double stdDev)
-{
- setRadius(stdDev);
-}
-
-void BlurFXNode::setRadius(double stdDev)
+void BlurFXNode::setRadius(float stdDev)
{
m_StdDev = stdDev;
if (m_pFilter) {
@@ -73,7 +63,7 @@ void BlurFXNode::setRadius(double stdDev)
setDirty();
}
-double BlurFXNode::getRadius() const
+float BlurFXNode::getRadius() const
{
return m_StdDev;
}
diff --git a/src/player/BlurFXNode.h b/src/player/BlurFXNode.h
index 62eb535..24b5f8c 100644
--- a/src/player/BlurFXNode.h
+++ b/src/player/BlurFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -33,22 +33,21 @@ namespace avg {
class AVG_API BlurFXNode: public FXNode {
public:
- BlurFXNode();
+ BlurFXNode(float radius=1.f);
virtual ~BlurFXNode();
void connect();
virtual void disconnect();
- void setParam(double stdDev);
- void setRadius(double stdDev);
- double getRadius() const;
+ void setRadius(float stdDev);
+ float getRadius() const;
private:
virtual GPUFilterPtr createFilter(const IntPoint& size);
GPUBlurFilterPtr m_pFilter;
- double m_StdDev;
+ float m_StdDev;
};
typedef boost::shared_ptr<BlurFXNode> BlurFXNodePtr;
diff --git a/src/player/BoostPython.h b/src/player/BoostPython.h
index db1c0c5..6fdc141 100644
--- a/src/player/BoostPython.h
+++ b/src/player/BoostPython.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,8 @@
#include "../api.h"
#include <boost/python.hpp>
+namespace py = boost::python;
+
#ifdef _WIN32
#pragma warning(pop)
#endif
diff --git a/src/player/CameraNode.cpp b/src/player/CameraNode.cpp
index 8f08dfa..c091a4e 100644
--- a/src/player/CameraNode.cpp
+++ b/src/player/CameraNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "CameraNode.h"
#include "OGLSurface.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/Logger.h"
#include "../base/Exception.h"
@@ -31,6 +31,7 @@
#include "../graphics/Filterfill.h"
#include "../graphics/TextureMover.h"
#include "../graphics/GLTexture.h"
+#include "../graphics/BitmapLoader.h"
#include "../imaging/Camera.h"
#include "../imaging/FWCamera.h"
@@ -46,15 +47,15 @@ using namespace std;
namespace avg {
-NodeDefinition CameraNode::createDefinition()
+void CameraNode::registerType()
{
- return NodeDefinition("camera", Node::buildNode<CameraNode>)
- .extendDefinition(RasterNode::createDefinition())
+ TypeDefinition def = TypeDefinition("camera", "rasternode",
+ ExportedObject::buildObject<CameraNode>)
.addArg(Arg<string>("driver", "firewire"))
.addArg(Arg<string>("device", ""))
.addArg(Arg<int>("unit", -1))
.addArg(Arg<bool>("fw800", false))
- .addArg(Arg<double>("framerate", 15))
+ .addArg(Arg<float>("framerate", 15))
.addArg(Arg<int>("capturewidth", 640))
.addArg(Arg<int>("captureheight", 480))
.addArg(Arg<string>("pixelformat", "RGB"))
@@ -66,6 +67,7 @@ NodeDefinition CameraNode::createDefinition()
.addArg(Arg<int>("shutter", -1))
.addArg(Arg<int>("gain", -1))
.addArg(Arg<int>("strobeduration", -1));
+ TypeRegistry::get()->registerType(def);
}
CameraNode::CameraNode(const ArgList& args)
@@ -79,7 +81,7 @@ CameraNode::CameraNode(const ArgList& args)
string sDevice = args.getArgVal<string>("device");
int unit = args.getArgVal<int>("unit");
bool bFW800 = args.getArgVal<bool>("fw800");
- double frameRate = args.getArgVal<double>("framerate");
+ float frameRate = args.getArgVal<float>("framerate");
int width = args.getArgVal<int>("capturewidth");
int height = args.getArgVal<int>("captureheight");
string sPF = args.getArgVal<string>("pixelformat");
@@ -90,7 +92,11 @@ CameraNode::CameraNode(const ArgList& args)
}
PixelFormat destPF;
if (pixelFormatIsColored(camPF)) {
- destPF = B8G8R8X8;
+ if (BitmapLoader::get()->isBlueFirst()) {
+ destPF = B8G8R8X8;
+ } else {
+ destPF = R8G8B8X8;
+ }
} else {
destPF = I8;
}
@@ -98,8 +104,8 @@ CameraNode::CameraNode(const ArgList& args)
m_pCamera = createCamera(sDriver, sDevice, unit, bFW800, IntPoint(width, height),
camPF, destPF, frameRate);
- AVG_TRACE(Logger::CONFIG, "Got Camera " << m_pCamera->getDevice() << " from driver: "
- << m_pCamera->getDriverName());
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO, "Got Camera " <<
+ m_pCamera->getDevice() << " from driver: " << m_pCamera->getDriverName());
m_pCamera->setFeature(CAM_FEATURE_BRIGHTNESS, args.getArgVal<int>("brightness"));
m_pCamera->setFeature(CAM_FEATURE_EXPOSURE, args.getArgVal<int>("exposure"));
@@ -273,9 +279,10 @@ BitmapPtr CameraNode::getBitmap()
}
}
-void CameraNode::dumpCameras()
+CamerasInfosVector CameraNode::getCamerasInfos()
{
- avg::dumpCameras();
+ CamerasInfosVector camInfos = avg::getCamerasInfos();
+ return camInfos;
}
void CameraNode::resetFirewireBus()
@@ -283,7 +290,7 @@ void CameraNode::resetFirewireBus()
FWCamera::resetBus();
}
-double CameraNode::getFPS() const
+float CameraNode::getFPS() const
{
return m_pCamera->getFrameRate();
}
@@ -298,6 +305,7 @@ void CameraNode::open()
m_pTex = GLTexturePtr(new GLTexture(size, pf, bMipmap));
m_pTex->enableStreaming();
getSurface()->create(pf, m_pTex);
+ newSurface();
BitmapPtr pBmp = m_pTex->lockStreamingBmp();
if (pf == B8G8R8X8 || pf == B8G8R8A8) {
@@ -308,6 +316,7 @@ void CameraNode::open()
Filter.applyInPlace(pBmp);
}
m_pTex->unlockStreamingBmp(true);
+ setupFX(true);
}
int CameraNode::getFeature(CameraFeature feature) const
@@ -328,9 +337,10 @@ int CameraNode::getFrameNum() const
static ProfilingZoneID CameraFetchImage("Camera fetch image");
static ProfilingZoneID CameraDownloadProfilingZone("Camera tex download");
-void CameraNode::preRender()
+void CameraNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
if (isAutoUpdateCameraImage()) {
ScopeTimer Timer(CameraFetchImage);
updateToLatestCameraImage();
@@ -346,19 +356,19 @@ void CameraNode::preRender()
AVG_ASSERT(pBmp->getPixelFormat() == m_pCurBmp->getPixelFormat());
pBmp->copyPixels(*m_pCurBmp);
m_pTex->unlockStreamingBmp(true);
- bind();
renderFX(getSize(), Pixel32(255, 255, 255, 255), false);
m_bNewBmp = false;
}
+ calcVertexArray(pVA);
}
static ProfilingZoneID CameraProfilingZone("Camera::render");
-void CameraNode::render(const DRect& rect)
+void CameraNode::render()
{
if (m_bIsPlaying) {
ScopeTimer Timer(CameraProfilingZone);
- blt32(getSize(), getEffectiveOpacity(), getBlendMode());
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
}
}
@@ -381,7 +391,7 @@ void CameraNode::updateCameraImage()
{
if (!isAutoUpdateCameraImage()) {
m_pCurBmp = m_pCamera->getImage(false);
- blt32(getSize(), getEffectiveOpacity(), getBlendMode());
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
}
}
diff --git a/src/player/CameraNode.h b/src/player/CameraNode.h
index 874593b..1aef572 100644
--- a/src/player/CameraNode.h
+++ b/src/player/CameraNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,7 @@
#include "RasterNode.h"
#include "../imaging/Camera.h"
+#include "../imaging/CameraInfo.h"
#include <boost/thread/thread.hpp>
@@ -38,11 +39,12 @@ namespace avg {
class TextureMover;
typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
+typedef std::vector<CameraInfo> CamerasInfosVector;
class AVG_API CameraNode : public RasterNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
CameraNode(const ArgList& args);
virtual ~CameraNode();
@@ -65,7 +67,7 @@ class AVG_API CameraNode : public RasterNode
return m_pCamera->getDriverName();
}
- double getFrameRate() const
+ float getFrameRate() const
{
return m_pCamera->getFrameRate();
}
@@ -94,21 +96,22 @@ class AVG_API CameraNode : public RasterNode
void setAutoUpdateCameraImage(bool bVal);
bool isImageAvailable() const;
- virtual void preRender();
- virtual void render(const DRect& Rect);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
int getFrameNum() const;
IntPoint getMediaSize();
virtual BitmapPtr getBitmap();
- static void dumpCameras();
+ static CamerasInfosVector getCamerasInfos();
static void resetFirewireBus();
private:
int getFeature (CameraFeature feature) const;
void setFeature (CameraFeature feature, int value);
- virtual double getFPS() const;
+ virtual float getFPS() const;
virtual void open();
virtual PixelFormat getPixelFormat();
void setFeature(int FeatureID);
diff --git a/src/player/Canvas.cpp b/src/player/Canvas.cpp
index 0a21f8a..ae0723e 100644
--- a/src/player/Canvas.cpp
+++ b/src/player/Canvas.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,8 @@
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
+#include "../graphics/StandardShader.h"
+
#include <iostream>
using namespace std;
@@ -37,8 +39,6 @@ using namespace boost;
namespace avg {
-CanvasPtr Canvas::s_pActiveCanvas;
-
Canvas::Canvas(Player * pPlayer)
: m_pPlayer(pPlayer),
m_bIsPlaying(false),
@@ -57,8 +57,8 @@ void Canvas::setRoot(NodePtr pRootNode)
{
assert(!m_pRootNode);
m_pRootNode = dynamic_pointer_cast<CanvasNode>(pRootNode);
- m_pRootNode->setParent(DivNodeWeakPtr(), Node::NS_CONNECTED,
- shared_from_this());
+ CanvasPtr pThis = dynamic_pointer_cast<Canvas>(shared_from_this());
+ m_pRootNode->setParent(0, Node::NS_CONNECTED, pThis);
registerNode(m_pRootNode);
}
@@ -67,16 +67,20 @@ void Canvas::initPlayback(int multiSampleSamples)
m_bIsPlaying = true;
m_pRootNode->connectDisplay();
m_MultiSampleSamples = multiSampleSamples;
+ m_pVertexArray = VertexArrayPtr(new VertexArray(2000, 3000));
}
-void Canvas::stopPlayback()
+void Canvas::stopPlayback(bool bIsAbort)
{
if (m_bIsPlaying) {
- m_PlaybackEndSignal.emit();
+ if (!bIsAbort) {
+ m_PlaybackEndSignal.emit();
+ }
m_pRootNode->disconnect(true);
m_pRootNode = CanvasNodePtr();
m_IDMap.clear();
m_bIsPlaying = false;
+ m_pVertexArray = VertexArrayPtr();
}
}
@@ -85,7 +89,6 @@ NodePtr Canvas::getElementByID(const std::string& id)
if (m_IDMap.find(id) != m_IDMap.end()) {
return m_IDMap.find(id)->second;
} else {
- AVG_TRACE(Logger::WARNING, "getElementByID(\"" << id << "\") failed.");
return NodePtr();
}
}
@@ -138,25 +141,26 @@ static ProfilingZoneID RenderProfilingZone("Render");
void Canvas::doFrame(bool bPythonAvailable)
{
- s_pActiveCanvas = shared_from_this();
emitPreRenderSignal();
if (!m_pPlayer->isStopping()) {
ScopeTimer Timer(RenderProfilingZone);
+ Player::get()->startTraversingTree();
if (bPythonAvailable) {
Py_BEGIN_ALLOW_THREADS;
try {
- render();
+ renderTree();
} catch(...) {
Py_BLOCK_THREADS;
+ Player::get()->endTraversingTree();
throw;
}
Py_END_ALLOW_THREADS;
} else {
- render();
+ renderTree();
}
+ Player::get()->endTraversingTree();
}
emitFrameEndSignal();
- s_pActiveCanvas = CanvasPtr();
}
IntPoint Canvas::getSize() const
@@ -165,20 +169,20 @@ IntPoint Canvas::getSize() const
}
static ProfilingZoneID PushClipRectProfilingZone("pushClipRect");
-void Canvas::pushClipRect(VertexArrayPtr pVA)
+void Canvas::pushClipRect(const glm::mat4& transform, SubVertexArray& va)
{
ScopeTimer timer(PushClipRectProfilingZone);
m_ClipLevel++;
- clip(pVA, GL_INCR);
+ clip(transform, va, GL_INCR);
}
static ProfilingZoneID PopClipRectProfilingZone("popClipRect");
-void Canvas::popClipRect(VertexArrayPtr pVA)
+void Canvas::popClipRect(const glm::mat4& transform, SubVertexArray& va)
{
ScopeTimer timer(PopClipRectProfilingZone);
m_ClipLevel--;
- clip(pVA, GL_DECR);
+ clip(transform, va, GL_DECR);
}
void Canvas::registerPlaybackEndListener(IPlaybackEndListener* pListener)
@@ -211,102 +215,69 @@ void Canvas::unregisterPreRenderListener(IPreRenderListener* pListener)
m_PreRenderSignal.disconnect(pListener);
}
-bool Canvas::operator ==(const Canvas& other) const
-{
- return this == &other;
-}
-
-bool Canvas::operator !=(const Canvas& other) const
-{
- return this != &other;
-}
-
-long Canvas::getHash() const
-{
- return long(this);
-}
-
-CanvasPtr Canvas::getActive()
-{
- return s_pActiveCanvas;
-}
-
Player* Canvas::getPlayer() const
{
return m_pPlayer;
}
-vector<NodeWeakPtr> Canvas::getElementsByPos(const DPoint& pos) const
+vector<NodePtr> Canvas::getElementsByPos(const glm::vec2& pos) const
{
- vector<NodeWeakPtr> elements;
+ vector<NodePtr> elements;
m_pRootNode->getElementsByPos(pos, elements);
return elements;
}
static ProfilingZoneID PreRenderProfilingZone("PreRender");
+static ProfilingZoneID VATransferProfilingZone("VA Transfer");
-void Canvas::render(IntPoint windowSize, bool bUpsideDown, FBOPtr pFBO,
- ProfilingZoneID& renderProfilingZone)
+void Canvas::preRender()
{
+ ScopeTimer Timer(PreRenderProfilingZone);
+ m_pVertexArray->reset();
+ m_pRootNode->preRender(m_pVertexArray, true, 1.0f);
{
- ScopeTimer Timer(PreRenderProfilingZone);
- m_pRootNode->preRender();
- }
- if (pFBO) {
- pFBO->activate();
- } else {
- glproc::BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "Canvas::render: BindFramebuffer()");
- }
- if (m_MultiSampleSamples > 1) {
- glEnable(GL_MULTISAMPLE);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "Canvas::render: glEnable(GL_MULTISAMPLE)");
- } else {
- glDisable(GL_MULTISAMPLE);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "Canvas::render: glDisable(GL_MULTISAMPLE)");
+ ScopeTimer Timer(VATransferProfilingZone);
+ m_pVertexArray->update();
}
- clearGLBuffers(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void Canvas::render(IntPoint windowSize, bool bOffscreen)
+{
+ clearGLBuffers(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ !bOffscreen);
glViewport(0, 0, windowSize.x, windowSize.y);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "Canvas::render: glViewport()");
- glMatrixMode(GL_PROJECTION);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "Canvas::render: glMatrixMode()");
- glLoadIdentity();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "Canvas::render: glLoadIdentity()");
- IntPoint size = IntPoint(m_pRootNode->getSize());
- if (bUpsideDown) {
- gluOrtho2D(0, size.x, 0, size.y);
+ GLContext::checkError("Canvas::render: glViewport()");
+ glm::vec2 size = m_pRootNode->getSize();
+ glm::mat4 projMat;
+ if (bOffscreen) {
+ projMat = glm::ortho(0.f, size.x, 0.f, size.y);
} else {
- gluOrtho2D(0, size.x, size.y, 0);
+ projMat = glm::ortho(0.f, size.x, size.y, 0.f);
}
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "Canvas::render: gluOrtho2D()");
-
- const DRect rc(0,0, size.x, size.y);
- glMatrixMode(GL_MODELVIEW);
- {
- ScopeTimer Timer(renderProfilingZone);
- m_pRootNode->maybeRender(rc);
+ m_pVertexArray->activate();
+ m_pRootNode->maybeRender(projMat);
- renderOutlines();
- }
+ renderOutlines(projMat);
}
-void Canvas::renderOutlines()
+void Canvas::renderOutlines(const glm::mat4& transform)
{
- GLContext* pContext = GLContext::getCurrent();
+ GLContext* pContext = GLContext::getMain();
VertexArrayPtr pVA(new VertexArray);
pContext->setBlendMode(GLContext::BLEND_BLEND, false);
m_pRootNode->renderOutlines(pVA, Pixel32(0,0,0,0));
- if (pVA->getCurVert() != 0) {
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pShader->setTransform(transform);
+ pShader->setUntextured();
+ pShader->setAlpha(0.5f);
+ pShader->activate();
+ if (pVA->getNumVerts() != 0) {
pVA->update();
- pContext->enableTexture(false);
- pContext->enableGLColorArray(true);
pVA->draw();
}
}
-void Canvas::clip(VertexArrayPtr pVA, GLenum stencilOp)
+void Canvas::clip(const glm::mat4& transform, SubVertexArray& va, GLenum stencilOp)
{
// Disable drawing to color buffer
glColorMask(0, 0, 0, 0);
@@ -318,7 +289,11 @@ void Canvas::clip(VertexArrayPtr pVA, GLenum stencilOp)
glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(stencilOp, stencilOp, stencilOp);
- pVA->draw();
+ StandardShaderPtr pShader = GLContext::getMain()->getStandardShader();
+ pShader->setUntextured();
+ pShader->setTransform(transform);
+ pShader->activate();
+ va.draw();
// Set stencil test to only let
glStencilFunc(GL_LEQUAL, m_ClipLevel, ~0);
diff --git a/src/player/Canvas.h b/src/player/Canvas.h
index a5e30ac..38259a5 100644
--- a/src/player/Canvas.h
+++ b/src/player/Canvas.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,13 +21,16 @@
#ifndef _Canvas_H_
#define _Canvas_H_
-
+
#include "../api.h"
+#include "FontStyle.h"
+
#include "../base/IPlaybackEndListener.h"
#include "../base/IFrameEndListener.h"
#include "../base/IPreRenderListener.h"
#include "../base/Signal.h"
+#include "../base/GLMHelper.h"
#include "../graphics/OGLHelper.h"
#include "../graphics/Bitmap.h"
@@ -48,9 +51,9 @@ class ProfilingZoneID;
class Canvas;
class FBO;
class VertexArray;
+class SubVertexArray;
typedef boost::shared_ptr<Node> NodePtr;
-typedef boost::weak_ptr<Node> NodeWeakPtr;
typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
typedef boost::shared_ptr<FBO> FBOPtr;
typedef boost::shared_ptr<VertexArray> VertexArrayPtr;
@@ -59,14 +62,14 @@ class Canvas;
typedef boost::shared_ptr<Canvas> CanvasPtr;
typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
-class AVG_API Canvas: public boost::enable_shared_from_this<Canvas>
+class AVG_API Canvas: public ExportedObject
{
public:
Canvas(Player * pPlayer);
virtual ~Canvas();
virtual void setRoot(NodePtr pRootNode);
void initPlayback(int multiSampleSamples);
- virtual void stopPlayback();
+ virtual void stopPlayback(bool bIsAbort);
CanvasNodePtr getRootNode() const;
NodePtr getElementByID(const std::string& id);
@@ -76,8 +79,8 @@ class AVG_API Canvas: public boost::enable_shared_from_this<Canvas>
virtual void doFrame(bool bPythonAvailable);
IntPoint getSize() const;
virtual BitmapPtr screenshot() const = 0;
- virtual void pushClipRect(VertexArrayPtr pVA);
- virtual void popClipRect(VertexArrayPtr pVA);
+ virtual void pushClipRect(const glm::mat4& transform, SubVertexArray& va);
+ virtual void popClipRect(const glm::mat4& transform, SubVertexArray& va);
void registerPlaybackEndListener(IPlaybackEndListener* pListener);
void unregisterPlaybackEndListener(IPlaybackEndListener* pListener);
@@ -86,30 +89,25 @@ class AVG_API Canvas: public boost::enable_shared_from_this<Canvas>
void registerPreRenderListener(IPreRenderListener* pListener);
void unregisterPreRenderListener(IPreRenderListener* pListener);
- std::vector<NodeWeakPtr> getElementsByPos(const DPoint& Pos) const;
-
- bool operator ==(const Canvas& other) const;
- bool operator !=(const Canvas& other) const;
- long getHash() const;
+ std::vector<NodePtr> getElementsByPos(const glm::vec2& Pos) const;
- static CanvasPtr getActive();
+ virtual void render(IntPoint windowSize, bool bOffscreen);
protected:
Player * getPlayer() const;
- void render(IntPoint windowSize, bool bUpsideDown, FBOPtr pFBO,
- ProfilingZoneID& renderProfilingZone);
+ void preRender();
void emitPreRenderSignal();
void emitFrameEndSignal();
-
private:
- virtual void render()=0;
- void renderOutlines();
+ virtual void renderTree()=0;
+ void renderOutlines(const glm::mat4& transform);
- void clip(VertexArrayPtr pVA, GLenum stencilOp);
+ void clip(const glm::mat4& transform, SubVertexArray& va, GLenum stencilOp);
Player * m_pPlayer;
CanvasNodePtr m_pRootNode;
bool m_bIsPlaying;
+ VertexArrayPtr m_pVertexArray;
typedef std::map<std::string, NodePtr> NodeIDMap;
NodeIDMap m_IDMap;
@@ -120,8 +118,6 @@ class AVG_API Canvas: public boost::enable_shared_from_this<Canvas>
int m_MultiSampleSamples;
int m_ClipLevel;
-
- static CanvasPtr s_pActiveCanvas;
};
}
diff --git a/src/player/CanvasNode.cpp b/src/player/CanvasNode.cpp
index cfa836e..3c267d3 100644
--- a/src/player/CanvasNode.cpp
+++ b/src/player/CanvasNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
#include "CanvasNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/FileHelper.h"
#include "../base/Exception.h"
@@ -31,17 +31,18 @@ using namespace std;
namespace avg {
-NodeDefinition CanvasNode::createDefinition()
+void CanvasNode::registerType()
{
- return NodeDefinition("canvasbase", Node::buildNode<CanvasNode>)
- .extendDefinition(DivNode::createDefinition());
+ TypeDefinition def = TypeDefinition("canvasbase", "div",
+ ExportedObject::buildObject<CanvasNode>);
+ TypeRegistry::get()->registerType(def);
}
CanvasNode::CanvasNode(const ArgList& args)
: DivNode(args)
{
args.setMembers(this);
- if (getSize() == DPoint(0, 0)) {
+ if (getSize() == glm::vec2(0, 0)) {
throw (Exception(AVG_ERR_OUT_OF_RANGE,
"<avg> and <canvas> node width and height attributes are mandatory."));
}
diff --git a/src/player/CanvasNode.h b/src/player/CanvasNode.h
index eaf361d..b336a4a 100644
--- a/src/player/CanvasNode.h
+++ b/src/player/CanvasNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,12 +32,13 @@ namespace avg {
class AVG_API CanvasNode : public DivNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
CanvasNode(const ArgList& args);
virtual ~CanvasNode();
virtual std::string getEffectiveMediaDir();
+
};
typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
diff --git a/src/player/ChromaKeyFXNode.cpp b/src/player/ChromaKeyFXNode.cpp
index f243ba2..4e70454 100644
--- a/src/player/ChromaKeyFXNode.cpp
+++ b/src/player/ChromaKeyFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
#include "ChromaKeyFXNode.h"
#include "../base/ObjectCounter.h"
-#include "../graphics/ShaderRegistry.h"
#include <string>
@@ -31,7 +30,7 @@ using namespace std;
namespace avg {
ChromaKeyFXNode::ChromaKeyFXNode()
- : FXNode(),
+ : FXNode(false),
m_sColorName("00FF00"),
m_Color(0, 255, 0),
m_HTolerance(0.0),
@@ -68,46 +67,46 @@ const std::string& ChromaKeyFXNode::getColor() const
return m_sColorName;
}
-void ChromaKeyFXNode::setHTolerance(double tolerance)
+void ChromaKeyFXNode::setHTolerance(float tolerance)
{
m_HTolerance = tolerance;
updateFilter();
}
-double ChromaKeyFXNode::getHTolerance() const
+float ChromaKeyFXNode::getHTolerance() const
{
return m_HTolerance;
}
-void ChromaKeyFXNode::setSTolerance(double tolerance)
+void ChromaKeyFXNode::setSTolerance(float tolerance)
{
m_STolerance = tolerance;
updateFilter();
}
-double ChromaKeyFXNode::getSTolerance() const
+float ChromaKeyFXNode::getSTolerance() const
{
return m_STolerance;
}
-void ChromaKeyFXNode::setLTolerance(double tolerance)
+void ChromaKeyFXNode::setLTolerance(float tolerance)
{
m_LTolerance = tolerance;
updateFilter();
}
-double ChromaKeyFXNode::getLTolerance() const
+float ChromaKeyFXNode::getLTolerance() const
{
return m_LTolerance;
}
-void ChromaKeyFXNode::setSoftness(double softness)
+void ChromaKeyFXNode::setSoftness(float softness)
{
m_Softness = softness;
updateFilter();
}
-double ChromaKeyFXNode::getSoftness() const
+float ChromaKeyFXNode::getSoftness() const
{
return m_Softness;
}
@@ -123,20 +122,20 @@ int ChromaKeyFXNode::getErosion() const
return m_Erosion;
}
-void ChromaKeyFXNode::setSpillThreshold(double spillThreshold)
+void ChromaKeyFXNode::setSpillThreshold(float spillThreshold)
{
m_SpillThreshold = spillThreshold;
updateFilter();
}
-double ChromaKeyFXNode::getSpillThreshold() const
+float ChromaKeyFXNode::getSpillThreshold() const
{
return m_SpillThreshold;
}
GPUFilterPtr ChromaKeyFXNode::createFilter(const IntPoint& size)
{
- m_pFilter = GPUChromaKeyFilterPtr(new GPUChromaKeyFilter(size, B8G8R8A8, false));
+ m_pFilter = GPUChromaKeyFilterPtr(new GPUChromaKeyFilter(size, false));
m_pFilter->setParams(m_Color, m_HTolerance, m_STolerance, m_LTolerance, m_Softness,
m_Erosion, m_SpillThreshold);
setDirty();
diff --git a/src/player/ChromaKeyFXNode.h b/src/player/ChromaKeyFXNode.h
index c8cbe33..3653448 100644
--- a/src/player/ChromaKeyFXNode.h
+++ b/src/player/ChromaKeyFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -40,18 +40,18 @@ public:
void setColor(const std::string& sColorName);
const std::string& getColor() const;
- void setHTolerance(double tolerance);
- double getHTolerance() const;
- void setSTolerance(double tolerance);
- double getSTolerance() const;
- void setLTolerance(double tolerance);
- double getLTolerance() const;
- void setSoftness(double softness);
- double getSoftness() const;
+ void setHTolerance(float tolerance);
+ float getHTolerance() const;
+ void setSTolerance(float tolerance);
+ float getSTolerance() const;
+ void setLTolerance(float tolerance);
+ float getLTolerance() const;
+ void setSoftness(float softness);
+ float getSoftness() const;
void setErosion(int erosion);
int getErosion() const;
- void setSpillThreshold(double spillThreshold);
- double getSpillThreshold() const;
+ void setSpillThreshold(float spillThreshold);
+ float getSpillThreshold() const;
private:
virtual GPUFilterPtr createFilter(const IntPoint& size);
@@ -61,12 +61,12 @@ private:
std::string m_sColorName;
Pixel32 m_Color;
- double m_HTolerance;
- double m_STolerance;
- double m_LTolerance;
- double m_Softness;
+ float m_HTolerance;
+ float m_STolerance;
+ float m_LTolerance;
+ float m_Softness;
int m_Erosion;
- double m_SpillThreshold;
+ float m_SpillThreshold;
};
typedef boost::shared_ptr<ChromaKeyFXNode> ChromaKeyFXNodePtr;
diff --git a/src/player/CircleNode.cpp b/src/player/CircleNode.cpp
index 1691d4d..8d00a8e 100644
--- a/src/player/CircleNode.cpp
+++ b/src/player/CircleNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,9 +21,10 @@
#include "CircleNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/Exception.h"
+#include "../base/MathHelper.h"
#include <iostream>
#include <sstream>
@@ -32,15 +33,16 @@ using namespace std;
namespace avg {
-NodeDefinition CircleNode::createDefinition()
+void CircleNode::registerType()
{
- return NodeDefinition("circle", Node::buildNode<CircleNode>)
- .extendDefinition(FilledVectorNode::createDefinition())
- .addArg(Arg<DPoint>("pos", DPoint(0,0), false, offsetof(CircleNode, m_Pos)))
- .addArg(Arg<double>("r", 1, false, offsetof(CircleNode, m_Radius)))
- .addArg(Arg<double>("texcoord1", 0, false, offsetof(CircleNode, m_TC1)))
- .addArg(Arg<double>("texcoord2", 1, false, offsetof(CircleNode, m_TC2)))
+ TypeDefinition def = TypeDefinition("circle", "filledvectornode",
+ ExportedObject::buildObject<CircleNode>)
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0,0), false, offsetof(CircleNode, m_Pos)))
+ .addArg(Arg<float>("r", 1, false, offsetof(CircleNode, m_Radius)))
+ .addArg(Arg<float>("texcoord1", 0, false, offsetof(CircleNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, false, offsetof(CircleNode, m_TC2)))
;
+ TypeRegistry::get()->registerType(def);
}
CircleNode::CircleNode(const ArgList& args)
@@ -53,23 +55,23 @@ CircleNode::~CircleNode()
{
}
-const DPoint& CircleNode::getPos() const
+const glm::vec2& CircleNode::getPos() const
{
return m_Pos;
}
-void CircleNode::setPos(const DPoint& pt)
+void CircleNode::setPos(const glm::vec2& pt)
{
m_Pos = pt;
setDrawNeeded();
}
-double CircleNode::getR() const
+float CircleNode::getR() const
{
return m_Radius;
}
-void CircleNode::setR(double r)
+void CircleNode::setR(float r)
{
if (int(r) <= 0) {
throw Exception(AVG_ERR_OUT_OF_RANGE, "Circle radius must be a positive number.");
@@ -78,189 +80,191 @@ void CircleNode::setR(double r)
setDrawNeeded();
}
-double CircleNode::getTexCoord1() const
+float CircleNode::getTexCoord1() const
{
return m_TC1;
}
-void CircleNode::setTexCoord1(double tc)
+void CircleNode::setTexCoord1(float tc)
{
m_TC1 = tc;
setDrawNeeded();
}
-double CircleNode::getTexCoord2() const
+float CircleNode::getTexCoord2() const
{
return m_TC2;
}
-void CircleNode::setTexCoord2(double tc)
+void CircleNode::setTexCoord2(float tc)
{
m_TC2 = tc;
setDrawNeeded();
}
-void CircleNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void CircleNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
- if (calcDist(pos, m_Pos) <= m_Radius && reactsToMouseEvents()) {
- pElements.push_back(shared_from_this());
+ if (glm::length(pos-m_Pos) <= m_Radius && reactsToMouseEvents()) {
+ pElements.push_back(getSharedThis());
}
}
-void CircleNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void CircleNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
// TODO: This gets called whenever the circle position changes and is quite
// expensive. Should be optimized away.
- DPoint firstPt1 = getCirclePt(0, m_Radius+getStrokeWidth()/2)+m_Pos;
- DPoint firstPt2 = getCirclePt(0, m_Radius-getStrokeWidth()/2)+m_Pos;
+ glm::vec2 firstPt1 = getCirclePt(0, m_Radius+getStrokeWidth()/2)+m_Pos;
+ glm::vec2 firstPt2 = getCirclePt(0, m_Radius-getStrokeWidth()/2)+m_Pos;
int curVertex = 0;
- pVertexArray->appendPos(firstPt1, DPoint(m_TC1, 0), color);
- pVertexArray->appendPos(firstPt2, DPoint(m_TC1, 1), color);
- vector<DPoint> innerCircle;
+ pVertexData->appendPos(firstPt1, glm::vec2(m_TC1, 0), color);
+ pVertexData->appendPos(firstPt2, glm::vec2(m_TC1, 1), color);
+ vector<glm::vec2> innerCircle;
getEigthCirclePoints(innerCircle, m_Radius-getStrokeWidth()/2);
- vector<DPoint> outerCircle;
+ vector<glm::vec2> outerCircle;
getEigthCirclePoints(outerCircle, m_Radius+getStrokeWidth()/2);
- typedef vector<DPoint>::iterator DPointIt;
- typedef vector<DPoint>::reverse_iterator DPointRIt;
+ typedef vector<glm::vec2>::iterator Vec2It;
+ typedef vector<glm::vec2>::reverse_iterator Vec2RIt;
int i = 0;
- for (DPointIt iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
iit != innerCircle.end(); ++iit, ++oit)
{
- appendCirclePoint(pVertexArray, *iit, *oit, color, i, curVertex);
+ appendCirclePoint(pVertexData, *iit, *oit, color, i, curVertex);
}
- for (DPointRIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
iit != innerCircle.rend(); ++iit, ++oit)
{
- DPoint iPt = DPoint(-iit->y, -iit->x);
- DPoint oPt = DPoint(-oit->y, -oit->x);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(-iit->y, -iit->x);
+ glm::vec2 oPt = glm::vec2(-oit->y, -oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointIt iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
iit != innerCircle.end(); ++iit, ++oit)
{
- DPoint iPt = DPoint(-iit->y, iit->x);
- DPoint oPt = DPoint(-oit->y, oit->x);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(-iit->y, iit->x);
+ glm::vec2 oPt = glm::vec2(-oit->y, oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointRIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
iit !=innerCircle.rend(); ++iit, ++oit)
{
- DPoint iPt = DPoint(iit->x, -iit->y);
- DPoint oPt = DPoint(oit->x, -oit->y);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(iit->x, -iit->y);
+ glm::vec2 oPt = glm::vec2(oit->x, -oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointIt iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
iit != innerCircle.end(); ++iit, ++oit)
{
- DPoint iPt = DPoint(-iit->x, -iit->y);
- DPoint oPt = DPoint(-oit->x, -oit->y);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(-iit->x, -iit->y);
+ glm::vec2 oPt = glm::vec2(-oit->x, -oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointRIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
iit != innerCircle.rend(); ++iit, ++oit)
{
- DPoint iPt = DPoint(iit->y, iit->x);
- DPoint oPt = DPoint(oit->y, oit->x);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(iit->y, iit->x);
+ glm::vec2 oPt = glm::vec2(oit->y, oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointIt iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
+ for (Vec2It iit = innerCircle.begin()+1, oit = outerCircle.begin()+1;
iit != innerCircle.end(); ++iit, ++oit)
{
- DPoint iPt = DPoint(iit->y, -iit->x);
- DPoint oPt = DPoint(oit->y, -oit->x);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(iit->y, -iit->x);
+ glm::vec2 oPt = glm::vec2(oit->y, -oit->x);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
- for (DPointRIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
+ for (Vec2RIt iit = innerCircle.rbegin()+1, oit = outerCircle.rbegin()+1;
iit != innerCircle.rend(); ++iit, ++oit)
{
- DPoint iPt = DPoint(-iit->x, iit->y);
- DPoint oPt = DPoint(-oit->x, oit->y);
- appendCirclePoint(pVertexArray, iPt, oPt, color, i, curVertex);
+ glm::vec2 iPt = glm::vec2(-iit->x, iit->y);
+ glm::vec2 oPt = glm::vec2(-oit->x, oit->y);
+ appendCirclePoint(pVertexData, iPt, oPt, color, i, curVertex);
}
}
-void CircleNode::calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void CircleNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
- DPoint minPt = m_Pos-DPoint(m_Radius, m_Radius);
- DPoint maxPt = m_Pos+DPoint(m_Radius, m_Radius);
- DPoint centerTexCoord = calcFillTexCoord(m_Pos, minPt, maxPt);
- pVertexArray->appendPos(m_Pos, centerTexCoord, color);
+ glm::vec2 minPt = m_Pos-glm::vec2(m_Radius, m_Radius);
+ glm::vec2 maxPt = m_Pos+glm::vec2(m_Radius, m_Radius);
+ glm::vec2 centerTexCoord = calcFillTexCoord(m_Pos, minPt, maxPt);
+ pVertexData->appendPos(m_Pos, centerTexCoord, color);
int curVertex = 1;
- DPoint firstPt = getCirclePt(0, m_Radius)+m_Pos;
- DPoint firstTexCoord = calcFillTexCoord(firstPt, minPt, maxPt);
- pVertexArray->appendPos(firstPt, firstTexCoord, color);
- vector<DPoint> circlePoints;
+ glm::vec2 firstPt = getCirclePt(0, m_Radius)+m_Pos;
+ glm::vec2 firstTexCoord = calcFillTexCoord(firstPt, minPt, maxPt);
+ pVertexData->appendPos(firstPt, firstTexCoord, color);
+ vector<glm::vec2> circlePoints;
getEigthCirclePoints(circlePoints, m_Radius);
- for (vector<DPoint>::iterator it = circlePoints.begin()+1; it != circlePoints.end();
- ++it)
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
{
- DPoint curPt = *it+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = *it+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::reverse_iterator it = circlePoints.rbegin()+1;
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
it != circlePoints.rend(); ++it)
{
- DPoint curPt = DPoint(-it->y, -it->x)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(-it->y, -it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::iterator it = circlePoints.begin()+1; it != circlePoints.end();
- ++it)
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
{
- DPoint curPt = DPoint(-it->y, it->x)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(-it->y, it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::reverse_iterator it = circlePoints.rbegin()+1;
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
it != circlePoints.rend(); ++it)
{
- DPoint curPt = DPoint(it->x, -it->y)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(it->x, -it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::iterator it = circlePoints.begin()+1; it != circlePoints.end();
- ++it)
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
{
- DPoint curPt = DPoint(-it->x, -it->y)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(-it->x, -it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::reverse_iterator it = circlePoints.rbegin()+1;
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
it != circlePoints.rend(); ++it)
{
- DPoint curPt = DPoint(it->y, it->x)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(it->y, it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::iterator it = circlePoints.begin()+1; it != circlePoints.end();
- ++it)
+ for (vector<glm::vec2>::iterator it = circlePoints.begin()+1;
+ it != circlePoints.end(); ++it)
{
- DPoint curPt = DPoint(it->y, -it->x)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(it->y, -it->x)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
- for (vector<DPoint>::reverse_iterator it = circlePoints.rbegin()+1;
+ for (vector<glm::vec2>::reverse_iterator it = circlePoints.rbegin()+1;
it != circlePoints.rend(); ++it)
{
- DPoint curPt = DPoint(-it->x, it->y)+m_Pos;
- appendFillCirclePoint(pVertexArray, curPt, minPt, maxPt, color, curVertex);
+ glm::vec2 curPt = glm::vec2(-it->x, it->y)+m_Pos;
+ appendFillCirclePoint(pVertexData, curPt, minPt, maxPt, color, curVertex);
}
}
-void CircleNode::appendCirclePoint(VertexArrayPtr& pVertexArray, const DPoint& iPt,
- const DPoint& oPt, Pixel32 color, int& i, int& curVertex)
+void CircleNode::appendCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& iPt, const glm::vec2& oPt, Pixel32 color, int& i,
+ int& curVertex)
{
i++;
- double ratio = (double(i)/getNumCircumferencePoints());
- double curTC = (1-ratio)*m_TC1+ratio*m_TC2;
- pVertexArray->appendPos(oPt+m_Pos, DPoint(curTC, 0), color);
- pVertexArray->appendPos(iPt+m_Pos, DPoint(curTC, 1), color);
- pVertexArray->appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
+ float ratio = (float(i)/getNumCircumferencePoints());
+ float curTC = (1-ratio)*m_TC1+ratio*m_TC2;
+ pVertexData->appendPos(oPt+m_Pos, glm::vec2(curTC, 0), color);
+ pVertexData->appendPos(iPt+m_Pos, glm::vec2(curTC, 1), color);
+ pVertexData->appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
curVertex += 2;
}
-void CircleNode::appendFillCirclePoint(VertexArrayPtr& pVertexArray, const DPoint& curPt,
- const DPoint& minPt, const DPoint& maxPt, Pixel32 color, int& curVertex)
+void CircleNode::appendFillCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& curPt, const glm::vec2& minPt, const glm::vec2& maxPt,
+ Pixel32 color, int& curVertex)
{
- DPoint curTexCoord = calcFillTexCoord(curPt, minPt, maxPt);
- pVertexArray->appendPos(curPt, curTexCoord, color);
- pVertexArray->appendTriIndexes(0, curVertex, curVertex+1);
+ glm::vec2 curTexCoord = calcFillTexCoord(curPt, minPt, maxPt);
+ pVertexData->appendPos(curPt, curTexCoord, color);
+ pVertexData->appendTriIndexes(0, curVertex, curVertex+1);
curVertex++;
}
@@ -269,19 +273,19 @@ int CircleNode::getNumCircumferencePoints()
return int(ceil((m_Radius*3)/8)*8);
}
-void CircleNode::getEigthCirclePoints(vector<DPoint>& pts, double radius)
+void CircleNode::getEigthCirclePoints(vector<glm::vec2>& pts, float radius)
{
int numPts = getNumCircumferencePoints();
for (int i = 0; i <= numPts/8; ++i) {
- double ratio = (double(i)/numPts);
- double angle = ratio*2*3.14159;
+ float ratio = (float(i)/numPts);
+ float angle = ratio*2*PI;
pts.push_back(getCirclePt(angle, radius));
}
}
-DPoint CircleNode::getCirclePt(double angle, double radius)
+glm::vec2 CircleNode::getCirclePt(float angle, float radius)
{
- return DPoint(sin(angle)*radius, -cos(angle)*radius);
+ return glm::vec2(sin(angle)*radius, -cos(angle)*radius);
}
}
diff --git a/src/player/CircleNode.h b/src/player/CircleNode.h
index 10ce112..afc4160 100644
--- a/src/player/CircleNode.h
+++ b/src/player/CircleNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,41 +32,43 @@ namespace avg {
class AVG_API CircleNode : public FilledVectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
CircleNode(const ArgList& args);
virtual ~CircleNode();
- const DPoint& getPos() const;
- void setPos(const DPoint& pt);
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
- double getR() const;
- void setR(double r);
+ float getR() const;
+ void setR(float r);
- double getTexCoord1() const;
- void setTexCoord1(double tc);
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
- double getTexCoord2() const;
- void setTexCoord2(double tc);
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
- virtual void calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- void appendCirclePoint(VertexArrayPtr& pVertexArray, const DPoint& iPt,
- const DPoint& oPt, Pixel32 color, int& i, int& curVertex);
- void appendFillCirclePoint(VertexArrayPtr& pVertexArray, const DPoint& curPt,
- const DPoint& minPt, const DPoint& maxPt, Pixel32 color, int& curVertex);
+ void appendCirclePoint(const VertexDataPtr& pVertexData, const glm::vec2& iPt,
+ const glm::vec2& oPt, Pixel32 color, int& i, int& curVertex);
+ void appendFillCirclePoint(const VertexDataPtr& pVertexData,
+ const glm::vec2& curPt, const glm::vec2& minPt, const glm::vec2& maxPt,
+ Pixel32 color, int& curVertex);
int getNumCircumferencePoints();
- void getEigthCirclePoints(std::vector<DPoint>& pts, double radius);
- DPoint getCirclePt(double angle, double radius);
- DPoint calcTexCoord(const DPoint& pt, const DPoint& minPt, const DPoint& maxPt);
+ void getEigthCirclePoints(std::vector<glm::vec2>& pts, float radius);
+ glm::vec2 getCirclePt(float angle, float radius);
+ glm::vec2 calcTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt);
- DPoint m_Pos;
- double m_Radius;
- double m_TC1;
- double m_TC2;
+ glm::vec2 m_Pos;
+ float m_Radius;
+ float m_TC1;
+ float m_TC2;
};
}
diff --git a/src/player/Contact.cpp b/src/player/Contact.cpp
index a19abcc..b80615a 100644
--- a/src/player/Contact.cpp
+++ b/src/player/Contact.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,9 +24,11 @@
#include "CursorEvent.h"
#include "BoostPython.h"
#include "Player.h"
+#include "PublisherDefinition.h"
#include "../base/Exception.h"
#include "../base/StringHelper.h"
+#include "../base/Logger.h"
#include <iostream>
@@ -36,8 +38,16 @@ namespace avg {
int Contact::s_LastListenerID = 0;
+void Contact::registerType()
+{
+ PublisherDefinitionPtr pPubDef = PublisherDefinition::create("Contact");
+ pPubDef->addMessage("CURSOR_MOTION");
+ pPubDef->addMessage("CURSOR_UP");
+}
+
Contact::Contact(CursorEventPtr pEvent)
- : m_bSendingEvents(false),
+ : Publisher("Contact"),
+ m_bSendingEvents(false),
m_bCurListenerIsDead(false),
m_CursorID(pEvent->getCursorID()),
m_DistanceTravelled(0)
@@ -51,6 +61,7 @@ Contact::~Contact()
int Contact::connectListener(PyObject* pMotionCallback, PyObject* pUpCallback)
{
+ avgDeprecationWarning("1.8", "Contact.connectListener()", "Contact.subscribe()");
s_LastListenerID++;
pair<int, Listener> val =
pair<int, Listener>(s_LastListenerID, Listener(pMotionCallback, pUpCallback));
@@ -60,6 +71,8 @@ int Contact::connectListener(PyObject* pMotionCallback, PyObject* pUpCallback)
void Contact::disconnectListener(int id)
{
+ avgDeprecationWarning("1.8", "Contact.disconnectListener()",
+ "Contact.unsubscribe()");
map<int, Listener>::iterator it = m_ListenerMap.find(id);
if (it == m_ListenerMap.end() || (m_CurListenerID == id && m_bCurListenerIsDead)) {
throw Exception(AVG_ERR_INVALID_ARGS,
@@ -77,27 +90,27 @@ long long Contact::getAge() const
return m_Events.back()->getWhen() - m_Events[0]->getWhen();
}
-double Contact::getDistanceFromStart() const
+float Contact::getDistanceFromStart() const
{
- return getMotionVec().getNorm();
+ return glm::length(getMotionVec());
}
-double Contact::getMotionAngle() const
+float Contact::getMotionAngle() const
{
- DPoint motion = getMotionVec();
- if (motion == DPoint(0,0)) {
+ glm::vec2 motion = getMotionVec();
+ if (motion == glm::vec2(0,0)) {
return 0;
} else {
- return motion.getAngle();
+ return getAngle(motion);
}
}
-DPoint Contact::getMotionVec() const
+glm::vec2 Contact::getMotionVec() const
{
return m_Events.back()->getPos() - m_Events[0]->getPos();
}
-double Contact::getDistanceTravelled() const
+float Contact::getDistanceTravelled() const
{
return m_DistanceTravelled;
}
@@ -110,24 +123,31 @@ vector<CursorEventPtr> Contact::getEvents() const
void Contact::addEvent(CursorEventPtr pEvent)
{
pEvent->setCursorID(m_CursorID);
- pEvent->setContact(shared_from_this());
+ pEvent->setContact(boost::dynamic_pointer_cast<Contact>(shared_from_this()));
calcSpeed(pEvent, m_Events.back());
updateDistanceTravelled(m_Events.back(), pEvent);
m_Events.back()->removeBlob();
+ m_Events.back()->setNode(NodePtr());
m_Events.push_back(pEvent);
}
-bool Contact::hasListeners() const
-{
- return !(m_ListenerMap.empty() ||
- (m_ListenerMap.size() == 1 && m_bCurListenerIsDead));
-}
-
void Contact::sendEventToListeners(CursorEventPtr pCursorEvent)
{
+ switch (pCursorEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ break;
+ case Event::CURSOR_MOTION:
+ notifySubscribers("CURSOR_MOTION", pCursorEvent);
+ break;
+ case Event::CURSOR_UP:
+ notifySubscribers("CURSOR_UP", pCursorEvent);
+ removeSubscribers();
+ break;
+ default:
+ AVG_ASSERT_MSG(false, pCursorEvent->typeStr().c_str());
+ }
m_bSendingEvents = true;
AVG_ASSERT(pCursorEvent->getContact() == shared_from_this());
- EventPtr pEvent = boost::dynamic_pointer_cast<Event>(pCursorEvent);
m_bCurListenerIsDead = false;
for (map<int, Listener>::iterator it = m_ListenerMap.begin();
it != m_ListenerMap.end();)
@@ -136,14 +156,14 @@ void Contact::sendEventToListeners(CursorEventPtr pCursorEvent)
m_CurListenerID = it->first;
m_bCurListenerIsDead = false;
switch (pCursorEvent->getType()) {
- case Event::CURSORMOTION:
+ case Event::CURSOR_MOTION:
if (listener.m_pMotionCallback != Py_None) {
- boost::python::call<void>(listener.m_pMotionCallback, pEvent);
+ py::call<void>(listener.m_pMotionCallback, pCursorEvent);
}
break;
- case Event::CURSORUP:
+ case Event::CURSOR_UP:
if (listener.m_pUpCallback != Py_None) {
- boost::python::call<void>(listener.m_pUpCallback, pEvent);
+ py::call<void>(listener.m_pUpCallback, pCursorEvent);
}
break;
default:
@@ -164,36 +184,20 @@ int Contact::getID() const
return m_CursorID;
}
-bool Contact::operator ==(const Contact& other) const
-{
- return (shared_from_this() == other.shared_from_this());
-}
-
-bool Contact::operator !=(const Contact& other) const
-{
- return (shared_from_this() != other.shared_from_this());
-}
-
-long Contact::getHash() const
-{
- return long(&*shared_from_this());
-
-}
-
void Contact::calcSpeed(CursorEventPtr pEvent, CursorEventPtr pOldEvent)
{
- if (pEvent->getSpeed() == DPoint(0,0)) {
- DPoint posDiff = pEvent->getPos() - pOldEvent->getPos();
+ if (pEvent->getSpeed() == glm::vec2(0,0)) {
+ glm::vec2 posDiff = pEvent->getPos() - pOldEvent->getPos();
long long timeDiff = pEvent->getWhen() - pOldEvent->getWhen();
if (timeDiff != 0) {
- pEvent->setSpeed(posDiff/double(timeDiff));
+ pEvent->setSpeed(posDiff/float(timeDiff));
}
}
}
void Contact::updateDistanceTravelled(CursorEventPtr pEvent1, CursorEventPtr pEvent2)
{
- double dist = (pEvent2->getPos() - pEvent1->getPos()).getNorm();
+ float dist = glm::length(pEvent2->getPos() - pEvent1->getPos());
m_DistanceTravelled += dist;
}
diff --git a/src/player/Contact.h b/src/player/Contact.h
index 922dff8..846b422 100644
--- a/src/player/Contact.h
+++ b/src/player/Contact.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,9 @@
#ifndef _Contact_H_
#define _Contact_H_
-#include "../base/Point.h"
+#include "Publisher.h"
+
+#include "../base/GLMHelper.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
@@ -41,10 +43,10 @@ class CursorEvent;
typedef boost::shared_ptr<class CursorEvent> CursorEventPtr;
class Contact;
typedef boost::shared_ptr<class Contact> ContactPtr;
-//typedef boost::weak_ptr<class Contact> ContactWeakPtr;
-class AVG_API Contact: public boost::enable_shared_from_this<Contact> {
+class AVG_API Contact: public Publisher {
public:
+ static void registerType();
Contact(CursorEventPtr pEvent);
virtual ~Contact();
@@ -52,22 +54,17 @@ public:
void disconnectListener(int id);
long long getAge() const;
- double getDistanceFromStart() const;
- double getMotionAngle() const;
- DPoint getMotionVec() const;
- double getDistanceTravelled() const;
+ float getDistanceFromStart() const;
+ float getMotionAngle() const;
+ glm::vec2 getMotionVec() const;
+ float getDistanceTravelled() const;
std::vector<CursorEventPtr> getEvents() const;
void addEvent(CursorEventPtr pEvent);
- bool hasListeners() const;
void sendEventToListeners(CursorEventPtr pCursorEvent);
int getID() const;
- bool operator ==(const Contact& other) const;
- bool operator !=(const Contact& other) const;
- long getHash() const;
-
private:
void calcSpeed(CursorEventPtr pEvent, CursorEventPtr pOldEvent);
void updateDistanceTravelled(CursorEventPtr pEvent1, CursorEventPtr pEvent2);
@@ -91,7 +88,7 @@ private:
int m_CurListenerID;
bool m_bCurListenerIsDead;
int m_CursorID;
- double m_DistanceTravelled;
+ float m_DistanceTravelled;
};
}
diff --git a/src/player/CursorEvent.cpp b/src/player/CursorEvent.cpp
index df71c5c..ee4ba92 100644
--- a/src/player/CursorEvent.cpp
+++ b/src/player/CursorEvent.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -55,14 +55,14 @@ CursorEventPtr CursorEvent::cloneAs(Type eventType) const
return pClone;
}
-void CursorEvent::setPos(const DPoint& pos)
+void CursorEvent::setPos(const glm::vec2& pos)
{
m_Position = IntPoint(pos);
}
-DPoint CursorEvent::getPos() const
+glm::vec2 CursorEvent::getPos() const
{
- return DPoint(m_Position);
+ return glm::vec2(m_Position);
}
int CursorEvent::getXPosition() const
@@ -92,15 +92,15 @@ void CursorEvent::setNode(NodePtr pNode)
NodePtr CursorEvent::getNode() const
{
- return m_pNode.lock();
+ return m_pNode;
}
-void CursorEvent::setSpeed(DPoint speed)
+void CursorEvent::setSpeed(glm::vec2 speed)
{
m_Speed = speed;
}
-const DPoint& CursorEvent::getSpeed() const
+const glm::vec2& CursorEvent::getSpeed() const
{
return m_Speed;
}
@@ -124,10 +124,11 @@ bool operator ==(const CursorEvent& event1, const CursorEvent& event2)
void CursorEvent::trace()
{
string sType = typeStr();
- if (m_pNode.expired()) {
- AVG_TRACE(Logger::EVENTS, sType);
+ if (!m_pNode) {
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG, sType);
} else {
- AVG_TRACE(Logger::EVENTS, m_pNode.lock()->getID()+", "+sType);
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG,
+ m_pNode->getID()+", "+sType);
}
}
diff --git a/src/player/CursorEvent.h b/src/player/CursorEvent.h
index 5c6e699..e84272a 100644
--- a/src/player/CursorEvent.h
+++ b/src/player/CursorEvent.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "../api.h"
#include "Event.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
@@ -54,16 +54,16 @@ class AVG_API CursorEvent: public Event
int when=-1);
virtual ~CursorEvent();
virtual CursorEventPtr cloneAs(Type eventType) const;
- void setPos(const DPoint& pos);
- DPoint getPos() const;
+ void setPos(const glm::vec2& pos);
+ glm::vec2 getPos() const;
int getXPosition() const;
int getYPosition() const;
void setCursorID(int id);
int getCursorID() const;
void setNode(NodePtr pNode);
NodePtr getNode() const;
- void setSpeed(DPoint speed);
- virtual const DPoint& getSpeed() const;
+ void setSpeed(glm::vec2 speed);
+ virtual const glm::vec2& getSpeed() const;
void setContact(ContactPtr pContact);
ContactPtr getContact() const;
@@ -76,8 +76,8 @@ class AVG_API CursorEvent: public Event
IntPoint m_Position;
int m_ID;
ContactWeakPtr m_pContact;
- NodeWeakPtr m_pNode;
- DPoint m_Speed;
+ NodePtr m_pNode;
+ glm::vec2 m_Speed;
};
bool operator ==(const CursorEvent& event1, const CursorEvent& event2);
diff --git a/src/player/CursorState.cpp b/src/player/CursorState.cpp
index d1f52bb..4408946 100644
--- a/src/player/CursorState.cpp
+++ b/src/player/CursorState.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@ using namespace std;
namespace avg {
CursorState::CursorState(const CursorEventPtr pEvent,
- const vector<NodeWeakPtr>& pNodes)
+ const vector<NodePtr>& pNodes)
: m_pNodes(pNodes)
{
m_pLastEvent = pEvent;
@@ -38,13 +38,13 @@ CursorState::~CursorState()
}
void CursorState::setInfo(const CursorEventPtr pEvent,
- const vector<NodeWeakPtr>& pNodes)
+ const vector<NodePtr>& pNodes)
{
m_pLastEvent = pEvent;
m_pNodes = pNodes;
}
-const vector<NodeWeakPtr>& CursorState::getNodes() const
+const vector<NodePtr>& CursorState::getNodes() const
{
return m_pNodes;
}
diff --git a/src/player/CursorState.h b/src/player/CursorState.h
index b9d7693..8cec4c7 100644
--- a/src/player/CursorState.h
+++ b/src/player/CursorState.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -30,23 +30,23 @@
namespace avg {
class Node;
-typedef boost::weak_ptr<Node> NodeWeakPtr;
+typedef boost::shared_ptr<Node> NodePtr;
class CursorEvent;
typedef boost::shared_ptr<CursorEvent> CursorEventPtr;
class AVG_API CursorState {
public:
- CursorState(const CursorEventPtr pEvent, const std::vector<NodeWeakPtr>& pNodes);
+ CursorState(const CursorEventPtr pEvent, const std::vector<NodePtr>& pNodes);
~CursorState();
- void setInfo(const CursorEventPtr pEvent, const std::vector<NodeWeakPtr>& pNodes);
- const std::vector<NodeWeakPtr>& getNodes() const;
+ void setInfo(const CursorEventPtr pEvent, const std::vector<NodePtr>& pNodes);
+ const std::vector<NodePtr>& getNodes() const;
CursorEventPtr getLastEvent() const;
private:
CursorState(const CursorState&);
- std::vector<NodeWeakPtr> m_pNodes;
+ std::vector<NodePtr> m_pNodes;
CursorEventPtr m_pLastEvent;
};
diff --git a/src/player/CurveNode.cpp b/src/player/CurveNode.cpp
index adaabe5..7a685f5 100644
--- a/src/player/CurveNode.cpp
+++ b/src/player/CurveNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "CurveNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
@@ -37,16 +37,17 @@ using namespace std;
namespace avg {
-NodeDefinition CurveNode::createDefinition()
+void CurveNode::registerType()
{
- return NodeDefinition("curve", Node::buildNode<CurveNode>)
- .extendDefinition(VectorNode::createDefinition())
- .addArg(Arg<DPoint>("pos1", DPoint(0,0), false, offsetof(CurveNode, m_P1)))
- .addArg(Arg<DPoint>("pos2", DPoint(0,0), false, offsetof(CurveNode, m_P2)))
- .addArg(Arg<DPoint>("pos3", DPoint(0,0), false, offsetof(CurveNode, m_P3)))
- .addArg(Arg<DPoint>("pos4", DPoint(0,0), false, offsetof(CurveNode, m_P4)))
- .addArg(Arg<double>("texcoord1", 0, true, offsetof(CurveNode, m_TC1)))
- .addArg(Arg<double>("texcoord2", 1, true, offsetof(CurveNode, m_TC2)));
+ TypeDefinition def = TypeDefinition("curve", "vectornode",
+ ExportedObject::buildObject<CurveNode>)
+ .addArg(Arg<glm::vec2>("pos1", glm::vec2(0,0), false, offsetof(CurveNode, m_P1)))
+ .addArg(Arg<glm::vec2>("pos2", glm::vec2(0,0), false, offsetof(CurveNode, m_P2)))
+ .addArg(Arg<glm::vec2>("pos3", glm::vec2(0,0), false, offsetof(CurveNode, m_P3)))
+ .addArg(Arg<glm::vec2>("pos4", glm::vec2(0,0), false, offsetof(CurveNode, m_P4)))
+ .addArg(Arg<float>("texcoord1", 0, true, offsetof(CurveNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, true, offsetof(CurveNode, m_TC2)));
+ TypeRegistry::get()->registerType(def);
}
CurveNode::CurveNode(const ArgList& args)
@@ -59,118 +60,122 @@ CurveNode::~CurveNode()
{
}
-const DPoint& CurveNode::getPos1() const
+const glm::vec2& CurveNode::getPos1() const
{
return m_P1;
}
-void CurveNode::setPos1(const DPoint& pt)
+void CurveNode::setPos1(const glm::vec2& pt)
{
m_P1 = pt;
setDrawNeeded();
}
-const DPoint& CurveNode::getPos2() const
+const glm::vec2& CurveNode::getPos2() const
{
return m_P2;
}
-void CurveNode::setPos2(const DPoint& pt)
+void CurveNode::setPos2(const glm::vec2& pt)
{
m_P2 = pt;
setDrawNeeded();
}
-const DPoint& CurveNode::getPos3() const
+const glm::vec2& CurveNode::getPos3() const
{
return m_P3;
}
-void CurveNode::setPos3(const DPoint& pt)
+void CurveNode::setPos3(const glm::vec2& pt)
{
m_P3 = pt;
setDrawNeeded();
}
-const DPoint& CurveNode::getPos4() const
+const glm::vec2& CurveNode::getPos4() const
{
return m_P4;
}
-void CurveNode::setPos4(const DPoint& pt)
+void CurveNode::setPos4(const glm::vec2& pt)
{
m_P4 = pt;
setDrawNeeded();
}
-double CurveNode::getTexCoord1() const
+float CurveNode::getTexCoord1() const
{
return m_TC1;
}
-void CurveNode::setTexCoord1(double tc)
+void CurveNode::setTexCoord1(float tc)
{
m_TC1 = tc;
setDrawNeeded();
}
-double CurveNode::getTexCoord2() const
+float CurveNode::getTexCoord2() const
{
return m_TC2;
}
-void CurveNode::setTexCoord2(double tc)
+void CurveNode::setTexCoord2(float tc)
{
m_TC2 = tc;
setDrawNeeded();
}
+
+int CurveNode::getCurveLen() const
+{
+ // Calc. upper bound for spline length.
+ float curveLen = glm::length(m_P2-m_P1) + glm::length(m_P3 - m_P2)
+ + glm::length(m_P4-m_P3);
+ return int(curveLen);
+}
-void CurveNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+glm::vec2 CurveNode::getPtOnCurve(float t) const
{
- updateLines();
-
- pVertexArray->appendPos(m_LeftCurve[0], DPoint(m_TC1,1), color);
- pVertexArray->appendPos(m_RightCurve[0], DPoint(m_TC2,0), color);
- for (unsigned i = 0; i < m_LeftCurve.size()-1; ++i) {
- double ratio = i/double(m_LeftCurve.size());
- double tc = (1-ratio)*m_TC1+ratio*m_TC2;
- pVertexArray->appendPos(m_LeftCurve[i+1], DPoint(tc,1), color);
- pVertexArray->appendPos(m_RightCurve[i+1], DPoint(tc,0), color);
- pVertexArray->appendQuadIndexes((i+1)*2, i*2, (i+1)*2+1, i*2+1);
- }
+ BezierCurve curve(m_P1, m_P2, m_P3, m_P4);
+ return curve.interpolate(t);
}
-int CurveNode::getCurveLen()
+void CurveNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
- // Calc. upper bound for spline length.
- double curveLen = calcDist(m_P2,m_P1)+calcDist(m_P3,m_P2)+calcDist(m_P4,m_P3);
- if (curveLen > 50000) {
- throw Exception(AVG_ERR_OUT_OF_RANGE, "Illegal points in curve.");
+ updateLines();
+
+ pVertexData->appendPos(m_LeftCurve[0], glm::vec2(m_TC1,1), color);
+ pVertexData->appendPos(m_RightCurve[0], glm::vec2(m_TC2,0), color);
+ for (unsigned i = 0; i < m_LeftCurve.size()-1; ++i) {
+ float ratio = i/float(m_LeftCurve.size());
+ float tc = (1-ratio)*m_TC1+ratio*m_TC2;
+ pVertexData->appendPos(m_LeftCurve[i+1], glm::vec2(tc,1), color);
+ pVertexData->appendPos(m_RightCurve[i+1], glm::vec2(tc,0), color);
+ pVertexData->appendQuadIndexes((i+1)*2, i*2, (i+1)*2+1, i*2+1);
}
- return int(curveLen);
}
void CurveNode::updateLines()
{
BezierCurve curve(m_P1, m_P2, m_P3, m_P4);
- double len = getCurveLen();
+ float len = float(getCurveLen());
m_LeftCurve.clear();
m_RightCurve.clear();
- m_LeftCurve.reserve(int(len+1.5));
- m_RightCurve.reserve(int(len+1.5));
+ m_LeftCurve.reserve(int(len+1.5f));
+ m_RightCurve.reserve(int(len+1.5f));
for (unsigned i = 0; i < len; ++i) {
- double t = i/len;
+ float t = i/len;
addLRCurvePoint(curve.interpolate(t), curve.getDeriv(t));
}
addLRCurvePoint(curve.interpolate(1), curve.getDeriv(1));
}
-void CurveNode::addLRCurvePoint(const DPoint& pos, const DPoint& deriv)
+void CurveNode::addLRCurvePoint(const glm::vec2& pos, const glm::vec2& deriv)
{
- DPoint m = deriv.getNormalized();
- DPoint w = DPoint(m.y, -m.x)*getStrokeWidth()/2;
+ glm::vec2 m = glm::normalize(deriv);
+ glm::vec2 w = glm::vec2(m.y, -m.x)*float(getStrokeWidth()/2);
m_LeftCurve.push_back(pos-w);
m_RightCurve.push_back(pos+w);
}
diff --git a/src/player/CurveNode.h b/src/player/CurveNode.h
index 0a93292..45efc05 100644
--- a/src/player/CurveNode.h
+++ b/src/player/CurveNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,44 +32,46 @@ namespace avg {
class AVG_API CurveNode : public VectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
CurveNode(const ArgList& args);
virtual ~CurveNode();
- const DPoint& getPos1() const;
- void setPos1(const DPoint& pt);
+ const glm::vec2& getPos1() const;
+ void setPos1(const glm::vec2& pt);
- const DPoint& getPos2() const;
- void setPos2(const DPoint& pt);
+ const glm::vec2& getPos2() const;
+ void setPos2(const glm::vec2& pt);
- const DPoint& getPos3() const;
- void setPos3(const DPoint& pt);
+ const glm::vec2& getPos3() const;
+ void setPos3(const glm::vec2& pt);
- const DPoint& getPos4() const;
- void setPos4(const DPoint& pt);
+ const glm::vec2& getPos4() const;
+ void setPos4(const glm::vec2& pt);
- double getTexCoord1() const;
- void setTexCoord1(double tc);
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
- double getTexCoord2() const;
- void setTexCoord2(double tc);
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ int getCurveLen() const;
+ glm::vec2 getPtOnCurve(float t) const;
+
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- int getCurveLen();
void updateLines();
- void addLRCurvePoint(const DPoint& pos, const DPoint& deriv);
- DPoint m_P1;
- DPoint m_P2;
- DPoint m_P3;
- DPoint m_P4;
- double m_TC1;
- double m_TC2;
-
- std::vector<DPoint> m_LeftCurve;
- std::vector<DPoint> m_RightCurve;
+ void addLRCurvePoint(const glm::vec2& pos, const glm::vec2& deriv);
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ glm::vec2 m_P3;
+ glm::vec2 m_P4;
+ float m_TC1;
+ float m_TC2;
+
+ std::vector<glm::vec2> m_LeftCurve;
+ std::vector<glm::vec2> m_RightCurve;
};
}
diff --git a/src/player/DisplayEngine.cpp b/src/player/DisplayEngine.cpp
index 1f46847..7144e36 100644
--- a/src/player/DisplayEngine.cpp
+++ b/src/player/DisplayEngine.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,9 @@
#include "../base/ScopeTimer.h"
#include "../base/TimeSource.h"
#include "../base/Exception.h"
-#include "../base/ObjectCounter.h"
+
+#include "../graphics/GLContext.h"
+#include "../graphics/Display.h"
using namespace std;
@@ -38,12 +40,10 @@ DisplayEngine::DisplayEngine()
m_bInitialized(false),
m_EffFramerate(0)
{
- ObjectCounter::get()->incRef(&typeid(*this));
}
DisplayEngine::~DisplayEngine()
{
- ObjectCounter::get()->decRef(&typeid(*this));
}
@@ -64,42 +64,48 @@ void DisplayEngine::initRender()
void DisplayEngine::deinitRender()
{
- AVG_TRACE(Logger::PROFILE, "Framerate statistics: ");
- AVG_TRACE(Logger::PROFILE, " Total frames: " << m_NumFrames);
- double TotalTime = double(TimeSource::get()->getCurrentMicrosecs()
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ "Framerate statistics: ");
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Total frames: " <<m_NumFrames);
+ float TotalTime = float(TimeSource::get()->getCurrentMicrosecs()
-m_StartTime)/1000000;
- AVG_TRACE(Logger::PROFILE, " Total time: " << TotalTime << " seconds");
- double actualFramerate = (m_NumFrames+1)/TotalTime;
- AVG_TRACE(Logger::PROFILE, " Framerate achieved: "
- << actualFramerate);
- AVG_TRACE(Logger::PROFILE, " Frames too late: " << m_FramesTooLate);
- AVG_TRACE(Logger::PROFILE, " Percent of time spent waiting: "
- << double (m_TimeSpentWaiting)/(10000*TotalTime));
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Total time: " << TotalTime << " seconds");
+ float actualFramerate = (m_NumFrames+1)/TotalTime;
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Framerate achieved: " << actualFramerate);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Frames too late: " << m_FramesTooLate);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Percent of time spent waiting: "
+ << float (m_TimeSpentWaiting)/(10000*TotalTime));
if (m_Framerate != 0) {
- AVG_TRACE(Logger::PROFILE, " Framerate goal was: " << m_Framerate);
+ AVG_TRACE(Logger::category::PROFILE, Logger::severity::INFO,
+ " Framerate goal was: " << m_Framerate);
if (m_Framerate*2 < actualFramerate && m_NumFrames > 10) {
- AVG_TRACE(Logger::WARNING,
- "Actual framerate was a lot higher than framerate goal. Is vblank sync forced off?");
+ AVG_LOG_WARNING("Actual framerate was a lot higher than framerate goal.\
+ Is vblank sync forced off?");
}
}
m_bInitialized = false;
}
-void DisplayEngine::setFramerate(double rate)
+void DisplayEngine::setFramerate(float rate)
{
if (rate != 0 && m_bInitialized) {
- initVBlank(0);
+ GLContext::getMain()->initVBlank(0);
}
m_Framerate = rate;
m_VBRate = 0;
}
-double DisplayEngine::getFramerate()
+float DisplayEngine::getFramerate()
{
return m_Framerate;
}
-double DisplayEngine::getEffectiveFramerate()
+float DisplayEngine::getEffectiveFramerate()
{
return m_EffFramerate;
}
@@ -108,10 +114,10 @@ void DisplayEngine::setVBlankRate(int rate)
{
m_VBRate = rate;
if (m_bInitialized) {
- bool bOK = initVBlank(rate);
- m_Framerate = getRefreshRate()/m_VBRate;
+ bool bOK = GLContext::getMain()->initVBlank(rate);
+ m_Framerate = Display::get()->getRefreshRate()/m_VBRate;
if (!bOK || rate == 0) {
- AVG_TRACE(Logger::WARNING, "Using framerate of " << m_Framerate <<
+ AVG_LOG_WARNING("Using framerate of " << m_Framerate <<
" instead of VBRate of " << m_VBRate);
m_VBRate = 0;
}
@@ -133,15 +139,12 @@ void DisplayEngine::frameWait()
m_FrameWaitStartTime = TimeSource::get()->getCurrentMicrosecs();
m_TargetTime = m_LastFrameTime+(long long)(1000000/m_Framerate);
- if (m_VBRate != 0) {
- m_bFrameLate = !vbWait(m_VBRate);
- } else {
- m_bFrameLate = false;
+ m_bFrameLate = false;
+ if (m_VBRate == 0) {
if (m_FrameWaitStartTime <= m_TargetTime) {
long long WaitTime = (m_TargetTime-m_FrameWaitStartTime)/1000;
if (WaitTime > 5000) {
- AVG_TRACE (Logger::WARNING,
- "DisplayEngine: waiting " << WaitTime << " ms.");
+ AVG_LOG_WARNING("DisplayEngine: waiting " << WaitTime << " ms.");
}
TimeSource::get()->sleepUntil(m_TargetTime/1000);
}
@@ -160,7 +163,7 @@ void DisplayEngine::checkJitter()
} else {
long long CurIntervalTime = TimeSource::get()->getCurrentMicrosecs()
-m_LastFrameTime;
- m_EffFramerate = 1000000.0/CurIntervalTime;
+ m_EffFramerate = 1000000.0f/CurIntervalTime;
}
long long frameTime = TimeSource::get()->getCurrentMicrosecs();
@@ -171,9 +174,6 @@ void DisplayEngine::checkJitter()
maxDelay = 6;
}
if ((frameTime - m_TargetTime)/1000 > maxDelay || m_bFrameLate) {
- AVG_TRACE (Logger::PROFILE_LATEFRAMES,
- "DisplayEngine: frame too late by "
- << (frameTime - m_TargetTime)/1000 << " ms.");
m_bFrameLate = true;
m_FramesTooLate++;
}
diff --git a/src/player/DisplayEngine.h b/src/player/DisplayEngine.h
index 1025f6a..9b53e45 100644
--- a/src/player/DisplayEngine.h
+++ b/src/player/DisplayEngine.h
@@ -1,6 +1,6 @@
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -46,13 +46,12 @@ class AVG_API DisplayEngine
virtual void teardown() = 0;
void initRender();
void deinitRender();
- void setFramerate(double rate);
- double getFramerate();
- double getEffectiveFramerate();
+ void setFramerate(float rate);
+ float getFramerate();
+ float getEffectiveFramerate();
void setVBlankRate(int rate);
bool wasFrameLate();
- virtual double getRefreshRate() = 0;
- virtual void setGamma(double Red, double Green, double Blue) = 0;
+ virtual void setGamma(float Red, float Green, float Blue) = 0;
virtual void setMousePos(const IntPoint& pos) = 0;
virtual int getKeyModifierState() const = 0;
@@ -70,9 +69,6 @@ class AVG_API DisplayEngine
protected:
private:
- virtual bool initVBlank(int rate) = 0;
- virtual bool vbWait(int rate) = 0;
-
int m_NumFrames;
int m_FramesTooLate;
long long m_StartTime;
@@ -83,11 +79,11 @@ class AVG_API DisplayEngine
long long m_FrameWaitStartTime;
long long m_TargetTime;
int m_VBRate;
- double m_Framerate;
+ float m_Framerate;
bool m_bInitialized;
bool m_bFrameLate;
- double m_EffFramerate;
+ float m_EffFramerate;
};
typedef boost::shared_ptr<DisplayEngine> DisplayEnginePtr;
diff --git a/src/player/DisplayParams.cpp b/src/player/DisplayParams.cpp
index eb376c5..096da33 100644
--- a/src/player/DisplayParams.cpp
+++ b/src/player/DisplayParams.cpp
@@ -1,5 +1,5 @@
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,6 @@
#include "DisplayParams.h"
-#include "../base/ObjectCounter.h"
-
#include <iostream>
using namespace std;
@@ -37,18 +35,15 @@ DisplayParams::DisplayParams()
m_bShowCursor(true),
m_VBRate(1),
m_Framerate(0),
- m_bHasWindowFrame(true),
- m_DotsPerMM(0)
+ m_bHasWindowFrame(true)
{
- ObjectCounter::get()->incRef(&typeid(*this));
- m_Gamma[0] = -1.0;
- m_Gamma[1] = -1.0;
- m_Gamma[2] = -1.0;
+ m_Gamma[0] = -1.0f;
+ m_Gamma[1] = -1.0f;
+ m_Gamma[2] = -1.0f;
}
DisplayParams::~DisplayParams()
{
- ObjectCounter::get()->decRef(&typeid(*this));
}
void DisplayParams::dump() const
@@ -63,7 +58,6 @@ void DisplayParams::dump() const
cerr << " vbrate: " << m_VBRate << endl;
cerr << " framerate: " << m_Framerate << endl;
cerr << " has window frame: " << m_bHasWindowFrame << endl;
- cerr << " dots per mm: " << m_DotsPerMM << endl;
}
}
diff --git a/src/player/DisplayParams.h b/src/player/DisplayParams.h
index 1a2114d..178abbf 100644
--- a/src/player/DisplayParams.h
+++ b/src/player/DisplayParams.h
@@ -1,6 +1,6 @@
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,7 @@
#include "../api.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
namespace avg {
@@ -41,11 +41,10 @@ struct AVG_API DisplayParams {
IntPoint m_WindowSize;
bool m_bShowCursor;
int m_VBRate;
- double m_Framerate;
+ float m_Framerate;
bool m_bHasWindowFrame;
- double m_DotsPerMM;
- double m_Gamma[3];
+ float m_Gamma[3];
};
}
diff --git a/src/player/DivNode.cpp b/src/player/DivNode.cpp
index 7d3dc7c..7397c10 100644
--- a/src/player/DivNode.cpp
+++ b/src/player/DivNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,10 +21,9 @@
#include "DivNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Canvas.h"
-#include "../base/Point.h"
#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/StringHelper.h"
@@ -39,36 +38,35 @@
using namespace std;
using namespace boost;
-#define DEFAULT_SIZE 100000
-
namespace avg {
-NodeDefinition DivNode::createDefinition()
+void DivNode::registerType()
{
string sChildArray[] = {"image", "div", "canvas", "words", "video", "camera",
"panoimage", "sound", "line", "rect", "curve", "polyline", "polygon",
"circle", "mesh"};
vector<string> sChildren = vectorFromCArray(
sizeof(sChildArray) / sizeof(*sChildArray), sChildArray);
- return NodeDefinition("div", Node::buildNode<DivNode>)
- .extendDefinition(AreaNode::createDefinition())
+ TypeDefinition def = TypeDefinition("div", "areanode",
+ ExportedObject::buildObject<DivNode>)
.addChildren(sChildren)
.addArg(Arg<bool>("crop", false, false, offsetof(DivNode, m_bCrop)))
- .addArg(Arg<string>("elementoutlinecolor", "", false,
- offsetof(DivNode, m_sElementOutlineColor)))
.addArg(Arg<UTF8String>("mediadir", "", false, offsetof(DivNode, m_sMediaDir)));
+ TypeRegistry::get()->registerType(def);
}
DivNode::DivNode(const ArgList& args)
{
args.setMembers(this);
- setElementOutlineColor(m_sElementOutlineColor);
ObjectCounter::get()->incRef(&typeid(*this));
}
DivNode::~DivNode()
{
+ for (unsigned i = 0; i < getNumChildren(); ++i) {
+ getChild(i)->removeParent();
+ }
ObjectCounter::get()->decRef(&typeid(*this));
}
@@ -78,7 +76,6 @@ void DivNode::connectDisplay()
for (unsigned i = 0; i < getNumChildren(); ++i) {
getChild(i)->connectDisplay();
}
- m_pClipVertexes = VertexArrayPtr(new VertexArray());
}
void DivNode::connect(CanvasPtr pCanvas)
@@ -94,18 +91,12 @@ void DivNode::disconnect(bool bKill)
for (unsigned i = 0; i < getNumChildren(); ++i) {
getChild(i)->disconnect(bKill);
}
- if (m_pClipVertexes) {
- m_pClipVertexes = VertexArrayPtr();
- }
AreaNode::disconnect(bKill);
}
-DPoint DivNode::getPivot() const
+glm::vec2 DivNode::getPivot() const
{
- DPoint pivot = AreaNode::getPivot();
- if (pivot == DPoint(DEFAULT_SIZE / 2, DEFAULT_SIZE / 2)) {
- return DPoint(0, 0);
- }
+ glm::vec2 pivot = AreaNode::getPivot();
return pivot;
}
@@ -163,8 +154,7 @@ void DivNode::insertChild(NodePtr pChild, unsigned i)
if (getState() == NS_CONNECTED || getState() == NS_CANRENDER) {
getCanvas()->registerNode(pChild);
}
- DivNodePtr ptr = dynamic_pointer_cast<DivNode>(shared_from_this());
- pChild->checkSetParentError(ptr);
+ pChild->checkSetParentError(this);
if (!isChildTypeAllowed(pChild->getTypeStr())) {
throw(Exception(AVG_ERR_ALREADY_CONNECTED,
"Can't insert a node of type "+pChild->getTypeStr()+
@@ -177,7 +167,7 @@ void DivNode::insertChild(NodePtr pChild, unsigned i)
std::vector<NodePtr>::iterator pos = m_Children.begin()+i;
m_Children.insert(pos, pChild);
try {
- pChild->setParent(ptr, getState(), getCanvas());
+ pChild->setParent(this, getState(), getCanvas());
} catch (Exception&) {
m_Children.erase(m_Children.begin()+i);
throw;
@@ -267,21 +257,6 @@ void DivNode::setCrop(bool bCrop)
m_bCrop = bCrop;
}
-const std::string& DivNode::getElementOutlineColor() const
-{
- return m_sElementOutlineColor;
-}
-
-void DivNode::setElementOutlineColor(const std::string& sColor)
-{
- m_sElementOutlineColor = sColor;
- if (sColor == "") {
- m_ElementOutlineColor = Pixel32(0,0,0,0);
- } else {
- m_ElementOutlineColor = colorStringToColor(m_sElementOutlineColor);
- }
-}
-
const UTF8String& DivNode::getMediaDir() const
{
return m_sMediaDir;
@@ -289,88 +264,80 @@ const UTF8String& DivNode::getMediaDir() const
void DivNode::setMediaDir(const UTF8String& sMediaDir)
{
+// avgDeprecationWarning("1.7", "DivNode.mediadir", "");
m_sMediaDir = sMediaDir;
checkReload();
}
-void DivNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void DivNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
if (reactsToMouseEvents() &&
- ((getSize() == DPoint(DEFAULT_SIZE, DEFAULT_SIZE) ||
+ ((getSize() == glm::vec2(0,0) ||
(pos.x >= 0 && pos.y >= 0 && pos.x < getSize().x && pos.y < getSize().y))))
{
for (int i = getNumChildren()-1; i >= 0; i--) {
NodePtr pCurChild = getChild(i);
- DPoint relPos = pCurChild->toLocal(pos);
+ glm::vec2 relPos = pCurChild->toLocal(pos);
pCurChild->getElementsByPos(relPos, pElements);
if (!pElements.empty()) {
- pElements.push_back(shared_from_this());
+ pElements.push_back(getSharedThis());
return;
}
}
// pos isn't in any of the children.
- if (getSize() != DPoint(DEFAULT_SIZE, DEFAULT_SIZE)) {
+ if (getSize() != glm::vec2(0,0)) {
// Explicit width/height given for div - div reacts on its own.
- pElements.push_back(shared_from_this());
+ pElements.push_back(getSharedThis());
}
}
}
-void DivNode::preRender()
+void DivNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ pVA->startSubVA(m_ClipVA);
+ glm::vec2 viewport = getSize();
+ m_ClipVA.appendPos(glm::vec2(0,0), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(glm::vec2(0,viewport.y), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(glm::vec2(viewport.x,0), glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendPos(viewport, glm::vec2(0,0), Pixel32(0,0,0,0));
+ m_ClipVA.appendQuadIndexes(0, 1, 2, 3);
+ }
for (unsigned i = 0; i < getNumChildren(); i++) {
- getChild(i)->preRender();
+ getChild(i)->preRender(pVA, bIsParentActive, getEffectiveOpacity());
}
}
-void DivNode::render(const DRect& rect)
+void DivNode::render()
{
- DPoint viewport = getSize();
-
- m_pClipVertexes->reset();
- m_pClipVertexes->appendPos(DPoint(0,0), DPoint(0,0), Pixel32(0,0,0,0));
- m_pClipVertexes->appendPos(DPoint(0,viewport.y), DPoint(0,0), Pixel32(0,0,0,0));
- m_pClipVertexes->appendPos(DPoint(viewport.x,0), DPoint(0,0), Pixel32(0,0,0,0));
- m_pClipVertexes->appendPos(viewport, DPoint(0,0), Pixel32(0,0,0,0));
- m_pClipVertexes->appendQuadIndexes(0, 1, 2, 3);
-
- if (getCrop()) {
- getCanvas()->pushClipRect(m_pClipVertexes);
+ const glm::mat4& transform = getTransform();
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ getCanvas()->pushClipRect(transform, m_ClipVA);
}
for (unsigned i = 0; i < getNumChildren(); i++) {
- getChild(i)->maybeRender(rect);
+ getChild(i)->maybeRender(transform);
}
- if (getCrop()) {
- getCanvas()->popClipRect(m_pClipVertexes);
+ if (getCrop() && getSize() != glm::vec2(0,0)) {
+ getCanvas()->popClipRect(transform, m_ClipVA);
}
}
-void DivNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 color)
+void DivNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor)
{
- Pixel32 effColor = color;
- if (m_ElementOutlineColor != Pixel32(0,0,0,0)) {
- effColor = m_ElementOutlineColor;
- effColor.setA(128);
- }
+ Pixel32 effColor = getEffectiveOutlineColor(parentColor);
if (effColor != Pixel32(0,0,0,0)) {
- DPoint size = getSize();
- if (size == DPoint(DEFAULT_SIZE, DEFAULT_SIZE)) {
- DPoint p0 = getAbsPos(DPoint(-4, 0.5));
- DPoint p1 = getAbsPos(DPoint(5, 0.5));
- DPoint p2 = getAbsPos(DPoint(0.5, -4));
- DPoint p3 = getAbsPos(DPoint(0.5, 5));
+ glm::vec2 size = getSize();
+ if (size == glm::vec2(0,0)) {
+ glm::vec2 p0 = getAbsPos(glm::vec2(-4, 0.5));
+ glm::vec2 p1 = getAbsPos(glm::vec2(5, 0.5));
+ glm::vec2 p2 = getAbsPos(glm::vec2(0.5, -4));
+ glm::vec2 p3 = getAbsPos(glm::vec2(0.5, 5));
pVA->addLineData(effColor, p0, p1, 1);
pVA->addLineData(effColor, p2, p3, 1);
} else {
- DPoint p0 = getAbsPos(DPoint(0.5, 0.5));
- DPoint p1 = getAbsPos(DPoint(size.x+0.5,0.5));
- DPoint p2 = getAbsPos(DPoint(size.x+0.5,size.y+0.5));
- DPoint p3 = getAbsPos(DPoint(0.5,size.y+0.5));
- pVA->addLineData(effColor, p0, p1, 1);
- pVA->addLineData(effColor, p1, p2, 1);
- pVA->addLineData(effColor, p2, p3, 1);
- pVA->addLineData(effColor, p3, p0, 1);
+ AreaNode::renderOutlines(pVA, parentColor);
}
}
for (unsigned i = 0; i < getNumChildren(); i++) {
@@ -414,7 +381,7 @@ string DivNode::dump(int indent)
IntPoint DivNode::getMediaSize()
{
- return IntPoint(DEFAULT_SIZE, DEFAULT_SIZE);
+ return IntPoint(0, 0);
}
bool DivNode::isChildTypeAllowed(const string& sType)
diff --git a/src/player/DivNode.h b/src/player/DivNode.h
index 573f2e5..080bf56 100644
--- a/src/player/DivNode.h
+++ b/src/player/DivNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,19 +25,18 @@
#include "../api.h"
#include "AreaNode.h"
+#include "../graphics/SubVertexArray.h"
+
#include "../base/UTF8String.h"
-#include "../graphics/VertexArray.h"
#include <string>
namespace avg {
-class VertexArray;
-
class AVG_API DivNode : public AreaNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
DivNode(const ArgList& args);
virtual ~DivNode();
@@ -59,20 +58,18 @@ class AVG_API DivNode : public AreaNode
void removeChild(NodePtr pNode, bool bKill);
void removeChild(unsigned i, bool bKill);
- virtual DPoint getPivot() const;
+ virtual glm::vec2 getPivot() const;
bool getCrop() const;
void setCrop(bool bCrop);
- const std::string& getElementOutlineColor() const;
- void setElementOutlineColor(const std::string& sColor);
-
const UTF8String& getMediaDir() const;
void setMediaDir(const UTF8String& mediaDir);
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
- virtual void preRender();
- virtual void render(const DRect& rect);
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 color);
virtual std::string getEffectiveMediaDir();
@@ -86,10 +83,8 @@ class AVG_API DivNode : public AreaNode
UTF8String m_sMediaDir;
bool m_bCrop;
- std::string m_sElementOutlineColor;
- Pixel32 m_ElementOutlineColor;
- VertexArrayPtr m_pClipVertexes;
+ SubVertexArray m_ClipVA;
std::vector<NodePtr> m_Children;
};
diff --git a/src/player/Event.cpp b/src/player/Event.cpp
index a12d31c..07d274b 100644
--- a/src/player/Event.cpp
+++ b/src/player/Event.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -106,24 +106,22 @@ string Event::typeStr() const
string Event::typeStr(Event::Type type)
{
switch(type) {
- case KEYUP:
- return "KEYUP";
- case KEYDOWN:
- return "KEYDOWN";
- case CURSORMOTION:
- return "CURSORMOTION";
- case CURSORUP:
- return "CURSORUP";
- case CURSORDOWN:
- return "CURSORDOWN";
- case CURSOROVER:
- return "CURSOROVER";
- case CURSOROUT:
- return "CURSOROUT";
- case CUSTOMEVENT:
- return "CUSTOMEVENT";
- case RESIZE:
- return "RESIZE";
+ case KEY_UP:
+ return "KEY_UP";
+ case KEY_DOWN:
+ return "KEY_DOWN";
+ case CURSOR_MOTION:
+ return "CURSOR_MOTION";
+ case CURSOR_UP:
+ return "CURSOR_UP";
+ case CURSOR_DOWN:
+ return "CURSOR_DOWN";
+ case CURSOR_OVER:
+ return "CURSOR_OVER";
+ case CURSOR_OUT:
+ return "CURSOR_OUT";
+ case CUSTOM_EVENT:
+ return "CUSTOM_EVENT";
case QUIT:
return "QUIT";
default:
@@ -135,7 +133,7 @@ string Event::typeStr(Event::Type type)
void Event::trace()
{
string sType = typeStr();
- AVG_TRACE(Logger::EVENTS, sType);
+ AVG_TRACE(Logger::category::EVENTS,Logger::severity::INFO, sType);
}
}
diff --git a/src/player/Event.h b/src/player/Event.h
index 9ac5a89..d1b6d9f 100644
--- a/src/player/Event.h
+++ b/src/player/Event.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -39,15 +39,15 @@ typedef boost::weak_ptr<class IInputDevice> IInputDeviceWeakPtr;
class AVG_API Event {
public:
enum Type {
- KEYUP,
- KEYDOWN,
- CURSORMOTION,
- CURSORUP,
- CURSORDOWN,
- CURSOROVER,
- CURSOROUT,
- CUSTOMEVENT,
- RESIZE,
+ // XXX: Hack to make sure this enum can't be passed to Node.subscribe.
+ KEY_UP = 10000,
+ KEY_DOWN,
+ CURSOR_MOTION,
+ CURSOR_UP,
+ CURSOR_DOWN,
+ CURSOR_OVER,
+ CURSOR_OUT,
+ CUSTOM_EVENT,
QUIT
};
enum Source {MOUSE=1, TOUCH=2, TRACK=4, CUSTOM=8, NONE=16};
diff --git a/src/player/EventDispatcher.cpp b/src/player/EventDispatcher.cpp
index f63c42a..23caff2 100644
--- a/src/player/EventDispatcher.cpp
+++ b/src/player/EventDispatcher.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include "CursorEvent.h"
#include "../base/Exception.h"
+#include "../base/OSHelper.h"
#include <string>
@@ -34,9 +35,10 @@ using namespace boost;
namespace avg {
-EventDispatcher::EventDispatcher(Player* pPlayer)
+EventDispatcher::EventDispatcher(Player* pPlayer, bool bMouseEnabled)
: m_pPlayer(pPlayer),
- m_NumMouseButtonsDown(0)
+ m_NumMouseButtonsDown(0),
+ m_bMouseEnabled(bMouseEnabled)
{
}
@@ -63,10 +65,13 @@ void EventDispatcher::dispatch()
vector<EventPtr>::iterator it;
for (it = events.begin(); it != events.end(); ++it) {
EventPtr pEvent = *it;
-// cerr << " " << pEvent->typeStr() << ", " << pEvent->getSource() << endl;
- testAddContact(pEvent);
- handleEvent(*it);
- testRemoveContact(pEvent);
+ bool bHookEatsEvent = processEventHook(pEvent);
+ if (!(!m_bMouseEnabled && pEvent->getSource() == Event::MOUSE) &&
+ !bHookEatsEvent) {
+ testAddContact(pEvent);
+ handleEvent(*it);
+ testRemoveContact(pEvent);
+ }
}
}
@@ -80,6 +85,11 @@ void EventDispatcher::sendEvent(EventPtr pEvent)
handleEvent(pEvent);
}
+void EventDispatcher::enableMouse(bool bEnabled)
+{
+ m_bMouseEnabled = bEnabled;
+}
+
ContactPtr EventDispatcher::getContact(int id)
{
std::map<int, ContactPtr>::iterator it = m_ContactMap.find(id);
@@ -95,13 +105,25 @@ void EventDispatcher::handleEvent(EventPtr pEvent)
m_pPlayer->handleEvent(pEvent);
}
+bool EventDispatcher::processEventHook(EventPtr pEvent)
+{
+ PyObject * pEventHook = m_pPlayer->getEventHook();
+ if (pEventHook != Py_None) {
+ // If the hook returns true, stop processing the event
+ if (py::call<bool>(pEventHook, pEvent)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void EventDispatcher::testAddContact(EventPtr pEvent)
{
ContactPtr pContact;
CursorEventPtr pCursorEvent = dynamic_pointer_cast<CursorEvent>(pEvent);
if (pCursorEvent) {
switch (pCursorEvent->getType()) {
- case Event::CURSORDOWN:
+ case Event::CURSOR_DOWN:
if (pCursorEvent->getSource() == Event::MOUSE) {
m_NumMouseButtonsDown++;
if (m_NumMouseButtonsDown == 1) {
@@ -114,8 +136,8 @@ void EventDispatcher::testAddContact(EventPtr pEvent)
m_ContactMap[pCursorEvent->getCursorID()] = pContact;
}
break;
- case Event::CURSORMOTION:
- case Event::CURSORUP: {
+ case Event::CURSOR_MOTION:
+ case Event::CURSOR_UP: {
pContact = getContact(pCursorEvent->getCursorID());
AVG_ASSERT(pContact || (
pCursorEvent->getSource() == Event::MOUSE &&
@@ -125,7 +147,7 @@ void EventDispatcher::testAddContact(EventPtr pEvent)
}
}
break;
- case Event::CUSTOMEVENT:
+ case Event::CUSTOM_EVENT:
break;
default:
cerr << pCursorEvent->typeStr() << endl;
@@ -140,13 +162,16 @@ void EventDispatcher::testAddContact(EventPtr pEvent)
void EventDispatcher::testRemoveContact(EventPtr pEvent)
{
- if (pEvent->getType() == Event::CURSORUP) {
+ if (pEvent->getType() == Event::CURSOR_UP) {
if (pEvent->getSource() == Event::MOUSE) {
- AVG_ASSERT(m_NumMouseButtonsDown > 0);
- m_NumMouseButtonsDown--;
- if (m_NumMouseButtonsDown == 0) {
- int rc = m_ContactMap.erase(MOUSECURSORID);
- AVG_ASSERT(rc == 1);
+ // The following if is only false if the CURSOR_DOWN wasn't registered because
+ // it was outside the application window (or on the window border).
+ if (m_NumMouseButtonsDown > 0) {
+ m_NumMouseButtonsDown--;
+ if (m_NumMouseButtonsDown == 0) {
+ int rc = m_ContactMap.erase(MOUSECURSORID);
+ AVG_ASSERT(rc == 1);
+ }
}
} else {
int rc = m_ContactMap.erase(
diff --git a/src/player/EventDispatcher.h b/src/player/EventDispatcher.h
index 51da86e..19c3f78 100644
--- a/src/player/EventDispatcher.h
+++ b/src/player/EventDispatcher.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -38,17 +38,19 @@ class Player;
class AVG_API EventDispatcher {
public:
- EventDispatcher(Player* pPlayer);
+ EventDispatcher(Player* pPlayer, bool bMouseEnabled);
virtual ~EventDispatcher();
void dispatch();
void addInputDevice(IInputDevicePtr pInputDevice);
void sendEvent(EventPtr pEvent);
+ void enableMouse(bool bEnabled);
ContactPtr getContact(int id);
private:
void handleEvent(EventPtr pEvent);
+ bool processEventHook(EventPtr pEvent);
void testAddContact(EventPtr pEvent);
void testRemoveContact(EventPtr pEvent);
@@ -56,6 +58,7 @@ class AVG_API EventDispatcher {
Player* m_pPlayer;
std::map<int, ContactPtr> m_ContactMap;
int m_NumMouseButtonsDown;
+ bool m_bMouseEnabled;
};
typedef boost::shared_ptr<EventDispatcher> EventDispatcherPtr;
diff --git a/src/player/ExportedObject.cpp b/src/player/ExportedObject.cpp
new file mode 100644
index 0000000..b50a72a
--- /dev/null
+++ b/src/player/ExportedObject.cpp
@@ -0,0 +1,105 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ExportedObject.h"
+#include "TypeDefinition.h"
+#include "Arg.h"
+
+#include "../base/Exception.h"
+#include "../base/Logger.h"
+#include "../base/ObjectCounter.h"
+
+#include <string>
+
+using namespace std;
+
+namespace avg {
+
+ExportedObject::ExportedObject()
+ : m_pSelf(0)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ExportedObject::ExportedObject(const ExportedObject& other)
+ : m_pSelf(0)
+{
+ AVG_ASSERT(!other.m_pSelf);
+ m_pDefinition = other.m_pDefinition;
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+ExportedObject::~ExportedObject()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void ExportedObject::registerInstance(PyObject* pSelf)
+{
+ m_pSelf = pSelf;
+}
+
+ExportedObjectPtr ExportedObject::getSharedThis()
+{
+ // Just using shared_from_this causes strange behaviour when derived classes
+ // are written in python: The pointer returned by shared_from_this doesn't know
+ // about the python part of the object and cuts it off. Because of this, we remember
+ // a pointer to the python object in m_pSelf and use that to create a functioning
+ // and complete ExportedObjectPtr if there is a python derived class.
+ if (m_pSelf) {
+ return py::extract<ExportedObjectPtr>(m_pSelf);
+ } else {
+ return shared_from_this();
+ }
+}
+
+void ExportedObject::setTypeInfo(const TypeDefinition * pDefinition)
+{
+ m_pDefinition = pDefinition;
+}
+
+const TypeDefinition* ExportedObject::getDefinition() const
+{
+ return m_pDefinition;
+}
+
+string ExportedObject::getTypeStr() const
+{
+ return m_pDefinition->getName();
+}
+
+bool ExportedObject::operator ==(const ExportedObject& other) const
+{
+ return this == &other;
+}
+
+bool ExportedObject::operator !=(const ExportedObject& other) const
+{
+ return this != &other;
+}
+
+long ExportedObject::getHash() const
+{
+ return long(this);
+}
+
+
+}
diff --git a/src/player/ExportedObject.h b/src/player/ExportedObject.h
new file mode 100644
index 0000000..810e787
--- /dev/null
+++ b/src/player/ExportedObject.h
@@ -0,0 +1,73 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ExportedObject_H_
+#define _ExportedObject_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+namespace avg {
+
+class TypeDefinition;
+class ArgList;
+
+class ExportedObject;
+typedef boost::shared_ptr<ExportedObject> ExportedObjectPtr;
+
+class AVG_API ExportedObject: public boost::enable_shared_from_this<ExportedObject>
+{
+ public:
+ ExportedObject();
+ ExportedObject(const ExportedObject& other);
+ virtual ~ExportedObject()=0;
+
+ void registerInstance(PyObject* pSelf);
+ ExportedObjectPtr getSharedThis();
+
+ template<class Type>
+ static ExportedObjectPtr buildObject(const ArgList& Args)
+ {
+ return ExportedObjectPtr(new Type(Args));
+ }
+ virtual void setTypeInfo(const TypeDefinition * pDefinition);
+
+ virtual void setArgs(const ArgList& args) {};
+ std::string getTypeStr() const;
+ virtual const TypeDefinition* getDefinition() const;
+
+ bool operator ==(const ExportedObject& other) const;
+ bool operator !=(const ExportedObject& other) const;
+ long getHash() const;
+
+ private:
+ const TypeDefinition* m_pDefinition;
+ PyObject* m_pSelf;
+};
+
+}
+
+#endif
diff --git a/src/player/FXNode.cpp b/src/player/FXNode.cpp
index c0483e5..9aa2fde 100644
--- a/src/player/FXNode.cpp
+++ b/src/player/FXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,8 +29,9 @@ namespace avg {
using namespace std;
-FXNode::FXNode()
+FXNode::FXNode(bool bSupportsGLES)
: m_Size(0, 0),
+ m_bSupportsGLES(bSupportsGLES),
m_bDirty(true)
{
ObjectCounter::get()->incRef(&typeid(*this));
@@ -43,6 +44,7 @@ FXNode::~FXNode()
void FXNode::connect()
{
+ checkGLES();
if (m_Size != IntPoint(0,0)) {
m_pFilter = createFilter(m_Size);
}
@@ -66,7 +68,7 @@ void FXNode::setSize(const IntPoint& newSize)
void FXNode::apply(GLTexturePtr pSrcTex)
{
// blt overwrites everything, so no glClear necessary before.
- GLContext::getCurrent()->setBlendMode(GLContext::BLEND_COPY);
+ GLContext::getMain()->setBlendMode(GLContext::BLEND_COPY);
m_pFilter->apply(pSrcTex);
}
@@ -80,7 +82,7 @@ BitmapPtr FXNode::getImage()
return m_pFilter->getImage();
}
-DRect FXNode::getRelDestRect() const
+FRect FXNode::getRelDestRect() const
{
return m_pFilter->getRelDestRect();
}
@@ -105,4 +107,11 @@ void FXNode::setDirty()
m_bDirty = true;
}
+void FXNode::checkGLES() const
+{
+ if (!m_bSupportsGLES && GLContext::getCurrent()->isGLES()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "This effect is unsupported under OpenGL ES.");
+ }
+}
+
}
diff --git a/src/player/FXNode.h b/src/player/FXNode.h
index e602a9a..05a902e 100644
--- a/src/player/FXNode.h
+++ b/src/player/FXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ namespace avg {
class AVG_API FXNode {
public:
- FXNode();
+ FXNode(bool bSupportsGLES=true);
virtual ~FXNode();
virtual void connect();
@@ -43,7 +43,7 @@ public:
GLTexturePtr getTex();
BitmapPtr getImage();
- DRect getRelDestRect() const;
+ FRect getRelDestRect() const;
bool isDirty() const;
void resetDirty();
@@ -54,10 +54,12 @@ protected:
private:
virtual GPUFilterPtr createFilter(const IntPoint& size) = 0;
+ void checkGLES() const;
IntPoint m_Size;
GPUFilterPtr m_pFilter;
+ bool m_bSupportsGLES;
bool m_bDirty;
};
diff --git a/src/player/FilledVectorNode.cpp b/src/player/FilledVectorNode.cpp
index 69d833b..a804958 100644
--- a/src/player/FilledVectorNode.cpp
+++ b/src/player/FilledVectorNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "FilledVectorNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Image.h"
#include "DivNode.h"
@@ -34,21 +34,21 @@ using namespace boost;
namespace avg {
-NodeDefinition FilledVectorNode::createDefinition()
+void FilledVectorNode::registerType()
{
- return NodeDefinition("filledvector")
- .extendDefinition(VectorNode::createDefinition())
+ TypeDefinition def = TypeDefinition("filledvectornode", "vectornode")
.addArg(Arg<UTF8String>("filltexhref", "", false,
offsetof(FilledVectorNode, m_FillTexHRef)))
- .addArg(Arg<double>("fillopacity", 0, false,
+ .addArg(Arg<float>("fillopacity", 0, false,
offsetof(FilledVectorNode, m_FillOpacity)))
- .addArg(Arg<string>("fillcolor", "FFFFFF", false,
+ .addArg(Arg<UTF8String>("fillcolor", "FFFFFF", false,
offsetof(FilledVectorNode, m_sFillColorName)))
- .addArg(Arg<DPoint>("filltexcoord1", DPoint(0,0), false,
+ .addArg(Arg<glm::vec2>("filltexcoord1", glm::vec2(0,0), false,
offsetof(FilledVectorNode, m_FillTexCoord1)))
- .addArg(Arg<DPoint>("filltexcoord2", DPoint(1,1), false,
+ .addArg(Arg<glm::vec2>("filltexcoord2", glm::vec2(1,1), false,
offsetof(FilledVectorNode, m_FillTexCoord2)))
;
+ TypeRegistry::get()->registerType(def);
}
FilledVectorNode::FilledVectorNode(const ArgList& args)
@@ -57,7 +57,7 @@ FilledVectorNode::FilledVectorNode(const ArgList& args)
{
m_FillTexHRef = args.getArgVal<UTF8String>("filltexhref");
setFillTexHRef(m_FillTexHRef);
- m_sFillColorName = args.getArgVal<string>("fillcolor");
+ m_sFillColorName = args.getArgVal<UTF8String>("fillcolor");
m_FillColor = colorStringToColor(m_sFillColorName);
}
@@ -112,70 +112,71 @@ void FilledVectorNode::setFillBitmap(BitmapPtr pBmp)
setDrawNeeded();
}
-const DPoint& FilledVectorNode::getFillTexCoord1() const
+const glm::vec2& FilledVectorNode::getFillTexCoord1() const
{
return m_FillTexCoord1;
}
-void FilledVectorNode::setFillTexCoord1(const DPoint& pt)
+void FilledVectorNode::setFillTexCoord1(const glm::vec2& pt)
{
m_FillTexCoord1 = pt;
setDrawNeeded();
}
-const DPoint& FilledVectorNode::getFillTexCoord2() const
+const glm::vec2& FilledVectorNode::getFillTexCoord2() const
{
return m_FillTexCoord2;
}
-void FilledVectorNode::setFillTexCoord2(const DPoint& pt)
+void FilledVectorNode::setFillTexCoord2(const glm::vec2& pt)
{
m_FillTexCoord2 = pt;
setDrawNeeded();
}
-double FilledVectorNode::getFillOpacity() const
+float FilledVectorNode::getFillOpacity() const
{
return m_FillOpacity;
}
-void FilledVectorNode::setFillOpacity(double opacity)
+void FilledVectorNode::setFillOpacity(float opacity)
{
m_FillOpacity = opacity;
setDrawNeeded();
}
-void FilledVectorNode::preRender()
+void FilledVectorNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
- double curOpacity = getParent()->getEffectiveOpacity()*m_FillOpacity;
- VertexArrayPtr pFillVA;
- pFillVA = m_pFillShape->getVertexArray();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
+ float curOpacity = parentEffectiveOpacity*m_FillOpacity;
+
+ VertexDataPtr pShapeVD = m_pFillShape->getVertexData();
if (isDrawNeeded() || curOpacity != m_OldOpacity) {
- pFillVA->reset();
+ pShapeVD->reset();
Pixel32 color = getFillColorVal();
- color.setA((unsigned char)(curOpacity*255));
- calcFillVertexes(pFillVA, color);
- pFillVA->update();
+ calcFillVertexes(pShapeVD, color);
m_OldOpacity = curOpacity;
}
- VectorNode::preRender();
+ if (isVisible()) {
+ m_pFillShape->setVertexArray(pVA);
+ }
+ VectorNode::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
}
static ProfilingZoneID RenderProfilingZone("FilledVectorNode::render");
-void FilledVectorNode::render(const DRect& rect)
+void FilledVectorNode::render()
{
ScopeTimer Timer(RenderProfilingZone);
- double curOpacity = getParent()->getEffectiveOpacity()*m_FillOpacity;
+ float curOpacity = getParent()->getEffectiveOpacity()*m_FillOpacity;
if (curOpacity > 0.01) {
- glColor4d(1.0, 1.0, 1.0, curOpacity);
- m_pFillShape->draw();
+ m_pFillShape->draw(getTransform(), curOpacity);
}
- VectorNode::render(rect);
+ VectorNode::render();
}
-void FilledVectorNode::setFillColor(const string& sColor)
+void FilledVectorNode::setFillColor(const UTF8String& sColor)
{
if (m_sFillColorName != sColor) {
m_sFillColorName = sColor;
@@ -184,7 +185,7 @@ void FilledVectorNode::setFillColor(const string& sColor)
}
}
-const string& FilledVectorNode::getFillColor() const
+const UTF8String& FilledVectorNode::getFillColor() const
{
return m_sFillColorName;
}
@@ -194,10 +195,10 @@ Pixel32 FilledVectorNode::getFillColorVal() const
return m_FillColor;
}
-DPoint FilledVectorNode::calcFillTexCoord(const DPoint& pt, const DPoint& minPt,
- const DPoint& maxPt)
+glm::vec2 FilledVectorNode::calcFillTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt)
{
- DPoint texPt;
+ glm::vec2 texPt;
texPt.x = (m_FillTexCoord2.x-m_FillTexCoord1.x)*(pt.x-minPt.x)/(maxPt.x-minPt.x)
+m_FillTexCoord1.x;
texPt.y = (m_FillTexCoord2.y-m_FillTexCoord1.y)*(pt.y-minPt.y)/(maxPt.y-minPt.y)
@@ -207,7 +208,7 @@ DPoint FilledVectorNode::calcFillTexCoord(const DPoint& pt, const DPoint& minPt,
bool FilledVectorNode::isVisible() const
{
- return getActive() && (getEffectiveOpacity() > 0.01 ||
+ return getEffectiveActive() && (getEffectiveOpacity() > 0.01 ||
getParent()->getEffectiveOpacity()*m_FillOpacity > 0.01);
}
diff --git a/src/player/FilledVectorNode.h b/src/player/FilledVectorNode.h
index ff8451d..ae98595 100644
--- a/src/player/FilledVectorNode.h
+++ b/src/player/FilledVectorNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ namespace avg {
class AVG_API FilledVectorNode : public VectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
FilledVectorNode(const ArgList& args);
virtual ~FilledVectorNode();
@@ -44,37 +44,39 @@ class AVG_API FilledVectorNode : public VectorNode
void setFillTexHRef(const UTF8String& href);
void setFillBitmap(BitmapPtr pBmp);
- const DPoint& getFillTexCoord1() const;
- void setFillTexCoord1(const DPoint& pt);
- const DPoint& getFillTexCoord2() const;
- void setFillTexCoord2(const DPoint& pt);
+ const glm::vec2& getFillTexCoord1() const;
+ void setFillTexCoord1(const glm::vec2& pt);
+ const glm::vec2& getFillTexCoord2() const;
+ void setFillTexCoord2(const glm::vec2& pt);
- void setFillColor(const std::string& sColor);
- const std::string& getFillColor() const;
+ void setFillColor(const UTF8String& sColor);
+ const UTF8String& getFillColor() const;
- double getFillOpacity() const;
- void setFillOpacity(double opacity);
+ float getFillOpacity() const;
+ void setFillOpacity(float opacity);
- virtual void preRender();
- virtual void render(const DRect& rect);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
- virtual void calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color) = 0;
+ virtual void calcFillVertexes(
+ const VertexDataPtr& pVertexData, Pixel32 color) = 0;
protected:
Pixel32 getFillColorVal() const;
- DPoint calcFillTexCoord(const DPoint& pt, const DPoint& minPt,
- const DPoint& maxPt);
+ glm::vec2 calcFillTexCoord(const glm::vec2& pt, const glm::vec2& minPt,
+ const glm::vec2& maxPt);
virtual bool isVisible() const;
private:
- double m_OldOpacity;
+ float m_OldOpacity;
UTF8String m_FillTexHRef;
- DPoint m_FillTexCoord1;
- DPoint m_FillTexCoord2;
+ glm::vec2 m_FillTexCoord1;
+ glm::vec2 m_FillTexCoord2;
ShapePtr m_pFillShape;
- double m_FillOpacity;
- std::string m_sFillColorName;
+ float m_FillOpacity;
+ UTF8String m_sFillColorName;
Pixel32 m_FillColor;
};
diff --git a/src/player/FontStyle.cpp b/src/player/FontStyle.cpp
new file mode 100644
index 0000000..2980aa3
--- /dev/null
+++ b/src/player/FontStyle.cpp
@@ -0,0 +1,315 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "FontStyle.h"
+
+#include "../base/ObjectCounter.h"
+#include "../base/Exception.h"
+
+#include "TypeDefinition.h"
+#include "Arg.h"
+
+using namespace std;
+
+namespace avg {
+
+void FontStyle::registerType()
+{
+ TypeDefinition def = TypeDefinition("fontstyle", "",
+ ExportedObject::buildObject<FontStyle>)
+ .addArg(Arg<string>("font", "sans", false, offsetof(FontStyle, m_sName)))
+ .addArg(Arg<string>("variant", "", false, offsetof(FontStyle, m_sVariant)))
+ .addArg(Arg<string>("color", "FFFFFF", false, offsetof(FontStyle, m_sColorName)))
+ .addArg(Arg<float>("aagamma", 1.0f, false, offsetof(FontStyle, m_AAGamma)))
+ .addArg(Arg<float>("fontsize", 15, false, offsetof(FontStyle, m_Size)))
+ .addArg(Arg<int>("indent", 0, false, offsetof(FontStyle, m_Indent)))
+ .addArg(Arg<float>("linespacing", 0, false, offsetof(FontStyle, m_LineSpacing)))
+ .addArg(Arg<string>("alignment", "left"))
+ .addArg(Arg<string>("wrapmode", "word"))
+ .addArg(Arg<bool>("justify", false, false, offsetof(FontStyle, m_bJustify)))
+ .addArg(Arg<float>("letterspacing", 0, false,
+ offsetof(FontStyle, m_LetterSpacing)))
+ .addArg(Arg<bool>("hint", true, false, offsetof(FontStyle, m_bHint)))
+ .addArg(Arg<FontStylePtr>("basestyle", FontStylePtr()))
+ ;
+ TypeRegistry::get()->registerType(def);
+}
+
+FontStyle::FontStyle(const ArgList& args)
+{
+ args.setMembers(this);
+ setAlignment(args.getArgVal<string>("alignment"));
+ setWrapMode(args.getArgVal<string>("wrapmode"));
+ m_Color = colorStringToColor(m_sColorName);
+ if (args.getArgVal<FontStylePtr>("basestyle") != 0) {
+ applyBaseStyle(*(args.getArgVal<FontStylePtr>("basestyle")), args);
+ }
+}
+
+FontStyle::FontStyle()
+{
+ const ArgList& args = TypeRegistry::get()->getTypeDef("fontstyle").getDefaultArgs();
+ args.setMembers(this);
+ setAlignment(args.getArgVal<string>("alignment"));
+ setWrapMode(args.getArgVal<string>("wrapmode"));
+ m_Color = colorStringToColor(m_sColorName);
+}
+
+FontStyle::~FontStyle()
+{
+}
+
+template<class ATTR>
+void setDefaultedAttr(ATTR& member, const string& sName, const ArgList& args,
+ const ATTR& attr)
+{
+ if (args.getArg(sName)->isDefault()) {
+ member = attr;
+ }
+}
+
+void FontStyle::applyBaseStyle(const FontStyle& baseStyle, const ArgList& args)
+{
+ setDefaultedAttr(m_sName, "font", args, baseStyle.getFont());
+ setDefaultedAttr(m_sVariant, "variant", args, baseStyle.getFontVariant());
+ setDefaultedAttr(m_sColorName, "color", args, baseStyle.getColor());
+ m_Color = colorStringToColor(m_sColorName);
+ setDefaultedAttr(m_AAGamma, "aagamma", args, baseStyle.getAAGamma());
+ setDefaultedAttr(m_Size, "fontsize", args, baseStyle.getFontSize());
+ setDefaultedAttr(m_Indent, "indent", args, baseStyle.getIndent());
+ setDefaultedAttr(m_LineSpacing, "linespacing", args, baseStyle.getLineSpacing());
+ setDefaultedAttr(m_Alignment, "alignment", args, baseStyle.getAlignmentVal());
+ setDefaultedAttr(m_WrapMode, "wrapmode", args, baseStyle.getWrapModeVal());
+ setDefaultedAttr(m_bJustify, "justify", args, baseStyle.getJustify());
+ setDefaultedAttr(m_LetterSpacing, "letterspacing", args,
+ baseStyle.getLetterSpacing());
+ setDefaultedAttr(m_bHint, "hint", args, baseStyle.getHint());
+}
+
+template<class ARG>
+void setDefaultedArg(ARG& member, const string& sName, const ArgList& args)
+{
+ if (!args.getArg(sName)->isDefault()) {
+ member = args.getArgVal<ARG>(sName);
+ }
+}
+
+void FontStyle::setDefaultedArgs(const ArgList& args)
+{
+ // Warning: The ArgList here contains args that are for a different class originally,
+ // so the member offsets are wrong.
+ setDefaultedArg(m_sName, "font", args);
+ setDefaultedArg(m_sVariant, "variant", args);
+ setDefaultedArg(m_sColorName, "color", args);
+ setColor(m_sColorName);
+ setDefaultedArg(m_AAGamma, "aagamma", args);
+ setDefaultedArg(m_Size, "fontsize", args);
+ setDefaultedArg(m_Indent, "indent", args);
+ setDefaultedArg(m_LineSpacing, "linespacing", args);
+ string s = getAlignment();
+ setDefaultedArg(s, "alignment", args);
+ setAlignment(s);
+ s = getWrapMode();
+ setDefaultedArg(s, "wrapmode", args);
+ setWrapMode(s);
+ setDefaultedArg(m_bJustify, "justify", args);
+ setDefaultedArg(m_LetterSpacing, "letterspacing", args);
+ setDefaultedArg(m_bHint, "hint", args);
+}
+
+const std::string& FontStyle::getFont() const
+{
+ return m_sName;
+}
+
+void FontStyle::setFont(const string& sName)
+{
+ m_sName = sName;
+}
+
+const std::string& FontStyle::getFontVariant() const
+{
+ return m_sVariant;
+}
+
+void FontStyle::setFontVariant(const std::string& sVariant)
+{
+ m_sVariant = sVariant;
+}
+
+const std::string& FontStyle::getColor() const
+{
+ return m_sColorName;
+}
+
+void FontStyle::setColor(const string& sColor)
+{
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(m_sColorName);
+}
+
+float FontStyle::getAAGamma() const
+{
+ return m_AAGamma;
+}
+
+void FontStyle::setAAGamma(float gamma)
+{
+ m_AAGamma = gamma;
+}
+
+float FontStyle::getFontSize() const
+{
+ return m_Size;
+}
+
+void FontStyle::setFontSize(float size)
+{
+ if (size <= 1) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Font size < 1 is illegal.");
+ }
+ m_Size = size;
+}
+
+int FontStyle::getIndent() const
+{
+ return m_Indent;
+}
+
+void FontStyle::setIndent(int indent)
+{
+ m_Indent = indent;
+}
+
+float FontStyle::getLineSpacing() const
+{
+ return m_LineSpacing;
+}
+
+void FontStyle::setLineSpacing(float lineSpacing)
+{
+ m_LineSpacing = lineSpacing;
+}
+
+string FontStyle::getAlignment() const
+{
+ switch(m_Alignment) {
+ case PANGO_ALIGN_LEFT:
+ return "left";
+ case PANGO_ALIGN_CENTER:
+ return "center";
+ case PANGO_ALIGN_RIGHT:
+ return "right";
+ default:
+ AVG_ASSERT(false);
+ return "";
+ }
+}
+
+void FontStyle::setAlignment(const string& sAlign)
+{
+ if (sAlign == "left") {
+ m_Alignment = PANGO_ALIGN_LEFT;
+ } else if (sAlign == "center") {
+ m_Alignment = PANGO_ALIGN_CENTER;
+ } else if (sAlign == "right") {
+ m_Alignment = PANGO_ALIGN_RIGHT;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Alignment "+sAlign+" not supported."));
+ }
+}
+
+void FontStyle::setWrapMode(const string& sWrapMode)
+{
+ if (sWrapMode == "word") {
+ m_WrapMode = PANGO_WRAP_WORD;
+ } else if (sWrapMode == "char") {
+ m_WrapMode = PANGO_WRAP_CHAR;
+ } else if (sWrapMode == "wordchar") {
+ m_WrapMode = PANGO_WRAP_WORD_CHAR;
+ } else {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "FontStyle wrapping mode "+sWrapMode+" not supported."));
+ }
+}
+
+string FontStyle::getWrapMode() const
+{
+ switch(m_WrapMode) {
+ case PANGO_WRAP_WORD:
+ return "word";
+ case PANGO_WRAP_CHAR:
+ return "char";
+ case PANGO_WRAP_WORD_CHAR:
+ return "wordchar";
+ default:
+ AVG_ASSERT(false);
+ return "";
+ }
+}
+
+bool FontStyle::getJustify() const
+{
+ return m_bJustify;
+}
+
+void FontStyle::setJustify(bool bJustify)
+{
+ m_bJustify = bJustify;
+}
+
+float FontStyle::getLetterSpacing() const
+{
+ return m_LetterSpacing;
+}
+
+void FontStyle::setLetterSpacing(float letterSpacing)
+{
+ m_LetterSpacing = letterSpacing;
+}
+
+bool FontStyle::getHint() const
+{
+ return m_bHint;
+}
+
+void FontStyle::setHint(bool bHint)
+{
+ m_bHint = bHint;
+}
+
+PangoAlignment FontStyle::getAlignmentVal() const
+{
+ return m_Alignment;
+}
+
+PangoWrapMode FontStyle::getWrapModeVal() const
+{
+ return m_WrapMode;
+}
+
+Pixel32 FontStyle::getColorVal() const
+{
+ return m_Color;
+}
+
+}
diff --git a/src/player/FontStyle.h b/src/player/FontStyle.h
new file mode 100644
index 0000000..513aa14
--- /dev/null
+++ b/src/player/FontStyle.h
@@ -0,0 +1,114 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _FontStyle_H_
+#define _FontStyle_H_
+
+#include "../api.h"
+
+#include "ExportedObject.h"
+
+#include "../graphics/Pixel32.h"
+
+#include <pango/pango.h>
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace avg {
+
+class FontStyle;
+typedef boost::shared_ptr<class FontStyle> FontStylePtr;
+
+class AVG_API FontStyle: public ExportedObject
+{
+ public:
+ static void registerType();
+
+ FontStyle(const ArgList& args);
+ FontStyle();
+ virtual ~FontStyle();
+
+ void setDefaultedArgs(const ArgList& args);
+
+ const std::string& getFont() const;
+ void setFont(const std::string& sName);
+
+ const std::string& getFontVariant() const;
+ void setFontVariant(const std::string& sVariant);
+
+ const std::string& getColor() const;
+ void setColor(const std::string& sColor);
+
+ virtual float getAAGamma() const;
+ virtual void setAAGamma(float gamma);
+
+ float getFontSize() const;
+ void setFontSize(float size);
+
+ int getIndent() const;
+ void setIndent(int indent);
+
+ float getLineSpacing() const;
+ void setLineSpacing(float lineSpacing);
+
+ std::string getAlignment() const;
+ void setAlignment(const std::string& sAlignment);
+
+ std::string getWrapMode() const;
+ void setWrapMode(const std::string& sWrapMode);
+
+ bool getJustify() const;
+ void setJustify(bool bJustify);
+
+ float getLetterSpacing() const;
+ void setLetterSpacing(float letterSpacing);
+
+ bool getHint() const;
+ void setHint(bool bHint);
+
+ PangoAlignment getAlignmentVal() const;
+ PangoWrapMode getWrapModeVal() const;
+ Pixel32 getColorVal() const;
+
+ private:
+ void applyBaseStyle(const FontStyle& baseStyle, const ArgList& args);
+
+ std::string m_sName;
+ std::string m_sVariant;
+ std::string m_sColorName;
+ Pixel32 m_Color;
+ float m_AAGamma;
+ float m_Size;
+ int m_Indent;
+ float m_LineSpacing;
+ PangoAlignment m_Alignment;
+ PangoWrapMode m_WrapMode;
+ bool m_bJustify;
+ float m_LetterSpacing;
+ bool m_bHint;
+
+};
+
+typedef boost::shared_ptr<class FontStyle> FontStylePtr;
+
+}
+#endif
diff --git a/src/player/HueSatFXNode.cpp b/src/player/HueSatFXNode.cpp
index c65e9fa..b15f333 100644
--- a/src/player/HueSatFXNode.cpp
+++ b/src/player/HueSatFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,8 @@
#include "../base/ObjectCounter.h"
#include "../base/Logger.h"
-#include "../graphics/ShaderRegistry.h"
+
+#include "../graphics/BitmapLoader.h"
#include<sstream>
@@ -32,13 +33,12 @@ using namespace std;
namespace avg {
-HueSatFXNode::HueSatFXNode(int hue, int saturation, int lightness,
- bool tint):
- FXNode(),
- m_fHue(hue),
- m_fLightnessOffset(lightness),
- m_fSaturation(saturation),
- m_bColorize(tint)
+HueSatFXNode::HueSatFXNode(int hue, int saturation, int lightness, bool bColorize)
+ : FXNode(),
+ m_fHue(hue),
+ m_fLightnessOffset(lightness),
+ m_fSaturation(saturation),
+ m_bColorize(bColorize)
{
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -94,9 +94,9 @@ void HueSatFXNode::setHue(int hue)
void HueSatFXNode::setSaturation(int saturation)
{
- if(m_bColorize){
+ if (m_bColorize) {
m_fSaturation = clamp(saturation, 0, 100);
- }else{
+ } else {
m_fSaturation = clamp(saturation, -100, 100);
}
setFilterParams();
@@ -104,23 +104,19 @@ void HueSatFXNode::setSaturation(int saturation)
void HueSatFXNode::setLightnessOffset(int lightnessOffset)
{
- m_fLightnessOffset= clamp(lightnessOffset, -100, 100);
+ m_fLightnessOffset = clamp(lightnessOffset, -100, 100);
setFilterParams();
}
void HueSatFXNode::setColorizing(bool colorize)
{
m_bColorize = colorize;
- m_fHue = 0;
- m_fLightnessOffset = 0;
- m_fSaturation = m_bColorize ? 50 : 0;
setFilterParams();
}
GPUFilterPtr HueSatFXNode::createFilter(const IntPoint& size)
{
- filterPtr = GPUHueSatFilterPtr(new GPUHueSatFilter(size, B8G8R8A8,
- false));
+ filterPtr = GPUHueSatFilterPtr(new GPUHueSatFilter(size, true, false));
setFilterParams();
return filterPtr;
}
@@ -145,9 +141,9 @@ std::string HueSatFXNode::toString()
int HueSatFXNode::clamp(int val, int min, int max)
{
int result = val;
- if(val < min){
+ if (val < min) {
result = min;
- }else if(val > max){
+ } else if (val > max) {
result = max;
}
return result;
diff --git a/src/player/HueSatFXNode.h b/src/player/HueSatFXNode.h
index 780c271..410a7ec 100644
--- a/src/player/HueSatFXNode.h
+++ b/src/player/HueSatFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -37,8 +37,7 @@ namespace avg {
class AVG_API HueSatFXNode : public FXNode {
public:
- HueSatFXNode(int hue=0, int saturation=0, int lightness=0,
- bool tint=false);
+ HueSatFXNode(int hue=0, int saturation=0, int lightness=0, bool bColorize=false);
virtual ~HueSatFXNode();
virtual void disconnect();
@@ -67,7 +66,7 @@ private:
};
typedef boost::shared_ptr<HueSatFXNode> HueSatFXNodePtr;
-} //end namespace avg
+}
#endif
diff --git a/src/player/IBitmapLoadedListener.h b/src/player/IBitmapLoadedListener.h
new file mode 100644
index 0000000..da32f8b
--- /dev/null
+++ b/src/player/IBitmapLoadedListener.h
@@ -0,0 +1,44 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _IBitmapLoadedListener_H_
+#define _IBitmapLoadedListener_H_
+
+#include "../api.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace avg {
+
+class Bitmap;
+typedef boost::shared_ptr<Bitmap> BitmapPtr;
+class Exception;
+
+class AVG_API IBitmapLoadedListener {
+public:
+ virtual ~IBitmapLoadedListener() {};
+ virtual void onBitmapLoaded(BitmapPtr pBmp) = 0;
+ virtual void onBitmapLoadError(const Exception* e) = 0;
+};
+
+}
+
+#endif
diff --git a/src/player/IInputDevice.h b/src/player/IInputDevice.h
index 709809d..b155efe 100644
--- a/src/player/IInputDevice.h
+++ b/src/player/IInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/Image.cpp b/src/player/Image.cpp
index 35e6801..5ac5fb9 100644
--- a/src/player/Image.cpp
+++ b/src/player/Image.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,8 @@
#include "../base/ObjectCounter.h"
#include "../graphics/Filterfliprgb.h"
+#include "../graphics/TextureMover.h"
+#include "../graphics/BitmapLoader.h"
#include "OGLSurface.h"
#include "OffscreenCanvas.h"
@@ -122,8 +124,8 @@ void Image::setEmpty()
void Image::setFilename(const std::string& sFilename, TextureCompression comp)
{
assertValid();
- AVG_TRACE(Logger::MEMORY, "Loading " << sFilename);
- BitmapPtr pBmp(new Bitmap(sFilename));
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Loading " << sFilename);
+ BitmapPtr pBmp = loadBitmap(sFilename);
if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) {
throw Exception(AVG_ERR_UNSUPPORTED,
"B5G6R5-compressed textures with an alpha channel are not supported.");
@@ -136,6 +138,9 @@ void Image::setFilename(const std::string& sFilename, TextureCompression comp)
switch (comp) {
case TEXTURECOMPRESSION_B5G6R5:
m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), B5G6R5, sFilename));
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
m_pBmp->copyPixels(*pBmp);
break;
case TEXTURECOMPRESSION_NONE:
@@ -165,10 +170,13 @@ void Image::setBitmap(BitmapPtr pBmp, TextureCompression comp)
PixelFormat pf;
switch (comp) {
case TEXTURECOMPRESSION_NONE:
- pf = calcSurfacePF(*pBmp);
+ pf = pBmp->getPixelFormat();
break;
case TEXTURECOMPRESSION_B5G6R5:
pf = B5G6R5;
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
break;
default:
assert(false);
@@ -179,7 +187,7 @@ void Image::setBitmap(BitmapPtr pBmp, TextureCompression comp)
m_pSurface->getPixelFormat() != pf)
{
pTex = GLTexturePtr(new GLTexture(pBmp->getSize(), pf,
- m_Material.getUseMipmaps(), m_Material.getWrapSMode(),
+ m_Material.getUseMipmaps(), 0, m_Material.getWrapSMode(),
m_Material.getWrapTMode()));
m_pSurface->create(pf, pTex);
}
@@ -265,23 +273,25 @@ IntPoint Image::getSize()
PixelFormat Image::getPixelFormat()
{
- if (m_Source == NONE) {
- return B8G8R8X8;
+ PixelFormat pf;
+ if (BitmapLoader::get()->isBlueFirst()) {
+ pf = B8G8R8X8;
} else {
+ pf = R8G8B8X8;
+ }
+ if (m_Source != NONE) {
switch (m_State) {
case CPU:
- if (m_Source == SCENE) {
- return B8G8R8X8;
- } else {
- return m_pBmp->getPixelFormat();
+ if (m_Source != SCENE) {
+ pf = m_pBmp->getPixelFormat();
}
case GPU:
- return m_pSurface->getPixelFormat();
+ pf = m_pSurface->getPixelFormat();
default:
AVG_ASSERT(false);
- return B8G8R8X8;
}
}
+ return pf;
}
OGLSurface* Image::getSurface()
@@ -327,34 +337,16 @@ string Image::compression2String(TextureCompression compression)
void Image::setupSurface()
{
- PixelFormat pf = calcSurfacePF(*m_pBmp);
+ PixelFormat pf = m_pBmp->getPixelFormat();
+// cerr << "setupSurface: " << pf << endl;
GLTexturePtr pTex(new GLTexture(m_pBmp->getSize(), pf, m_Material.getUseMipmaps(),
- m_Material.getWrapSMode(), m_Material.getWrapTMode()));
+ 0, m_Material.getWrapSMode(), m_Material.getWrapTMode()));
m_pSurface->create(pf, pTex);
TextureMoverPtr pMover = TextureMover::create(m_pBmp->getSize(), pf, GL_STATIC_DRAW);
- BitmapPtr pMoverBmp = pMover->lock();
- pMoverBmp->copyPixels(*m_pBmp);
- pMover->unlock();
- pMover->moveToTexture(*pTex);
+ pMover->moveBmpToTexture(m_pBmp, *pTex);
m_pBmp = BitmapPtr();
}
-PixelFormat Image::calcSurfacePF(const Bitmap& bmp)
-{
- PixelFormat pf;
- pf = B8G8R8X8;
- if (bmp.hasAlpha()) {
- pf = B8G8R8A8;
- }
- if (bmp.getPixelFormat() == I8) {
- pf = I8;
- }
- if (bmp.getPixelFormat() == B5G6R5) {
- pf = B5G6R5;
- }
- return pf;
-}
-
bool Image::changeSource(Source newSource)
{
if (newSource != m_Source) {
@@ -388,8 +380,7 @@ void Image::assertValid() const
AVG_ASSERT((m_Source == SCENE) == bool(m_pCanvas));
switch (m_State) {
case CPU:
- AVG_ASSERT((m_Source == FILE || m_Source == BITMAP) ==
- bool(m_pBmp));
+ AVG_ASSERT((m_Source == FILE || m_Source == BITMAP) == bool(m_pBmp));
AVG_ASSERT(!(m_pSurface->isCreated()));
break;
case GPU:
diff --git a/src/player/Image.h b/src/player/Image.h
index f7be873..6b6ad83 100644
--- a/src/player/Image.h
+++ b/src/player/Image.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,7 @@
#include "MaterialInfo.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../graphics/Bitmap.h"
#include <boost/shared_ptr.hpp>
@@ -76,7 +76,6 @@ class AVG_API Image
private:
void setupSurface();
- PixelFormat calcSurfacePF(const Bitmap& Bmp);
bool changeSource(Source newSource);
void assertValid() const;
diff --git a/src/player/ImageNode.cpp b/src/player/ImageNode.cpp
index d584ef4..18543c2 100644
--- a/src/player/ImageNode.cpp
+++ b/src/player/ImageNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "ImageNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "OGLSurface.h"
#include "Player.h"
#include "OffscreenCanvas.h"
@@ -41,12 +41,13 @@ using namespace std;
namespace avg {
-NodeDefinition ImageNode::createDefinition()
+void ImageNode::registerType()
{
- return NodeDefinition("image", Node::buildNode<ImageNode>)
- .extendDefinition(RasterNode::createDefinition())
+ TypeDefinition def = TypeDefinition("image", "rasternode",
+ ExportedObject::buildObject<ImageNode>)
.addArg(Arg<UTF8String>("href", "", false, offsetof(ImageNode, m_href)))
.addArg(Arg<string>("compression", "none"));
+ TypeRegistry::get()->registerType(def);
}
ImageNode::ImageNode(const ArgList& args)
@@ -73,7 +74,6 @@ void ImageNode::connectDisplay()
if (m_pImage->getSource() == Image::SCENE) {
checkCanvasValid(m_pImage->getCanvas());
}
- getSurface()->attach();
m_pImage->moveToGPU();
RasterNode::connectDisplay();
if (m_pImage->getSource() == Image::SCENE) {
@@ -135,33 +135,40 @@ const string ImageNode::getCompression() const
void ImageNode::setBitmap(BitmapPtr pBmp)
{
- if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER)
- {
+ if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER) {
m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
}
m_pImage->setBitmap(pBmp, m_Compression);
if (getState() == Node::NS_CANRENDER) {
- bind();
+ newSurface();
}
m_href = "";
setViewport(-32767, -32767, -32767, -32767);
}
-void ImageNode::preRender()
+static ProfilingZoneID PrerenderProfilingZone("ImageNode::prerender");
+
+void ImageNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
+ ScopeTimer timer(PrerenderProfilingZone);
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
if (isVisible()) {
- renderFX(getSize(), Pixel32(255, 255, 255, 255), bool(m_pImage->getCanvas()));
+ bool bHasCanvas = bool(m_pImage->getCanvas());
+ if (m_pImage->getSource() != Image::NONE) {
+ renderFX(getSize(), Pixel32(255, 255, 255, 255), bHasCanvas, bHasCanvas);
+ }
}
+ calcVertexArray(pVA);
}
static ProfilingZoneID RenderProfilingZone("ImageNode::render");
-void ImageNode::render(const DRect& Rect)
+void ImageNode::render()
{
ScopeTimer Timer(RenderProfilingZone);
if (m_pImage->getSource() != Image::NONE) {
- blt32(getSize(), getEffectiveOpacity(), getBlendMode(),
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode(),
bool(m_pImage->getCanvas()));
}
}
@@ -184,21 +191,25 @@ void ImageNode::checkReload()
if (getState() == NS_CANRENDER) {
pCanvas->addDependentCanvas(getCanvas());
}
+ newSurface();
} else {
- Node::checkReload(m_href, m_pImage, m_Compression);
+ bool bNewImage = Node::checkReload(m_href, m_pImage, m_Compression);
+ if (bNewImage) {
+ newSurface();
+ }
}
setViewport(-32767, -32767, -32767, -32767);
RasterNode::checkReload();
}
-void ImageNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void ImageNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
if (reactsToMouseEvents()) {
OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
if (pCanvas && pCanvas->getHandleEvents()) {
- DPoint nodeSize(getSize());
- DPoint canvasSize(pCanvas->getSize());
- DPoint localPos(pos.x*(canvasSize.x/nodeSize.x),
+ glm::vec2 nodeSize(getSize());
+ glm::vec2 canvasSize(pCanvas->getSize());
+ glm::vec2 localPos(pos.x*(canvasSize.x/nodeSize.x),
pos.y*(canvasSize.y/nodeSize.y));
pCanvas->getRootNode()->getElementsByPos(localPos, pElements);
} else {
diff --git a/src/player/ImageNode.h b/src/player/ImageNode.h
index e460c98..fce7d71 100644
--- a/src/player/ImageNode.h
+++ b/src/player/ImageNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -36,7 +36,7 @@ namespace avg {
class AVG_API ImageNode : public RasterNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
ImageNode(const ArgList& args);
virtual ~ImageNode();
@@ -50,10 +50,11 @@ class AVG_API ImageNode : public RasterNode
const std::string getCompression() const;
void setBitmap(BitmapPtr pBmp);
- virtual void preRender();
- virtual void render(const DRect& Rect);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
virtual BitmapPtr getBitmap();
virtual IntPoint getMediaSize();
diff --git a/src/player/InvertFXNode.cpp b/src/player/InvertFXNode.cpp
index 589675a..c99cfa0 100644
--- a/src/player/InvertFXNode.cpp
+++ b/src/player/InvertFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,8 @@
#include "../base/ObjectCounter.h"
#include "../base/Logger.h"
-#include "../graphics/ShaderRegistry.h"
+
+#include "../graphics/BitmapLoader.h"
#include <sstream>
@@ -31,13 +32,14 @@ using namespace std;
namespace avg {
-InvertFXNode::InvertFXNode():
- FXNode()
+InvertFXNode::InvertFXNode()
+ : FXNode()
{
ObjectCounter::get()->incRef(&typeid(*this));
}
-InvertFXNode::~InvertFXNode() {
+InvertFXNode::~InvertFXNode()
+{
ObjectCounter::get()->decRef(&typeid(*this));
}
@@ -49,8 +51,7 @@ void InvertFXNode::disconnect()
GPUFilterPtr InvertFXNode::createFilter(const IntPoint& size)
{
- filterPtr = GPUInvertFilterPtr(new GPUInvertFilter(size, B8G8R8A8,
- false));
+ filterPtr = GPUInvertFilterPtr(new GPUInvertFilter(size, true, false));
setDirty();
return filterPtr;
}
diff --git a/src/player/InvertFXNode.h b/src/player/InvertFXNode.h
index 5b148b2..53a6973 100644
--- a/src/player/InvertFXNode.h
+++ b/src/player/InvertFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/KeyEvent.cpp b/src/player/KeyEvent.cpp
index b922280..5ff8ce3 100644
--- a/src/player/KeyEvent.cpp
+++ b/src/player/KeyEvent.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -72,8 +72,8 @@ int KeyEvent::getModifiers() const
void KeyEvent::trace()
{
Event::trace();
- AVG_TRACE(Logger::EVENTS2, "Scancode: " << m_ScanCode
- << ", Keycode: " << m_KeyCode << ", KeyString: "
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG,
+ "Scancode: " << m_ScanCode << ", Keycode: " << m_KeyCode << ", KeyString: "
<< m_KeyString << ", Modifiers: " << m_Modifiers);
}
diff --git a/src/player/KeyEvent.h b/src/player/KeyEvent.h
index 7559b7c..84ef8cf 100644
--- a/src/player/KeyEvent.h
+++ b/src/player/KeyEvent.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/LibMTDevInputDevice.cpp b/src/player/LibMTDevInputDevice.cpp
index 30eb11c..edfd061 100644
--- a/src/player/LibMTDevInputDevice.cpp
+++ b/src/player/LibMTDevInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,6 @@
#include "TouchStatus.h"
#include "../base/Logger.h"
-#include "../base/Point.h"
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"
#include "../base/OSHelper.h"
@@ -86,7 +85,8 @@ void LibMTDevInputDevice::start()
m_Dimensions.br.y = pAbsInfo->maximum;
MultitouchInputDevice::start();
- AVG_TRACE(Logger::CONFIG, "Linux MTDev Multitouch event source created.");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Linux MTDev Multitouch event source created.");
}
std::vector<EventPtr> LibMTDevInputDevice::pollEvents()
@@ -117,7 +117,7 @@ std::vector<EventPtr> LibMTDevInputDevice::pollEvents()
TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
TouchEventPtr pUpEvent =
boost::dynamic_pointer_cast<TouchEvent>(
- pOldEvent->cloneAs(Event::CURSORUP));
+ pOldEvent->cloneAs(Event::CURSOR_UP));
pTouchStatus->pushEvent(pUpEvent);
removeTouchStatus(pTouch->id);
}
@@ -162,14 +162,15 @@ void LibMTDevInputDevice::processEvents(const set<int>& changedIDs)
if (!pTouchStatus) {
// Down
m_LastID++;
- TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSORDOWN,
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN,
touch.pos);
// cerr << "down <" << touch.id << "> --> [" << m_LastID << "]" << endl;
addTouchStatus((long)touch.id, pEvent);
} else {
// cerr << "move <" << touch.id << "> --> " << touch.pos << endl;
// Move
- TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION, touch.pos);
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION,
+ touch.pos);
pTouchStatus->pushEvent(pEvent);
}
}
@@ -179,9 +180,9 @@ void LibMTDevInputDevice::processEvents(const set<int>& changedIDs)
TouchEventPtr LibMTDevInputDevice::createEvent(int id, Event::Type type, IntPoint pos)
{
- DPoint size = getWindowSize();
- DPoint normPos = DPoint(double(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
- double(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
+ glm::vec2 size(Player::get()->getScreenResolution());
+ glm::vec2 normPos(float(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
+ float(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
IntPoint screenPos(int(normPos.x*size.x+0.5), int(normPos.y*size.y+0.5));
return TouchEventPtr(new TouchEvent(id, type, screenPos, Event::TOUCH));
}
diff --git a/src/player/LibMTDevInputDevice.h b/src/player/LibMTDevInputDevice.h
index cb07695..d8417c1 100644
--- a/src/player/LibMTDevInputDevice.h
+++ b/src/player/LibMTDevInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/LineNode.cpp b/src/player/LineNode.cpp
index 1ee299f..39a1b57 100644
--- a/src/player/LineNode.cpp
+++ b/src/player/LineNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "LineNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/Exception.h"
@@ -32,15 +32,16 @@ using namespace std;
namespace avg {
-NodeDefinition LineNode::createDefinition()
+void LineNode::registerType()
{
- return NodeDefinition("line", Node::buildNode<LineNode>)
- .extendDefinition(VectorNode::createDefinition())
- .addArg(Arg<DPoint>("pos1", DPoint(0,0), false, offsetof(LineNode, m_P1)))
- .addArg(Arg<DPoint>("pos2", DPoint(0,0), false, offsetof(LineNode, m_P2)))
- .addArg(Arg<double>("texcoord1", 0, false, offsetof(LineNode, m_TC1)))
- .addArg(Arg<double>("texcoord2", 1, false, offsetof(LineNode, m_TC2)))
+ TypeDefinition def = TypeDefinition("line", "vectornode",
+ ExportedObject::buildObject<LineNode>)
+ .addArg(Arg<glm::vec2>("pos1", glm::vec2(0,0), false, offsetof(LineNode, m_P1)))
+ .addArg(Arg<glm::vec2>("pos2", glm::vec2(0,0), false, offsetof(LineNode, m_P2)))
+ .addArg(Arg<float>("texcoord1", 0, false, offsetof(LineNode, m_TC1)))
+ .addArg(Arg<float>("texcoord2", 1, false, offsetof(LineNode, m_TC2)))
;
+ TypeRegistry::get()->registerType(def);
}
LineNode::LineNode(const ArgList& args)
@@ -53,53 +54,53 @@ LineNode::~LineNode()
{
}
-const DPoint& LineNode::getPos1() const
+const glm::vec2& LineNode::getPos1() const
{
return m_P1;
}
-void LineNode::setPos1(const DPoint& pt)
+void LineNode::setPos1(const glm::vec2& pt)
{
m_P1 = pt;
setDrawNeeded();
}
-const DPoint& LineNode::getPos2() const
+const glm::vec2& LineNode::getPos2() const
{
return m_P2;
}
-void LineNode::setPos2(const DPoint& pt)
+void LineNode::setPos2(const glm::vec2& pt)
{
m_P2 = pt;
setDrawNeeded();
}
-double LineNode::getTexCoord1() const
+float LineNode::getTexCoord1() const
{
return m_TC1;
}
-void LineNode::setTexCoord1(double tc)
+void LineNode::setTexCoord1(float tc)
{
m_TC1 = tc;
setDrawNeeded();
}
-double LineNode::getTexCoord2() const
+float LineNode::getTexCoord2() const
{
return m_TC2;
}
-void LineNode::setTexCoord2(double tc)
+void LineNode::setTexCoord2(float tc)
{
m_TC2 = tc;
setDrawNeeded();
}
-void LineNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void LineNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
- pVertexArray->addLineData(color, m_P1, m_P2, getStrokeWidth(), m_TC1, m_TC2);
+ pVertexData->addLineData(color, m_P1, m_P2, getStrokeWidth(), m_TC1, m_TC2);
}
}
diff --git a/src/player/LineNode.h b/src/player/LineNode.h
index daa5fbd..2843b48 100644
--- a/src/player/LineNode.h
+++ b/src/player/LineNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,30 +32,30 @@ namespace avg {
class AVG_API LineNode : public VectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
LineNode(const ArgList& args);
virtual ~LineNode();
- const DPoint& getPos1() const;
- void setPos1(const DPoint& pt);
+ const glm::vec2& getPos1() const;
+ void setPos1(const glm::vec2& pt);
- const DPoint& getPos2() const;
- void setPos2(const DPoint& pt);
+ const glm::vec2& getPos2() const;
+ void setPos2(const glm::vec2& pt);
- double getTexCoord1() const;
- void setTexCoord1(double tc);
+ float getTexCoord1() const;
+ void setTexCoord1(float tc);
- double getTexCoord2() const;
- void setTexCoord2(double tc);
+ float getTexCoord2() const;
+ void setTexCoord2(float tc);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- DPoint m_P1;
- DPoint m_P2;
- double m_TC1;
- double m_TC2;
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ float m_TC1;
+ float m_TC2;
};
}
diff --git a/src/player/MainCanvas.cpp b/src/player/MainCanvas.cpp
index c85db63..2af29fc 100644
--- a/src/player/MainCanvas.cpp
+++ b/src/player/MainCanvas.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -59,7 +59,7 @@ void MainCanvas::setRoot(NodePtr pRootNode)
void MainCanvas::initPlayback(const SDLDisplayEnginePtr& pDisplayEngine)
{
m_pDisplayEngine = pDisplayEngine;
- Canvas::initPlayback(GLContext::getCurrent()->getConfig().m_MultiSampleSamples);
+ Canvas::initPlayback(GLContext::getMain()->getConfig().m_MultiSampleSamples);
}
BitmapPtr MainCanvas::screenshot() const
@@ -73,10 +73,15 @@ BitmapPtr MainCanvas::screenshot() const
static ProfilingZoneID RootRenderProfilingZone("Render MainCanvas");
-void MainCanvas::render()
+void MainCanvas::renderTree()
{
- Canvas::render(m_pDisplayEngine->getWindowSize(), false, FBOPtr(),
- RootRenderProfilingZone);
+ preRender();
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ GLContext::checkError("Canvas::renderTree: BindFramebuffer()");
+ {
+ ScopeTimer Timer(RootRenderProfilingZone);
+ Canvas::render(m_pDisplayEngine->getWindowSize(), false);
+ }
}
}
diff --git a/src/player/MainCanvas.h b/src/player/MainCanvas.h
index c6d2310..55f68d6 100644
--- a/src/player/MainCanvas.h
+++ b/src/player/MainCanvas.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -41,7 +41,7 @@ class AVG_API MainCanvas: public Canvas
virtual BitmapPtr screenshot() const;
private:
- virtual void render();
+ virtual void renderTree();
SDLDisplayEnginePtr m_pDisplayEngine;
};
diff --git a/src/player/Makefile.am b/src/player/Makefile.am
index 6dfd5e2..40d95d4 100644
--- a/src/player/Makefile.am
+++ b/src/player/Makefile.am
@@ -1,17 +1,26 @@
-INCLUDES = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
- @PANGOFT2_CFLAGS@ @PYTHON_INCLUDES@ @GL_CFLAGS@ @FFMPEG_CFLAGS@ \
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
+ @PANGOFT2_CFLAGS@ @PYTHON_CPPFLAGS@ @GL_CFLAGS@ \
@DC1394_2_CFLAGS@ @LIBRSVG_CFLAGS@ @FONTCONFIG_CFLAGS@ \
$(MTDEV_CFLAGS)
-
+
if APPLE
APPLE_SOURCES = SDLMain.m AppleTrackpadInputDevice.cpp
- APPLE_LINKFLAGS=-read_only_relocs suppress -F/System/Library/PrivateFrameworks -framework MultitouchSupport
+ APPLE_LINKFLAGS = -read_only_relocs suppress -F/System/Library/PrivateFrameworks \
+ -framework MultitouchSupport
XGL_LIBS =
else
APPLE_SOURCES =
- APPLE_LINKFLAGS=
+ APPLE_LINKFLAGS =
+if ENABLE_RPI
+ XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
+if ENABLE_EGL
+ XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+else
XGL_LIBS = -lXxf86vm -lX11
endif
+endif
+endif
if ENABLE_MTDEV
MTDEV_SOURCES = LibMTDevInputDevice.cpp
@@ -37,66 +46,76 @@ endif
GL_SOURCES = OGLSurface.cpp SDLDisplayEngine.cpp
GL_INCLUDES = OGLSurface.h SDLDisplayEngine.h
-ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
-ALL_H = Player.h PluginManager.h IInputDevice.h VideoNode.h \
- DisplayEngine.h NodeRegistry.h Arg.h ArgBase.h ArgList.h \
- Node.h AreaNode.h DisplayParams.h NodeDefinition.h TextEngine.h \
+ALL_H = Player.h PluginManager.h IInputDevice.h VideoNode.h ExportedObject.h \
+ DisplayEngine.h TypeRegistry.h Arg.h ArgBase.h ArgList.h \
+ Node.h AreaNode.h DisplayParams.h TypeDefinition.h TextEngine.h \
AVGNode.h DivNode.h CursorState.h MaterialInfo.h Canvas.h MainCanvas.h \
Image.h ImageNode.h Timeout.h WordsNode.h WrapPython.h OffscreenCanvas.h \
EventDispatcher.h CursorEvent.h MouseEvent.h \
- Event.h KeyEvent.h PanoImageNode.h TestHelper.h CanvasNode.h \
+ Event.h KeyEvent.h TestHelper.h CanvasNode.h \
OffscreenCanvasNode.h MultitouchInputDevice.h \
RasterNode.h CameraNode.h TrackerInputDevice.h TrackerCalibrator.h \
TouchEvent.h Contact.h TouchStatus.h TrackerTouchStatus.h BoostPython.h \
- SoundNode.h \
+ SoundNode.h FontStyle.h \
VectorNode.h FilledVectorNode.h LineNode.h PolyLineNode.h RectNode.h \
CurveNode.h PolygonNode.h CircleNode.h Shape.h MeshNode.h FXNode.h \
NullFXNode.h BlurFXNode.h ShadowFXNode.h ChromaKeyFXNode.h HueSatFXNode.h \
InvertFXNode.h TUIOInputDevice.h VideoWriter.h VideoWriterThread.h \
- SVG.h SVGElement.h \
+ SVG.h SVGElement.h Publisher.h SubscriberInfo.h PublisherDefinition.h \
+ PublisherDefinitionRegistry.h MessageID.h VersionInfo.h \
+ PythonLogSink.h BitmapManager.h BitmapManagerThread.h IBitmapLoadedListener.h \
+ BitmapManagerMsg.h \
$(MTDEV_INCLUDES) $(GL_INCLUDES) $(XINPUT2_INCLUDES)
-TESTS=testcalibrator testplayer
+TESTS = testcalibrator testplayer
EXTRA_DIST = SDLMain.h
noinst_LTLIBRARIES = libplayer.la
noinst_PROGRAMS = testcalibrator testplayer
-testplayer_SOURCES=testplayer.cpp
+testplayer_SOURCES = testplayer.cpp
testplayer_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
../lmfit/liblmfit.la ../oscpack/liboscpack.la \
- @XML2_LIBS@ -l@BOOST_THREAD_LIB@ -lboost_system @PTHREAD_LIBS@ @PANGOFT2_LIBS@ @LIBRSVG_LIBS@\
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @PANGOFT2_LIBS@ \
+ @LIBRSVG_LIBS@ \
@DC1394_2_LIBS@ @GLU_LIBS@ $(ALL_GL_LIBS) $(XI2_1_LIBS) $(XI2_2_LIBS) \
- @LIBFFMPEG@ $(BOOST_PYTHON_LIBS) $(PYTHON_LIBS) @GDK_PIXBUF_LIBS@ \
+ @LIBFFMPEG@ $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) @GDK_PIXBUF_LIBS@ \
@FONTCONFIG_LIBS@
-
+
testplayer_LDFLAGS = $(APPLE_LINKFLAGS) -module -XCClinker
-testcalibrator_SOURCES=testcalibrator.cpp
+testcalibrator_SOURCES = testcalibrator.cpp
testcalibrator_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
../lmfit/liblmfit.la ../oscpack/liboscpack.la \
- @XML2_LIBS@ -l@BOOST_THREAD_LIB@ -lboost_system @PTHREAD_LIBS@ @LIBRSVG_LIBS@ @GDK_PIXBUF_LIBS@
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @LIBRSVG_LIBS@ \
+ @GDK_PIXBUF_LIBS@
-libplayer_la_LIBADD = $(BOOST_PYTHON_LIBS) $(PYTHON_LIBS) $(MTDEV_LIBS)
+libplayer_la_LIBADD = $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) $(MTDEV_LIBS)
libplayer_la_SOURCES = $(GL_SOURCES) \
- Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp \
- Player.cpp PluginManager.cpp NodeRegistry.cpp ArgBase.cpp ArgList.cpp \
+ Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp ExportedObject.cpp \
+ Player.cpp PluginManager.cpp TypeRegistry.cpp ArgBase.cpp ArgList.cpp \
DisplayEngine.cpp Canvas.cpp CanvasNode.cpp OffscreenCanvasNode.cpp \
- MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp \
- PanoImageNode.cpp WordsNode.cpp CameraNode.cpp NodeDefinition.cpp TextEngine.cpp \
+ MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp WrapPython.cpp \
+ WordsNode.cpp CameraNode.cpp TypeDefinition.cpp TextEngine.cpp \
Timeout.cpp Event.cpp DisplayParams.cpp CursorState.cpp MaterialInfo.cpp \
Image.cpp ImageNode.cpp EventDispatcher.cpp KeyEvent.cpp CursorEvent.cpp \
MouseEvent.cpp TouchEvent.cpp AVGNode.cpp TestHelper.cpp \
TrackerInputDevice.cpp TrackerTouchStatus.cpp TrackerCalibrator.cpp \
- SoundNode.cpp \
+ SoundNode.cpp FontStyle.cpp \
VectorNode.cpp FilledVectorNode.cpp LineNode.cpp PolyLineNode.cpp \
RectNode.cpp CurveNode.cpp PolygonNode.cpp CircleNode.cpp Shape.cpp MeshNode.cpp \
Contact.cpp TouchStatus.cpp OffscreenCanvas.cpp FXNode.cpp TUIOInputDevice.cpp \
NullFXNode.cpp BlurFXNode.cpp ShadowFXNode.cpp ChromaKeyFXNode.cpp \
InvertFXNode.cpp HueSatFXNode.cpp VideoWriter.cpp VideoWriterThread.cpp \
- SVG.cpp SVGElement.cpp \
+ SVG.cpp SVGElement.cpp Publisher.cpp SubscriberInfo.cpp PublisherDefinition.cpp \
+ PublisherDefinitionRegistry.cpp MessageID.cpp VersionInfo.cpp \
+ PythonLogSink.cpp BitmapManager.cpp BitmapManagerThread.cpp \
+ BitmapManagerMsg.cpp \
$(MTDEV_SOURCES) $(XINPUT2_SOURCES) $(APPLE_SOURCES) $(ALL_H)
libplayer_a_CXXFLAGS = -DPREFIXDIR=\"$(prefix)\"
diff --git a/src/player/Makefile.in b/src/player/Makefile.in
index 047b46a..a87be83 100644
--- a/src/player/Makefile.in
+++ b/src/player/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -44,11 +44,12 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_cxx_namespaces.m4 \
$(top_srcdir)/m4/ac_path_generic.m4 \
$(top_srcdir)/m4/ax_boost_thread.m4 \
- $(top_srcdir)/m4/ax_check_gl.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/python_dev.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/m4/ax_check_gl.m4 \
+ $(top_srcdir)/m4/ax_python_devel.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/avg_version.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -61,42 +62,52 @@ libplayer_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__libplayer_la_SOURCES_DIST = OGLSurface.cpp SDLDisplayEngine.cpp \
Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp \
- Player.cpp PluginManager.cpp NodeRegistry.cpp ArgBase.cpp \
- ArgList.cpp DisplayEngine.cpp Canvas.cpp CanvasNode.cpp \
- OffscreenCanvasNode.cpp MainCanvas.cpp Node.cpp \
- MultitouchInputDevice.cpp PanoImageNode.cpp WordsNode.cpp \
- CameraNode.cpp NodeDefinition.cpp TextEngine.cpp Timeout.cpp \
- Event.cpp DisplayParams.cpp CursorState.cpp MaterialInfo.cpp \
- Image.cpp ImageNode.cpp EventDispatcher.cpp KeyEvent.cpp \
- CursorEvent.cpp MouseEvent.cpp TouchEvent.cpp AVGNode.cpp \
- TestHelper.cpp TrackerInputDevice.cpp TrackerTouchStatus.cpp \
- TrackerCalibrator.cpp SoundNode.cpp VectorNode.cpp \
- FilledVectorNode.cpp LineNode.cpp PolyLineNode.cpp \
- RectNode.cpp CurveNode.cpp PolygonNode.cpp CircleNode.cpp \
- Shape.cpp MeshNode.cpp Contact.cpp TouchStatus.cpp \
- OffscreenCanvas.cpp FXNode.cpp TUIOInputDevice.cpp \
- NullFXNode.cpp BlurFXNode.cpp ShadowFXNode.cpp \
- ChromaKeyFXNode.cpp InvertFXNode.cpp HueSatFXNode.cpp \
- VideoWriter.cpp VideoWriterThread.cpp SVG.cpp SVGElement.cpp \
+ ExportedObject.cpp Player.cpp PluginManager.cpp \
+ TypeRegistry.cpp ArgBase.cpp ArgList.cpp DisplayEngine.cpp \
+ Canvas.cpp CanvasNode.cpp OffscreenCanvasNode.cpp \
+ MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp \
+ WrapPython.cpp WordsNode.cpp CameraNode.cpp TypeDefinition.cpp \
+ TextEngine.cpp Timeout.cpp Event.cpp DisplayParams.cpp \
+ CursorState.cpp MaterialInfo.cpp Image.cpp ImageNode.cpp \
+ EventDispatcher.cpp KeyEvent.cpp CursorEvent.cpp \
+ MouseEvent.cpp TouchEvent.cpp AVGNode.cpp TestHelper.cpp \
+ TrackerInputDevice.cpp TrackerTouchStatus.cpp \
+ TrackerCalibrator.cpp SoundNode.cpp FontStyle.cpp \
+ VectorNode.cpp FilledVectorNode.cpp LineNode.cpp \
+ PolyLineNode.cpp RectNode.cpp CurveNode.cpp PolygonNode.cpp \
+ CircleNode.cpp Shape.cpp MeshNode.cpp Contact.cpp \
+ TouchStatus.cpp OffscreenCanvas.cpp FXNode.cpp \
+ TUIOInputDevice.cpp NullFXNode.cpp BlurFXNode.cpp \
+ ShadowFXNode.cpp ChromaKeyFXNode.cpp InvertFXNode.cpp \
+ HueSatFXNode.cpp VideoWriter.cpp VideoWriterThread.cpp SVG.cpp \
+ SVGElement.cpp Publisher.cpp SubscriberInfo.cpp \
+ PublisherDefinition.cpp PublisherDefinitionRegistry.cpp \
+ MessageID.cpp VersionInfo.cpp PythonLogSink.cpp \
+ BitmapManager.cpp BitmapManagerThread.cpp BitmapManagerMsg.cpp \
LibMTDevInputDevice.cpp XInputMTInputDevice.cpp SDLMain.m \
AppleTrackpadInputDevice.cpp Player.h PluginManager.h \
- IInputDevice.h VideoNode.h DisplayEngine.h NodeRegistry.h \
- Arg.h ArgBase.h ArgList.h Node.h AreaNode.h DisplayParams.h \
- NodeDefinition.h TextEngine.h AVGNode.h DivNode.h \
- CursorState.h MaterialInfo.h Canvas.h MainCanvas.h Image.h \
- ImageNode.h Timeout.h WordsNode.h WrapPython.h \
+ IInputDevice.h VideoNode.h ExportedObject.h DisplayEngine.h \
+ TypeRegistry.h Arg.h ArgBase.h ArgList.h Node.h AreaNode.h \
+ DisplayParams.h TypeDefinition.h TextEngine.h AVGNode.h \
+ DivNode.h CursorState.h MaterialInfo.h Canvas.h MainCanvas.h \
+ Image.h ImageNode.h Timeout.h WordsNode.h WrapPython.h \
OffscreenCanvas.h EventDispatcher.h CursorEvent.h MouseEvent.h \
- Event.h KeyEvent.h PanoImageNode.h TestHelper.h CanvasNode.h \
+ Event.h KeyEvent.h TestHelper.h CanvasNode.h \
OffscreenCanvasNode.h MultitouchInputDevice.h RasterNode.h \
CameraNode.h TrackerInputDevice.h TrackerCalibrator.h \
TouchEvent.h Contact.h TouchStatus.h TrackerTouchStatus.h \
- BoostPython.h SoundNode.h VectorNode.h FilledVectorNode.h \
- LineNode.h PolyLineNode.h RectNode.h CurveNode.h PolygonNode.h \
- CircleNode.h Shape.h MeshNode.h FXNode.h NullFXNode.h \
- BlurFXNode.h ShadowFXNode.h ChromaKeyFXNode.h HueSatFXNode.h \
- InvertFXNode.h TUIOInputDevice.h VideoWriter.h \
- VideoWriterThread.h SVG.h SVGElement.h LibMTDevInputDevice.h \
- OGLSurface.h SDLDisplayEngine.h XInputMTInputDevice.h
+ BoostPython.h SoundNode.h FontStyle.h VectorNode.h \
+ FilledVectorNode.h LineNode.h PolyLineNode.h RectNode.h \
+ CurveNode.h PolygonNode.h CircleNode.h Shape.h MeshNode.h \
+ FXNode.h NullFXNode.h BlurFXNode.h ShadowFXNode.h \
+ ChromaKeyFXNode.h HueSatFXNode.h InvertFXNode.h \
+ TUIOInputDevice.h VideoWriter.h VideoWriterThread.h SVG.h \
+ SVGElement.h Publisher.h SubscriberInfo.h \
+ PublisherDefinition.h PublisherDefinitionRegistry.h \
+ MessageID.h VersionInfo.h PythonLogSink.h BitmapManager.h \
+ BitmapManagerThread.h IBitmapLoadedListener.h \
+ BitmapManagerMsg.h LibMTDevInputDevice.h OGLSurface.h \
+ SDLDisplayEngine.h XInputMTInputDevice.h
am__objects_1 = OGLSurface.lo SDLDisplayEngine.lo
@ENABLE_MTDEV_TRUE@am__objects_2 = LibMTDevInputDevice.lo
@HAVE_XI2_1_FALSE@@HAVE_XI2_2_TRUE@am__objects_3 = \
@@ -106,46 +117,50 @@ am__objects_1 = OGLSurface.lo SDLDisplayEngine.lo
am__objects_5 =
am__objects_6 = $(am__objects_5) $(am__objects_5) $(am__objects_5)
am_libplayer_la_OBJECTS = $(am__objects_1) Arg.lo AreaNode.lo \
- RasterNode.lo DivNode.lo VideoNode.lo Player.lo \
- PluginManager.lo NodeRegistry.lo ArgBase.lo ArgList.lo \
- DisplayEngine.lo Canvas.lo CanvasNode.lo \
+ RasterNode.lo DivNode.lo VideoNode.lo ExportedObject.lo \
+ Player.lo PluginManager.lo TypeRegistry.lo ArgBase.lo \
+ ArgList.lo DisplayEngine.lo Canvas.lo CanvasNode.lo \
OffscreenCanvasNode.lo MainCanvas.lo Node.lo \
- MultitouchInputDevice.lo PanoImageNode.lo WordsNode.lo \
- CameraNode.lo NodeDefinition.lo TextEngine.lo Timeout.lo \
+ MultitouchInputDevice.lo WrapPython.lo WordsNode.lo \
+ CameraNode.lo TypeDefinition.lo TextEngine.lo Timeout.lo \
Event.lo DisplayParams.lo CursorState.lo MaterialInfo.lo \
Image.lo ImageNode.lo EventDispatcher.lo KeyEvent.lo \
CursorEvent.lo MouseEvent.lo TouchEvent.lo AVGNode.lo \
TestHelper.lo TrackerInputDevice.lo TrackerTouchStatus.lo \
- TrackerCalibrator.lo SoundNode.lo VectorNode.lo \
+ TrackerCalibrator.lo SoundNode.lo FontStyle.lo VectorNode.lo \
FilledVectorNode.lo LineNode.lo PolyLineNode.lo RectNode.lo \
CurveNode.lo PolygonNode.lo CircleNode.lo Shape.lo MeshNode.lo \
Contact.lo TouchStatus.lo OffscreenCanvas.lo FXNode.lo \
TUIOInputDevice.lo NullFXNode.lo BlurFXNode.lo ShadowFXNode.lo \
ChromaKeyFXNode.lo InvertFXNode.lo HueSatFXNode.lo \
VideoWriter.lo VideoWriterThread.lo SVG.lo SVGElement.lo \
- $(am__objects_2) $(am__objects_3) $(am__objects_4) \
- $(am__objects_6)
+ Publisher.lo SubscriberInfo.lo PublisherDefinition.lo \
+ PublisherDefinitionRegistry.lo MessageID.lo VersionInfo.lo \
+ PythonLogSink.lo BitmapManager.lo BitmapManagerThread.lo \
+ BitmapManagerMsg.lo $(am__objects_2) $(am__objects_3) \
+ $(am__objects_4) $(am__objects_6)
libplayer_la_OBJECTS = $(am_libplayer_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
PROGRAMS = $(noinst_PROGRAMS)
am_testcalibrator_OBJECTS = testcalibrator.$(OBJEXT)
testcalibrator_OBJECTS = $(am_testcalibrator_OBJECTS)
testcalibrator_DEPENDENCIES = libplayer.la ../video/libvideo.la \
- ../audio/libaudio.la ../imaging/libimaging.la \
- ../graphics/libgraphics.la ../base/libbase.la \
- ../lmfit/liblmfit.la ../oscpack/liboscpack.la
+ ../audio/libaudio.la ../base/triangulate/libtriangulate.la \
+ ../imaging/libimaging.la ../graphics/libgraphics.la \
+ ../base/libbase.la ../lmfit/liblmfit.la \
+ ../oscpack/liboscpack.la
am_testplayer_OBJECTS = testplayer.$(OBJEXT)
testplayer_OBJECTS = $(am_testplayer_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
testplayer_DEPENDENCIES = libplayer.la ../video/libvideo.la \
- ../audio/libaudio.la ../imaging/libimaging.la \
- ../graphics/libgraphics.la ../base/libbase.la \
- ../lmfit/liblmfit.la ../oscpack/liboscpack.la \
- $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+ ../audio/libaudio.la ../base/triangulate/libtriangulate.la \
+ ../imaging/libimaging.la ../graphics/libgraphics.la \
+ ../base/libbase.la ../lmfit/liblmfit.la \
+ ../oscpack/liboscpack.la $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
testplayer_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(testplayer_LDFLAGS) $(LDFLAGS) -o $@
@@ -159,18 +174,18 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
-AM_V_CXX = $(am__v_CXX_$(V))
-am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CXXLD = $(am__v_CXXLD_$(V))
-am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
OBJCCOMPILE = $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS)
@@ -178,15 +193,15 @@ LTOBJCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_OBJCFLAGS) $(OBJCFLAGS)
-AM_V_OBJC = $(am__v_OBJC_$(V))
-am__v_OBJC_ = $(am__v_OBJC_$(AM_DEFAULT_VERBOSITY))
+AM_V_OBJC = $(am__v_OBJC_@AM_V@)
+am__v_OBJC_ = $(am__v_OBJC_@AM_DEFAULT_V@)
am__v_OBJC_0 = @echo " OBJC " $@;
OBJCLD = $(OBJC)
OBJCLINK = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(OBJCLD) $(AM_OBJCFLAGS) $(OBJCFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_OBJCLD = $(am__v_OBJCLD_$(V))
-am__v_OBJCLD_ = $(am__v_OBJCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_OBJCLD = $(am__v_OBJCLD_@AM_V@)
+am__v_OBJCLD_ = $(am__v_OBJCLD_@AM_DEFAULT_V@)
am__v_OBJCLD_0 = @echo " OBJCLD" $@;
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -194,18 +209,18 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libplayer_la_SOURCES) $(testcalibrator_SOURCES) \
$(testplayer_SOURCES)
@@ -225,7 +240,7 @@ AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BOOST_PYTHON_LIBS = @BOOST_PYTHON_LIBS@
-BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -240,6 +255,7 @@ DC1394_2_CFLAGS = @DC1394_2_CFLAGS@
DC1394_2_LIBS = @DC1394_2_LIBS@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -280,6 +296,7 @@ LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MTDEV_CFLAGS = @MTDEV_CFLAGS@
MTDEV_LIBS = @MTDEV_LIBS@
@@ -309,11 +326,13 @@ PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDES = @PYTHON_INCLUDES@
-PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
@@ -336,6 +355,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -370,7 +390,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -394,16 +413,20 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-INCLUDES = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
- @PANGOFT2_CFLAGS@ @PYTHON_INCLUDES@ @GL_CFLAGS@ @FFMPEG_CFLAGS@ \
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
+ @PANGOFT2_CFLAGS@ @PYTHON_CPPFLAGS@ @GL_CFLAGS@ \
@DC1394_2_CFLAGS@ @LIBRSVG_CFLAGS@ @FONTCONFIG_CFLAGS@ \
$(MTDEV_CFLAGS)
@APPLE_FALSE@APPLE_SOURCES =
@APPLE_TRUE@APPLE_SOURCES = SDLMain.m AppleTrackpadInputDevice.cpp
@APPLE_FALSE@APPLE_LINKFLAGS =
-@APPLE_TRUE@APPLE_LINKFLAGS = -read_only_relocs suppress -F/System/Library/PrivateFrameworks -framework MultitouchSupport
-@APPLE_FALSE@XGL_LIBS = -lXxf86vm -lX11
+@APPLE_TRUE@APPLE_LINKFLAGS = -read_only_relocs suppress -F/System/Library/PrivateFrameworks \
+@APPLE_TRUE@ -framework MultitouchSupport
+
+@APPLE_FALSE@@ENABLE_EGL_FALSE@@ENABLE_RPI_FALSE@XGL_LIBS = -lXxf86vm -lX11
+@APPLE_FALSE@@ENABLE_EGL_TRUE@@ENABLE_RPI_FALSE@XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
+@APPLE_FALSE@@ENABLE_RPI_TRUE@XGL_LIBS = -lXxf86vm -lX11 -lGLESv2 -lEGL
@APPLE_TRUE@XGL_LIBS =
@ENABLE_MTDEV_FALSE@MTDEV_SOURCES =
@ENABLE_MTDEV_TRUE@MTDEV_SOURCES = LibMTDevInputDevice.cpp
@@ -417,61 +440,71 @@ INCLUDES = -I.. @XML2_CFLAGS@ @FREETYPE_CFLAGS@ \
@HAVE_XI2_1_TRUE@XINPUT2_INCLUDES = XInputMTInputDevice.h
GL_SOURCES = OGLSurface.cpp SDLDisplayEngine.cpp
GL_INCLUDES = OGLSurface.h SDLDisplayEngine.h
-ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
-ALL_H = Player.h PluginManager.h IInputDevice.h VideoNode.h \
- DisplayEngine.h NodeRegistry.h Arg.h ArgBase.h ArgList.h \
- Node.h AreaNode.h DisplayParams.h NodeDefinition.h TextEngine.h \
+ALL_GL_LIBS = @GL_LIBS@ @SDL_LIBS@ $(XGL_LIBS)
+ALL_H = Player.h PluginManager.h IInputDevice.h VideoNode.h ExportedObject.h \
+ DisplayEngine.h TypeRegistry.h Arg.h ArgBase.h ArgList.h \
+ Node.h AreaNode.h DisplayParams.h TypeDefinition.h TextEngine.h \
AVGNode.h DivNode.h CursorState.h MaterialInfo.h Canvas.h MainCanvas.h \
Image.h ImageNode.h Timeout.h WordsNode.h WrapPython.h OffscreenCanvas.h \
EventDispatcher.h CursorEvent.h MouseEvent.h \
- Event.h KeyEvent.h PanoImageNode.h TestHelper.h CanvasNode.h \
+ Event.h KeyEvent.h TestHelper.h CanvasNode.h \
OffscreenCanvasNode.h MultitouchInputDevice.h \
RasterNode.h CameraNode.h TrackerInputDevice.h TrackerCalibrator.h \
TouchEvent.h Contact.h TouchStatus.h TrackerTouchStatus.h BoostPython.h \
- SoundNode.h \
+ SoundNode.h FontStyle.h \
VectorNode.h FilledVectorNode.h LineNode.h PolyLineNode.h RectNode.h \
CurveNode.h PolygonNode.h CircleNode.h Shape.h MeshNode.h FXNode.h \
NullFXNode.h BlurFXNode.h ShadowFXNode.h ChromaKeyFXNode.h HueSatFXNode.h \
InvertFXNode.h TUIOInputDevice.h VideoWriter.h VideoWriterThread.h \
- SVG.h SVGElement.h \
+ SVG.h SVGElement.h Publisher.h SubscriberInfo.h PublisherDefinition.h \
+ PublisherDefinitionRegistry.h MessageID.h VersionInfo.h \
+ PythonLogSink.h BitmapManager.h BitmapManagerThread.h IBitmapLoadedListener.h \
+ BitmapManagerMsg.h \
$(MTDEV_INCLUDES) $(GL_INCLUDES) $(XINPUT2_INCLUDES)
EXTRA_DIST = SDLMain.h
noinst_LTLIBRARIES = libplayer.la
testplayer_SOURCES = testplayer.cpp
testplayer_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
../lmfit/liblmfit.la ../oscpack/liboscpack.la \
- @XML2_LIBS@ -l@BOOST_THREAD_LIB@ @PTHREAD_LIBS@ @PANGOFT2_LIBS@ @LIBRSVG_LIBS@\
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @PANGOFT2_LIBS@ \
+ @LIBRSVG_LIBS@ \
@DC1394_2_LIBS@ @GLU_LIBS@ $(ALL_GL_LIBS) $(XI2_1_LIBS) $(XI2_2_LIBS) \
- @LIBFFMPEG@ $(BOOST_PYTHON_LIBS) $(PYTHON_LIBS) @GDK_PIXBUF_LIBS@ \
+ @LIBFFMPEG@ $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) @GDK_PIXBUF_LIBS@ \
@FONTCONFIG_LIBS@
testplayer_LDFLAGS = $(APPLE_LINKFLAGS) -module -XCClinker
testcalibrator_SOURCES = testcalibrator.cpp
testcalibrator_LDADD = libplayer.la ../video/libvideo.la ../audio/libaudio.la \
+ ../base/triangulate/libtriangulate.la \
../imaging/libimaging.la ../graphics/libgraphics.la ../base/libbase.la \
../lmfit/liblmfit.la ../oscpack/liboscpack.la \
- @XML2_LIBS@ -l@BOOST_THREAD_LIB@ @PTHREAD_LIBS@ @LIBRSVG_LIBS@ @GDK_PIXBUF_LIBS@
+ @XML2_LIBS@ @BOOST_THREAD_LIBS@ @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @LIBRSVG_LIBS@ \
+ @GDK_PIXBUF_LIBS@
-libplayer_la_LIBADD = $(BOOST_PYTHON_LIBS) $(PYTHON_LIBS) $(MTDEV_LIBS)
+libplayer_la_LIBADD = $(BOOST_PYTHON_LIBS) $(PYTHON_LDFLAGS) $(MTDEV_LIBS)
libplayer_la_SOURCES = $(GL_SOURCES) \
- Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp \
- Player.cpp PluginManager.cpp NodeRegistry.cpp ArgBase.cpp ArgList.cpp \
+ Arg.cpp AreaNode.cpp RasterNode.cpp DivNode.cpp VideoNode.cpp ExportedObject.cpp \
+ Player.cpp PluginManager.cpp TypeRegistry.cpp ArgBase.cpp ArgList.cpp \
DisplayEngine.cpp Canvas.cpp CanvasNode.cpp OffscreenCanvasNode.cpp \
- MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp \
- PanoImageNode.cpp WordsNode.cpp CameraNode.cpp NodeDefinition.cpp TextEngine.cpp \
+ MainCanvas.cpp Node.cpp MultitouchInputDevice.cpp WrapPython.cpp \
+ WordsNode.cpp CameraNode.cpp TypeDefinition.cpp TextEngine.cpp \
Timeout.cpp Event.cpp DisplayParams.cpp CursorState.cpp MaterialInfo.cpp \
Image.cpp ImageNode.cpp EventDispatcher.cpp KeyEvent.cpp CursorEvent.cpp \
MouseEvent.cpp TouchEvent.cpp AVGNode.cpp TestHelper.cpp \
TrackerInputDevice.cpp TrackerTouchStatus.cpp TrackerCalibrator.cpp \
- SoundNode.cpp \
+ SoundNode.cpp FontStyle.cpp \
VectorNode.cpp FilledVectorNode.cpp LineNode.cpp PolyLineNode.cpp \
RectNode.cpp CurveNode.cpp PolygonNode.cpp CircleNode.cpp Shape.cpp MeshNode.cpp \
Contact.cpp TouchStatus.cpp OffscreenCanvas.cpp FXNode.cpp TUIOInputDevice.cpp \
NullFXNode.cpp BlurFXNode.cpp ShadowFXNode.cpp ChromaKeyFXNode.cpp \
InvertFXNode.cpp HueSatFXNode.cpp VideoWriter.cpp VideoWriterThread.cpp \
- SVG.cpp SVGElement.cpp \
+ SVG.cpp SVGElement.cpp Publisher.cpp SubscriberInfo.cpp PublisherDefinition.cpp \
+ PublisherDefinitionRegistry.cpp MessageID.cpp VersionInfo.cpp \
+ PythonLogSink.cpp BitmapManager.cpp BitmapManagerThread.cpp \
+ BitmapManagerMsg.cpp \
$(MTDEV_SOURCES) $(XINPUT2_SOURCES) $(APPLE_SOURCES) $(ALL_H)
libplayer_a_CXXFLAGS = -DPREFIXDIR=\"$(prefix)\"
@@ -518,7 +551,7 @@ clean-noinstLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libplayer.la: $(libplayer_la_OBJECTS) $(libplayer_la_DEPENDENCIES)
+libplayer.la: $(libplayer_la_OBJECTS) $(libplayer_la_DEPENDENCIES) $(EXTRA_libplayer_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(libplayer_la_OBJECTS) $(libplayer_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@@ -529,10 +562,10 @@ clean-noinstPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
-testcalibrator$(EXEEXT): $(testcalibrator_OBJECTS) $(testcalibrator_DEPENDENCIES)
+testcalibrator$(EXEEXT): $(testcalibrator_OBJECTS) $(testcalibrator_DEPENDENCIES) $(EXTRA_testcalibrator_DEPENDENCIES)
@rm -f testcalibrator$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(testcalibrator_OBJECTS) $(testcalibrator_LDADD) $(LIBS)
-testplayer$(EXEEXT): $(testplayer_OBJECTS) $(testplayer_DEPENDENCIES)
+testplayer$(EXEEXT): $(testplayer_OBJECTS) $(testplayer_DEPENDENCIES) $(EXTRA_testplayer_DEPENDENCIES)
@rm -f testplayer$(EXEEXT)
$(AM_V_CXXLD)$(testplayer_LINK) $(testplayer_OBJECTS) $(testplayer_LDADD) $(LIBS)
@@ -548,6 +581,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Arg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ArgBase.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ArgList.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitmapManager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitmapManagerMsg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitmapManagerThread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BlurFXNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CameraNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Canvas.Plo@am__quote@
@@ -563,8 +599,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DivNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Event.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EventDispatcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExportedObject.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FXNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FilledVectorNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontStyle.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HueSatFXNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Image.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ImageNode.Plo@am__quote@
@@ -575,20 +613,22 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MainCanvas.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MaterialInfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MeshNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageID.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MouseEvent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultitouchInputDevice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Node.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NodeDefinition.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NodeRegistry.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NullFXNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OGLSurface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OffscreenCanvas.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OffscreenCanvasNode.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PanoImageNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Player.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PluginManager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PolyLineNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PolygonNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Publisher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PublisherDefinition.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PublisherDefinitionRegistry.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PythonLogSink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RasterNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RectNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SDLDisplayEngine.Plo@am__quote@
@@ -598,6 +638,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShadowFXNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Shape.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoundNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SubscriberInfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TUIOInputDevice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TextEngine.Plo@am__quote@
@@ -607,11 +648,15 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerCalibrator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerInputDevice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerTouchStatus.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TypeDefinition.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TypeRegistry.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VectorNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VersionInfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VideoNode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VideoWriter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VideoWriterThread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WordsNode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WrapPython.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XInputMTInputDevice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcalibrator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testplayer.Po@am__quote@
@@ -619,50 +664,44 @@ distclean-compile:
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
.m.o:
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(OBJCCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepOBJC_FALSE@ $(AM_V_OBJC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ $(AM_V_OBJC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepOBJC_FALSE@ $(OBJCCOMPILE) -c -o $@ $<
+@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(OBJCCOMPILE) -c -o $@ $<
.m.obj:
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(OBJCCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepOBJC_FALSE@ $(AM_V_OBJC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ $(AM_V_OBJC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepOBJC_FALSE@ $(OBJCCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(OBJCCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.m.lo:
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(LTOBJCCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepOBJC_FALSE@ $(AM_V_OBJC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ $(AM_V_OBJC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepOBJC_FALSE@ $(LTOBJCCOMPILE) -c -o $@ $<
+@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(LTOBJCCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -803,14 +842,15 @@ check-TESTS: $(TESTS)
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
if test "$$failed" -eq 0; then \
- echo "$$grn$$dashes"; \
+ col="$$grn"; \
else \
- echo "$$red$$dashes"; \
+ col="$$red"; \
fi; \
- echo "$$banner"; \
- test -z "$$skipped" || echo "$$skipped"; \
- test -z "$$report" || echo "$$report"; \
- echo "$$dashes$$std"; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
test "$$failed" -eq 0; \
else :; fi
@@ -859,10 +899,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
diff --git a/src/player/MaterialInfo.cpp b/src/player/MaterialInfo.cpp
index f77d89e..2b25b48 100644
--- a/src/player/MaterialInfo.cpp
+++ b/src/player/MaterialInfo.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/MaterialInfo.h b/src/player/MaterialInfo.h
index 871e48f..7f1d987 100644
--- a/src/player/MaterialInfo.h
+++ b/src/player/MaterialInfo.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,8 +24,6 @@
#include "../api.h"
-#include "../base/Point.h"
-
namespace avg {
class AVG_API MaterialInfo {
diff --git a/src/player/MeshNode.cpp b/src/player/MeshNode.cpp
index 363e00a..09e577f 100644
--- a/src/player/MeshNode.cpp
+++ b/src/player/MeshNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,11 +21,10 @@
#include "MeshNode.h"
-#include "../wrapper/WrapHelper.h"
#include "../base/Logger.h"
#include "../base/Exception.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "VectorNode.h"
#include <cstdlib>
@@ -33,25 +32,27 @@
#include <iostream>
using namespace std;
-using namespace boost::python;
namespace avg {
-NodeDefinition MeshNode::createDefinition()
+void MeshNode::registerType()
{
- vector<DPoint> vVert;
- vector<DPoint> vTex;
- vector<IntTriple> vTriangle;
+ vector<glm::vec2> vVert;
+ vector<glm::vec2> vTex;
+ vector<glm::ivec3> vTriangle;
- return NodeDefinition("mesh", (NodeBuilder)MeshNode::buildNode<MeshNode>)
- .extendDefinition(VectorNode::createDefinition())
- .addArg(Arg<vector<DPoint> >("vertexcoords", vVert, false,
+ TypeDefinition def = TypeDefinition("mesh", "vectornode",
+ ExportedObject::buildObject<MeshNode>)
+ .addArg(Arg<vector<glm::vec2> >("vertexcoords", vVert, false,
offsetof(MeshNode, m_VertexCoords)))
- .addArg(Arg<vector<DPoint> >("texcoords", vTex, false,
+ .addArg(Arg<vector<glm::vec2> >("texcoords", vTex, false,
offsetof(MeshNode, m_TexCoords)))
- .addArg(Arg<vector<IntTriple> >("triangles", vTriangle, false,
+ .addArg(Arg<vector<glm::ivec3> >("triangles", vTriangle, false,
offsetof(MeshNode, m_Triangles)))
+ .addArg(Arg<bool>("backfacecull", false, false,
+ offsetof(MeshNode, m_bBackfaceCull)))
;
+ TypeRegistry::get()->registerType(def);
}
MeshNode::MeshNode(const ArgList& args)
@@ -65,7 +66,7 @@ MeshNode::~MeshNode()
{
}
-void MeshNode::isValid(const vector<DPoint>& coords)
+void MeshNode::isValid(const vector<glm::vec2>& coords)
{
if (coords.size() != m_VertexCoords.size()) {
throw(Exception(AVG_ERR_OUT_OF_RANGE,
@@ -73,43 +74,41 @@ void MeshNode::isValid(const vector<DPoint>& coords)
}
}
-const vector<DPoint>& MeshNode::getVertexCoords() const
+const vector<glm::vec2>& MeshNode::getVertexCoords() const
{
return m_VertexCoords;
}
-void MeshNode::setVertexCoords(const vector<DPoint>& coords)
+void MeshNode::setVertexCoords(const vector<glm::vec2>& coords)
{
isValid(coords);
m_VertexCoords = coords;
setDrawNeeded();
}
-const vector<DPoint>& MeshNode::getTexCoords() const
+const vector<glm::vec2>& MeshNode::getTexCoords() const
{
return m_TexCoords;
}
-void MeshNode::setTexCoords(const vector<DPoint>& coords)
+void MeshNode::setTexCoords(const vector<glm::vec2>& coords)
{
isValid(coords);
m_TexCoords = coords;
setDrawNeeded();
}
-const vector<IntTriple>& MeshNode::getTriangles() const
+const vector<glm::ivec3>& MeshNode::getTriangles() const
{
return m_Triangles;
}
-void MeshNode::setTriangles(const vector<IntTriple>& triangles)
+void MeshNode::setTriangles(const vector<glm::ivec3>& triangles)
{
for (unsigned int i = 0; i < triangles.size(); i++) {
- if (static_cast<unsigned int>(triangles[i].x) < 0 ||
- static_cast<unsigned int>(triangles[i].y) < 0 ||
- static_cast<unsigned int>(triangles[i].z) < 0)
+ if (triangles[i].x < 0 || triangles[i].y < 0 || triangles[i].z < 0)
{
throw(Exception(AVG_ERR_OUT_OF_RANGE,
"Triangle Index Out of Range < 0"));
@@ -127,16 +126,39 @@ void MeshNode::setTriangles(const vector<IntTriple>& triangles)
setDrawNeeded();
}
-void MeshNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+bool MeshNode::getBackfaceCull() const
+{
+ return m_bBackfaceCull;
+}
+
+void MeshNode::setBackfaceCull(const bool bBackfaceCull)
+{
+ m_bBackfaceCull = bBackfaceCull;
+}
+
+void MeshNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
for (unsigned int i = 0; i < m_VertexCoords.size(); i++) {
- pVertexArray->appendPos(m_VertexCoords[i],m_TexCoords[i], color);
+ pVertexData->appendPos(m_VertexCoords[i],m_TexCoords[i], color);
}
for (unsigned int i = 0; i < m_Triangles.size(); i++) {
- pVertexArray->appendTriIndexes(m_Triangles[i].x, m_Triangles[i].y,
+ pVertexData->appendTriIndexes(m_Triangles[i].x, m_Triangles[i].y,
m_Triangles[i].z);
}
}
+void MeshNode::render()
+{
+ if (m_bBackfaceCull) {
+ glEnable(GL_CULL_FACE);
+ }
+
+ VectorNode::render();
+
+ if (m_bBackfaceCull) {
+ glDisable(GL_CULL_FACE);
+ }
+}
+
}
diff --git a/src/player/MeshNode.h b/src/player/MeshNode.h
index 5f8f40b..e921c12 100644
--- a/src/player/MeshNode.h
+++ b/src/player/MeshNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,10 @@
#include "../api.h"
#include "VectorNode.h"
+
+#include "../base/GLMHelper.h"
#include "../graphics/Pixel32.h"
-#include "../base/Triple.h"
+
#include <vector>
namespace avg {
@@ -34,28 +36,35 @@ namespace avg {
class AVG_API MeshNode : public VectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
MeshNode(const ArgList& args);
virtual ~MeshNode();
- void isValid(const std::vector<DPoint>& coords);
+ void isValid(const std::vector<glm::vec2>& coords);
- const std::vector<DPoint>& getVertexCoords() const;
- void setVertexCoords(const std::vector<DPoint>& coords);
+ const std::vector<glm::vec2>& getVertexCoords() const;
+ void setVertexCoords(const std::vector<glm::vec2>& coords);
- const std::vector<DPoint>& getTexCoords() const;
- void setTexCoords(const std::vector<DPoint>& coords);
+ const std::vector<glm::vec2>& getTexCoords() const;
+ void setTexCoords(const std::vector<glm::vec2>& coords);
- const std::vector<IntTriple>& getTriangles() const;
- void setTriangles(const std::vector<IntTriple>& pts);
+ const std::vector<glm::ivec3>& getTriangles() const;
+ void setTriangles(const std::vector<glm::ivec3>& pts);
+
+ bool getBackfaceCull() const;
+ void setBackfaceCull(const bool bBackfaceCull);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+
+ virtual void render();
private:
- std::vector<DPoint> m_TexCoords;
- std::vector<DPoint> m_VertexCoords;
- std::vector<IntTriple> m_Triangles;
+ std::vector<glm::vec2> m_TexCoords;
+ std::vector<glm::vec2> m_VertexCoords;
+ std::vector<glm::ivec3> m_Triangles;
+
+ bool m_bBackfaceCull;
};
}
#endif
diff --git a/src/player/MessageID.cpp b/src/player/MessageID.cpp
new file mode 100644
index 0000000..6617e0e
--- /dev/null
+++ b/src/player/MessageID.cpp
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "MessageID.h"
+
+#include "../base/StringHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+MessageID::MessageID(const string& sName, int id)
+ : m_sName(sName),
+ m_ID(id)
+{
+}
+
+bool MessageID::operator < (const MessageID& other) const
+{
+ return m_ID < other.m_ID;
+}
+
+bool MessageID::operator == (const MessageID& other) const
+{
+ return m_ID == other.m_ID;
+}
+
+std::string MessageID::getRepr()
+{
+ if (m_sName != "") {
+ return m_sName;
+ } else {
+ return toString(m_ID);
+ }
+}
+
+std::ostream& operator <<(ostream& os, const MessageID& id)
+{
+ os << "(" << id.m_sName << ", " << id.m_ID << ")";
+ return os;
+}
+
+}
+
diff --git a/src/player/MessageID.h b/src/player/MessageID.h
new file mode 100644
index 0000000..f7ec6d6
--- /dev/null
+++ b/src/player/MessageID.h
@@ -0,0 +1,48 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _MessageID_H_
+#define _MessageID_H_
+
+#include "../api.h"
+
+#include <string>
+#include <iostream>
+
+namespace avg {
+
+struct MessageID {
+ MessageID(const std::string& sName, int id);
+
+ bool operator < (const MessageID& other) const;
+ bool operator == (const MessageID& other) const;
+
+ std::string getRepr();
+
+ std::string m_sName;
+ int m_ID;
+};
+
+std::ostream& operator <<(std::ostream& os, const MessageID& id);
+
+}
+
+#endif
diff --git a/src/player/MouseEvent.cpp b/src/player/MouseEvent.cpp
index 39acc83..c56dd8c 100644
--- a/src/player/MouseEvent.cpp
+++ b/src/player/MouseEvent.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -33,7 +33,7 @@ namespace avg {
MouseEvent::MouseEvent(Event::Type eventType,
bool leftButtonState, bool middleButtonState, bool rightButtonState,
- const IntPoint& pos, int button, const DPoint& speed, int when)
+ const IntPoint& pos, int button, const glm::vec2& speed, int when)
: CursorEvent(MOUSECURSORID, eventType, pos, MOUSE, when)
{
m_LeftButtonState = leftButtonState;
@@ -75,7 +75,7 @@ bool MouseEvent::isAnyButtonPressed() const
void MouseEvent::trace()
{
CursorEvent::trace();
- AVG_TRACE(Logger::EVENTS2, "pos: " << getPos()
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::DEBUG, "pos: " << getPos()
<< ", button: " << m_Button);
}
diff --git a/src/player/MouseEvent.h b/src/player/MouseEvent.h
index 0c8e3ab..fb67dde 100644
--- a/src/player/MouseEvent.h
+++ b/src/player/MouseEvent.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ class AVG_API MouseEvent : public CursorEvent {
public:
MouseEvent(Event::Type eventType,
bool leftButtonState, bool middleButtonState, bool rightButtonState,
- const IntPoint& pos, int button, const DPoint& speed=DPoint(0,0),
+ const IntPoint& pos, int button, const glm::vec2& speed=glm::vec2(0,0),
int when=-1);
virtual ~MouseEvent();
diff --git a/src/player/MultitouchInputDevice.cpp b/src/player/MultitouchInputDevice.cpp
index b89aaef..507f3fb 100644
--- a/src/player/MultitouchInputDevice.cpp
+++ b/src/player/MultitouchInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -18,8 +18,6 @@
//
// Current versions can be found at www.libavg.de
//
-// Original author of this file is igor@c-base.org
-//
#include "MultitouchInputDevice.h"
#include "TouchEvent.h"
@@ -38,6 +36,11 @@ namespace avg {
MultitouchInputDevice::MultitouchInputDevice()
: IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(MultitouchInputDevice))
{
+ m_TouchArea = ConfigMgr::get()->getSizeOption("touch", "area");
+ if (m_TouchArea.x == 0) {
+ m_TouchArea = Player::get()->getScreenResolution();
+ }
+ m_TouchOffset = ConfigMgr::get()->getSizeOption("touch", "offset");
}
MultitouchInputDevice::~MultitouchInputDevice()
@@ -46,23 +49,22 @@ MultitouchInputDevice::~MultitouchInputDevice()
void MultitouchInputDevice::start()
{
- m_WindowSize = Player::get()->getRootNode()->getSize();
m_pMutex = MutexPtr(new boost::mutex);
}
vector<EventPtr> MultitouchInputDevice::pollEvents()
{
- boost::mutex::scoped_lock lock(*m_pMutex);
+ lock_guard lock(*m_pMutex);
vector<EventPtr> events;
vector<TouchStatusPtr>::iterator it;
// cerr << "--------poll---------" << endl;
for (it = m_Touches.begin(); it != m_Touches.end(); ) {
-// cerr << it->first << " ";
+// cerr << (*it)->getID() << " ";
CursorEventPtr pEvent = (*it)->pollEvent();
if (pEvent) {
events.push_back(pEvent);
- if (pEvent->getType() == Event::CURSORUP) {
+ if (pEvent->getType() == Event::CURSOR_UP) {
it = m_Touches.erase(it);
} else {
++it;
@@ -75,11 +77,6 @@ vector<EventPtr> MultitouchInputDevice::pollEvents()
return events;
}
-const DPoint& MultitouchInputDevice::getWindowSize() const
-{
- return m_WindowSize;
-}
-
int MultitouchInputDevice::getNumTouches() const
{
return m_TouchIDMap.size();
@@ -120,6 +117,17 @@ void MultitouchInputDevice::getDeadIDs(const set<int>& liveIDs, set<int>& deadID
}
}
+glm::vec2 MultitouchInputDevice::getTouchArea() const
+{
+ return m_TouchArea;
+}
+
+IntPoint MultitouchInputDevice::getScreenPos(const glm::vec2& pos) const
+{
+ return IntPoint(int(pos.x * m_TouchArea.x + m_TouchOffset.x + 0.5),
+ int(pos.y * m_TouchArea.y + m_TouchOffset.y) + 0.5);
+}
+
boost::mutex& MultitouchInputDevice::getMutex()
{
return *m_pMutex;
diff --git a/src/player/MultitouchInputDevice.h b/src/player/MultitouchInputDevice.h
index 71aa2c5..7ccbfe5 100644
--- a/src/player/MultitouchInputDevice.h
+++ b/src/player/MultitouchInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,8 @@
#include "../api.h"
#include "IInputDevice.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
+#include "../base/ConfigMgr.h"
#include <boost/thread.hpp>
#include <map>
@@ -48,11 +49,10 @@ public:
MultitouchInputDevice();
virtual ~MultitouchInputDevice() = 0;
virtual void start();
-
+
std::vector<EventPtr> pollEvents();
protected:
- const DPoint& getWindowSize() const;
int getNumTouches() const;
// Note that the id used here is not the libavg cursor id but a touch-driver-specific
// id handed up from the driver level.
@@ -60,13 +60,16 @@ protected:
void addTouchStatus(int id, TouchEventPtr pInitialEvent);
void removeTouchStatus(int id);
void getDeadIDs(const std::set<int>& liveIDs, std::set<int>& deadIDs);
+ glm::vec2 getTouchArea() const;
+ IntPoint getScreenPos(const glm::vec2& pos) const;
boost::mutex& getMutex();
private:
std::map<int, TouchStatusPtr> m_TouchIDMap;
std::vector<TouchStatusPtr> m_Touches;
- DPoint m_WindowSize;
MutexPtr m_pMutex;
+ glm::vec2 m_TouchArea;
+ glm::vec2 m_TouchOffset;
};
typedef boost::shared_ptr<MultitouchInputDevice> MultitouchInputDevicePtr;
diff --git a/src/player/Node.cpp b/src/player/Node.cpp
index eeedc5f..7c3f331 100644
--- a/src/player/Node.cpp
+++ b/src/player/Node.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,12 +21,13 @@
#include "Node.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Arg.h"
#include "Canvas.h"
#include "DivNode.h"
#include "Player.h"
#include "CursorEvent.h"
+#include "PublisherDefinition.h"
#include "../base/Exception.h"
#include "../base/Logger.h"
@@ -37,27 +38,39 @@
#include <string>
using namespace std;
+using namespace boost;
namespace avg {
-NodeDefinition Node::createDefinition()
-{
- return NodeDefinition("node")
+void Node::registerType()
+{
+ PublisherDefinitionPtr pPubDef = PublisherDefinition::create("Node");
+ pPubDef->addMessage("CURSOR_DOWN");
+ pPubDef->addMessage("CURSOR_MOTION");
+ pPubDef->addMessage("CURSOR_UP");
+ pPubDef->addMessage("CURSOR_OVER");
+ pPubDef->addMessage("CURSOR_OUT");
+ pPubDef->addMessage("HOVER_DOWN");
+ pPubDef->addMessage("HOVER_MOTION");
+ pPubDef->addMessage("HOVER_UP");
+ pPubDef->addMessage("HOVER_OVER");
+ pPubDef->addMessage("HOVER_OUT");
+ pPubDef->addMessage("END_OF_FILE");
+ pPubDef->addMessage("SIZE_CHANGED");
+
+ TypeDefinition def = TypeDefinition("node")
.addArg(Arg<string>("id", "", false, offsetof(Node, m_ID)))
- .addArg(Arg<string>("oncursormove", ""))
- .addArg(Arg<string>("oncursorup", ""))
- .addArg(Arg<string>("oncursordown", ""))
- .addArg(Arg<string>("oncursorover", ""))
- .addArg(Arg<string>("oncursorout", ""))
.addArg(Arg<bool>("active", true, false, offsetof(Node, m_bActive)))
.addArg(Arg<bool>("sensitive", true, false, offsetof(Node, m_bSensitive)))
- .addArg(Arg<double>("opacity", 1.0, false, offsetof(Node, m_Opacity)));
+ .addArg(Arg<float>("opacity", 1.0, false, offsetof(Node, m_Opacity)));
+ TypeRegistry::get()->registerType(def);
}
-Node::Node()
- : m_pCanvas(),
+Node::Node(const std::string& sPublisherName)
+ : Publisher(sPublisherName),
+ m_pParent(0),
+ m_pCanvas(),
m_State(NS_UNCONNECTED)
-
{
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -68,30 +81,27 @@ Node::~Node()
ObjectCounter::get()->decRef(&typeid(*this));
}
-void Node::setArgs(const ArgList& args)
-{
- addArgEventHandlers(Event::CURSORMOTION, args.getArgVal<string> ("oncursormove"));
- addArgEventHandlers(Event::CURSORUP, args.getArgVal<string> ("oncursorup"));
- addArgEventHandlers(Event::CURSORDOWN, args.getArgVal<string> ("oncursordown"));
- addArgEventHandlers(Event::CURSOROVER, args.getArgVal<string> ("oncursorover"));
- addArgEventHandlers(Event::CURSOROUT, args.getArgVal<string> ("oncursorout"));
-}
-
-void Node::setTypeInfo(const NodeDefinition * pDefinition)
+void Node::registerInstance(PyObject* pSelf, const DivNodePtr& pParent)
{
- m_pDefinition = pDefinition;
+ ExportedObject::registerInstance(pSelf);
+ if (pParent) {
+ pParent->appendChild(getSharedThis());
+ }
}
-void Node::checkSetParentError(DivNodeWeakPtr pParent)
+void Node::checkSetParentError(DivNode* pParent)
{
- if (getParent() && !!(pParent.lock())) {
+ if (getParent() && pParent != 0) {
throw(Exception(AVG_ERR_UNSUPPORTED,
string("Can't change parent of node (") + getID() + ")."));
}
+ if (getSharedThis() == NodePtr()) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "Node not registered. Please use Node.registerInstance() when deriving from libavg Nodes in python."));
+ }
}
-void Node::setParent(DivNodeWeakPtr pParent, NodeState parentState,
- CanvasPtr pCanvas)
+void Node::setParent(DivNode* pParent, NodeState parentState, CanvasPtr pCanvas)
{
AVG_ASSERT(getState() == NS_UNCONNECTED);
checkSetParentError(pParent);
@@ -103,22 +113,23 @@ void Node::setParent(DivNodeWeakPtr pParent, NodeState parentState,
void Node::removeParent()
{
- m_pParent = DivNodePtr();
+ m_pParent = 0;
}
DivNodePtr Node::getParent() const
{
- if (m_pParent.expired()) {
+ if (m_pParent == 0) {
return DivNodePtr();
} else {
- return m_pParent.lock();
+ NodePtr pParent = m_pParent->getSharedThis();
+ return boost::dynamic_pointer_cast<DivNode>(pParent);
}
}
-vector<NodeWeakPtr> Node::getParentChain()
+vector<NodePtr> Node::getParentChain()
{
- vector<NodeWeakPtr> pNodes;
- boost::shared_ptr<Node> pCurNode = shared_from_this();
+ vector<NodePtr> pNodes;
+ NodePtr pCurNode = getSharedThis();
while (pCurNode) {
pNodes.push_back(pCurNode);
pCurNode = pCurNode->getParent();
@@ -152,7 +163,7 @@ void Node::unlink(bool bKill)
{
DivNodePtr pParent = getParent();
if (pParent != DivNodePtr()) {
- pParent->removeChild(shared_from_this(), bKill);
+ pParent->removeChild(getSharedThis(), bKill);
}
}
@@ -170,12 +181,12 @@ void Node::setID(const std::string& id)
m_ID = id;
}
-double Node::getOpacity() const
+float Node::getOpacity() const
{
return m_Opacity;
}
-void Node::setOpacity(double opacity)
+void Node::setOpacity(float opacity)
{
m_Opacity = opacity;
if (m_Opacity < 0.0) {
@@ -219,7 +230,7 @@ void Node::releaseMouseEventCapture()
void Node::setEventCapture(int cursorID)
{
- Player::get()->setEventCapture(shared_from_this(), cursorID);
+ Player::get()->setEventCapture(getSharedThis(), cursorID);
}
void Node::releaseEventCapture(int cursorID)
@@ -229,6 +240,7 @@ void Node::releaseEventCapture(int cursorID)
void Node::setEventHandler(Event::Type type, int sources, PyObject * pFunc)
{
+ avgDeprecationWarning("1.7", "Node.setEventHandler()", "Node.subscribe()");
for (int source = 1; source <= Event::NONE; source *= 2) {
if (source & sources) {
EventID id(type, (Event::Source)source);
@@ -246,6 +258,7 @@ void Node::setEventHandler(Event::Type type, int sources, PyObject * pFunc)
void Node::connectEventHandler(Event::Type type, int sources,
PyObject * pObj, PyObject * pFunc)
{
+ avgDeprecationWarning("1.8", "Node.connectEventHandler()", "Node.subscribe()");
for (int source = 1; source <= Event::NONE; source *= 2) {
if (source & sources) {
EventID id(type, (Event::Source)source);
@@ -258,6 +271,7 @@ void Node::connectEventHandler(Event::Type type, int sources,
void Node::disconnectEventHandler(PyObject * pObj, PyObject * pFunc)
{
+ avgDeprecationWarning("1.8", "Node.disconnectEventHandler()", "Node.unsubscribe()");
int numDisconnected = 0;
EventHandlerMap::iterator it;
for (it = m_EventHandlerMap.begin(); it != m_EventHandlerMap.end();) {
@@ -294,62 +308,59 @@ bool Node::reactsToMouseEvents()
return m_bActive && m_bSensitive;
}
-DPoint Node::getRelPos(const DPoint& absPos) const
+glm::vec2 Node::getRelPos(const glm::vec2& absPos) const
{
- DPoint parentPos;
- if (m_pParent.expired()) {
+ glm::vec2 parentPos;
+ if (m_pParent == 0) {
parentPos = absPos;
} else {
- parentPos = m_pParent.lock()->getRelPos(absPos);
+ parentPos = m_pParent->getSharedThis()->getRelPos(absPos);
}
return toLocal(parentPos);
}
-DPoint Node::getAbsPos(const DPoint& relPos) const
+glm::vec2 Node::getAbsPos(const glm::vec2& relPos) const
{
- DPoint thisPos = toGlobal(relPos);
- DPoint parentPos;
- if (m_pParent.expired()) {
+ glm::vec2 thisPos = toGlobal(relPos);
+ glm::vec2 parentPos;
+ if (m_pParent == 0) {
parentPos = thisPos;
} else {
- parentPos = m_pParent.lock()->getAbsPos(thisPos);
+ parentPos = m_pParent->getSharedThis()->getAbsPos(thisPos);
}
return parentPos;
}
-DPoint Node::toLocal(const DPoint& globalPos) const
+glm::vec2 Node::toLocal(const glm::vec2& globalPos) const
{
return globalPos;
}
-DPoint Node::toGlobal(const DPoint& localPos) const
+glm::vec2 Node::toGlobal(const glm::vec2& localPos) const
{
return localPos;
}
-NodePtr Node::getElementByPos(const DPoint& pos)
+NodePtr Node::getElementByPos(const glm::vec2& pos)
{
- vector<NodeWeakPtr> elements;
+ vector<NodePtr> elements;
getElementsByPos(pos, elements);
if (elements.empty()) {
return NodePtr();
} else {
- return elements[0].lock();
+ return elements[0];
}
}
-void Node::getElementsByPos(const DPoint& pos,
- vector<NodeWeakPtr>& pElements)
+void Node::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
}
-void Node::preRender()
+void Node::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- if (getParent()) {
- m_EffectiveOpacity = m_Opacity*getParent()->getEffectiveOpacity();
- } else {
- m_EffectiveOpacity = m_Opacity;
- }
+ m_EffectiveOpacity = m_Opacity*parentEffectiveOpacity;
+ m_bEffectiveActive = bIsParentActive && m_bActive;
}
Node::NodeState Node::getState() const
@@ -364,6 +375,11 @@ CanvasPtr Node::getCanvas() const
bool Node::handleEvent(EventPtr pEvent)
{
+ if (pEvent->getSource() != Event::NONE && pEvent->getSource() != Event::CUSTOM) {
+ string messageID = getEventMessageID(pEvent);
+ notifySubscribers(messageID, pEvent);
+ }
+
EventID id(pEvent->getType(), pEvent->getSource());
EventHandlerMap::iterator it = m_EventHandlerMap.find(id);
if (it != m_EventHandlerMap.end()) {
@@ -381,24 +397,7 @@ bool Node::handleEvent(EventPtr pEvent)
}
}
-void Node::addArgEventHandlers(Event::Type eventType, const string& sCode)
-{
- addArgEventHandler(eventType, Event::MOUSE, sCode);
- addArgEventHandler(eventType, Event::TOUCH, sCode);
- addArgEventHandler(eventType, Event::TRACK, sCode);
-}
-
-void Node::addArgEventHandler(Event::Type eventType, Event::Source source,
- const string& sCode)
-{
- PyObject * pFunc = findPythonFunc(sCode);
- if (pFunc) {
- EventID id(eventType, source);
- connectOneEventHandler(id, Py_None, pFunc);
- }
-}
-
-double Node::getEffectiveOpacity() const
+float Node::getEffectiveOpacity() const
{
return m_EffectiveOpacity;
}
@@ -456,7 +455,7 @@ void Node::initFilename(string& sFilename)
}
}
-void Node::checkReload(const std::string& sHRef, const ImagePtr& pImage,
+bool Node::checkReload(const std::string& sHRef, const ImagePtr& pImage,
Image::TextureCompression comp)
{
string sLastFilename = pImage->getFilename();
@@ -473,11 +472,14 @@ void Node::checkReload(const std::string& sHRef, const ImagePtr& pImage,
} catch (Exception& ex) {
pImage->setEmpty();
if (getState() != Node::NS_UNCONNECTED) {
- AVG_TRACE(Logger::ERROR, ex.getStr());
+ AVG_LOG_ERROR(ex.getStr());
} else {
- AVG_TRACE(Logger::MEMORY, ex.getStr());
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, ex.getStr());
}
}
+ return true;
+ } else {
+ return false;
}
}
@@ -488,11 +490,12 @@ bool Node::isVisible() const
bool Node::getEffectiveActive() const
{
- if (getParent()) {
- return m_bActive && getParent()->getEffectiveActive();
- } else {
- return m_bActive;
- }
+ return m_bEffectiveActive;
+}
+
+NodePtr Node::getSharedThis()
+{
+ return dynamic_pointer_cast<Node>(ExportedObject::getSharedThis());
}
void Node::connectOneEventHandler(const EventID& id, PyObject * pObj,
@@ -528,58 +531,52 @@ void Node::dumpEventHandlers()
cerr << "-----" << endl;
}
-PyObject * Node::findPythonFunc(const string& sCode)
-{
- if (sCode.empty()) {
- return 0;
- } else {
- PyObject * pModule = PyImport_AddModule("__main__");
- if (!pModule) {
- cerr << "Could not find module __main__." << endl;
- exit(-1);
+string Node::getEventMessageID(const EventPtr& pEvent)
+{
+ Event::Source source = pEvent->getSource();
+ if (source == Event::MOUSE || source == Event::TOUCH) {
+ switch (pEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ return "CURSOR_DOWN";
+ case Event::CURSOR_MOTION:
+ return "CURSOR_MOTION";
+ case Event::CURSOR_UP:
+ return "CURSOR_UP";
+ case Event::CURSOR_OVER:
+ return "CURSOR_OVER";
+ case Event::CURSOR_OUT:
+ return "CURSOR_OUT";
+ default:
+ AVG_ASSERT_MSG(false,
+ (string("Unknown message type ")+pEvent->typeStr()).c_str());
+ return "";
}
- PyObject * pDict = PyModule_GetDict(pModule);
- PyObject * pFunc = PyDict_GetItemString(pDict, sCode.c_str());
- if (!pFunc) {
- AVG_TRACE(Logger::ERROR, "Function \"" << sCode <<
- "\" not defined for node with id '"+getID()+"'. Aborting.");
- exit(-1);
+ } else {
+ switch (pEvent->getType()) {
+ case Event::CURSOR_DOWN:
+ return "HOVER_DOWN";
+ case Event::CURSOR_MOTION:
+ return "HOVER_MOTION";
+ case Event::CURSOR_UP:
+ return "HOVER_UP";
+ case Event::CURSOR_OVER:
+ return "HOVER_OVER";
+ case Event::CURSOR_OUT:
+ return "HOVER_OUT";
+ default:
+ AVG_ASSERT_MSG(false,
+ (string("Unknown message type ")+pEvent->typeStr()).c_str());
+ return "";
}
- return pFunc;
}
}
bool Node::callPython(PyObject * pFunc, EventPtr pEvent)
{
- bool bOk = boost::python::call<bool>(pFunc, pEvent);
+ bool bOk = py::call<bool>(pFunc, pEvent);
return bOk;
}
-bool Node::operator ==(const Node& other) const
-{
- return this == &other;
-}
-
-bool Node::operator !=(const Node& other) const
-{
- return this != &other;
-}
-
-long Node::getHash() const
-{
- return long(this);
-}
-
-const NodeDefinition* Node::getDefinition() const
-{
- return m_pDefinition;
-}
-
-string Node::getTypeStr() const
-{
- return m_pDefinition->getName();
-}
-
Node::EventID::EventID(Event::Type eventType, Event::Source source)
: m_Type(eventType),
m_Source(source)
diff --git a/src/player/Node.h b/src/player/Node.h
index 1130607..9e2b439 100644
--- a/src/player/Node.h
+++ b/src/player/Node.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "../api.h"
+#include "Publisher.h"
#include "Event.h"
#include "Image.h"
@@ -32,15 +33,12 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#include <string>
-#include <vector>
// Python docs say python.h should be included before any standard headers (!)
#include "WrapPython.h"
#include <string>
+#include <vector>
#include <list>
#include <map>
@@ -48,19 +46,15 @@ namespace avg {
class Node;
typedef boost::shared_ptr<Node> NodePtr;
-typedef boost::weak_ptr<Node> NodeWeakPtr;
class DivNode;
typedef boost::shared_ptr<DivNode> DivNodePtr;
-typedef boost::weak_ptr<DivNode> DivNodeWeakPtr;
class ArgList;
-class NodeDefinition;
+class TypeDefinition;
class CanvasNode;
typedef boost::shared_ptr<CanvasNode> CanvasNodePtr;
-typedef boost::weak_ptr<CanvasNode> CanvasNodeWeakPtr;
class AVGNode;
typedef boost::shared_ptr<AVGNode> AVGNodePtr;
-typedef boost::weak_ptr<AVGNode> AVGNodeWeakPtr;
class Image;
typedef boost::shared_ptr<Image> ImagePtr;
class VertexArray;
@@ -69,27 +63,21 @@ class Canvas;
typedef boost::shared_ptr<Canvas> CanvasPtr;
typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
-class AVG_API Node: public boost::enable_shared_from_this<Node>
+class AVG_API Node: public Publisher
{
public:
enum NodeState {NS_UNCONNECTED, NS_CONNECTED, NS_CANRENDER};
-
- static NodeDefinition createDefinition();
- template<class NodeType>
- static NodePtr buildNode(const ArgList& Args)
- {
- return NodePtr(new NodeType(Args));
- }
- virtual void setTypeInfo(const NodeDefinition * pDefinition);
+
+ static void registerType();
+ void registerInstance(PyObject* pSelf, const DivNodePtr& pParent);
virtual ~Node();
- virtual void setArgs(const ArgList& args);
- virtual void setParent(DivNodeWeakPtr pParent, NodeState parentState,
+ virtual void setParent(DivNode* pParent, NodeState parentState,
CanvasPtr pCanvas);
virtual void removeParent();
- void checkSetParentError(DivNodeWeakPtr pParent);
+ void checkSetParentError(DivNode* pParent);
DivNodePtr getParent() const;
- std::vector<NodeWeakPtr> getParentChain();
+ std::vector<NodePtr> getParentChain();
virtual void connectDisplay();
virtual void connect(CanvasPtr pCanvas);
@@ -100,8 +88,8 @@ class AVG_API Node: public boost::enable_shared_from_this<Node>
virtual void setID(const std::string& ID);
- double getOpacity() const;
- void setOpacity(double opacity);
+ float getOpacity() const;
+ void setOpacity(float opacity);
bool getActive() const;
void setActive(bool bActive);
@@ -118,19 +106,21 @@ class AVG_API Node: public boost::enable_shared_from_this<Node>
PyObject * pObj, PyObject * pFunc);
void disconnectEventHandler(PyObject * pObj, PyObject * pFunc=0);
- DPoint getRelPos(const DPoint& absPos) const;
- DPoint getAbsPos(const DPoint& relPos) const;
- virtual DPoint toLocal(const DPoint& pos) const;
- virtual DPoint toGlobal(const DPoint& pos) const;
- NodePtr getElementByPos(const DPoint& pos);
- virtual void getElementsByPos(const DPoint& pos,
- std::vector<NodeWeakPtr>& pElements);
-
- virtual void preRender();
- virtual void maybeRender(const DRect& Rect) {};
- virtual void render(const DRect& Rect) {};
+ glm::vec2 getRelPos(const glm::vec2& absPos) const;
+ glm::vec2 getAbsPos(const glm::vec2& relPos) const;
+ virtual glm::vec2 toLocal(const glm::vec2& pos) const;
+ virtual glm::vec2 toGlobal(const glm::vec2& pos) const;
+ NodePtr getElementByPos(const glm::vec2& pos);
+ virtual void getElementsByPos(const glm::vec2& pos,
+ std::vector<NodePtr>& pElements);
+
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void maybeRender(const glm::mat4& parentTransform) {};
+ virtual void render() {};
+ virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 color) {};
- double getEffectiveOpacity() const;
+ float getEffectiveOpacity() const;
virtual std::string dump(int indent = 0);
NodeState getState() const;
@@ -139,36 +129,24 @@ class AVG_API Node: public boost::enable_shared_from_this<Node>
virtual bool handleEvent(EventPtr pEvent);
virtual const std::string& getID() const;
- std::string getTypeStr() const;
-
- bool operator ==(const Node& other) const;
- bool operator !=(const Node& other) const;
- long getHash() const;
-
- virtual const NodeDefinition* getDefinition() const;
-
- virtual void renderOutlines(const VertexArrayPtr& pVA, Pixel32 color) {};
-
+
protected:
- Node();
+ Node(const std::string& sPublisherName="Node");
- void addArgEventHandlers(Event::Type eventType, const std::string& sCode);
- void addArgEventHandler(Event::Type eventType, Event::Source source,
- const std::string& sCode);
bool reactsToMouseEvents();
void setState(NodeState state);
void initFilename(std::string& sFilename);
- void checkReload(const std::string& sHRef, const ImagePtr& pImage,
+ bool checkReload(const std::string& sHRef, const ImagePtr& pImage,
Image::TextureCompression comp = Image::TEXTURECOMPRESSION_NONE);
virtual bool isVisible() const;
bool getEffectiveActive() const;
+ NodePtr getSharedThis();
private:
std::string m_ID;
- const NodeDefinition* m_pDefinition;
- DivNodeWeakPtr m_pParent;
+ DivNode* m_pParent;
struct EventID {
EventID(Event::Type eventType, Event::Source source);
@@ -194,19 +172,20 @@ class AVG_API Node: public boost::enable_shared_from_this<Node>
void connectOneEventHandler(const EventID& id, PyObject * pObj, PyObject * pFunc);
void dumpEventHandlers();
- PyObject * findPythonFunc(const std::string& sCode);
+ std::string getEventMessageID(const EventPtr& pEvent);
bool callPython(PyObject * pFunc, avg::EventPtr pEvent);
EventHandlerMap m_EventHandlerMap;
CanvasWeakPtr m_pCanvas;
- double m_Opacity;
+ float m_Opacity;
NodeState m_State;
bool m_bActive;
bool m_bSensitive;
- double m_EffectiveOpacity;
+ float m_EffectiveOpacity;
+ bool m_bEffectiveActive;
};
}
diff --git a/src/player/NodeRegistry.cpp b/src/player/NodeRegistry.cpp
deleted file mode 100644
index 854e827..0000000
--- a/src/player/NodeRegistry.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-// Original author of this file is Nick Hebner (hebnern@gmail.com).
-//
-
-#include "NodeRegistry.h"
-#include "NodeDefinition.h"
-
-#include "../base/Exception.h"
-
-#include <set>
-
-using namespace std;
-
-namespace avg {
-
-NodeRegistry::NodeRegistry()
-{
-}
-
-NodeRegistry::~NodeRegistry()
-{
-}
-
-void NodeRegistry::registerNodeType(const NodeDefinition& def)
-{
- m_NodeDefs.insert(NodeDefMap::value_type(def.getName(), def));
-}
-
-void NodeRegistry::updateNodeDefinition(const NodeDefinition& def)
-{
- m_NodeDefs[def.getName()] = def;
-}
-
-NodePtr NodeRegistry::createNode(const string& sType, const xmlNodePtr xmlNode)
-{
- const NodeDefinition& def = getNodeDef(sType);
- ArgList args(def.getDefaultArgs(), xmlNode);
- NodeBuilder builder = def.getBuilder();
- NodePtr pNode = builder(args);
- pNode->setTypeInfo(&def);
- return pNode;
-}
-
-NodePtr NodeRegistry::createNode(const string& sType, const boost::python::dict& pyDict)
-{
- const NodeDefinition& def = getNodeDef(sType);
- ArgList args(def.getDefaultArgs(), pyDict);
- NodeBuilder builder = def.getBuilder();
- NodePtr pNode = builder(args);
- pNode->setTypeInfo(&def);
- return pNode;
-}
-
-string NodeRegistry::getDTD() const
-{
- if (m_NodeDefs.empty()) {
- return string("");
- }
-
- stringstream ss;
-
- for (NodeDefMap::const_iterator defIt = m_NodeDefs.begin();
- defIt != m_NodeDefs.end(); defIt++)
- {
- const NodeDefinition& def = defIt->second;
- writeNodeDTD(def, ss);
- }
-
- for (NodeDefMap::const_iterator defIt = m_NodeDefs.begin();
- defIt != m_NodeDefs.end(); defIt++)
- {
- const NodeDefinition& def = defIt->second;
- ss << def.getDTDElements();
- }
-
- return ss.str();
-}
-
-const NodeDefinition& NodeRegistry::getNodeDef(const string& sType)
-{
- NodeDefMap::const_iterator it = m_NodeDefs.find(sType);
- if (it == m_NodeDefs.end()) {
- throw (Exception (AVG_ERR_XML_NODE_UNKNOWN,
- string("Unknown node type ") + sType + " encountered."));
- }
- return it->second;
-}
-
-void NodeRegistry::writeNodeDTD(const NodeDefinition& def, stringstream& ss) const
-{
- ss << "<!ELEMENT " << def.getName() << " " << def.getDTDChildrenString() << " >\n";
- if (!def.getDefaultArgs().getArgMap().empty()) {
- ss << "<!ATTLIST " << def.getName();
- for (ArgMap::const_iterator argIt = def.getDefaultArgs().getArgMap().begin();
- argIt != def.getDefaultArgs().getArgMap().end(); argIt++)
- {
- string argName = argIt->first;
- string argType = (argName == "id") ? "ID" : "CDATA";
- string argRequired = def.getDefaultArgs().getArg(argName)->isRequired() ?
- "#REQUIRED" : "#IMPLIED";
- ss << "\n " << argName << " " << argType << " " << argRequired;
- }
- ss << " >\n";
- }
-}
-
-}
diff --git a/src/player/NullFXNode.cpp b/src/player/NullFXNode.cpp
index 544b6d9..d0d943d 100644
--- a/src/player/NullFXNode.cpp
+++ b/src/player/NullFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
#include "NullFXNode.h"
#include "../base/ObjectCounter.h"
-#include "../graphics/ShaderRegistry.h"
#include <string>
diff --git a/src/player/NullFXNode.h b/src/player/NullFXNode.h
index b79c7b4..107ce4b 100644
--- a/src/player/NullFXNode.h
+++ b/src/player/NullFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/OGLSurface.cpp b/src/player/OGLSurface.cpp
index c83acbe..b0aa58e 100644
--- a/src/player/OGLSurface.cpp
+++ b/src/player/OGLSurface.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,23 +27,21 @@
#include "../base/ScopeTimer.h"
#include "../base/ObjectCounter.h"
-#include "../graphics/ShaderRegistry.h"
#include "../graphics/GLContext.h"
#include "../graphics/GLTexture.h"
#include <iostream>
#include <sstream>
-using namespace std;
+#include "../glm/gtc/matrix_transform.hpp"
-#define COLORSPACE_SHADER "COLORSPACE"
+using namespace std;
-static float yuvCoeff[3][4] =
-{
- {1.0f, 0.0f, 1.40f, 0.0f},
- {1.0f, -0.34f, -0.71f, 0.0f},
- {1.0f, 1.77f, 0.0f, 0.0f},
-};
+static glm::mat4 yuvCoeff(
+ 1.0f, 1.0f, 1.0f, 0.0f,
+ 0.0f, -0.34f, 1.77f, 0.0f,
+ 1.40f, -0.71f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
namespace avg {
@@ -52,6 +50,7 @@ OGLSurface::OGLSurface()
m_Gamma(1,1,1),
m_Brightness(1,1,1),
m_Contrast(1,1,1),
+ m_AlphaGamma(1),
m_bIsDirty(true)
{
ObjectCounter::get()->incRef(&typeid(*this));
@@ -62,20 +61,6 @@ OGLSurface::~OGLSurface()
ObjectCounter::get()->decRef(&typeid(*this));
}
-void OGLSurface::attach()
-{
- if (!GLContext::getCurrent()->isUsingShaders()) {
- if (m_pMaskTexture) {
- throw Exception(AVG_ERR_VIDEO_GENERAL,
- "Can't set mask bitmap since shader support is disabled.");
- }
- if (gammaIsModified() || colorIsModified()) {
- throw Exception(AVG_ERR_VIDEO_GENERAL,
- "Can't use color correction (gamma, brightness, contrast) since shader support is disabled.");
- }
- }
-}
-
void OGLSurface::create(PixelFormat pf, GLTexturePtr pTex0, GLTexturePtr pTex1,
GLTexturePtr pTex2, GLTexturePtr pTex3)
{
@@ -116,82 +101,68 @@ void OGLSurface::destroy()
void OGLSurface::activate(const IntPoint& logicalSize, bool bPremultipliedAlpha) const
{
- if (useShader()) {
- OGLShaderPtr pShader = getShader(COLORSPACE_SHADER);
- pShader->activate();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OGLSurface::activate()");
- switch (m_pf) {
- case YCbCr420p:
- case YCbCrJ420p:
- pShader->setUniformIntParam("colorModel", 1);
- break;
- case YCbCrA420p:
- pShader->setUniformIntParam("colorModel", 3);
- break;
- case A8:
- pShader->setUniformIntParam("colorModel", 2);
- break;
- default:
- pShader->setUniformIntParam("colorModel", 0);
- }
-
- m_pTextures[0]->activate(GL_TEXTURE0);
- pShader->setUniformIntParam("texture", 0);
-
- if (pixelFormatIsPlanar(m_pf)) {
- m_pTextures[1]->activate(GL_TEXTURE1);
- pShader->setUniformIntParam("cbTexture", 1);
- m_pTextures[2]->activate(GL_TEXTURE2);
- pShader->setUniformIntParam("crTexture", 2);
- if (m_pf == YCbCrA420p) {
- m_pTextures[3]->activate(GL_TEXTURE3);
- pShader->setUniformIntParam("aTexture", 3);
- }
- }
- if (pixelFormatIsPlanar(m_pf) || colorIsModified()) {
- Matrix3x4 mat = calcColorspaceMatrix();
- pShader->setUniformVec4fParam("colorCoeff0",
- mat.val[0][0], mat.val[1][0], mat.val[2][0], 0);
- pShader->setUniformVec4fParam("colorCoeff1",
- mat.val[0][1], mat.val[1][1], mat.val[2][1], 0);
- pShader->setUniformVec4fParam("colorCoeff2",
- mat.val[0][2], mat.val[1][2], mat.val[2][2], 0);
- pShader->setUniformVec4fParam("colorCoeff3",
- mat.val[0][3], mat.val[1][3], mat.val[2][3], 1);
- }
+ StandardShaderPtr pShader = StandardShader::get();
+
+ GLContext::checkError("OGLSurface::activate()");
+ switch (m_pf) {
+ case YCbCr420p:
+ case YCbCrJ420p:
+ pShader->setColorModel(1);
+ break;
+ case YCbCrA420p:
+ pShader->setColorModel(3);
+ break;
+ case A8:
+ pShader->setColorModel(2);
+ break;
+ default:
+ pShader->setColorModel(0);
+ }
- pShader->setUniformVec4fParam("gamma", float(1/m_Gamma.x), float(1/m_Gamma.y),
- float(1/m_Gamma.z), 1.0);
- pShader->setUniformIntParam("bUseColorCoeff", colorIsModified());
+ m_pTextures[0]->activate(GL_TEXTURE0);
- pShader->setUniformIntParam("bPremultipliedAlpha", bPremultipliedAlpha);
- pShader->setUniformIntParam("bUseMask", bool(m_pMaskTexture));
- if (m_pMaskTexture) {
- m_pMaskTexture->activate(GL_TEXTURE4);
- pShader->setUniformIntParam("maskTexture", 4);
- pShader->setUniformDPointParam("maskPos", m_MaskPos);
- // maskScale is (1,1) for everything excepting words nodes.
- DPoint maskScale(1,1);
- if (logicalSize != IntPoint(0,0)) {
- maskScale = DPoint((double)logicalSize.x/m_Size.x,
- (double)logicalSize.y/m_Size.y);
- }
- pShader->setUniformDPointParam("maskSize", m_MaskSize*maskScale);
+ if (pixelFormatIsPlanar(m_pf)) {
+ m_pTextures[1]->activate(GL_TEXTURE1);
+ m_pTextures[2]->activate(GL_TEXTURE2);
+ if (m_pf == YCbCrA420p) {
+ m_pTextures[3]->activate(GL_TEXTURE3);
}
-
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OGLSurface::activate: params");
+ }
+ if (pixelFormatIsPlanar(m_pf) || colorIsModified()) {
+ glm::mat4 mat = calcColorspaceMatrix();
+ pShader->setColorspaceMatrix(mat);
} else {
- m_pTextures[0]->activate(GL_TEXTURE0);
- if (GLContext::getCurrent()->isUsingShaders()) {
- glproc::UseProgramObject(0);
- }
- for (int i=1; i<5; ++i) {
- glproc::ActiveTexture(GL_TEXTURE0 + i);
- glDisable(GL_TEXTURE_2D);
+ pShader->disableColorspaceMatrix();
+ }
+ pShader->setGamma(glm::vec4(1/m_Gamma.x, 1/m_Gamma.y, 1/m_Gamma.z,
+ 1./m_AlphaGamma));
+
+ pShader->setPremultipliedAlpha(bPremultipliedAlpha);
+ if (m_pMaskTexture) {
+ m_pMaskTexture->activate(GL_TEXTURE4);
+ // Special case for pot textures:
+ // The tex coords in the vertex array are scaled to fit the image texture. We
+ // need to undo this and fit to the mask texture. In the npot case, everything
+ // evaluates to (1,1);
+ glm::vec2 texSize = glm::vec2(m_pTextures[0]->getGLSize());
+ glm::vec2 imgSize = glm::vec2(m_pTextures[0]->getSize());
+ glm::vec2 maskTexSize = glm::vec2(m_pMaskTexture->getGLSize());
+ glm::vec2 maskImgSize = glm::vec2(m_pMaskTexture->getSize());
+ glm::vec2 maskScale = glm::vec2(maskTexSize.x/maskImgSize.x,
+ maskTexSize.y/maskImgSize.y);
+ glm::vec2 imgScale = glm::vec2(texSize.x/imgSize.x, texSize.y/imgSize.y);
+ glm::vec2 maskPos = m_MaskPos/maskScale;
+ // Special case for words nodes.
+ if (logicalSize != IntPoint(0,0)) {
+ maskScale *= glm::vec2((float)logicalSize.x/m_Size.x,
+ (float)logicalSize.y/m_Size.y);
}
- glproc::ActiveTexture(GL_TEXTURE0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "OGLSurface::activate: fixed function");
+ pShader->setMask(true, maskPos, m_MaskSize*maskScale/imgScale);
+ } else {
+ pShader->setMask(false);
}
+ pShader->activate();
+ GLContext::checkError("OGLSurface::activate");
}
GLTexturePtr OGLSurface::getTex(int i) const
@@ -199,7 +170,7 @@ GLTexturePtr OGLSurface::getTex(int i) const
return m_pTextures[i];
}
-void OGLSurface::setMaskCoords(DPoint maskPos, DPoint maskSize)
+void OGLSurface::setMaskCoords(glm::vec2 maskPos, glm::vec2 maskSize)
{
m_MaskPos = maskPos;
m_MaskSize = maskSize;
@@ -226,94 +197,19 @@ bool OGLSurface::isCreated() const
return m_pTextures[0];
}
-void OGLSurface::setColorParams(const DTriple& gamma, const DTriple& brightness,
- const DTriple& contrast)
+void OGLSurface::setColorParams(const glm::vec3& gamma, const glm::vec3& brightness,
+ const glm::vec3& contrast)
{
m_Gamma = gamma;
m_Brightness = brightness;
m_Contrast = contrast;
- if (!GLContext::getCurrent()->isUsingShaders() &&
- (gammaIsModified() || colorIsModified()))
- {
- throw Exception(AVG_ERR_VIDEO_GENERAL,
- "Can't use color correction (gamma, brightness, contrast) since shader support is disabled.");
- }
m_bIsDirty = true;
}
-void OGLSurface::createShader()
+void OGLSurface::setAlphaGamma(float gamma)
{
- string sProgram =
- "uniform sampler2D texture;\n"
- "uniform sampler2D yTexture;\n"
- "uniform sampler2D cbTexture;\n"
- "uniform sampler2D crTexture;\n"
- "uniform sampler2D aTexture;\n"
- "uniform sampler2D maskTexture;\n"
- "uniform int colorModel; // 0=rgb, 1=yuv, 2=greyscale, 3=yuva\n"
- "uniform vec4 colorCoeff0;\n"
- "uniform vec4 colorCoeff1;\n"
- "uniform vec4 colorCoeff2;\n"
- "uniform vec4 colorCoeff3;\n"
- "uniform bool bUseColorCoeff;\n"
- "uniform vec4 gamma;\n"
- "uniform bool bPremultipliedAlpha;\n"
- "uniform bool bUseMask;\n"
- "uniform vec2 maskPos;\n"
- "uniform vec2 maskSize;\n"
- "\n"
- "vec4 convertYCbCr(mat4 colorCoeff)\n"
- "{\n"
- " vec4 yuv;\n"
- " yuv = vec4(texture2D(texture, gl_TexCoord[0].st).r,\n"
- " texture2D(cbTexture, (gl_TexCoord[0].st)).r,\n"
- " texture2D(crTexture, (gl_TexCoord[0].st)).r,\n"
- " 1.0);\n"
- " vec4 rgb;\n"
- " rgb = colorCoeff*yuv;\n"
- " return vec4(rgb.rgb, gl_Color.a);\n"
- "}\n"
- "\n"
- "void main(void)\n"
- "{\n"
- " vec4 rgba;\n"
- " mat4 colorCoeff;\n"
- " colorCoeff[0] = colorCoeff0;\n"
- " colorCoeff[1] = colorCoeff1;\n"
- " colorCoeff[2] = colorCoeff2;\n"
- " colorCoeff[3] = colorCoeff3;\n"
- " if (colorModel == 0) {\n"
- " rgba = texture2D(texture, gl_TexCoord[0].st);\n"
- " if (bUseColorCoeff) {\n"
- " rgba = colorCoeff*rgba;\n"
- " };\n"
- " rgba.a *= gl_Color.a;\n"
- " } else if (colorModel == 1) {\n"
- " rgba = convertYCbCr(colorCoeff);\n"
- " } else if (colorModel == 2) {\n"
- " rgba = gl_Color;\n"
- " if (bUseColorCoeff) {\n"
- " rgba = colorCoeff*rgba;\n"
- " };\n"
- " rgba.a *= texture2D(texture, gl_TexCoord[0].st).a;\n"
- " } else if (colorModel == 3) {\n"
- " rgba = convertYCbCr(colorCoeff);\n"
- " rgba.a *= texture2D(aTexture, gl_TexCoord[0].st).r;\n"
- " } else {\n"
- " rgba = vec4(1,1,1,1);\n"
- " }\n"
- " rgba = pow(rgba, gamma);\n"
- " if (bUseMask) {\n"
- " if (bPremultipliedAlpha) {\n"
- " rgba.rgb *= texture2D(maskTexture,\n"
- " (gl_TexCoord[0].st/maskSize)-maskPos).r;\n"
- " }\n"
- " rgba.a *= texture2D(maskTexture,\n"
- " (gl_TexCoord[0].st/maskSize)-maskPos).r;\n"
- " }\n"
- " gl_FragColor = rgba;\n"
- "}\n";
- getOrCreateShader(COLORSPACE_SHADER, sProgram);
+ m_AlphaGamma = gamma;
+ m_bIsDirty = true;
}
bool OGLSurface::isDirty() const
@@ -335,40 +231,27 @@ void OGLSurface::resetDirty()
}
}
-bool OGLSurface::useShader() const
-{
- return GLContext::getCurrent()->isUsingShaders() &&
- (m_pMaskTexture || pixelFormatIsPlanar(m_pf) || gammaIsModified() ||
- colorIsModified());
-}
-
-Matrix3x4 OGLSurface::calcColorspaceMatrix() const
+glm::mat4 OGLSurface::calcColorspaceMatrix() const
{
- Matrix3x4 mat;
+ glm::mat4 mat;
if (colorIsModified()) {
- mat *= Matrix3x4::createScale(m_Brightness);
- mat *= Matrix3x4::createTranslate(float(0.5-m_Contrast.x/2),
- float(0.5-m_Contrast.y/2), float(0.5-m_Contrast.z/2));
- mat *= Matrix3x4::createScale(m_Contrast);
+ mat = glm::scale(mat, m_Brightness);
+ glm::vec3 contrast = glm::vec3(0.5f, 0.5f, 0.5f) - m_Contrast/2.f;
+ mat = glm::translate(mat, contrast);
+ mat = glm::scale(mat, m_Contrast);
}
if (m_pf == YCbCr420p || m_pf == YCbCrJ420p || m_pf == YCbCrA420p) {
- mat *= Matrix3x4(*yuvCoeff);
- mat *= Matrix3x4::createTranslate(0.0, -0.5, -0.5);
+ mat *= yuvCoeff;
+ mat = glm::translate(mat, glm::vec3(0.0, -0.5, -0.5));
if (m_pf == YCbCr420p || m_pf == YCbCrA420p) {
- mat *= Matrix3x4::createScale(255.0f/(235-16), 255.0f/(240-16) ,
- 255.0f/(240-16));
- mat *= Matrix3x4::createTranslate(-16.0f/255, -16.0f/255, -16.0f/255);
+ mat = glm::scale(mat,
+ glm::vec3(255.0f/(235-16), 255.0f/(235-16), 255.0f/(235-16)));
+ mat = glm::translate(mat, glm::vec3(-16.0f/255, -16.0f/255, -16.0f/255));
}
}
return mat;
}
-bool OGLSurface::gammaIsModified() const
-{
- return (fabs(m_Gamma.x-1.0) > 0.00001 || fabs(m_Gamma.y-1.0) > 0.00001 ||
- fabs(m_Gamma.z-1.0) > 0.00001);
-}
-
bool OGLSurface::colorIsModified() const
{
return (fabs(m_Brightness.x-1.0) > 0.00001 || fabs(m_Brightness.y-1.0) > 0.00001 ||
diff --git a/src/player/OGLSurface.h b/src/player/OGLSurface.h
index a780b4a..38e6ef4 100644
--- a/src/player/OGLSurface.h
+++ b/src/player/OGLSurface.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,12 +24,11 @@
#include "../api.h"
-#include "../base/Point.h"
-#include "../base/Triple.h"
-#include "../base/Matrix3x4.h"
+#include "../base/GLMHelper.h"
#include "../graphics/Bitmap.h"
#include "../graphics/OGLHelper.h"
+#include "../graphics/StandardShader.h"
#include <vector>
#include <string>
@@ -45,7 +44,6 @@ public:
OGLSurface();
virtual ~OGLSurface();
- void attach();
virtual void create(PixelFormat pf, GLTexturePtr pTex0,
GLTexturePtr pTex1 = GLTexturePtr(), GLTexturePtr pTex2 = GLTexturePtr(),
GLTexturePtr pTex3 = GLTexturePtr());
@@ -55,39 +53,38 @@ public:
bool bPremultipliedAlpha = false) const;
GLTexturePtr getTex(int i=0) const;
- void setMaskCoords(DPoint maskPos, DPoint maskSize);
+ void setMaskCoords(glm::vec2 maskPos, glm::vec2 maskSize);
PixelFormat getPixelFormat();
IntPoint getSize();
IntPoint getTextureSize();
bool isCreated() const;
- void setColorParams(const DTriple& gamma, const DTriple& brightness,
- const DTriple& contrast);
- static void createShader();
+ void setColorParams(const glm::vec3& gamma, const glm::vec3& brightness,
+ const glm::vec3& contrast);
+ void setAlphaGamma(float gamma);
bool isDirty() const;
void resetDirty();
private:
- bool useShader() const;
- Matrix3x4 calcColorspaceMatrix() const;
- bool gammaIsModified() const;
+ glm::mat4 calcColorspaceMatrix() const;
bool colorIsModified() const;
GLTexturePtr m_pTextures[4];
IntPoint m_Size;
PixelFormat m_pf;
GLTexturePtr m_pMaskTexture;
- DPoint m_MaskPos;
- DPoint m_MaskSize;
+ glm::vec2 m_MaskPos;
+ glm::vec2 m_MaskSize;
-
- DTriple m_Gamma;
- DTriple m_Brightness;
- DTriple m_Contrast;
+ glm::vec3 m_Gamma;
+ glm::vec3 m_Brightness;
+ glm::vec3 m_Contrast;
+ float m_AlphaGamma;
bool m_bIsDirty;
+
};
}
diff --git a/src/player/OffscreenCanvas.cpp b/src/player/OffscreenCanvas.cpp
index 6ff1c52..758bf43 100644
--- a/src/player/OffscreenCanvas.cpp
+++ b/src/player/OffscreenCanvas.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,10 +25,12 @@
#include "Player.h"
#include "../base/Exception.h"
-#include "../base/ProfilingZone.h"
+#include "../base/ProfilingZoneID.h"
#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
#include "../graphics/FilterUnmultiplyAlpha.h"
+#include "../graphics/BitmapLoader.h"
#include <iostream>
@@ -62,38 +64,40 @@ void OffscreenCanvas::setRoot(NodePtr pRootNode)
void OffscreenCanvas::initPlayback()
{
m_bUseMipmaps = getMipmap();
- m_pFBO = FBOPtr(new FBO(getSize(), B8G8R8A8, 1, getMultiSampleSamples(), true,
- m_bUseMipmaps));
+ PixelFormat pf;
+ if (BitmapLoader::get()->isBlueFirst()) {
+ pf = B8G8R8A8;
+ } else {
+ pf = R8G8B8A8;
+ }
+ bool bUseDepthBuffer = GLContext::getMain()->useDepthBuffer();
+ m_pFBO = FBOPtr(new FBO(getSize(), pf, 1, getMultiSampleSamples(), bUseDepthBuffer,
+ true, m_bUseMipmaps));
Canvas::initPlayback(getMultiSampleSamples());
m_bIsRendered = false;
}
-void OffscreenCanvas::stopPlayback()
+void OffscreenCanvas::stopPlayback(bool bIsAbort)
{
m_pFBO = FBOPtr();
- Canvas::stopPlayback();
+ Canvas::stopPlayback(bIsAbort);
m_bIsRendered = false;
}
BitmapPtr OffscreenCanvas::screenshot() const
{
- return screenshot(false);
+ BitmapPtr pBmp = screenshotIgnoreAlpha();
+ FilterUnmultiplyAlpha().applyInPlace(pBmp);
+ return pBmp;
}
-static ProfilingZoneID OffscreenRenderProfilingZone("Render OffscreenCanvas");
-
-BitmapPtr OffscreenCanvas::screenshot(bool bIgnoreAlpha) const
+BitmapPtr OffscreenCanvas::screenshotIgnoreAlpha() const
{
if (!isRunning() || !m_bIsRendered) {
throw(Exception(AVG_ERR_UNSUPPORTED,
"OffscreenCanvas::screenshot(): Canvas has not been rendered. No screenshot available"));
}
BitmapPtr pBmp = m_pFBO->getImage(0);
- if (bIgnoreAlpha) {
- pBmp->setPixelFormat(B8G8R8X8);
- } else {
- FilterUnmultiplyAlpha().applyInPlace(pBmp);
- }
return pBmp;
}
@@ -126,7 +130,7 @@ void OffscreenCanvas::setAutoRender(bool bAutoRender)
void OffscreenCanvas::manualRender()
{
emitPreRenderSignal();
- render();
+ renderTree();
emitFrameEndSignal();
}
@@ -184,10 +188,13 @@ bool OffscreenCanvas::isCameraImageAvailable() const
void OffscreenCanvas::addDependentCanvas(CanvasPtr pCanvas)
{
- AVG_ASSERT(!(pCanvas == shared_from_this()));
m_pDependentCanvases.push_back(pCanvas);
- Player::get()->newCanvasDependency(
- dynamic_pointer_cast<OffscreenCanvas>(shared_from_this()));
+ try {
+ Player::get()->newCanvasDependency();
+ } catch (Exception&) {
+ m_pDependentCanvases.pop_back();
+ throw;
+ }
}
void OffscreenCanvas::removeDependentCanvas(CanvasPtr pCanvas)
@@ -202,14 +209,9 @@ void OffscreenCanvas::removeDependentCanvas(CanvasPtr pCanvas)
AVG_ASSERT(false);
}
-bool OffscreenCanvas::hasDependentCanvas(CanvasPtr pCanvas) const
+const vector<CanvasPtr>& OffscreenCanvas::getDependentCanvases() const
{
- for (unsigned i = 0; i < m_pDependentCanvases.size(); ++i) {
- if (pCanvas == m_pDependentCanvases[i]) {
- return true;
- }
- }
- return false;
+ return m_pDependentCanvases;
}
unsigned OffscreenCanvas::getNumDependentCanvases() const
@@ -223,8 +225,11 @@ bool OffscreenCanvas::isSupported()
throw(Exception(AVG_ERR_UNSUPPORTED,
"OffscreenCanvas::isSupported(): Player.play() needs to be called before support can be queried."));
}
-
- return FBO::isFBOSupported() && FBO::isPackedDepthStencilSupported();
+ if (GLContext::getMain()->isGLES()) {
+ return true;
+ } else {
+ return FBO::isFBOSupported() && FBO::isPackedDepthStencilSupported();
+ }
}
bool OffscreenCanvas::isMultisampleSupported()
@@ -245,14 +250,20 @@ void OffscreenCanvas::dump() const
}
}
-void OffscreenCanvas::render()
+static ProfilingZoneID OffscreenRenderProfilingZone("Render OffscreenCanvas");
+
+void OffscreenCanvas::renderTree()
{
if (!isRunning()) {
throw(Exception(AVG_ERR_UNSUPPORTED,
- "OffscreenCanvas::render(): Player.play() needs to be called before rendering offscreen canvases."));
+ "OffscreenCanvas::renderTree(): Player.play() needs to be called before rendering offscreen canvases."));
+ }
+ preRender();
+ m_pFBO->activate();
+ {
+ ScopeTimer Timer(OffscreenRenderProfilingZone);
+ Canvas::render(IntPoint(getRootNode()->getSize()), true);
}
- Canvas::render(IntPoint(getRootNode()->getSize()), true, m_pFBO,
- OffscreenRenderProfilingZone);
m_pFBO->copyToDestTexture();
m_bIsRendered = true;
}
diff --git a/src/player/OffscreenCanvas.h b/src/player/OffscreenCanvas.h
index 808f950..4d740b6 100644
--- a/src/player/OffscreenCanvas.h
+++ b/src/player/OffscreenCanvas.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -41,10 +41,10 @@ class AVG_API OffscreenCanvas: public Canvas
virtual ~OffscreenCanvas();
virtual void setRoot(NodePtr pRootNode);
virtual void initPlayback();
- virtual void stopPlayback();
+ virtual void stopPlayback(bool bIsAbort);
virtual BitmapPtr screenshot() const;
- virtual BitmapPtr screenshot(bool bIgnoreAlpha) const;
+ virtual BitmapPtr screenshotIgnoreAlpha() const;
bool getHandleEvents() const;
int getMultiSampleSamples() const;
bool getMipmap() const;
@@ -65,7 +65,7 @@ class AVG_API OffscreenCanvas: public Canvas
void addDependentCanvas(CanvasPtr pCanvas);
void removeDependentCanvas(CanvasPtr pCanvas);
- bool hasDependentCanvas(CanvasPtr pCanvas) const;
+ const std::vector<CanvasPtr>& getDependentCanvases() const;
unsigned getNumDependentCanvases() const;
static bool isSupported();
@@ -73,7 +73,7 @@ class AVG_API OffscreenCanvas: public Canvas
void dump() const;
protected:
- virtual void render();
+ virtual void renderTree();
private:
FBOPtr m_pFBO;
@@ -82,7 +82,6 @@ class AVG_API OffscreenCanvas: public Canvas
bool m_bIsRendered;
CameraNode* m_pCameraNodeRef;
- int m_cameraFrameRate;
};
typedef boost::shared_ptr<OffscreenCanvas> OffscreenCanvasPtr;
diff --git a/src/player/OffscreenCanvasNode.cpp b/src/player/OffscreenCanvasNode.cpp
index 5c72802..8f712c3 100644
--- a/src/player/OffscreenCanvasNode.cpp
+++ b/src/player/OffscreenCanvasNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
#include "OffscreenCanvasNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/FileHelper.h"
@@ -30,10 +30,10 @@ using namespace std;
namespace avg {
-NodeDefinition OffscreenCanvasNode::createDefinition()
+void OffscreenCanvasNode::registerType()
{
- return NodeDefinition("canvas", Node::buildNode<OffscreenCanvasNode>)
- .extendDefinition(CanvasNode::createDefinition())
+ TypeDefinition def = TypeDefinition("canvas", "canvasbase",
+ ExportedObject::buildObject<OffscreenCanvasNode>)
.addArg(Arg<bool>("handleevents", false, false,
offsetof(OffscreenCanvasNode, m_bHandleEvents)))
.addArg(Arg<int>("multisamplesamples", 1, false,
@@ -42,6 +42,7 @@ NodeDefinition OffscreenCanvasNode::createDefinition()
offsetof(OffscreenCanvasNode, m_bMipmap)))
.addArg(Arg<bool>("autorender", true, false,
offsetof(OffscreenCanvasNode, m_bAutoRender)));
+ TypeRegistry::get()->registerType(def);
}
OffscreenCanvasNode::OffscreenCanvasNode(const ArgList& args)
diff --git a/src/player/OffscreenCanvasNode.h b/src/player/OffscreenCanvasNode.h
index 47e1ed7..9d2e850 100644
--- a/src/player/OffscreenCanvasNode.h
+++ b/src/player/OffscreenCanvasNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ namespace avg {
class AVG_API OffscreenCanvasNode : public CanvasNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
OffscreenCanvasNode(const ArgList& args);
virtual ~OffscreenCanvasNode();
diff --git a/src/player/PanoImageNode.cpp b/src/player/PanoImageNode.cpp
deleted file mode 100644
index 89157bb..0000000
--- a/src/player/PanoImageNode.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#include "PanoImageNode.h"
-#include "NodeDefinition.h"
-
-#include "../base/MathHelper.h"
-#include "../base/Logger.h"
-#include "../base/ProfilingZone.h"
-#include "../base/ScopeTimer.h"
-#include "../base/Exception.h"
-#include "../base/XMLHelper.h"
-
-#include "../graphics/OGLHelper.h"
-
-#include <iostream>
-#include <sstream>
-#include <math.h>
-
-using namespace std;
-
-const int TEX_WIDTH = 64;
-
-namespace avg {
-
-NodeDefinition PanoImageNode::createDefinition()
-{
- return NodeDefinition("panoimage", Node::buildNode<PanoImageNode>)
- .extendDefinition(AreaNode::createDefinition())
- .addArg(Arg<UTF8String>("href", "", false, offsetof(PanoImageNode, m_href)))
- .addArg(Arg<double>("sensorwidth", 1.0, false, offsetof(PanoImageNode, m_SensorWidth)))
- .addArg(Arg<double>("sensorheight", 1.0, false, offsetof(PanoImageNode, m_SensorHeight)))
- .addArg(Arg<double>("focallength", 10.0, false, offsetof(PanoImageNode, m_FocalLength)))
- .addArg(Arg<double>("rotation", -1.0, false, offsetof(PanoImageNode, m_Rotation)));
-}
-
-PanoImageNode::PanoImageNode (const ArgList& Args)
-{
- Args.setMembers(this);
- m_pBmp = BitmapPtr(new Bitmap(IntPoint(1,1), R8G8B8));
- load();
-}
-
-PanoImageNode::~PanoImageNode ()
-{
- clearTextures();
-}
-
-void PanoImageNode::connectDisplay()
-{
- AreaNode::connectDisplay();
-
- setupTextures();
-}
-
-void PanoImageNode::disconnect(bool bKill)
-{
- clearTextures();
- AreaNode::disconnect(bKill);
-}
-
-static ProfilingZoneID PanoRenderProfilingZone("PanoImageNode::render");
-
-void PanoImageNode::render(const DRect& Rect)
-{
- ScopeTimer Timer(PanoRenderProfilingZone);
- pushGLState();
- glproc::ActiveTexture(GL_TEXTURE0);
-
- gluLookAt(0, 0, 0, // Eye
- 0, 0, -1, // Center
- 0, 1, 0); // Up.
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: gluLookAt()");
-
- glMatrixMode(GL_PROJECTION);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glMatrixMode(GL_PROJECTION)");
- glLoadIdentity();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glLoadIdentity()");
-
- calcProjection();
- gluPerspective(m_fovy*180/M_PI, m_aspect, 0.1, 2);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: gluPerspective()");
- glMatrixMode(GL_MODELVIEW);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glMatrixMode(GL_MODELVIEW)");
-
- glDisable (GL_CLIP_PLANE0);
- glDisable (GL_CLIP_PLANE1);
- glDisable (GL_CLIP_PLANE2);
- glDisable (GL_CLIP_PLANE3);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glDisable(GL_CLIP_PLANEx)");
- DPoint Vpt = getSize();
- glViewport(0, 0, int(Vpt.x), int(Vpt.y));
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glViewport()");
- glColor4d(1.0, 1.0, 1.0, getEffectiveOpacity());
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glColor4d()");
-//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- double HorizOffset = m_Rotation+m_fovy*m_aspect/2;
-// glutWireSphere(1, 20, 16);
- for (unsigned int i=0; i<m_TileTextureIDs.size(); ++i) {
- unsigned int TexID = m_TileTextureIDs[i];
- glBindTexture(GL_TEXTURE_2D, TexID);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glBindTexture()");
- double StartAngle=i*m_SliceAngle-HorizOffset;
- double StartX = sin(StartAngle);
- double StartZ = -cos(StartAngle);
- double EndAngle;
- if (i<m_TileTextureIDs.size()-1) {
- EndAngle = (i+1)*m_SliceAngle-HorizOffset;
- } else {
- EndAngle = m_CylAngle-HorizOffset;
- }
- double EndX = sin(EndAngle);
- double EndZ = -cos(EndAngle);
- double TexPartUsed = double(m_pBmp->getSize().y)/m_TexHeight;
- glBegin(GL_QUADS);
- glTexCoord2d(0.0, 0.0);
- glVertex3d(StartX, m_CylHeight, StartZ);
- glTexCoord2d(0.0, TexPartUsed);
- glVertex3d(StartX, -m_CylHeight, StartZ);
- glTexCoord2d(1.0, TexPartUsed);
- glVertex3d(EndX, -m_CylHeight, EndZ);
- glTexCoord2d(1.0, 0.0);
- glVertex3d(EndX, m_CylHeight, EndZ);
- glEnd();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::render: glEnd()");
- }
-
- popGLState();
-}
-
-double PanoImageNode::getScreenPosFromAngle(double Angle) const
-{
- double HorizOffsetAngle = Angle-m_Rotation-m_fovy*m_aspect/2;
- double PixelDistFromCenter = m_FocalLength*tan(HorizOffsetAngle)/m_SensorWidth
- *getSize().x;
- return PixelDistFromCenter+getSize().x/2;
-}
-
-double PanoImageNode::getScreenPosFromPanoPos(int PanoPos) const
-{
- double AnglePerPixel = m_CylAngle*1/double(m_pBmp->getSize().x);
- return getScreenPosFromAngle(AnglePerPixel*PanoPos);
-}
-
-const UTF8String& PanoImageNode::getHRef() const
-{
- return m_href;
-}
-
-void PanoImageNode::setHRef(const UTF8String& href)
-{
- m_href = href;
- load();
- if (getState() == NS_CANRENDER) {
- setupTextures();
- }
-}
-
-double PanoImageNode::getSensorWidth () const
-{
- return m_SensorWidth;
-}
-
-void PanoImageNode::setSensorWidth (double sensorWidth)
-{
- m_SensorWidth = sensorWidth;
-}
-
-double PanoImageNode::getSensorHeight () const
-{
- return m_SensorHeight;
-}
-
-void PanoImageNode::setSensorHeight (double sensorHeight)
-{
- m_SensorHeight = sensorHeight;
-}
-
-double PanoImageNode::getFocalLength () const
-{
- return m_FocalLength;
-}
-
-void PanoImageNode::setFocalLength (double focalLength)
-{
- m_FocalLength = focalLength;
-}
-
-double PanoImageNode::getRotation () const
-{
- return m_Rotation;
-}
-
-void PanoImageNode::setRotation (double rotation)
-{
- m_Rotation = rotation;
-}
-
-double PanoImageNode::getMaxRotation () const
-{
- return m_MaxRotation;
-}
-
-void PanoImageNode::calcProjection()
-{
- // Takes SensorWidth, SensorHeight and FocalLength and calculates
- // loads of derived values needed for projection.
- m_fovy = 2*atan((m_SensorHeight/2)/m_FocalLength);
- m_aspect = m_SensorWidth/m_SensorHeight;
- m_CylHeight = tan(m_fovy)/2;
- m_CylAngle = m_fovy*m_pBmp->getSize().x/m_pBmp->getSize().y;
- m_SliceAngle = m_CylAngle*TEX_WIDTH/double(m_pBmp->getSize().x);
- m_MaxRotation = m_CylAngle-m_fovy*m_aspect;
-}
-
-DPoint PanoImageNode::getPreferredMediaSize()
-{
- double SensorAspect = m_SensorWidth/m_SensorHeight;
- double Width = m_pBmp->getSize().y*SensorAspect;
- return DPoint(Width, m_pBmp->getSize().y);
-}
-
-void PanoImageNode::load()
-{
- m_Filename = m_href;
- AVG_TRACE(Logger::MEMORY, "Loading " << m_Filename);
- if (m_Filename != "") {
- initFilename(m_Filename);
- try {
-
- m_pBmp = BitmapPtr(new Bitmap(m_Filename));
- } catch (Exception & ex) {
- AVG_TRACE(Logger::ERROR, ex.getStr());
- }
- }
-
- calcProjection();
- if (m_Rotation == -1) {
- m_Rotation = m_MaxRotation/2;
- }
-}
-
-void PanoImageNode::setupTextures()
-{
- if (!m_TileTextureIDs.empty()) {
- clearTextures();
- }
- m_TexHeight = nextpow2(m_pBmp->getSize().y);
- int NumTextures = int(ceil(double(m_pBmp->getSize().x)/TEX_WIDTH));
- glproc::ActiveTexture(GL_TEXTURE0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glproc::ActiveTexture(GL_TEXTURE0);");
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glPixelStorei(GL_UNPACK_ALIGNMENT)");
- glPixelStorei(GL_UNPACK_ROW_LENGTH, m_pBmp->getSize().x);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glPixelStorei(GL_UNPACK_ROW_LENGTH)");
- glEnable(GL_TEXTURE_2D);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glEnable(GL_TEXTURE_2D);");
- for (int i=0; i<NumTextures; i++) {
- BitmapPtr pRegion;
- if (i != NumTextures-1) {
- pRegion = BitmapPtr(new Bitmap(*m_pBmp,
- IntRect(i*TEX_WIDTH, 0, (i+1)*TEX_WIDTH, m_pBmp->getSize().y)));
- } else {
- // The last column isn't necessarily as wide as the others.
- pRegion = BitmapPtr(new Bitmap(*m_pBmp,
- IntRect(i*TEX_WIDTH, 0,
- m_pBmp->getSize().x, m_pBmp->getSize().y)));
- }
-
- unsigned int TexID;
- glGenTextures(1, &TexID);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glGenTextures()");
- m_TileTextureIDs.push_back(TexID);
- glBindTexture(GL_TEXTURE_2D, TexID);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glBindTexture()");
-
- glTexParameteri(GL_TEXTURE_2D,
- GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,
- GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glTexParameteri()");
-
- int DestMode;
- if (pRegion->getPixelFormat() == R8G8B8X8) {
- DestMode = GL_RGB;
- } else {
- DestMode = GL_RGBA;
- }
- glTexImage2D(GL_TEXTURE_2D, 0,
- DestMode, TEX_WIDTH, m_TexHeight, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, 0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glTexImage2D()");
- unsigned char * pStartPos = pRegion->getPixels();
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
- pRegion->getSize().x, pRegion->getSize().y,
- GL_RGBA, GL_UNSIGNED_BYTE, pStartPos);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL,
- "PanoImageNode::setupTextures: glTexSubImage2D()");
- }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-}
-
-void PanoImageNode::clearTextures()
-{
- for (unsigned int i=0; i<m_TileTextureIDs.size(); ++i) {
- unsigned int TexID = m_TileTextureIDs[i];
- glDeleteTextures(1, &TexID);
- }
- m_TileTextureIDs.clear();
-}
-
-}
diff --git a/src/player/PanoImageNode.h b/src/player/PanoImageNode.h
deleted file mode 100644
index 916d2f2..0000000
--- a/src/player/PanoImageNode.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#ifndef _PanoImageNode_H_
-#define _PanoImageNode_H_
-
-#include "../api.h"
-#include "../avgconfigwrapper.h"
-
-#include "AreaNode.h"
-#include "../base/UTF8String.h"
-#include "../graphics/Bitmap.h"
-
-#include <string>
-#include <vector>
-
-namespace avg {
-
-class AVG_API PanoImageNode: public AreaNode
-{
- public:
- static NodeDefinition createDefinition();
-
- PanoImageNode(const ArgList& Args);
- virtual ~PanoImageNode();
-
- virtual void connectDisplay();
- virtual void disconnect(bool bKill);
- virtual void render(const DRect& Rect);
-
- double getScreenPosFromPanoPos(int PanoPos) const;
- double getScreenPosFromAngle(double Angle) const;
- const UTF8String& getHRef() const;
- void setHRef(const UTF8String& href);
- double getSensorWidth() const;
- void setSensorWidth(double sensorWidth);
- double getSensorHeight() const;
- void setSensorHeight(double sensorHeight);
- double getFocalLength() const;
- void setFocalLength(double focalLength);
- double getRotation() const;
- void setRotation(double rotation);
- double getMaxRotation() const;
-
- protected:
- virtual DPoint getPreferredMediaSize();
-
- private:
- void load();
- void calcProjection();
- void setupTextures();
- void clearTextures();
-
- UTF8String m_href;
- std::string m_Filename;
- double m_SensorWidth;
- double m_SensorHeight;
- double m_FocalLength;
- BitmapPtr m_pBmp;
- int m_TexHeight;
- std::vector<unsigned int> m_TileTextureIDs;
-
- // Derived values calculated in calcProjection
- double m_fovy; // Vertical field of view
- double m_aspect; // Sensor aspect ratio
- double m_CylHeight;
- double m_CylAngle; // Total angle covered by panorama
- double m_SliceAngle; // Angle per slice
- double m_MaxRotation; // Maximum rotation angle (=Total angle - visible area)
-
- double m_Rotation;
-};
-
-}
-
-#endif //_PanoImageNode_H_
-
diff --git a/src/player/Player.cpp b/src/player/Player.cpp
index 086f168..77f27d0 100644
--- a/src/player/Player.cpp
+++ b/src/player/Player.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,6 @@
#include "VideoNode.h"
#include "CameraNode.h"
#include "ImageNode.h"
-#include "PanoImageNode.h"
#include "SoundNode.h"
#include "LineNode.h"
#include "RectNode.h"
@@ -38,7 +37,7 @@
#include "PolygonNode.h"
#include "CircleNode.h"
#include "MeshNode.h"
-#include "NodeDefinition.h"
+#include "FontStyle.h"
#include "PluginManager.h"
#include "TextEngine.h"
#include "TestHelper.h"
@@ -48,6 +47,7 @@
#include "SDLDisplayEngine.h"
#include "MultitouchInputDevice.h"
#include "TUIOInputDevice.h"
+#include "OGLSurface.h"
#ifdef __APPLE__
#include "AppleTrackpadInputDevice.h"
#endif
@@ -64,6 +64,8 @@
#include "KeyEvent.h"
#include "MouseEvent.h"
#include "EventDispatcher.h"
+#include "PublisherDefinition.h"
+#include "BitmapManager.h"
#include "../base/FileHelper.h"
#include "../base/StringHelper.h"
@@ -73,13 +75,16 @@
#include "../base/ConfigMgr.h"
#include "../base/XMLHelper.h"
#include "../base/ScopeTimer.h"
-#include "../base/MathHelper.h"
+#include "../base/WorkerThread.h"
+#include "../base/DAG.h"
-#include "../graphics/BitmapManager.h"
+#include "../graphics/BitmapLoader.h"
+#include "../graphics/ShaderRegistry.h"
+#include "../graphics/Display.h"
#include "../imaging/Camera.h"
-#include "../audio/SDLAudioEngine.h"
+#include "../audio/AudioEngine.h"
#include <libxml/xmlmemory.h>
@@ -94,6 +99,9 @@
#include <fenv.h>
#endif
+#include <glib-object.h>
+#include <typeinfo>
+
using namespace std;
using namespace boost;
@@ -102,23 +110,27 @@ namespace avg {
Player * Player::s_pPlayer=0;
Player::Player()
- : m_pDisplayEngine(),
+ : Publisher("Player"),
+ m_pDisplayEngine(),
+ m_bDisplayEngineBroken(false),
+ m_bIsTraversingTree(false),
m_pMultitouchInputDevice(),
m_bInHandleTimers(false),
m_bCurrentTimeoutDeleted(false),
+ m_bKeepWindowOpen(false),
m_bStopOnEscape(true),
m_bIsPlaying(false),
m_bFakeFPS(false),
m_FakeFPS(0),
m_FrameTime(0),
m_Volume(1),
- m_dtd(0),
m_bPythonAvailable(true),
- m_pLastMouseEvent(new MouseEvent(Event::CURSORMOTION, false, false, false,
- IntPoint(-1, -1), MouseEvent::NO_BUTTON, DPoint(-1, -1), 0)),
- m_EventHookPyFunc(Py_None)
+ m_pLastMouseEvent(new MouseEvent(Event::CURSOR_MOTION, false, false, false,
+ IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0)),
+ m_EventHookPyFunc(Py_None),
+ m_bMouseEnabled(true)
{
-string sDummy;
+ string sDummy;
#ifdef _WIN32
if (getEnv("AVG_WIN_CRASH_SILENTLY", sDummy)) {
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
@@ -129,31 +141,42 @@ string sDummy;
// Turning this on causes fp exceptions in the linux nvidia drivers.
// feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#endif
+ setAffinityMask(true);
+
if (s_pPlayer) {
throw Exception(AVG_ERR_UNKNOWN, "Player has already been instantiated.");
}
- ThreadProfilerPtr pProfiler = ThreadProfiler::get();
+ ThreadProfiler* pProfiler = ThreadProfiler::get();
pProfiler->setName("main");
+
+ SDLDisplayEngine::initSDL();
initConfig();
- // Register all node types
- registerNodeType(AVGNode::createDefinition());
- registerNodeType(OffscreenCanvasNode::createDefinition());
- registerNodeType(CanvasNode::createDefinition());
- registerNodeType(DivNode::createDefinition());
- registerNodeType(ImageNode::createDefinition());
- registerNodeType(WordsNode::createDefinition());
- registerNodeType(VideoNode::createDefinition());
- registerNodeType(CameraNode::createDefinition());
- registerNodeType(PanoImageNode::createDefinition());
- registerNodeType(SoundNode::createDefinition());
- registerNodeType(LineNode::createDefinition());
- registerNodeType(RectNode::createDefinition());
- registerNodeType(CurveNode::createDefinition());
- registerNodeType(PolyLineNode::createDefinition());
- registerNodeType(PolygonNode::createDefinition());
- registerNodeType(CircleNode::createDefinition());
- registerNodeType(MeshNode::createDefinition());
+ FontStyle::registerType();
+ Node::registerType();
+ AreaNode::registerType();
+ RasterNode::registerType();
+ VectorNode::registerType();
+ FilledVectorNode::registerType();
+
+ DivNode::registerType();
+ CanvasNode::registerType();
+ OffscreenCanvasNode::registerType();
+ AVGNode::registerType();
+ ImageNode::registerType();
+ WordsNode::registerType();
+ VideoNode::registerType();
+ CameraNode::registerType();
+ SoundNode::registerType();
+ LineNode::registerType();
+ RectNode::registerType();
+ CurveNode::registerType();
+ PolyLineNode::registerType();
+ PolygonNode::registerType();
+ CircleNode::registerType();
+ MeshNode::registerType();
+
+ Contact::registerType();
m_pTestHelper = TestHelperPtr(new TestHelper());
@@ -173,9 +196,11 @@ void deletePlayer()
Player::~Player()
{
- if (m_dtd) {
- xmlFreeDtd(m_dtd);
+ m_pMainCanvas = MainCanvasPtr();
+ if (m_pDisplayEngine) {
+ m_pDisplayEngine->teardown();
}
+ SDLDisplayEngine::quitSDL();
}
Player* Player::get()
@@ -225,19 +250,41 @@ void Player::setWindowPos(int x, int y)
m_DP.m_Pos.y = y;
}
-void Player::setOGLOptions(bool bUsePOTTextures, bool bUseShaders,
- bool bUsePixelBuffers, int multiSampleSamples)
+void Player::setWindowTitle(const string& sTitle)
+{
+ m_pDisplayEngine->setWindowTitle(sTitle);
+}
+
+void Player::useGLES(bool bGLES)
+{
+ errorIfPlaying("Player.useGLES");
+ m_GLConfig.m_bGLES = bGLES;
+#ifdef AVG_ENABLE_EGL
+ m_GLConfig.m_bGLES = true;
+#endif
+ BitmapLoader::init(!m_GLConfig.m_bGLES);
+}
+
+void Player::setOGLOptions(bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, GLConfig::ShaderUsage shaderUsage,
+ bool bUseDebugContext)
{
errorIfPlaying("Player.setOGLOptions");
m_GLConfig.m_bUsePOTTextures = bUsePOTTextures;
- m_GLConfig.m_bUseShaders = bUseShaders;
m_GLConfig.m_bUsePixelBuffers = bUsePixelBuffers;
- m_GLConfig.m_MultiSampleSamples = multiSampleSamples;
+ setMultiSampleSamples(multiSampleSamples);
+ m_GLConfig.m_ShaderUsage = shaderUsage;
+ m_GLConfig.m_bUseDebugContext = bUseDebugContext;
}
void Player::setMultiSampleSamples(int multiSampleSamples)
{
errorIfPlaying("Player.setMultiSampleSamples");
+ if (multiSampleSamples < 1) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "MultiSampleSamples must be 1 or greater (was " +
+ toString(multiSampleSamples) + ").");
+ }
m_GLConfig.m_MultiSampleSamples = multiSampleSamples;
}
@@ -248,40 +295,40 @@ void Player::setAudioOptions(int samplerate, int channels)
m_AP.m_Channels = channels;
}
-DPoint Player::getScreenResolution()
+void Player::enableGLErrorChecks(bool bEnable)
+{
+ GLContext::enableErrorChecks(bEnable);
+}
+
+glm::vec2 Player::getScreenResolution()
{
- return DPoint(safeGetDisplayEngine()->getScreenResolution());
+ return glm::vec2(Display::get()->getScreenResolution());
}
-double Player::getPixelsPerMM()
+float Player::getPixelsPerMM()
{
- return safeGetDisplayEngine()->getPixelsPerMM();
+ return Display::get()->getPixelsPerMM();
}
-DPoint Player::getPhysicalScreenDimensions()
+glm::vec2 Player::getPhysicalScreenDimensions()
{
- return safeGetDisplayEngine()->getPhysicalScreenDimensions();
+ return Display::get()->getPhysicalScreenDimensions();
}
-void Player::assumePixelsPerMM(double ppmm)
+void Player::assumePixelsPerMM(float ppmm)
{
- safeGetDisplayEngine()->assumePixelsPerMM(ppmm);
+ Display::get()->assumePixelsPerMM(ppmm);
}
CanvasPtr Player::loadFile(const string& sFilename)
{
errorIfPlaying("Player.loadFile");
NodePtr pNode = loadMainNodeFromFile(sFilename);
- m_pEventDispatcher = EventDispatcherPtr(new EventDispatcher(this));
if (m_pMainCanvas) {
- cleanup();
+ cleanup(false);
}
- m_pMainCanvas = MainCanvasPtr(new MainCanvas(this));
- m_pMainCanvas->setRoot(pNode);
- m_DP.m_Size = m_pMainCanvas->getSize();
-
- registerFrameEndListener(BitmapManager::get());
+ initMainCanvas(pNode);
return m_pMainCanvas;
}
@@ -290,16 +337,11 @@ CanvasPtr Player::loadString(const string& sAVG)
{
errorIfPlaying("Player.loadString");
if (m_pMainCanvas) {
- cleanup();
+ cleanup(false);
}
NodePtr pNode = loadMainNodeFromString(sAVG);
- m_pEventDispatcher = EventDispatcherPtr(new EventDispatcher(this));
- m_pMainCanvas = MainCanvasPtr(new MainCanvas(this));
- m_pMainCanvas->setRoot(pNode);
- m_DP.m_Size = m_pMainCanvas->getSize();
-
- registerFrameEndListener(BitmapManager::get());
+ initMainCanvas(pNode);
return m_pMainCanvas;
}
@@ -316,26 +358,20 @@ OffscreenCanvasPtr Player::loadCanvasString(const string& sAVG)
return registerOffscreenCanvas(pNode);
}
-CanvasPtr Player::createMainCanvas(const boost::python::dict& params)
+CanvasPtr Player::createMainCanvas(const py::dict& params)
{
errorIfPlaying("Player.createMainCanvas");
if (m_pMainCanvas) {
- cleanup();
+ cleanup(false);
}
NodePtr pNode = createNode("avg", params);
-
- m_pEventDispatcher = EventDispatcherPtr(new EventDispatcher(this));
- m_pMainCanvas = MainCanvasPtr(new MainCanvas(this));
- m_pMainCanvas->setRoot(pNode);
- m_DP.m_Size = m_pMainCanvas->getSize();
-
- registerFrameEndListener(BitmapManager::get());
+ initMainCanvas(pNode);
return m_pMainCanvas;
}
-OffscreenCanvasPtr Player::createCanvas(const boost::python::dict& params)
+OffscreenCanvasPtr Player::createCanvas(const py::dict& params)
{
NodePtr pNode = createNode("canvas", params);
return registerOffscreenCanvas(pNode);
@@ -351,7 +387,7 @@ void Player::deleteCanvas(const string& sID)
string("deleteCanvas: Canvas with id ")+sID
+" is still referenced."));
}
- (*it)->stopPlayback();
+ (*it)->stopPlayback(false);
m_pCanvases.erase(it);
return;
}
@@ -376,105 +412,75 @@ OffscreenCanvasPtr Player::getCanvas(const string& sID) const
}
}
-void Player::newCanvasDependency(const OffscreenCanvasPtr pCanvas)
+void Player::newCanvasDependency()
{
- OffscreenCanvasPtr pNewCanvas;
- unsigned i;
- for (i = 0; i < m_pCanvases.size(); ++i) {
- if (pCanvas == m_pCanvases[i]) {
- pNewCanvas = m_pCanvases[i];
- m_pCanvases.erase(m_pCanvases.begin()+i);
- continue;
+ DAG dag;
+ for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ set<long> dependentCanvasSet;
+ OffscreenCanvasPtr pCanvas = m_pCanvases[i];
+ const vector<CanvasPtr>& pDependents = pCanvas->getDependentCanvases();
+ for (unsigned j = 0; j < pDependents.size(); ++j) {
+ dependentCanvasSet.insert(pDependents[j]->getHash());
}
+ dag.addNode(pCanvas->getHash(), dependentCanvasSet);
}
- AVG_ASSERT(pNewCanvas);
- bool bFound = false;
- for (i = 0; i < m_pCanvases.size(); ++i) {
- if (pNewCanvas->hasDependentCanvas(m_pCanvases[i])) {
- bFound = true;
- break;
- }
+ dag.addNode(m_pMainCanvas->getHash(), set<long>());
+
+ vector<long> sortedCanvasIDs;
+ try {
+ dag.sort(sortedCanvasIDs);
+ } catch (Exception&) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Circular dependency between canvases.");
}
- if (bFound) {
- for (unsigned j = i; j < m_pCanvases.size(); ++j) {
- if (m_pCanvases[j]->hasDependentCanvas(pNewCanvas)) {
- throw Exception(AVG_ERR_INVALID_ARGS,
- "Circular dependency between canvases.");
+
+ vector<OffscreenCanvasPtr> pTempCanvases = m_pCanvases;
+ m_pCanvases.clear();
+ for (unsigned i = 0; i < sortedCanvasIDs.size(); ++i) {
+ long canvasID = sortedCanvasIDs[i];
+ for (unsigned j = 0; j < pTempCanvases.size(); ++j) {
+ OffscreenCanvasPtr pCandidateCanvas = pTempCanvases[j];
+ if (pCandidateCanvas->getHash() == canvasID) {
+ m_pCanvases.push_back(pCandidateCanvas);
+ break;
}
}
- m_pCanvases.insert(m_pCanvases.begin()+i, pNewCanvas);
- } else {
- AVG_ASSERT(pNewCanvas->hasDependentCanvas(m_pMainCanvas));
- m_pCanvases.push_back(pNewCanvas);
- }
-/*
- for (unsigned k=0; k<m_pCanvases.size(); ++k) {
- m_pCanvases[k]->dump();
}
-*/
}
NodePtr Player::loadMainNodeFromFile(const string& sFilename)
{
- string RealFilename;
- try {
- AVG_TRACE(Logger::MEMORY, std::string("Player::loadFile(") + sFilename + ")");
-
- // When loading an avg file, assets are loaded from a directory relative
- // to the file.
- char szBuf[1024];
- char * pBuf = getcwd(szBuf, 1024);
- if (sFilename[0] == '/') {
- RealFilename = sFilename;
- } else {
- m_CurDirName = string(pBuf)+"/";
- RealFilename = m_CurDirName+sFilename;
- }
- m_CurDirName = RealFilename.substr(0, RealFilename.rfind('/')+1);
-
- string sAVG;
- readWholeFile(RealFilename, sAVG);
- NodePtr pNode = internalLoad(sAVG);
+ string sRealFilename;
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO,
+ "Player::loadFile(" << sFilename << ")");
- // Reset the directory to load assets from to the current dir.
+ // When loading an avg file, assets are loaded from a directory relative
+ // to the file.
+ char szBuf[1024];
+ char * pBuf = getcwd(szBuf, 1024);
+ if (sFilename[0] == '/') {
+ sRealFilename = sFilename;
+ } else {
m_CurDirName = string(pBuf)+"/";
- return pNode;
- } catch (Exception& ex) {
- switch (ex.getCode()) {
- case AVG_ERR_XML_PARSE:
- throw (Exception(AVG_ERR_XML_PARSE,
- string("Error parsing xml document ")+RealFilename));
- break;
- case AVG_ERR_XML_VALID:
- throw (Exception(AVG_ERR_XML_VALID,
- RealFilename + " does not validate."));
- break;
- default:
- throw;
- }
+ sRealFilename = m_CurDirName+sFilename;
}
+ m_CurDirName = sRealFilename.substr(0, sRealFilename.rfind('/')+1);
+
+ string sAVG;
+ readWholeFile(sRealFilename, sAVG);
+ NodePtr pNode = internalLoad(sAVG, sRealFilename);
+
+ // Reset the directory to load assets from to the current dir.
+ m_CurDirName = string(pBuf)+"/";
+ return pNode;
}
NodePtr Player::loadMainNodeFromString(const string& sAVG)
{
- try {
- AVG_TRACE(Logger::MEMORY, "Player::loadString()");
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Player::loadString()");
- string sEffectiveDoc = removeStartEndSpaces(sAVG);
- NodePtr pNode = internalLoad(sEffectiveDoc);
- return pNode;
- } catch (Exception& ex) {
- switch (ex.getCode()) {
- case AVG_ERR_XML_PARSE:
- throw Exception(AVG_ERR_XML_PARSE, "Error parsing xml string.");
- break;
- case AVG_ERR_XML_VALID:
- throw Exception(AVG_ERR_XML_VALID, "Error validating xml string.");
- break;
- default:
- throw;
- }
- }
+ string sEffectiveDoc = removeStartEndSpaces(sAVG);
+ NodePtr pNode = internalLoad(sEffectiveDoc, "");
+ return pNode;
}
void Player::play()
@@ -484,21 +490,24 @@ void Player::play()
throw Exception(AVG_ERR_NO_NODE, "Play called, but no xml file loaded.");
}
initPlayback();
+ notifySubscribers("PLAYBACK_START");
try {
ThreadProfiler::get()->start();
doFrame(true);
while (!m_bStopping) {
doFrame(false);
}
+ notifySubscribers("PLAYBACK_END");
} catch (...) {
- cleanup();
+ cleanup(true);
+ m_bDisplayEngineBroken = true;
throw;
}
- cleanup();
- AVG_TRACE(Logger::PLAYER, "Playback ended.");
+ cleanup(false);
+ AVG_TRACE(Logger::category::PLAYER, Logger::severity::INFO, "Playback ended.");
} catch (Exception& ex) {
m_bIsPlaying = false;
- AVG_TRACE(Logger::ERROR, ex.getStr());
+ AVG_LOG_ERROR(ex.getStr());
throw;
}
}
@@ -508,7 +517,7 @@ void Player::stop()
if (m_bIsPlaying) {
m_bStopping = true;
} else {
- cleanup();
+ cleanup(false);
}
}
@@ -517,11 +526,11 @@ bool Player::isStopping()
return m_bStopping;
}
-void Player::initPlayback()
+void Player::initPlayback(const std::string& sShaderPath)
{
m_bIsPlaying = true;
- AVG_TRACE(Logger::PLAYER, "Playback started.");
- initGraphics();
+ AVG_TRACE(Logger::category::PLAYER, Logger::severity::INFO, "Playback started.");
+ initGraphics(sShaderPath);
initAudio();
try {
for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
@@ -529,7 +538,8 @@ void Player::initPlayback()
}
m_pMainCanvas->initPlayback(m_pDisplayEngine);
} catch (Exception&) {
- cleanup();
+ cleanup(true);
+ m_bDisplayEngineBroken = true;
throw;
}
m_pEventDispatcher->addInputDevice(
@@ -537,6 +547,7 @@ void Player::initPlayback()
m_pEventDispatcher->addInputDevice(m_pTestHelper);
m_pDisplayEngine->initRender();
+ Display::get()->rereadScreenResolution();
m_bStopping = false;
if (m_pMultitouchInputDevice) {
m_pMultitouchInputDevice->start();
@@ -551,27 +562,25 @@ bool Player::isPlaying()
return m_bIsPlaying;
}
-void Player::setFramerate(double rate)
+void Player::setFramerate(float rate)
{
if (m_bIsPlaying) {
m_pDisplayEngine->setFramerate(rate);
- } else {
- m_DP.m_Framerate = rate;
- m_DP.m_VBRate = 0;
}
+ m_DP.m_Framerate = rate;
+ m_DP.m_VBRate = 0;
}
void Player::setVBlankFramerate(int rate)
{
if (m_bIsPlaying) {
m_pDisplayEngine->setVBlankRate(rate);
- } else {
- m_DP.m_Framerate = 0;
- m_DP.m_VBRate = rate;
}
+ m_DP.m_Framerate = 0;
+ m_DP.m_VBRate = rate;
}
-double Player::getEffectiveFramerate()
+float Player::getEffectiveFramerate()
{
if (m_bIsPlaying) {
if (m_bFakeFPS) {
@@ -589,7 +598,7 @@ TestHelper * Player::getTestHelper()
return m_pTestHelper.get();
}
-void Player::setFakeFPS(double fps)
+void Player::setFakeFPS(float fps)
{
if (fabs(fps + 1.0) < 0.0001) {
// fps = -1
@@ -599,8 +608,8 @@ void Player::setFakeFPS(double fps)
m_FakeFPS = fps;
}
- if (SDLAudioEngine::get()) {
- SDLAudioEngine::get()->setAudioEnabled(!m_bFakeFPS);
+ if (AudioEngine::get()) {
+ AudioEngine::get()->setAudioEnabled(!m_bFakeFPS);
}
}
@@ -618,39 +627,24 @@ long long Player::getFrameTime()
return m_FrameTime;
}
-double Player::getFrameDuration()
+float Player::getFrameDuration()
{
if (!m_bIsPlaying) {
throw Exception(AVG_ERR_UNSUPPORTED,
"Must call Player.play() before getFrameDuration().");
}
if (m_bFakeFPS) {
- return 1000.0/m_FakeFPS;
+ return 1000.0f/m_FakeFPS;
} else {
- double framerate = m_pDisplayEngine->getEffectiveFramerate();
+ float framerate = m_pDisplayEngine->getEffectiveFramerate();
if (framerate > 0) {
- return 1000./framerate;
+ return 1000.f/framerate;
} else {
return 0;
}
}
}
-TrackerInputDevice * Player::addTracker()
-{
- if (!m_pMainCanvas) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "You must use loadFile() before addTracker().");
- }
- m_pMultitouchInputDevice = IInputDevicePtr(new TrackerInputDevice());
- addInputDevice(m_pMultitouchInputDevice);
- if (m_bIsPlaying) {
- m_pMultitouchInputDevice->start();
- }
-
- return dynamic_cast<TrackerInputDevice*>(m_pMultitouchInputDevice.get());
-}
-
TrackerInputDevice * Player::getTracker()
{
TrackerInputDevice* pTracker = dynamic_cast<TrackerInputDevice*>(
@@ -660,6 +654,10 @@ TrackerInputDevice * Player::getTracker()
void Player::enableMultitouch()
{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before enableMultitouch().");
+ }
string sDriver;
getEnv("AVG_MULTITOUCH_DRIVER", sDriver);
@@ -671,7 +669,7 @@ void Player::enableMultitouch()
#elif defined (AVG_ENABLE_MTDEV)
sDriver = "LINUXMTDEV";
#else
- AVG_TRACE(Logger::WARNING, "Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
+ AVG_LOG_WARNING("Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
throw Exception(AVG_ERR_MT_INIT,
"Multitouch support: No default driver available. Set AVG_MULTITOUCH_DRIVER.");
#endif
@@ -700,7 +698,7 @@ void Player::enableMultitouch()
} else if (sDriver == "TRACKER") {
m_pMultitouchInputDevice = IInputDevicePtr(new TrackerInputDevice);
} else {
- AVG_TRACE(Logger::WARNING, "Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
+ AVG_LOG_WARNING("Valid values for AVG_MULTITOUCH_DRIVER are WIN7TOUCH, XINPUT, LINUXMTDEV, TRACKER, TUIO and APPLETRACKPAD.");
throw Exception(AVG_ERR_UNSUPPORTED, string("Unsupported multitouch driver '")+
sDriver +"'.");
}
@@ -715,6 +713,15 @@ void Player::enableMultitouch()
addInputDevice(m_pMultitouchInputDevice);
}
+void Player::enableMouse(bool enabled)
+{
+ m_bMouseEnabled = enabled;
+
+ if (m_pEventDispatcher) {
+ m_pEventDispatcher->enableMouse(enabled);
+ }
+}
+
bool Player::isMultitouchAvailable() const
{
if (m_bIsPlaying) {
@@ -729,15 +736,17 @@ void Player::setEventCapture(NodePtr pNode, int cursorID=MOUSECURSORID)
{
std::map<int, EventCaptureInfoPtr>::iterator it =
m_EventCaptureInfoMap.find(cursorID);
- if (it != m_EventCaptureInfoMap.end() && !(it->second->m_pNode.expired())) {
+ if (it != m_EventCaptureInfoMap.end()) {
EventCaptureInfoPtr pCaptureInfo = it->second;
- NodePtr pOldNode = pCaptureInfo->m_pNode.lock();
- if (pOldNode == pNode) {
- pCaptureInfo->m_CaptureCount++;
- } else {
- throw Exception(AVG_ERR_INVALID_CAPTURE, "setEventCapture called for '"
- + pNode->getID() + "', but cursor already captured by '"
- + pOldNode->getID() + "'.");
+ NodePtr pOldNode = pCaptureInfo->m_pNode;
+ if (pOldNode->getState() != Node::NS_UNCONNECTED) {
+ if (pOldNode == pNode) {
+ pCaptureInfo->m_CaptureCount++;
+ } else {
+ throw Exception(AVG_ERR_INVALID_CAPTURE, "setEventCapture called for '"
+ + pNode->getID() + "', but cursor already captured by '"
+ + pOldNode->getID() + "'.");
+ }
}
} else {
m_EventCaptureInfoMap[cursorID] = EventCaptureInfoPtr(
@@ -749,7 +758,9 @@ void Player::releaseEventCapture(int cursorID)
{
std::map<int, EventCaptureInfoPtr>::iterator it =
m_EventCaptureInfoMap.find(cursorID);
- if (it == m_EventCaptureInfoMap.end() || (it->second->m_pNode.expired()) ) {
+ if (it == m_EventCaptureInfoMap.end() ||
+ (it->second->m_pNode->getState() == Node::NS_UNCONNECTED))
+ {
throw Exception(AVG_ERR_INVALID_CAPTURE,
"releaseEventCapture called, but cursor not captured.");
} else {
@@ -767,38 +778,40 @@ bool Player::isCaptured(int cursorID)
return (it != m_EventCaptureInfoMap.end());
}
-int Player::setInterval(int time, PyObject * pyfunc)
+void Player::removeDeadEventCaptures()
{
- Timeout* pTimeout = new Timeout(time, pyfunc, true, getFrameTime());
- if (m_bInHandleTimers) {
- m_NewTimeouts.push_back(pTimeout);
- } else {
- addTimeout(pTimeout);
+ std::map<int, EventCaptureInfoPtr>::iterator it;
+ for (it = m_EventCaptureInfoMap.begin(); it != m_EventCaptureInfoMap.end();) {
+ std::map<int, EventCaptureInfoPtr>::iterator lastIt = it;
+ it++;
+ if (lastIt->second->m_pNode->getState() == Node::NS_UNCONNECTED) {
+ m_EventCaptureInfoMap.erase(lastIt);
+ }
}
- return pTimeout->GetID();
+}
+
+int Player::setInterval(int time, PyObject * pyfunc)
+{
+ return internalSetTimeout(time, pyfunc, true);
}
int Player::setTimeout(int time, PyObject * pyfunc)
{
- Timeout* pTimeout = new Timeout(time, pyfunc, false, getFrameTime());
- if (m_bInHandleTimers) {
- m_NewTimeouts.push_back(pTimeout);
- } else {
- addTimeout(pTimeout);
- }
- return pTimeout->GetID();
+ return internalSetTimeout(time, pyfunc, false);
}
int Player::setOnFrameHandler(PyObject * pyfunc)
{
- return setInterval(0, pyfunc);
+ avgDeprecationWarning("1.8", "Player.setOnFrameHandler",
+ "Player.subscribe(Player.ON_FRAME)");
+ return internalSetTimeout(0, pyfunc, true);
}
bool Player::clearInterval(int id)
{
vector<Timeout*>::iterator it;
for (it = m_PendingTimeouts.begin(); it != m_PendingTimeouts.end(); it++) {
- if (id == (*it)->GetID()) {
+ if (id == (*it)->getID()) {
if (it == m_PendingTimeouts.begin() && m_bInHandleTimers) {
m_bCurrentTimeoutDeleted = true;
}
@@ -808,7 +821,7 @@ bool Player::clearInterval(int id)
}
}
for (it = m_NewTimeouts.begin(); it != m_NewTimeouts.end(); it++) {
- if (id == (*it)->GetID()) {
+ if (id == (*it)->getID()) {
delete *it;
m_NewTimeouts.erase(it);
return true;
@@ -817,11 +830,26 @@ bool Player::clearInterval(int id)
return false;
}
+void Player::callFromThread(PyObject * pyfunc)
+{
+ lock_guard lock(m_AsyncCallMutex);
+ Timeout* pTimeout = new Timeout(0, pyfunc, false, getFrameTime());
+ m_AsyncCalls.push_back(pTimeout);
+}
+
MouseEventPtr Player::getMouseState() const
{
return m_pLastMouseEvent;
}
+EventPtr Player::getCurrentEvent() const
+{
+ if (!m_pCurrentEvent) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "No current event.");
+ }
+ return m_pCurrentEvent;
+}
+
void Player::setMousePos(const IntPoint& pos)
{
m_pDisplayEngine->setMousePos(pos);
@@ -838,6 +866,11 @@ BitmapPtr Player::screenshot()
throw Exception(AVG_ERR_UNSUPPORTED,
"Must call Player.play() before screenshot().");
}
+ if (GLContext::getMain()->isGLES()) {
+ // Some GLES implementations invalidate the buffer after eglSwapBuffers.
+ // The only way we can get at the contents at this point is to rerender them.
+ m_pMainCanvas->render(m_pDisplayEngine->getWindowSize(), false);
+ }
return m_pDisplayEngine->screenshot();
}
@@ -849,6 +882,11 @@ void Player::showCursor(bool bShow)
m_DP.m_bShowCursor = bShow;
}
+bool Player::isCursorShown()
+{
+ return m_DP.m_bShowCursor;
+}
+
void Player::setCursor(const Bitmap* pBmp, IntPoint hotSpot)
{
IntPoint size = pBmp->getSize();
@@ -924,14 +962,26 @@ std::string Player::getRootMediaDir()
return sMediaDir;
}
-const NodeDefinition& Player::getNodeDef(const std::string& sType)
+void Player::disablePython()
{
- return m_NodeRegistry.getNodeDef(sType);
+ m_bPythonAvailable = false;
}
-void Player::disablePython()
+void Player::startTraversingTree()
{
- m_bPythonAvailable = false;
+ AVG_ASSERT(!m_bIsTraversingTree);
+ m_bIsTraversingTree = true;
+}
+
+void Player::endTraversingTree()
+{
+ AVG_ASSERT(m_bIsTraversingTree);
+ m_bIsTraversingTree = false;
+}
+
+bool Player::isTraversingTree() const
+{
+ return m_bIsTraversingTree;
}
void Player::registerFrameEndListener(IFrameEndListener* pListener)
@@ -976,21 +1026,15 @@ void Player::unregisterPreRenderListener(IPreRenderListener* pListener)
bool Player::handleEvent(EventPtr pEvent)
{
AVG_ASSERT(pEvent);
-
- PyObject * pEventHook = getEventHook();
- if (pEventHook != Py_None) {
- // If the catchall returns true, stop processing the event
- if (boost::python::call<bool>(pEventHook, pEvent)) {
- return true;
- }
- }
+ EventPtr pLastEvent = m_pCurrentEvent;
+ m_pCurrentEvent = pEvent;
if (MouseEventPtr pMouseEvent = boost::dynamic_pointer_cast<MouseEvent>(pEvent)) {
m_pLastMouseEvent = pMouseEvent;
}
if (CursorEventPtr pCursorEvent = boost::dynamic_pointer_cast<CursorEvent>(pEvent)) {
- if (pEvent->getType() == Event::CURSOROUT ||
- pEvent->getType() == Event::CURSOROVER)
+ if (pEvent->getType() == Event::CURSOR_OUT ||
+ pEvent->getType() == Event::CURSOR_OVER)
{
pEvent->trace();
pCursorEvent->getNode()->handleEvent(pEvent);
@@ -1001,8 +1045,18 @@ bool Player::handleEvent(EventPtr pEvent)
else if (KeyEventPtr pKeyEvent = boost::dynamic_pointer_cast<KeyEvent>(pEvent))
{
pEvent->trace();
+ switch (pEvent->getType()) {
+ case Event::KEY_DOWN:
+ notifySubscribers("KEY_DOWN", pEvent);
+ break;
+ case Event::KEY_UP:
+ notifySubscribers("KEY_UP", pEvent);
+ break;
+ default:
+ AVG_ASSERT(false);
+ }
getRootNode()->handleEvent(pKeyEvent);
- if (getStopOnEscape() && pEvent->getType() == Event::KEYDOWN
+ if (getStopOnEscape() && pEvent->getType() == Event::KEY_DOWN
&& pKeyEvent->getKeyCode() == avg::key::KEY_ESCAPE)
{
stop();
@@ -1017,20 +1071,23 @@ bool Player::handleEvent(EventPtr pEvent)
stop();
}
}
+ m_pCurrentEvent = pLastEvent;
return true;
}
static ProfilingZoneID MainProfilingZone("Player - Total frame time");
static ProfilingZoneID TimersProfilingZone("Player - handleTimers");
static ProfilingZoneID EventsProfilingZone("Dispatch events");
+static ProfilingZoneID MainCanvasProfilingZone("Main canvas rendering");
+static ProfilingZoneID OffscreenProfilingZone("Offscreen rendering");
void Player::doFrame(bool bFirstFrame)
{
{
ScopeTimer Timer(MainProfilingZone);
if (!bFirstFrame) {
+ m_NumFrames++;
if (m_bFakeFPS) {
- m_NumFrames++;
m_FrameTime = (long long)((m_NumFrames*1000.0)/m_FakeFPS);
} else {
m_FrameTime = m_pDisplayEngine->getDisplayTime();
@@ -1043,12 +1100,18 @@ void Player::doFrame(bool bFirstFrame)
ScopeTimer Timer(EventsProfilingZone);
m_pEventDispatcher->dispatch();
sendFakeEvents();
+ removeDeadEventCaptures();
}
}
for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
+ ScopeTimer Timer(OffscreenProfilingZone);
dispatchOffscreenRendering(m_pCanvases[i].get());
}
- m_pMainCanvas->doFrame(m_bPythonAvailable);
+ {
+ ScopeTimer Timer(MainCanvasProfilingZone);
+ m_pMainCanvas->doFrame(m_bPythonAvailable);
+ }
+ GLContext::mandatoryCheckError("End of frame");
if (m_bPythonAvailable) {
Py_BEGIN_ALLOW_THREADS;
try {
@@ -1062,11 +1125,10 @@ void Player::doFrame(bool bFirstFrame)
endFrame();
}
}
- if (m_pDisplayEngine->wasFrameLate()) {
- ThreadProfiler::get()->dumpFrame();
- }
-
ThreadProfiler::get()->reset();
+ if (m_NumFrames == 5) {
+ ThreadProfiler::get()->restart();
+ }
}
void Player::endFrame()
@@ -1076,7 +1138,7 @@ void Player::endFrame()
m_pDisplayEngine->checkJitter();
}
-double Player::getFramerate()
+float Player::getFramerate()
{
if (!m_pDisplayEngine) {
return m_DP.m_Framerate;
@@ -1084,32 +1146,37 @@ double Player::getFramerate()
return m_pDisplayEngine->getFramerate();
}
-double Player::getVideoRefreshRate()
+float Player::getVideoRefreshRate()
+{
+ return Display::get()->getRefreshRate();
+}
+
+size_t Player::getVideoMemInstalled()
{
if (!m_pDisplayEngine) {
- return 0;
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Player.getVideoMemInstalled must be called after Player.play().");
}
- return m_pDisplayEngine->getRefreshRate();
+ return GLContext::getMain()->getVideoMemInstalled();
}
-bool Player::isUsingShaders()
+size_t Player::getVideoMemUsed()
{
if (!m_pDisplayEngine) {
throw Exception(AVG_ERR_UNSUPPORTED,
- "Player.isUsingShaders must be called after Player.play().");
+ "Player.getVideoMemUsed must be called after Player.play().");
}
- return GLContext::getCurrent()->isUsingShaders();
+ return GLContext::getMain()->getVideoMemUsed();
}
-void Player::setGamma(double red, double green, double blue)
+void Player::setGamma(float red, float green, float blue)
{
if (m_pDisplayEngine) {
m_pDisplayEngine->setGamma(red, green, blue);
- } else {
- m_DP.m_Gamma[0] = red;
- m_DP.m_Gamma[1] = green;
- m_DP.m_Gamma[2] = blue;
}
+ m_DP.m_Gamma[0] = red;
+ m_DP.m_Gamma[1] = green;
+ m_DP.m_Gamma[2] = blue;
}
void Player::initConfig()
@@ -1119,8 +1186,7 @@ void Player::initConfig()
m_DP.m_BPP = atoi(pMgr->getOption("scr", "bpp")->c_str());
if (m_DP.m_BPP != 15 && m_DP.m_BPP != 16 && m_DP.m_BPP != 24 && m_DP.m_BPP != 32) {
- AVG_TRACE(Logger::ERROR,
- "BPP must be 15, 16, 24 or 32. Current value is "
+ AVG_LOG_ERROR("BPP must be 15, 16, 24 or 32. Current value is "
<< m_DP.m_BPP << ". Aborting." );
exit(-1);
}
@@ -1128,17 +1194,14 @@ void Player::initConfig()
m_DP.m_WindowSize.x = atoi(pMgr->getOption("scr", "windowwidth")->c_str());
m_DP.m_WindowSize.y = atoi(pMgr->getOption("scr", "windowheight")->c_str());
- m_DP.m_DotsPerMM = atof(pMgr->getOption("scr", "dotspermm")->c_str());
if (m_DP.m_bFullscreen && (m_DP.m_WindowSize != IntPoint(0, 0))) {
- AVG_TRACE(Logger::ERROR,
- "Can't set fullscreen and window size at once. Aborting.");
+ AVG_LOG_ERROR("Can't set fullscreen and window size at once. Aborting.");
exit(-1);
}
if (m_DP.m_WindowSize.x != 0 && m_DP.m_WindowSize.y != 0) {
- AVG_TRACE(Logger::ERROR, "Can't set window width and height at once");
- AVG_TRACE(Logger::ERROR,
- "(aspect ratio is determined by avg file). Aborting.");
+ AVG_LOG_ERROR("Can't set window width and height at once");
+ AVG_LOG_ERROR("(aspect ratio is determined by avg file). Aborting.");
exit(-1);
}
@@ -1147,90 +1210,111 @@ void Player::initConfig()
m_AP.m_OutputBufferSamples =
atoi(pMgr->getOption("aud", "outputbuffersamples")->c_str());
+ m_GLConfig.m_bGLES = pMgr->getBoolOption("scr", "gles", false);
m_GLConfig.m_bUsePOTTextures = pMgr->getBoolOption("scr", "usepow2textures", false);
- m_GLConfig.m_bUseShaders = pMgr->getBoolOption("scr", "useshaders", true);
m_GLConfig.m_bUsePixelBuffers = pMgr->getBoolOption("scr", "usepixelbuffers", true);
- m_GLConfig.m_MultiSampleSamples = pMgr->getIntOption("scr", "multisamplesamples", 4);
+ int multiSampleSamples = pMgr->getIntOption("scr", "multisamplesamples", 8);
+ if (multiSampleSamples < 1) {
+ AVG_LOG_ERROR("multisamplesamples must be >= 1. Aborting")
+ exit(-1);
+ }
+ m_GLConfig.m_MultiSampleSamples = multiSampleSamples;
+
+ string sShaderUsage;
+ pMgr->getStringOption("scr", "shaderusage", "auto", sShaderUsage);
+ if (sShaderUsage == "full") {
+ m_GLConfig.m_ShaderUsage = GLConfig::FULL;
+ } else if (sShaderUsage == "minimal") {
+ m_GLConfig.m_ShaderUsage = GLConfig::MINIMAL;
+ } else if (sShaderUsage == "auto") {
+ m_GLConfig.m_ShaderUsage = GLConfig::AUTO;
+ } else {
+ throw Exception(AVG_ERR_OUT_OF_RANGE,
+ "avgrc parameter shaderusage must be full, minimal, fragmentonly or auto");
+ }
+ string sDummy;
+ m_GLConfig.m_bUseDebugContext = getEnv("AVG_USE_DEBUG_GL_CONTEXT", sDummy);
+#ifdef AVG_ENABLE_EGL
+ m_GLConfig.m_bGLES = true;
+#endif
+ BitmapLoader::init(!m_GLConfig.m_bGLES);
+
pMgr->getGammaOption("scr", "gamma", m_DP.m_Gamma);
}
-void Player::initGraphics()
+void Player::initGraphics(const string& sShaderPath)
{
+ if (!Display::isInitialized()) {
+ ConfigMgr* pMgr = ConfigMgr::get();
+ float dotsPerMM = float(atof(pMgr->getOption("scr", "dotspermm")->c_str()));
+ Display::get()->assumePixelsPerMM(dotsPerMM);
+ }
// Init display configuration.
- AVG_TRACE(Logger::CONFIG, "Display bpp: " << m_DP.m_BPP);
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Display bpp: " << m_DP.m_BPP);
+
+ if (m_bDisplayEngineBroken) {
+ m_bDisplayEngineBroken = false;
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine = SDLDisplayEnginePtr();
+ }
if (!m_pDisplayEngine) {
m_pDisplayEngine = SDLDisplayEnginePtr(new SDLDisplayEngine());
}
- AVG_TRACE(Logger::CONFIG, "Requested OpenGL configuration: ");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Requested OpenGL configuration: ");
m_GLConfig.log();
- m_pDisplayEngine->init(m_DP, m_GLConfig);
+ m_DP.m_WindowSize = m_pDisplayEngine->calcWindowSize(m_DP);
+ if (m_pDisplayEngine->getWindowSize() != m_DP.m_WindowSize ||
+ m_pDisplayEngine->isFullscreen() == true)
+ {
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine->init(m_DP, m_GLConfig);
+ }
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Pixels per mm: " << Display::get()->getPixelsPerMM());
+ if (sShaderPath != "") {
+ ShaderRegistry::get()->setShaderPath(sShaderPath);
+ }
+ m_pDisplayEngine->setGamma(1.0, 1.0, 1.0);
+ m_GLConfig = GLContext::getCurrent()->getConfig();
}
void Player::initAudio()
{
- SDLAudioEngine* pAudioEngine = SDLAudioEngine::get();
+ AudioEngine* pAudioEngine = AudioEngine::get();
if (!pAudioEngine) {
- pAudioEngine = new SDLAudioEngine();
+ pAudioEngine = new AudioEngine();
}
pAudioEngine->init(m_AP, m_Volume);
pAudioEngine->setAudioEnabled(!m_bFakeFPS);
pAudioEngine->play();
}
-void Player::updateDTD()
+void Player::initMainCanvas(NodePtr pRootNode)
{
- if (m_dtd) {
- xmlFreeDtd(m_dtd);
- }
- // Find and parse dtd.
- registerDTDEntityLoader("avg.dtd", m_NodeRegistry.getDTD().c_str());
- string sDTDFName = "avg.dtd";
- m_dtd = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
- assert (m_dtd);
- m_bDirtyDTD = false;
+ m_pEventDispatcher = EventDispatcherPtr(new EventDispatcher(this, m_bMouseEnabled));
+ m_pMainCanvas = MainCanvasPtr(new MainCanvas(this));
+ m_pMainCanvas->setRoot(pRootNode);
+ m_DP.m_Size = m_pMainCanvas->getSize();
+
+ registerFrameEndListener(BitmapManager::get());
}
-NodePtr Player::internalLoad(const string& sAVG)
+NodePtr Player::internalLoad(const string& sAVG, const string& sFilename)
{
- xmlDocPtr doc = 0;
- try {
- xmlPedanticParserDefault(1);
- xmlDoValidityCheckingDefaultValue=0;
-
- doc = xmlParseMemory(sAVG.c_str(), sAVG.length());
- if (!doc) {
- throw (Exception(AVG_ERR_XML_PARSE, ""));
- }
-
- if (m_bDirtyDTD) {
- updateDTD();
- }
-
- xmlValidCtxtPtr cvp = xmlNewValidCtxt();
- cvp->error = xmlParserValidityError;
- cvp->warning = xmlParserValidityWarning;
- int valid=xmlValidateDtd(cvp, doc, m_dtd);
- xmlFreeValidCtxt(cvp);
- if (!valid) {
- throw (Exception(AVG_ERR_XML_VALID, ""));
- }
- xmlNodePtr xmlNode = xmlDocGetRootElement(doc);
- NodePtr pNode = createNodeFromXml(doc, xmlNode);
- if (!pNode) {
- throw (Exception(AVG_ERR_XML_PARSE,
- "Root node of an avg tree needs to be an <avg> node."));
- }
- xmlFreeDoc(doc);
- return pNode;
- } catch (Exception& ex) {
- AVG_TRACE(Logger::ERROR, ex.getStr());
- if (doc) {
- xmlFreeDoc(doc);
- }
- throw;
+ XMLParser parser;
+ parser.setDTD(TypeRegistry::get()->getDTD(), "avg.dtd");
+ parser.parse(sAVG, sFilename);
+ xmlNodePtr xmlNode = parser.getRootNode();
+ NodePtr pNode = createNodeFromXml(parser.getDoc(), xmlNode);
+ if (!pNode) {
+ throw (Exception(AVG_ERR_XML_PARSE,
+ "Root node of an avg tree needs to be an <avg> node."));
}
+ return pNode;
}
SDLDisplayEnginePtr Player::safeGetDisplayEngine()
@@ -1242,41 +1326,38 @@ SDLDisplayEnginePtr Player::safeGetDisplayEngine()
}
-void Player::registerNodeType(NodeDefinition def, const char* pParentNames[])
-{
- m_NodeRegistry.registerNodeType(def);
-
- if (pParentNames) {
- string sChildArray[1];
- sChildArray[0] = def.getName();
- vector<string> sChildren = vectorFromCArray(1, sChildArray);
- const char **ppCurParentName = pParentNames;
-
- while (*ppCurParentName) {
- NodeDefinition nodeDefinition = m_NodeRegistry.getNodeDef(*ppCurParentName);
- nodeDefinition.addChildren(sChildren);
- m_NodeRegistry.updateNodeDefinition(nodeDefinition);
-
- ++ppCurParentName;
- }
- }
- m_bDirtyDTD = true;
-}
-
-NodePtr Player::createNode(const string& sType, const boost::python::dict& params)
+NodePtr Player::createNode(const string& sType,
+ const py::dict& params, const boost::python::object& self)
{
DivNodePtr pParentNode;
- boost::python::dict attrs = params;
- boost::python::object parent;
+ py::dict attrs = params;
+ py::object parent;
if (params.has_key("parent")) {
parent = params["parent"];
attrs.attr("__delitem__")("parent");
- pParentNode = boost::python::extract<DivNodePtr>(parent);
- }
- NodePtr pNode = m_NodeRegistry.createNode(sType, attrs);
- if (pParentNode) {
- pParentNode->appendChild(pNode);
- }
+ pParentNode = py::extract<DivNodePtr>(parent);
+ }
+ NodePtr pNode = dynamic_pointer_cast<Node>(
+ TypeRegistry::get()->createObject(sType, attrs));
+
+ // See if the class names of self and pNode match. If they don't, there is a
+ // python derived class that's being constructed and we can't set parent here.
+ string sSelfClassName = py::extract<string>(
+ self.attr("__class__").attr("__name__"));
+ py::object pythonClassName =
+ (py::object(pNode).attr("__class__").attr("__name__"));
+ string sThisClassName = py::extract<string>(pythonClassName);
+ bool bHasDerivedClass = sSelfClassName != sThisClassName &&
+ sSelfClassName != "NoneType";
+ if (bHasDerivedClass) {
+ if (pParentNode) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Can't pass 'parent' parameter to C++ class constructor if there is a derived python class. Use Node.registerInstance() instead.");
+ }
+ pNode->registerInstance(self.ptr(), pParentNode);
+ } else {
+ pNode->registerInstance(0, pParentNode);
+ }
if (parent) {
attrs["parent"] = parent;
}
@@ -1288,43 +1369,29 @@ NodePtr Player::createNodeFromXmlString(const string& sXML)
xmlPedanticParserDefault(1);
xmlDoValidityCheckingDefaultValue =0;
- xmlDocPtr doc;
- doc = xmlParseMemory(sXML.c_str(), int(sXML.length()));
- if (!doc) {
- throw (Exception(AVG_ERR_XML_PARSE,
- string("Error parsing xml:\n ")+sXML));
- }
- NodePtr pNode = createNodeFromXml(doc, xmlDocGetRootElement(doc));
-
- if (m_bDirtyDTD)
- updateDTD();
+ XMLParser parser;
+ parser.setDTD(TypeRegistry::get()->getDTD(), "avg.dtd");
+ parser.parse(sXML, "");
- xmlValidCtxtPtr cvp = xmlNewValidCtxt();
- cvp->error = xmlParserValidityError;
- cvp->warning = xmlParserValidityWarning;
- int valid=xmlValidateDtd(cvp, doc, m_dtd);
- xmlFreeValidCtxt(cvp);
- if (!valid) {
- throw (Exception(AVG_ERR_XML_PARSE,
- "Could not validate '"+sXML+"'"));
- }
+// cvp->error = xmlParserValidityError;
+// cvp->warning = xmlParserValidityWarning;
+ xmlNodePtr xmlNode = parser.getRootNode();
+ NodePtr pNode = createNodeFromXml(parser.getDoc(), xmlNode);
- xmlFreeDoc(doc);
return pNode;
}
NodePtr Player::createNodeFromXml(const xmlDocPtr xmlDoc,
const xmlNodePtr xmlNode)
{
- NodePtr pCurNode;
const char * nodeType = (const char *)xmlNode->name;
- if (!strcmp (nodeType, "text") ||
- !strcmp (nodeType, "comment")) {
+ if (!strcmp (nodeType, "text") || !strcmp (nodeType, "comment")) {
// Ignore whitespace & comments
return NodePtr();
}
- pCurNode = m_NodeRegistry.createNode(nodeType, xmlNode);
+ NodePtr pCurNode = dynamic_pointer_cast<Node>(
+ TypeRegistry::get()->createObject(nodeType, xmlNode));
if (!strcmp(nodeType, "words")) {
// TODO: This is an end-run around the generic serialization mechanism
// that will probably break at some point.
@@ -1399,16 +1466,16 @@ void Player::sendOver(const CursorEventPtr pOtherEvent, Event::Type type,
void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
{
// Find all nodes under the cursor.
- vector<NodeWeakPtr> pCursorNodes;
+ vector<NodePtr> pCursorNodes;
DivNodePtr pEventReceiverNode = pEvent->getInputDevice()->getEventReceiverNode();
if (!pEventReceiverNode) {
pEventReceiverNode = getRootNode();
}
pEventReceiverNode->getElementsByPos(pEvent->getPos(), pCursorNodes);
ContactPtr pContact = pEvent->getContact();
- if (pContact && pContact->hasListeners() && !bOnlyCheckCursorOver) {
+ if (pContact && !bOnlyCheckCursorOver) {
if (!pCursorNodes.empty()) {
- NodePtr pNode = pCursorNodes.begin()->lock();
+ NodePtr pNode = *(pCursorNodes.begin());
pEvent->setNode(pNode);
}
pContact->sendEventToListeners(pEvent);
@@ -1417,7 +1484,7 @@ void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
int cursorID = pEvent->getCursorID();
// Determine the nodes the event should be sent to.
- vector<NodeWeakPtr> pDestNodes = pCursorNodes;
+ vector<NodePtr> pDestNodes = pCursorNodes;
if (m_EventCaptureInfoMap.find(cursorID) != m_EventCaptureInfoMap.end()) {
NodeWeakPtr pEventCaptureNode =
m_EventCaptureInfoMap[cursorID]->m_pNode;
@@ -1428,7 +1495,7 @@ void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
}
}
- vector<NodeWeakPtr> pLastCursorNodes;
+ vector<NodePtr> pLastCursorNodes;
{
map<int, CursorStatePtr>::iterator it;
it = m_pLastCursorStates.find(cursorID);
@@ -1438,50 +1505,48 @@ void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
}
// Send out events.
- vector<NodeWeakPtr>::const_iterator itLast;
- vector<NodeWeakPtr>::iterator itCur;
+ vector<NodePtr>::const_iterator itLast;
+ vector<NodePtr>::iterator itCur;
for (itLast = pLastCursorNodes.begin(); itLast != pLastCursorNodes.end();
++itLast)
{
- NodePtr pLastNode = itLast->lock();
+ NodePtr pLastNode = *itLast;
for (itCur = pCursorNodes.begin(); itCur != pCursorNodes.end(); ++itCur) {
- if (itCur->lock() == pLastNode) {
+ if (*itCur == pLastNode) {
break;
}
}
if (itCur == pCursorNodes.end()) {
- sendOver(pEvent, Event::CURSOROUT, pLastNode);
+ sendOver(pEvent, Event::CURSOR_OUT, pLastNode);
}
}
// Send over events.
for (itCur = pCursorNodes.begin(); itCur != pCursorNodes.end(); ++itCur) {
- NodePtr pCurNode = itCur->lock();
+ NodePtr pCurNode = *itCur;
for (itLast = pLastCursorNodes.begin(); itLast != pLastCursorNodes.end();
++itLast)
{
- if (itLast->lock() == pCurNode) {
+ if (*itLast == pCurNode) {
break;
}
}
if (itLast == pLastCursorNodes.end()) {
- sendOver(pEvent, Event::CURSOROVER, pCurNode);
+ sendOver(pEvent, Event::CURSOR_OVER, pCurNode);
}
}
if (!bOnlyCheckCursorOver) {
// Iterate through the nodes and send the event to all of them.
- vector<NodeWeakPtr>::iterator it;
+ vector<NodePtr>::iterator it;
for (it = pDestNodes.begin(); it != pDestNodes.end(); ++it) {
- NodePtr pNode = (*it).lock();
- if (pNode) {
- CursorEventPtr pNodeEvent = boost::dynamic_pointer_cast<CursorEvent>(
- pEvent->cloneAs(pEvent->getType()));
- pNodeEvent->setNode(pNode);
- if (pNodeEvent->getType() != Event::CURSORMOTION) {
- pNodeEvent->trace();
+ NodePtr pNode = *it;
+ if (pNode->getState() != Node::NS_UNCONNECTED) {
+ pEvent->setNode(pNode);
+ if (pEvent->getType() != Event::CURSOR_MOTION) {
+ pEvent->trace();
}
- if (pNode->handleEvent(pNodeEvent) == true) {
+ if (pNode->handleEvent(pEvent) == true) {
// stop bubbling
break;
}
@@ -1489,12 +1554,12 @@ void Player::handleCursorEvent(CursorEventPtr pEvent, bool bOnlyCheckCursorOver)
}
}
- if (pEvent->getType() == Event::CURSORUP && pEvent->getSource() != Event::MOUSE) {
+ if (pEvent->getType() == Event::CURSOR_UP && pEvent->getSource() != Event::MOUSE) {
// Cursor has disappeared: send out events.
- vector<NodeWeakPtr>::iterator it;
+ vector<NodePtr>::iterator it;
for (it = pCursorNodes.begin(); it != pCursorNodes.end(); ++it) {
- NodePtr pNode = it->lock();
- sendOver(pEvent, Event::CURSOROUT, pNode);
+ NodePtr pNode = *it;
+ sendOver(pEvent, Event::CURSOR_OUT, pNode);
}
m_pLastCursorStates.erase(cursorID);
} else {
@@ -1539,14 +1604,14 @@ void Player::handleTimers()
m_bInHandleTimers = true;
it = m_PendingTimeouts.begin();
- while (it != m_PendingTimeouts.end() && (*it)->IsReady(getFrameTime())
+ while (it != m_PendingTimeouts.end() && (*it)->isReady(getFrameTime())
&& !m_bStopping)
{
- (*it)->Fire(getFrameTime());
+ (*it)->fire(getFrameTime());
if (m_bCurrentTimeoutDeleted) {
it = m_PendingTimeouts.begin();
} else {
- if ((*it)->IsInterval()) {
+ if ((*it)->isInterval()) {
Timeout* pTempTimeout = *it;
it = m_PendingTimeouts.erase(it);
m_NewTimeouts.insert(m_NewTimeouts.begin(), pTempTimeout);
@@ -1561,8 +1626,25 @@ void Player::handleTimers()
addTimeout(*it);
}
m_NewTimeouts.clear();
+
+ notifySubscribers("ON_FRAME");
+
m_bInHandleTimers = false;
+ if (m_bPythonAvailable) {
+ std::vector<Timeout *> tempAsyncCalls;
+ Py_BEGIN_ALLOW_THREADS;
+ {
+ lock_guard lock(m_AsyncCallMutex);
+ tempAsyncCalls = m_AsyncCalls;
+ m_AsyncCalls.clear();
+ }
+ Py_END_ALLOW_THREADS;
+ for (it = tempAsyncCalls.begin(); it != tempAsyncCalls.end(); ++it) {
+ (*it)->fire(getFrameTime());
+ delete *it;
+ }
+ }
}
SDLDisplayEngine * Player::getDisplayEngine() const
@@ -1570,6 +1652,11 @@ SDLDisplayEngine * Player::getDisplayEngine() const
return m_pDisplayEngine.get();
}
+void Player::keepWindowOpen()
+{
+ m_bKeepWindowOpen = true;
+}
+
void Player::setStopOnEscape(bool bStop)
{
m_bStopOnEscape = bStop;
@@ -1580,19 +1667,44 @@ bool Player::getStopOnEscape() const
return m_bStopOnEscape;
}
-void Player::setVolume(double volume)
+void Player::setVolume(float volume)
{
m_Volume = volume;
- if (SDLAudioEngine::get()) {
- SDLAudioEngine::get()->setVolume(m_Volume);
+ if (AudioEngine::get()) {
+ AudioEngine::get()->setVolume(m_Volume);
}
}
-double Player::getVolume() const
+float Player::getVolume() const
{
return m_Volume;
}
+string Player::getConfigOption(const string& sSubsys, const string& sName) const
+{
+ const string* psValue = ConfigMgr::get()->getOption(sSubsys, sName);
+ if (!psValue) {
+ throw Exception(AVG_ERR_INVALID_ARGS, string("Unknown config option ") + sSubsys
+ + ":" + sName);
+ } else {
+ return *psValue;
+ }
+}
+
+bool Player::isUsingGLES() const
+{
+ return m_GLConfig.m_bGLES;
+}
+
+bool Player::areFullShadersSupported() const
+{
+ if (!m_bIsPlaying) {
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Must call Player.play() before areFullShadersSupported().");
+ }
+ return (m_GLConfig.m_ShaderUsage == GLConfig::FULL);
+}
+
OffscreenCanvasPtr Player::getCanvasFromURL(const std::string& sURL)
{
if (sURL.substr(0, 7) != "canvas:") {
@@ -1609,7 +1721,7 @@ OffscreenCanvasPtr Player::getCanvasFromURL(const std::string& sURL)
string("Canvas with url '")+sURL+"' not found.");
}
-void Player::cleanup()
+void Player::cleanup(bool bIsAbort)
{
// Kill all timeouts.
vector<Timeout*>::iterator it;
@@ -1624,7 +1736,7 @@ void Player::cleanup()
if (m_pMainCanvas) {
unregisterFrameEndListener(BitmapManager::get());
delete BitmapManager::get();
- m_pMainCanvas->stopPlayback();
+ m_pMainCanvas->stopPlayback(bIsAbort);
m_pMainCanvas = MainCanvasPtr();
}
@@ -1632,46 +1744,53 @@ void Player::cleanup()
m_pMultitouchInputDevice = IInputDevicePtr();
}
for (unsigned i = 0; i < m_pCanvases.size(); ++i) {
- m_pCanvases[i]->stopPlayback();
+ m_pCanvases[i]->stopPlayback(bIsAbort);
}
m_pCanvases.clear();
if (m_pDisplayEngine) {
- m_pDisplayEngine->deinitRender();
- m_pDisplayEngine->teardown();
+ m_DP.m_WindowSize = IntPoint(0,0);
+ if (!m_bKeepWindowOpen) {
+ m_pDisplayEngine->deinitRender();
+ m_pDisplayEngine->teardown();
+ m_pDisplayEngine = SDLDisplayEnginePtr();
+ }
}
- if (SDLAudioEngine::get()) {
- SDLAudioEngine::get()->teardown();
+ if (AudioEngine::get()) {
+ AudioEngine::get()->teardown();
}
m_pEventDispatcher = EventDispatcherPtr();
- m_pLastMouseEvent = MouseEventPtr(new MouseEvent(Event::CURSORMOTION, false, false,
- false, IntPoint(-1, -1), MouseEvent::NO_BUTTON, DPoint(-1, -1), 0));
+ m_pLastMouseEvent = MouseEventPtr(new MouseEvent(Event::CURSOR_MOTION, false, false,
+ false, IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0));
m_FrameTime = 0;
m_bIsPlaying = false;
m_CurDirName = getCWD();
+
+ removeSubscribers();
}
-int Player::addTimeout(Timeout* pTimeout)
+int Player::internalSetTimeout(int time, PyObject * pyfunc, bool bIsInterval)
{
- vector<Timeout*>::iterator it = m_PendingTimeouts.begin();
- while (it != m_PendingTimeouts.end() && (**it)<*pTimeout) {
- it++;
+ Timeout* pTimeout = new Timeout(time, pyfunc, bIsInterval, getFrameTime());
+ if (m_bInHandleTimers) {
+ m_NewTimeouts.push_back(pTimeout);
+ } else {
+ addTimeout(pTimeout);
}
- m_PendingTimeouts.insert(it, pTimeout);
- return pTimeout->GetID();
+ return pTimeout->getID();
}
-void Player::removeTimeout(Timeout* pTimeout)
+int Player::addTimeout(Timeout* pTimeout)
{
- delete pTimeout;
vector<Timeout*>::iterator it = m_PendingTimeouts.begin();
- while (*it != pTimeout) {
+ while (it != m_PendingTimeouts.end() && (**it)<*pTimeout) {
it++;
}
- m_PendingTimeouts.erase(it);
+ m_PendingTimeouts.insert(it, pTimeout);
+ return pTimeout->getID();
}
void Player::setPluginPath(const string& newPath)
@@ -1684,7 +1803,7 @@ string Player::getPluginPath() const
return PluginManager::get().getSearchPath();
}
-boost::python::object Player::loadPlugin(const std::string& name)
+py::object Player::loadPlugin(const std::string& name)
{
return PluginManager::get().loadPlugin(name);
}
diff --git a/src/player/Player.h b/src/player/Player.h
index 8c8e786..32d0da5 100644
--- a/src/player/Player.h
+++ b/src/player/Player.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,8 +23,9 @@
#define _Player_H_
#include "../api.h"
+#include "Publisher.h"
#include "Timeout.h"
-#include "NodeRegistry.h"
+#include "TypeRegistry.h"
#include "DisplayParams.h"
#include "CursorState.h"
#include "TestHelper.h"
@@ -35,6 +36,7 @@
#include <libxml/parser.h>
#include <boost/shared_ptr.hpp>
+#include <boost/thread/thread.hpp>
#include <string>
#include <vector>
@@ -57,6 +59,7 @@ class EventDispatcher;
class MouseEvent;
class CursorEvent;
class SDLDisplayEngine;
+class Display;
typedef boost::shared_ptr<Node> NodePtr;
typedef boost::weak_ptr<Node> NodeWeakPtr;
@@ -68,8 +71,9 @@ typedef boost::shared_ptr<EventDispatcher> EventDispatcherPtr;
typedef boost::shared_ptr<MouseEvent> MouseEventPtr;
typedef boost::shared_ptr<CursorEvent> CursorEventPtr;
typedef boost::shared_ptr<SDLDisplayEngine> SDLDisplayEnginePtr;
+typedef boost::shared_ptr<Display> DisplayPtr;
-class AVG_API Player
+class AVG_API Player: public Publisher
{
public:
Player();
@@ -82,60 +86,66 @@ class AVG_API Player
bool isFullscreen();
void setWindowFrame(bool bHasWindowFrame);
void setWindowPos(int x=0, int y=0);
- void setOGLOptions(bool bUsePOTTextures, bool bUseShaders,
- bool bUsePixelBuffers, int multiSampleSamples);
+ void setWindowTitle(const std::string& sTitle);
+ void useGLES(bool bGLES);
+ void setOGLOptions(bool bUsePOTTextures, bool bUsePixelBuffers,
+ int multiSampleSamples, GLConfig::ShaderUsage shaderUsage,
+ bool bUseDebugContext);
void setMultiSampleSamples(int multiSampleSamples);
void setAudioOptions(int samplerate, int channels);
- DPoint getScreenResolution();
- double getPixelsPerMM();
- DPoint getPhysicalScreenDimensions();
- void assumePixelsPerMM(double ppmm);
+ void enableGLErrorChecks(bool bEnable);
+ glm::vec2 getScreenResolution();
+ float getPixelsPerMM();
+ glm::vec2 getPhysicalScreenDimensions();
+ void assumePixelsPerMM(float ppmm);
CanvasPtr loadFile(const std::string& sFilename);
CanvasPtr loadString(const std::string& sAVG);
OffscreenCanvasPtr loadCanvasFile(const std::string& sFilename);
OffscreenCanvasPtr loadCanvasString(const std::string& sAVG);
- CanvasPtr createMainCanvas(const boost::python::dict& params);
- OffscreenCanvasPtr createCanvas(const boost::python::dict& params);
+ CanvasPtr createMainCanvas(const py::dict& params);
+ OffscreenCanvasPtr createCanvas(const py::dict& params);
void deleteCanvas(const std::string& sID);
CanvasPtr getMainCanvas() const;
OffscreenCanvasPtr getCanvas(const std::string& sID) const;
- void newCanvasDependency(const OffscreenCanvasPtr pCanvas);
+ void newCanvasDependency();
void play();
void stop();
bool isStopping();
- void initPlayback();
- void cleanup();
+ void initPlayback(const std::string& sShaderPath = "");
+ void cleanup(bool bIsAbort);
bool isPlaying();
- void setFramerate(double rate);
+ void setFramerate(float rate);
void setVBlankFramerate(int rate);
- double getEffectiveFramerate();
+ float getEffectiveFramerate();
TestHelper * getTestHelper();
- void setFakeFPS(double fps);
+ void setFakeFPS(float fps);
long long getFrameTime();
- double getFrameDuration();
+ float getFrameDuration();
- void registerNodeType(NodeDefinition Def, const char* pParentNames[] = 0);
-
- NodePtr createNode(const std::string& sType, const boost::python::dict& PyDict);
+ NodePtr createNode(const std::string& sType, const py::dict& PyDict,
+ const py::object& self=py::object());
NodePtr createNodeFromXmlString(const std::string& sXML);
int setInterval(int time, PyObject * pyfunc);
int setTimeout(int time, PyObject * pyfunc);
int setOnFrameHandler(PyObject * pyfunc);
bool clearInterval(int id);
+ void callFromThread(PyObject * pyfunc);
void addInputDevice(IInputDevicePtr pSource);
MouseEventPtr getMouseState() const;
- TrackerInputDevice * addTracker();
+ EventPtr getCurrentEvent() const;
TrackerInputDevice * getTracker();
void enableMultitouch();
+ void enableMouse(bool enabled);
bool isMultitouchAvailable() const;
void setEventCapture(NodePtr pNode, int cursorID);
void releaseEventCapture(int cursorID);
bool isCaptured(int cursorID);
+ void removeDeadEventCaptures();
EventPtr getCurEvent() const;
void setMousePos(const IntPoint& pos);
int getKeyModifierState() const;
@@ -143,29 +153,38 @@ class AVG_API Player
BitmapPtr screenshot();
void setCursor(const Bitmap* pBmp, IntPoint hotSpot);
void showCursor(bool bShow);
+ bool isCursorShown();
NodePtr getElementByID(const std::string& id);
AVGNodePtr getRootNode();
void doFrame(bool bFirstFrame);
- double getFramerate();
- double getVideoRefreshRate();
- bool isUsingShaders();
- void setGamma(double red, double green, double blue);
+ float getFramerate();
+ float getVideoRefreshRate();
+ size_t getVideoMemInstalled();
+ size_t getVideoMemUsed();
+ void setGamma(float red, float green, float blue);
SDLDisplayEngine * getDisplayEngine() const;
+ void keepWindowOpen();
void setStopOnEscape(bool bStop);
bool getStopOnEscape() const;
- void setVolume(double volume);
- double getVolume() const;
+ void setVolume(float volume);
+ float getVolume() const;
+ std::string getConfigOption(const std::string& sSubsys, const std::string& sName)
+ const;
+ bool isUsingGLES() const;
+ bool areFullShadersSupported() const;
OffscreenCanvasPtr getCanvasFromURL(const std::string& sURL);
std::string getCurDirName();
std::string getRootMediaDir();
- const NodeDefinition& getNodeDef(const std::string& sType);
void disablePython();
+ void startTraversingTree();
+ void endTraversingTree();
+ bool isTraversingTree() const;
- boost::python::object loadPlugin(const std::string& name);
+ py::object loadPlugin(const std::string& name);
void setPluginPath(const std::string& newPath);
std::string getPluginPath() const;
@@ -183,14 +202,13 @@ class AVG_API Player
private:
void initConfig();
- void initGraphics();
+ void initGraphics(const std::string& sShaderPath);
void initAudio();
-
- void updateDTD();
+ void initMainCanvas(NodePtr pRootNode);
NodePtr loadMainNodeFromFile(const std::string& sFilename);
NodePtr loadMainNodeFromString(const std::string& sAVG);
- NodePtr internalLoad(const std::string& sAVG);
+ NodePtr internalLoad(const std::string& sAVG, const std::string& sFilename);
SDLDisplayEnginePtr safeGetDisplayEngine();
NodePtr createNodeFromXml(const xmlDocPtr xmlDoc,
@@ -210,42 +228,44 @@ class AVG_API Player
MainCanvasPtr m_pMainCanvas;
SDLDisplayEnginePtr m_pDisplayEngine;
+ bool m_bDisplayEngineBroken;
TestHelperPtr m_pTestHelper;
std::string m_CurDirName;
+ bool m_bIsTraversingTree;
bool m_bStopping;
- NodeRegistry m_NodeRegistry;
IInputDevicePtr m_pMultitouchInputDevice;
+ // Timeout handling
+ int internalSetTimeout(int time, PyObject * pyfunc, bool bIsInterval);
int addTimeout(Timeout* pTimeout);
- void removeTimeout(Timeout* pTimeout);
void handleTimers();
bool m_bInHandleTimers;
bool m_bCurrentTimeoutDeleted;
std::vector<Timeout *> m_PendingTimeouts;
std::vector<Timeout *> m_NewTimeouts; // Timeouts to be added this frame.
+ std::vector<Timeout *> m_AsyncCalls;
+ boost::mutex m_AsyncCallMutex;
// Configuration variables.
DisplayParams m_DP;
AudioParams m_AP;
GLConfig m_GLConfig;
+ bool m_bKeepWindowOpen;
bool m_bStopOnEscape;
bool m_bIsPlaying;
// Time calculation
bool m_bFakeFPS;
- double m_FakeFPS;
+ float m_FakeFPS;
long long m_FrameTime;
long long m_PlayStartTime;
long long m_NumFrames;
- double m_Volume;
-
- bool m_bDirtyDTD;
- xmlDtdPtr m_dtd;
+ float m_Volume;
bool m_bPythonAvailable;
@@ -258,7 +278,7 @@ class AVG_API Player
struct EventCaptureInfo {
EventCaptureInfo(const NodeWeakPtr& pNode);
- NodeWeakPtr m_pNode;
+ NodePtr m_pNode;
int m_CaptureCount;
};
typedef boost::shared_ptr<EventCaptureInfo> EventCaptureInfoPtr;
@@ -266,11 +286,13 @@ class AVG_API Player
std::map<int, EventCaptureInfoPtr> m_EventCaptureInfoMap;
MouseEventPtr m_pLastMouseEvent;
+ EventPtr m_pCurrentEvent;
// The indexes of this map are cursorids.
std::map<int, CursorStatePtr> m_pLastCursorStates;
PyObject * m_EventHookPyFunc;
+ bool m_bMouseEnabled;
};
}
diff --git a/src/player/PluginManager.cpp b/src/player/PluginManager.cpp
index a117a5b..57d33f0 100644
--- a/src/player/PluginManager.cpp
+++ b/src/player/PluginManager.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,8 +23,6 @@
#include "PluginManager.h"
-#include "NodeDefinition.h"
-
#include "../base/DlfcnWrapper.h"
#include "../base/FileHelper.h"
#include "../base/Logger.h"
@@ -58,8 +56,10 @@ PluginManager& PluginManager::get()
PluginManager::PluginManager()
{
- setSearchPath(string("."PATH_DELIMITER) + "./plugin"PATH_DELIMITER +
- getAvgLibPath() + "plugin");
+ setSearchPath(string("."PATH_DELIMITER) +
+ "./plugin"PATH_DELIMITER +
+ "./plugin/.libs"PATH_DELIMITER +
+ getPath(getAvgLibPath()) + "plugin");
}
void PluginManager::setSearchPath(const string& sNewPath)
@@ -73,7 +73,7 @@ string PluginManager::getSearchPath() const
return m_sCurrentSearchPath;
}
-boost::python::object PluginManager::loadPlugin(const std::string& sPluginName)
+py::object PluginManager::loadPlugin(const std::string& sPluginName)
{
// is it loaded aready?
PluginMap::iterator i = m_LoadedPlugins.find(sPluginName);
@@ -89,7 +89,7 @@ boost::python::object PluginManager::loadPlugin(const std::string& sPluginName)
++referenceCount;
m_LoadedPlugins[sPluginName] = make_pair(i->second.first, referenceCount);
}
- boost::python::object sysModule(boost::python::handle<>(PyImport_ImportModule("sys")));
+ py::object sysModule(py::handle<>(PyImport_ImportModule("sys")));
return sysModule.attr("modules")[sPluginName];
}
@@ -106,7 +106,7 @@ string PluginManager::locateSharedObject(const string& sFilename)
}
string sMessage = "Unable to locate plugin file '" + sFilename
+ "'. Was looking in " + m_sCurrentSearchPath;
- AVG_TRACE(Logger::PLUGIN, sMessage);
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO, sMessage);
throw PluginNotFound(sMessage);
}
@@ -145,7 +145,8 @@ void PluginManager::parsePath(const string& sPath)
m_PathComponents.push_back(sDirectory);
} while (!sRemaining.empty());
- AVG_TRACE(Logger::PLUGIN, "Plugin search path set to '" << sPath << "'");
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::INFO,
+ "Plugin search path set to '" << sPath << "'");
}
void* PluginManager::internalLoadPlugin(const string& sFullpath)
@@ -153,7 +154,8 @@ void* PluginManager::internalLoadPlugin(const string& sFullpath)
void *handle = dlopen(sFullpath.c_str(), RTLD_LOCAL | RTLD_NOW);
if (!handle) {
string sMessage(dlerror());
- AVG_TRACE(Logger::PLUGIN, "Could not load plugin. dlopen failed with message '"
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::ERROR,
+ "Could not load plugin. dlopen failed with message '"
<< sMessage << "'");
throw PluginCorrupted(sMessage);
}
@@ -163,7 +165,8 @@ void* PluginManager::internalLoadPlugin(const string& sFullpath)
dlclose(handle);
throw e;
}
- AVG_TRACE(Logger::PLUGIN, "Loaded plugin '" << sFullpath << "'");
+ AVG_TRACE(Logger::category::PLUGIN,Logger::severity::INFO,
+ "Loaded plugin '" << sFullpath << "'");
return handle;
}
@@ -176,7 +179,8 @@ void PluginManager::registerPlugin(void* handle)
if (registerPlugin) {
registerPlugin();
} else {
- AVG_TRACE(Logger::PLUGIN, "No plugin registration function detected");
+ AVG_TRACE(Logger::category::PLUGIN, Logger::severity::ERROR,
+ "No plugin registration function detected");
throw PluginCorrupted("No plugin registration function detected");
}
}
diff --git a/src/player/PluginManager.h b/src/player/PluginManager.h
index f46b8d7..37a5d23 100644
--- a/src/player/PluginManager.h
+++ b/src/player/PluginManager.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -52,7 +52,7 @@ public:
void setSearchPath(const std::string& aNewPath);
std::string getSearchPath() const;
- boost::python::object loadPlugin(const std::string& aPluginName);
+ py::object loadPlugin(const std::string& aPluginName);
private:
PluginManager();
diff --git a/src/player/PolyLineNode.cpp b/src/player/PolyLineNode.cpp
index 48f40f6..16899f7 100644
--- a/src/player/PolyLineNode.cpp
+++ b/src/player/PolyLineNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "PolyLineNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
@@ -33,17 +33,18 @@ using namespace std;
namespace avg {
-NodeDefinition PolyLineNode::createDefinition()
+void PolyLineNode::registerType()
{
- vector<DPoint> v;
- vector<double> vd;
- return NodeDefinition("polyline", Node::buildNode<PolyLineNode>)
- .extendDefinition(VectorNode::createDefinition())
+ vector<glm::vec2> v;
+ vector<float> vd;
+ TypeDefinition def = TypeDefinition("polyline", "vectornode",
+ ExportedObject::buildObject<PolyLineNode>)
.addArg(Arg<string>("linejoin", "bevel"))
- .addArg(Arg<vector<DPoint> >("pos", v, false, offsetof(PolyLineNode, m_Pts)))
- .addArg(Arg<vector<double> >("texcoords", vd, false,
+ .addArg(Arg<vector<glm::vec2> >("pos", v, false, offsetof(PolyLineNode, m_Pts)))
+ .addArg(Arg<vector<float> >("texcoords", vd, false,
offsetof(PolyLineNode, m_TexCoords)))
;
+ TypeRegistry::get()->registerType(def);
}
PolyLineNode::PolyLineNode(const ArgList& args)
@@ -62,20 +63,13 @@ PolyLineNode::~PolyLineNode()
{
}
-const vector<DPoint>& PolyLineNode::getPos() const
+const vector<glm::vec2>& PolyLineNode::getPos() const
{
return m_Pts;
}
-void PolyLineNode::setPos(const vector<DPoint>& pts)
+void PolyLineNode::setPos(const vector<glm::vec2>& pts)
{
- vector<DPoint>::const_iterator it;
- for (it = pts.begin(); it != pts.end(); ++it) {
- if (it->isNaN() || it->isInf()) {
- throw Exception(AVG_ERR_INVALID_ARGS,
- "polyline positions must not be nan or inf.");
- }
- }
m_Pts = pts;
m_TexCoords.clear();
m_EffTexCoords.clear();
@@ -83,12 +77,12 @@ void PolyLineNode::setPos(const vector<DPoint>& pts)
setDrawNeeded();
}
-const vector<double>& PolyLineNode::getTexCoords() const
+const vector<float>& PolyLineNode::getTexCoords() const
{
return m_TexCoords;
}
-void PolyLineNode::setTexCoords(const vector<double>& coords)
+void PolyLineNode::setTexCoords(const vector<float>& coords)
{
if (coords.size() > m_Pts.size()) {
throw(Exception(AVG_ERR_OUT_OF_RANGE,
@@ -110,7 +104,7 @@ void PolyLineNode::setLineJoin(const string& s)
setDrawNeeded();
}
-void PolyLineNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void PolyLineNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
if (getNumDifferentPts(m_Pts) < 2) {
return;
@@ -118,7 +112,7 @@ void PolyLineNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
if (m_EffTexCoords.empty()) {
calcEffPolyLineTexCoords(m_EffTexCoords, m_TexCoords, m_CumulDist);
}
- calcPolyLine(m_Pts, m_EffTexCoords, false, m_LineJoin, pVertexArray, color);
+ calcPolyLine(m_Pts, m_EffTexCoords, false, m_LineJoin, pVertexData, color);
}
}
diff --git a/src/player/PolyLineNode.h b/src/player/PolyLineNode.h
index 80b4255..41ee162 100644
--- a/src/player/PolyLineNode.h
+++ b/src/player/PolyLineNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -35,27 +35,27 @@ namespace avg {
class AVG_API PolyLineNode : public VectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
PolyLineNode(const ArgList& args);
virtual ~PolyLineNode();
- const std::vector<DPoint>& getPos() const;
- void setPos(const std::vector<DPoint>& pts);
+ const std::vector<glm::vec2>& getPos() const;
+ void setPos(const std::vector<glm::vec2>& pts);
- const std::vector<double>& getTexCoords() const;
- void setTexCoords(const std::vector<double>& coords);
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
std::string getLineJoin() const;
void setLineJoin(const std::string& s);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- std::vector<DPoint> m_Pts;
- std::vector<double> m_CumulDist;
- std::vector<double> m_TexCoords;
- std::vector<double> m_EffTexCoords;
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_CumulDist;
+ std::vector<float> m_TexCoords;
+ std::vector<float> m_EffTexCoords;
LineJoin m_LineJoin;
};
diff --git a/src/player/PolygonNode.cpp b/src/player/PolygonNode.cpp
index 4c9411d..6e81b9b 100644
--- a/src/player/PolygonNode.cpp
+++ b/src/player/PolygonNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,12 +21,14 @@
#include "PolygonNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
#include "../base/GeomHelper.h"
-#include "../base/Triangulate.h"
+#include "../base/triangulate/Triangulate.h"
+
+#include "../glm/gtx/norm.hpp"
#include <iostream>
#include <sstream>
@@ -35,17 +37,20 @@ using namespace std;
namespace avg {
-NodeDefinition PolygonNode::createDefinition()
+void PolygonNode::registerType()
{
- vector<DPoint> v;
- vector<double> vd;
- return NodeDefinition("polygon", Node::buildNode<PolygonNode>)
- .extendDefinition(FilledVectorNode::createDefinition())
+ VectorVec2Vector cv;
+ vector<glm::vec2> v;
+ vector<float> vd;
+ TypeDefinition def = TypeDefinition("polygon", "filledvectornode",
+ ExportedObject::buildObject<PolygonNode>)
.addArg(Arg<string>("linejoin", "bevel"))
- .addArg(Arg<vector<DPoint> >("pos", v, false, offsetof(PolygonNode, m_Pts)))
- .addArg(Arg<vector<double> >("texcoords", vd, false,
+ .addArg(Arg<vector<glm::vec2> >("pos", v, false, offsetof(PolygonNode, m_Pts)))
+ .addArg(Arg<vector<float> >("texcoords", vd, false,
offsetof(PolygonNode, m_TexCoords)))
+ .addArg(Arg<VectorVec2Vector>("holes", cv, false, offsetof(PolygonNode, m_Holes)))
;
+ TypeRegistry::get()->registerType(def);
}
PolygonNode::PolygonNode(const ArgList& args)
@@ -56,6 +61,18 @@ PolygonNode::PolygonNode(const ArgList& args)
throw(Exception(AVG_ERR_OUT_OF_RANGE,
"Too many texture coordinates in polygon"));
}
+ if (m_Pts.size() != 0 && m_Pts.size() < 3) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "A polygon must have min. tree points."));
+ }
+ if (m_Holes.size() > 0) {
+ for (unsigned int i = 0; i < m_Holes.size(); i++) {
+ if (m_Holes[i].size() < 3) {
+ throw(Exception(AVG_ERR_UNSUPPORTED,
+ "A hole of a polygon must have min. tree points."));
+ }
+ }
+ }
setLineJoin(args.getArgVal<string>("linejoin"));
calcPolyLineCumulDist(m_CumulDist, m_Pts, true);
}
@@ -64,13 +81,14 @@ PolygonNode::~PolygonNode()
{
}
-const vector<DPoint>& PolygonNode::getPos() const
+const vector<glm::vec2>& PolygonNode::getPos() const
{
return m_Pts;
}
-void PolygonNode::setPos(const vector<DPoint>& pts)
+void PolygonNode::setPos(const vector<glm::vec2>& pts)
{
+ m_Pts.clear();
m_Pts = pts;
m_TexCoords.clear();
m_EffTexCoords.clear();
@@ -78,12 +96,25 @@ void PolygonNode::setPos(const vector<DPoint>& pts)
setDrawNeeded();
}
-const vector<double>& PolygonNode::getTexCoords() const
+const vector<float>& PolygonNode::getTexCoords() const
{
return m_TexCoords;
}
-void PolygonNode::setTexCoords(const vector<double>& coords)
+const VectorVec2Vector& PolygonNode::getHoles() const
+{
+ return m_Holes;
+}
+
+void PolygonNode::setHoles(const VectorVec2Vector& holes)
+{
+ m_Holes = holes;
+ m_TexCoords.clear();
+ m_EffTexCoords.clear();
+ setDrawNeeded();
+}
+
+void PolygonNode::setTexCoords(const vector<float>& coords)
{
if (coords.size() > m_Pts.size()+1) {
throw(Exception(AVG_ERR_OUT_OF_RANGE,
@@ -105,14 +136,14 @@ void PolygonNode::setLineJoin(const string& s)
setDrawNeeded();
}
-void PolygonNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void PolygonNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
if (reactsToMouseEvents() && pointInPolygon(pos, m_Pts)) {
- pElements.push_back(shared_from_this());
+ pElements.push_back(getSharedThis());
}
}
-void PolygonNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void PolygonNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
if (getNumDifferentPts(m_Pts) < 3) {
return;
@@ -120,28 +151,43 @@ void PolygonNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
if (m_EffTexCoords.empty()) {
calcEffPolyLineTexCoords(m_EffTexCoords, m_TexCoords, m_CumulDist);
}
- calcPolyLine(m_Pts, m_EffTexCoords, true, m_LineJoin, pVertexArray, color);
+ calcPolyLine(m_Pts, m_EffTexCoords, true, m_LineJoin, pVertexData, color);
+
+ for (unsigned i = 0; i < m_Holes.size(); i++) {
+ calcPolyLine(m_Holes[i], m_EffTexCoords, true, m_LineJoin, pVertexData, color);
+ }
}
-void PolygonNode::calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void PolygonNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
if (getNumDifferentPts(m_Pts) < 3) {
return;
}
// Remove duplicate points
- vector<DPoint> pts;
+ vector<glm::vec2> pts;
+ vector<unsigned int> holeIndexes;
pts.reserve(m_Pts.size());
- pts.push_back(m_Pts[0]);
+ if (glm::distance2(m_Pts[0], m_Pts[m_Pts.size()-1]) > 0.1) {
+ pts.push_back(m_Pts[0]);
+ }
for (unsigned i = 1; i < m_Pts.size(); ++i) {
- if (calcDistSquared(m_Pts[i], m_Pts[i-1]) > 0.1) {
+ if (glm::distance2(m_Pts[i], m_Pts[i-1]) > 0.1) {
pts.push_back(m_Pts[i]);
}
}
+ if (m_Holes.size() > 0) {
+ for (unsigned int i = 0; i < m_Holes.size(); i++) { //loop over collection
+ holeIndexes.push_back(pts.size());
+ for (unsigned int j = 0; j < m_Holes[i].size(); j++) { //loop over vector
+ pts.push_back(m_Holes[i][j]);
+ }
+ }
+ }
if (color.getA() > 0) {
- DPoint minCoord = pts[0];
- DPoint maxCoord = pts[0];
+ glm::vec2 minCoord = pts[0];
+ glm::vec2 maxCoord = pts[0];
for (unsigned i = 1; i < pts.size(); ++i) {
if (pts[i].x < minCoord.x) {
minCoord.x = pts[i].x;
@@ -156,14 +202,15 @@ void PolygonNode::calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
maxCoord.y = pts[i].y;
}
}
- vector<int> triIndexes;
- triangulatePolygon(pts, triIndexes);
+ vector<unsigned int> triIndexes;
+ triangulatePolygon(triIndexes, pts, holeIndexes);
+
for (unsigned i = 0; i < pts.size(); ++i) {
- DPoint texCoord = calcFillTexCoord(pts[i], minCoord, maxCoord);
- pVertexArray->appendPos(pts[i], texCoord, color);
+ glm::vec2 texCoord = calcFillTexCoord(pts[i], minCoord, maxCoord);
+ pVertexData->appendPos(pts[i], texCoord, color);
}
for (unsigned i = 0; i < triIndexes.size(); i+=3) {
- pVertexArray->appendTriIndexes(triIndexes[i], triIndexes[i+1],
+ pVertexData->appendTriIndexes(triIndexes[i], triIndexes[i+1],
triIndexes[i+2]);
}
}
diff --git a/src/player/PolygonNode.h b/src/player/PolygonNode.h
index e8d4899..850f88f 100644
--- a/src/player/PolygonNode.h
+++ b/src/player/PolygonNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,33 +32,39 @@
namespace avg {
+typedef std::vector<std::vector<glm::vec2> > VectorVec2Vector;
+
class AVG_API PolygonNode : public FilledVectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
PolygonNode(const ArgList& args);
virtual ~PolygonNode();
- const std::vector<DPoint>& getPos() const;
- void setPos(const std::vector<DPoint>& pts);
+ const std::vector<glm::vec2>& getPos() const;
+ void setPos(const std::vector<glm::vec2>& pts);
+
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
- const std::vector<double>& getTexCoords() const;
- void setTexCoords(const std::vector<double>& coords);
+ const VectorVec2Vector& getHoles() const;
+ void setHoles(const VectorVec2Vector& holes);
std::string getLineJoin() const;
void setLineJoin(const std::string& s);
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
- virtual void calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- std::vector<DPoint> m_Pts;
- std::vector<double> m_CumulDist;
- std::vector<double> m_TexCoords;
- std::vector<double> m_EffTexCoords;
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_CumulDist;
+ std::vector<float> m_TexCoords;
+ std::vector<float> m_EffTexCoords;
+ VectorVec2Vector m_Holes;
LineJoin m_LineJoin;
};
diff --git a/src/player/Publisher.cpp b/src/player/Publisher.cpp
new file mode 100644
index 0000000..01bbea3
--- /dev/null
+++ b/src/player/Publisher.cpp
@@ -0,0 +1,248 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "Publisher.h"
+
+#include "SubscriberInfo.h"
+#include "PublisherDefinitionRegistry.h"
+#include "Player.h"
+
+#include "../base/Exception.h"
+#include "../base/StringHelper.h"
+
+using namespace std;
+
+namespace avg {
+
+int Publisher::s_LastSubscriberID = 0;
+
+Publisher::Publisher()
+{
+ m_pPublisherDef = PublisherDefinition::create("");
+}
+
+Publisher::Publisher(const string& sTypeName)
+{
+ m_pPublisherDef = PublisherDefinitionRegistry::get()->getDefinition(sTypeName);
+ vector<MessageID> messageIDs = m_pPublisherDef->getMessageIDs();
+ for (unsigned i=0; i<messageIDs.size(); ++i) {
+ m_SignalMap[messageIDs[i]] = list<SubscriberInfoPtr>();
+ }
+}
+
+Publisher::~Publisher()
+{
+}
+
+int Publisher::subscribe(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ int subscriberID = s_LastSubscriberID;
+ s_LastSubscriberID++;
+// cerr << this << " subscribe " << messageID << ", " << subscriberID << endl;
+ subscribers.push_front(SubscriberInfoPtr(new SubscriberInfo(subscriberID, callable)));
+ return subscriberID;
+}
+
+void Publisher::unsubscribe(MessageID messageID, int subscriberID)
+{
+// cerr << this << " unsubscribe " << messageID << ", " << subscriberID << endl;
+// cerr << " ";
+// dumpSubscribers(messageID);
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->getID() == subscriberID) {
+ unsubscribeIterator(messageID, it);
+ return;
+ }
+ }
+// cerr << " End of unsubscribe: ";
+// dumpSubscribers(messageID);
+ throwSubscriberNotFound(messageID, subscriberID);
+}
+
+void Publisher::unsubscribe1(int subscriberID)
+{
+ SignalMap::iterator it;
+ for (it = m_SignalMap.begin(); it != m_SignalMap.end(); ++it) {
+ SubscriberInfoList& subscribers = it->second;
+ SubscriberInfoList::iterator it2;
+ for (it2 = subscribers.begin(); it2 != subscribers.end(); it2++) {
+ if ((*it2)->getID() == subscriberID) {
+ MessageID messageID = it->first;
+ unsubscribeIterator(messageID, it2);
+ return;
+ }
+ }
+ }
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "Subscriber with ID "+toString(subscriberID)+" not found.");
+}
+
+void Publisher::unsubscribeCallable(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->isCallable(callable)) {
+ unsubscribeIterator(messageID, it);
+ return;
+ }
+ }
+ throwSubscriberNotFound(messageID, -1);
+}
+
+int Publisher::getNumSubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ return subscribers.size();
+}
+
+bool Publisher::isSubscribed(MessageID messageID, int subscriberID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->getID() == subscriberID) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Publisher::isSubscribedCallable(MessageID messageID, const py::object& callable)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ if ((*it)->isCallable(callable)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Publisher::publish(MessageID messageID)
+{
+ if (m_SignalMap.find(messageID) != m_SignalMap.end()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ "already registered.");
+ }
+ m_SignalMap[messageID] = SubscriberInfoList();
+}
+
+void Publisher::removeSubscribers()
+{
+ SignalMap::iterator it;
+ for (it = m_SignalMap.begin(); it != m_SignalMap.end(); ++it) {
+ it->second = SubscriberInfoList();
+ }
+}
+
+void Publisher::notifySubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ if (!subscribers.empty()) {
+ py::list args;
+ notifySubscribersPy(messageID, args);
+ }
+}
+
+void Publisher::notifySubscribers(const string& sMsgName)
+{
+ MessageID messageID = m_pPublisherDef->getMessageID(sMsgName);
+ notifySubscribers(messageID);
+}
+
+void Publisher::notifySubscribersPy(MessageID messageID, const py::list& args)
+{
+// cerr << this << " notifySubscribers " << messageID << endl;
+// cerr << " ";
+// dumpSubscribers(messageID);
+ AVG_ASSERT(!(Player::get()->isTraversingTree()));
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ WeakSubscriberInfoList subRefs;
+ for (SubscriberInfoList::iterator it = subscribers.begin(); it != subscribers.end();
+ ++it)
+ {
+ subRefs.push_back(*it);
+ }
+ WeakSubscriberInfoList::iterator it;
+ for (it = subRefs.begin(); it != subRefs.end(); ++it) {
+// cerr << " next" << endl;
+ if (!(*it).expired()) {
+ SubscriberInfoPtr pSub = (*it).lock();
+ if (pSub->hasExpired()) {
+ // Python subscriber doesn't exist anymore -> auto-unsubscribe.
+ unsubscribe(messageID, pSub->getID());
+ } else {
+// cerr << " invoke: " << (*it)->getID() << endl;
+ pSub->invoke(args);
+ }
+ }
+ }
+// cerr << " end notify" << endl;
+}
+
+MessageID Publisher::genMessageID()
+{
+ return PublisherDefinitionRegistry::get()->genMessageID();
+}
+
+void Publisher::unsubscribeIterator(MessageID messageID, SubscriberInfoList::iterator it)
+{
+ m_SignalMap[messageID].erase(it);
+}
+
+
+Publisher::SubscriberInfoList& Publisher::safeFindSubscribers(MessageID messageID)
+{
+ if (m_SignalMap.find(messageID) == m_SignalMap.end()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "No signal with ID "+toString(messageID));
+ }
+ SubscriberInfoList& subscribers = m_SignalMap[messageID];
+ return subscribers;
+}
+
+void Publisher::throwSubscriberNotFound(MessageID messageID, int subscriberID)
+{
+ if (subscriberID == -1) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ " doesn't have a subscriber with the given callable.");
+ } else {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Signal with ID "+toString(messageID)+
+ " doesn't have a subscriber with ID "+toString(subscriberID));
+ }
+}
+
+void Publisher::dumpSubscribers(MessageID messageID)
+{
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ SubscriberInfoList::iterator it;
+ for (it = subscribers.begin(); it != subscribers.end(); it++) {
+ cerr << (*it)->getID() << " ";
+ }
+ cerr << endl;
+}
+
+
+}
diff --git a/src/player/Publisher.h b/src/player/Publisher.h
new file mode 100644
index 0000000..1270544
--- /dev/null
+++ b/src/player/Publisher.h
@@ -0,0 +1,113 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _Publisher_H_
+#define _Publisher_H_
+
+#include "../api.h"
+
+#include "ExportedObject.h"
+#include "BoostPython.h"
+#include "PublisherDefinition.h"
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <list>
+#include <map>
+
+namespace avg {
+
+class SubscriberInfo;
+typedef boost::shared_ptr<SubscriberInfo> SubscriberInfoPtr;
+typedef boost::weak_ptr<SubscriberInfo> SubscriberInfoWeakPtr;
+
+class Publisher;
+typedef boost::shared_ptr<Publisher> PublisherPtr;
+
+class AVG_API Publisher: public ExportedObject
+{
+public:
+ Publisher();
+ Publisher(const std::string& sTypeName);
+ virtual ~Publisher();
+
+ int subscribe(MessageID messageID, const py::object& callable);
+ void unsubscribe(MessageID messageID, int subscriberID);
+ void unsubscribe1(int subscriberID);
+ void unsubscribeCallable(MessageID messageID, const py::object& callable);
+ int getNumSubscribers(MessageID messageID);
+ bool isSubscribed(MessageID messageID, int subscriberID);
+ bool isSubscribedCallable(MessageID messageID, const py::object& callable);
+
+ // The following methods should really be protected, but python derived classes need
+ // to call them too.
+ void publish(MessageID messageID);
+
+ void notifySubscribers(MessageID messageID);
+ void notifySubscribers(const std::string& sMsgName);
+ template<class ARG_TYPE>
+ void notifySubscribers(const std::string& sMsgName, const ARG_TYPE& arg);
+ void notifySubscribersPy(MessageID messageID, const py::list& args);
+
+ static MessageID genMessageID();
+
+protected:
+ void removeSubscribers();
+
+private:
+ typedef std::list<SubscriberInfoWeakPtr> WeakSubscriberInfoList;
+ typedef std::list<SubscriberInfoPtr> SubscriberInfoList;
+ typedef std::map<MessageID, SubscriberInfoList> SignalMap;
+
+ void unsubscribeIterator(MessageID messageID, SubscriberInfoList::iterator it);
+ SubscriberInfoList& safeFindSubscribers(MessageID messageID);
+ void throwSubscriberNotFound(MessageID messageID, int subscriberID);
+ void dumpSubscribers(MessageID messageID);
+
+ PublisherDefinitionPtr m_pPublisherDef;
+ SignalMap m_SignalMap;
+ static int s_LastSubscriberID;
+
+ typedef std::pair<MessageID, int> UnsubscribeDescription;
+};
+
+template<class ARG_TYPE>
+void Publisher::notifySubscribers(const std::string& sMsgName, const ARG_TYPE& arg)
+{
+ MessageID messageID = m_pPublisherDef->getMessageID(sMsgName);
+ SubscriberInfoList& subscribers = safeFindSubscribers(messageID);
+ if (!subscribers.empty()) {
+ py::list args;
+ py::object pyArg(arg);
+ args.append(pyArg);
+ notifySubscribersPy(messageID, args);
+ }
+}
+
+
+}
+
+#endif
+
diff --git a/src/player/PublisherDefinition.cpp b/src/player/PublisherDefinition.cpp
new file mode 100644
index 0000000..33fddf0
--- /dev/null
+++ b/src/player/PublisherDefinition.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PublisherDefinition.h"
+
+#include "PublisherDefinitionRegistry.h"
+
+#include "../base/Exception.h"
+
+using namespace std;
+
+namespace avg {
+
+PublisherDefinition::PublisherDefinition(const string& sName, const string& sBaseName)
+ : m_sName(sName)
+{
+ if (sBaseName != "") {
+ PublisherDefinitionPtr pBaseDef =
+ PublisherDefinitionRegistry::get()->getDefinition(sBaseName);
+ m_MessageIDs = pBaseDef->m_MessageIDs;
+ }
+}
+
+PublisherDefinition::~PublisherDefinition()
+{
+}
+
+PublisherDefinitionPtr PublisherDefinition::create(const std::string& sName,
+ const std::string& sBaseName)
+{
+ PublisherDefinitionPtr pDef(new PublisherDefinition(sName, sBaseName));
+ PublisherDefinitionRegistry::get()->registerDefinition(pDef);
+ return pDef;
+}
+
+void PublisherDefinition::addMessage(const std::string& sName)
+{
+ m_MessageIDs.push_back(PublisherDefinitionRegistry::get()->genMessageID(sName));
+}
+
+const MessageID& PublisherDefinition::getMessageID(const std::string& sName) const
+{
+ for (unsigned i=0; i<m_MessageIDs.size(); ++i) {
+ if (m_MessageIDs[i].m_sName == sName) {
+ return m_MessageIDs[i];
+ }
+ }
+ AVG_ASSERT_MSG(false, (string("Message named '")+sName+("' unknown.")).c_str());
+ // Avoid compiler warning.
+ static MessageID nullMsg("", -1);
+ return nullMsg;
+}
+
+const std::vector<MessageID>& PublisherDefinition::getMessageIDs() const
+{
+ return m_MessageIDs;
+}
+
+const std::string& PublisherDefinition::getName() const
+{
+ return m_sName;
+}
+
+void PublisherDefinition::dump() const
+{
+ cerr << m_sName << endl;
+ for (unsigned i=0; i<m_MessageIDs.size(); ++i) {
+ cerr << " " << m_MessageIDs[i].m_sName << ": " << m_MessageIDs[i].m_ID << endl;
+ }
+}
+
+}
diff --git a/src/player/PublisherDefinition.h b/src/player/PublisherDefinition.h
new file mode 100644
index 0000000..a8d5e7e
--- /dev/null
+++ b/src/player/PublisherDefinition.h
@@ -0,0 +1,62 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PublisherDefinition_H_
+#define _PublisherDefinition_H_
+
+#include "../api.h"
+
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class PublisherDefinition;
+typedef boost::shared_ptr<PublisherDefinition> PublisherDefinitionPtr;
+
+class AVG_API PublisherDefinition
+{
+public:
+ virtual ~PublisherDefinition();
+ static PublisherDefinitionPtr create(const std::string& sName,
+ const std::string& sBaseName="");
+
+ void addMessage(const std::string& sName);
+ const MessageID& getMessageID(const std::string& sName) const;
+ const std::vector<MessageID> & getMessageIDs() const;
+
+ const std::string& getName() const;
+ void dump() const;
+
+private:
+ PublisherDefinition(const std::string& sName, const std::string& sBaseName);
+
+ std::string m_sName;
+ std::vector<MessageID> m_MessageIDs;
+};
+
+}
+
+#endif
+
diff --git a/src/player/PublisherDefinitionRegistry.cpp b/src/player/PublisherDefinitionRegistry.cpp
new file mode 100644
index 0000000..3972a32
--- /dev/null
+++ b/src/player/PublisherDefinitionRegistry.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "PublisherDefinitionRegistry.h"
+
+#include "PublisherDefinition.h"
+
+#include "../base/Exception.h"
+
+using namespace std;
+
+
+namespace avg {
+
+PublisherDefinitionRegistry* PublisherDefinitionRegistry::s_pInstance = 0;
+
+PublisherDefinitionRegistry::PublisherDefinitionRegistry()
+ : m_LastMessageID(-1)
+{
+ s_pInstance = this;
+ // The following should really happen in the player constructor, but the entries
+ // need to exist for the player to be constructed.
+ PublisherDefinitionPtr pPlayerDef = PublisherDefinition::create("Player");
+ pPlayerDef->addMessage("KEY_DOWN");
+ pPlayerDef->addMessage("KEY_UP");
+ pPlayerDef->addMessage("PLAYBACK_START");
+ pPlayerDef->addMessage("PLAYBACK_END");
+ pPlayerDef->addMessage("ON_FRAME");
+}
+
+PublisherDefinitionRegistry::~PublisherDefinitionRegistry()
+{
+}
+
+PublisherDefinitionRegistry* PublisherDefinitionRegistry::get()
+{
+ if (!s_pInstance) {
+ new PublisherDefinitionRegistry();
+ }
+ return s_pInstance;
+}
+
+void PublisherDefinitionRegistry::registerDefinition(PublisherDefinitionPtr def)
+{
+ m_Definitions.push_back(def);
+}
+
+PublisherDefinitionPtr PublisherDefinitionRegistry::getDefinition(const string& sName)
+ const
+{
+ for (unsigned i=0; i<m_Definitions.size(); ++i) {
+ if (m_Definitions[i]->getName() == sName) {
+ return m_Definitions[i];
+ }
+ }
+ AVG_ASSERT_MSG(false, (string("Can't find PublisherDefinition ")+sName).c_str());
+ return PublisherDefinitionPtr();
+}
+
+void PublisherDefinitionRegistry::dump() const
+{
+ for (unsigned i=0; i<m_Definitions.size(); ++i) {
+ m_Definitions[i]->dump();
+ }
+}
+
+MessageID PublisherDefinitionRegistry::genMessageID(const string& sName)
+{
+ return MessageID(sName, ++m_LastMessageID);
+}
+
+}
diff --git a/src/player/PublisherDefinitionRegistry.h b/src/player/PublisherDefinitionRegistry.h
new file mode 100644
index 0000000..8d3acac
--- /dev/null
+++ b/src/player/PublisherDefinitionRegistry.h
@@ -0,0 +1,63 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _PublisherDefinitionRegistry_H_
+#define _PublisherDefinitionRegistry_H_
+
+#include "../api.h"
+
+#include "MessageID.h"
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace avg {
+
+class PublisherDefinition;
+typedef boost::shared_ptr<PublisherDefinition> PublisherDefinitionPtr;
+
+class AVG_API PublisherDefinitionRegistry
+{
+public:
+ static PublisherDefinitionRegistry* get();
+ virtual ~PublisherDefinitionRegistry();
+
+ void registerDefinition(PublisherDefinitionPtr def);
+ PublisherDefinitionPtr getDefinition(const std::string& sName) const;
+
+ void dump() const;
+
+ MessageID genMessageID(const std::string& sName="");
+
+private:
+ PublisherDefinitionRegistry();
+ std::vector<PublisherDefinitionPtr> m_Definitions;
+ int m_LastMessageID;
+
+ static PublisherDefinitionRegistry* s_pInstance;
+};
+
+}
+
+#endif
+
+
diff --git a/src/player/PythonLogSink.cpp b/src/player/PythonLogSink.cpp
new file mode 100644
index 0000000..5da5829
--- /dev/null
+++ b/src/player/PythonLogSink.cpp
@@ -0,0 +1,90 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "PythonLogSink.h"
+#include "WrapPython.h"
+#include "../base/Logger.h"
+
+#include <iostream>
+#include <boost/algorithm/string.hpp>
+#include <boost/python/errors.hpp>
+
+namespace avg
+{
+
+PythonLogSink::PythonLogSink(PyObject *pyLogger):
+ m_pyLogger(pyLogger)
+{
+ Py_INCREF(pyLogger);
+ assert(pyLogger);
+}
+
+PythonLogSink::~PythonLogSink()
+{
+ Py_DecRef(m_pyLogger);
+}
+
+const char * PythonLogSink::LogSeverityToPythonString(severity_t severity)
+{
+ if(severity == Logger::severity::CRITICAL) {
+ return "critical";
+ } else if(severity == Logger::severity::ERROR) {
+ return "error";
+ } else if(severity == Logger::severity::WARNING) {
+ return "warning";
+ } else if(severity == Logger::severity::INFO) {
+ return "info";
+ } else if(severity == Logger::severity::DEBUG) {
+ return "debug";
+ }
+ throw Exception(AVG_ERR_UNKNOWN, "Unkown log severity");
+}
+
+void PythonLogSink::logMessage(const tm* pTime, unsigned millis,
+ const category_t& category, severity_t severity, const UTF8String& sMsg)
+{
+ try {
+ aquirePyGIL aquireGil;
+ PyObject * extra = PyDict_New();
+ PyObject * pyCat = PyString_FromString(category.c_str());
+
+ PyDict_SetItemString(extra, "category", pyCat);
+
+ PyObject * pyMsg = PyString_FromString(sMsg.c_str());
+ PyObject * args = PyTuple_New(1);
+ PyObject * kwargs = PyDict_New();
+ PyDict_SetItemString(kwargs, "extra", extra);
+ PyTuple_SetItem(args, 0, pyMsg);
+
+ PyObject_Call(PyObject_GetAttrString(m_pyLogger,
+ LogSeverityToPythonString(severity)), args, kwargs);
+
+ Py_DECREF(extra);
+ Py_DECREF(pyCat);
+ Py_DECREF(args);
+ Py_DECREF(kwargs);
+ } catch (const boost::python::error_already_set &) {
+ std::cerr << "PythonLogSink: Python raised exception\n";
+ } catch (const exception &) {
+ std::cerr << "PythonLogSink: Couldn't log to python logger.\n";
+ }
+}
+
+}
diff --git a/src/player/PythonLogSink.h b/src/player/PythonLogSink.h
new file mode 100644
index 0000000..045eb4e
--- /dev/null
+++ b/src/player/PythonLogSink.h
@@ -0,0 +1,46 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#ifndef _PYTHONLOGHANDLER_H_
+#define _PYTHONLOGHANDLER_H_
+
+#include "../base/ILogSink.h"
+#include "../player/WrapPython.h"
+
+namespace avg
+{
+class PythonLogSink: public ILogSink
+{
+public:
+ PythonLogSink(PyObject *pyLogger);
+ virtual ~PythonLogSink ();
+
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg);
+
+private:
+
+ PyObject *m_pyLogger;
+ static const char * LogSeverityToPythonString(severity_t severity);
+};
+
+}
+
+#endif
diff --git a/src/player/RasterNode.cpp b/src/player/RasterNode.cpp
index 0bf304c..daace6b 100644
--- a/src/player/RasterNode.cpp
+++ b/src/player/RasterNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,11 +21,13 @@
#include "RasterNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "OGLSurface.h"
#include "FXNode.h"
#include "../graphics/ImagingProjection.h"
+#include "../graphics/ShaderRegistry.h"
+#include "../graphics/BitmapLoader.h"
#include "../base/MathHelper.h"
#include "../base/Logger.h"
@@ -37,10 +39,9 @@ using namespace std;
namespace avg {
-NodeDefinition RasterNode::createDefinition()
+void RasterNode::registerType()
{
- return NodeDefinition("rasternode")
- .extendDefinition(AreaNode::createDefinition())
+ TypeDefinition def = TypeDefinition("rasternode", "areanode")
.addArg(Arg<int>("maxtilewidth", -1, false,
offsetof(RasterNode, m_MaxTileSize.x)))
.addArg(Arg<int>("maxtileheight", -1, false,
@@ -49,24 +50,23 @@ NodeDefinition RasterNode::createDefinition()
offsetof(RasterNode, m_sBlendMode)))
.addArg(Arg<bool>("mipmap", false))
.addArg(Arg<UTF8String>("maskhref", "", false, offsetof(RasterNode, m_sMaskHref)))
- .addArg(Arg<DPoint>("maskpos", DPoint(0,0), false,
+ .addArg(Arg<glm::vec2>("maskpos", glm::vec2(0,0), false,
offsetof(RasterNode, m_MaskPos)))
- .addArg(Arg<DPoint>("masksize", DPoint(0,0), false,
+ .addArg(Arg<glm::vec2>("masksize", glm::vec2(0,0), false,
offsetof(RasterNode, m_MaskSize)))
- .addArg(Arg<DTriple>("gamma", DTriple(1.0,1.0,1.0), false,
+ .addArg(Arg<glm::vec3>("gamma", glm::vec3(1.0f,1.0f,1.0f), false,
offsetof(RasterNode, m_Gamma)))
- .addArg(Arg<DTriple>("contrast", DTriple(1.0,1.0,1.0), false,
+ .addArg(Arg<glm::vec3>("contrast", glm::vec3(1.0f,1.0f,1.0f), false,
offsetof(RasterNode, m_Contrast)))
- .addArg(Arg<DTriple>("intensity", DTriple(1.0,1.0,1.0), false,
+ .addArg(Arg<glm::vec3>("intensity", glm::vec3(1.0f,1.0f,1.0f), false,
offsetof(RasterNode, m_Intensity)));
+ TypeRegistry::get()->registerType(def);
}
RasterNode::RasterNode()
: m_pSurface(0),
m_Material(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false),
- m_bBound(false),
m_TileSize(-1,-1),
- m_pVertexes(0),
m_bFXDirty(true)
{
}
@@ -95,15 +95,12 @@ void RasterNode::setArgs(const ArgList& args)
void RasterNode::connectDisplay()
{
- checkMaskSupport(m_sMaskHref);
AreaNode::connectDisplay();
- m_pSurface->attach();
- m_bBound = false;
if (m_MaxTileSize != IntPoint(-1, -1)) {
m_TileSize = m_MaxTileSize;
}
- calcVertexGrid(m_TileVertices);
+ newSurface();
setBlendModeStr(m_sBlendMode);
if (m_pMaskBmp) {
downloadMask();
@@ -115,10 +112,6 @@ void RasterNode::connectDisplay()
void RasterNode::disconnect(bool bKill)
{
- if (m_pVertexes) {
- delete m_pVertexes;
- m_pVertexes = 0;
- }
if (m_pSurface) {
m_pSurface->destroy();
}
@@ -143,13 +136,9 @@ void RasterNode::checkReload()
m_sMaskFilename = sMaskFilename;
try {
if (m_sMaskFilename != "") {
- AVG_TRACE(Logger::MEMORY, "Loading " << m_sMaskFilename);
- m_pMaskBmp = BitmapPtr(new Bitmap(m_sMaskFilename));
- if (m_pMaskBmp->getPixelFormat() != I8) {
- BitmapPtr pTempBmp = m_pMaskBmp;
- m_pMaskBmp = BitmapPtr(new Bitmap(m_pMaskBmp->getSize(), I8));
- m_pMaskBmp->copyPixels(*pTempBmp);
- }
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO,
+ "Loading " << m_sMaskFilename);
+ m_pMaskBmp = loadBitmap(m_sMaskFilename, I8);
setMaskCoords();
}
} catch (Exception & ex) {
@@ -158,9 +147,9 @@ void RasterNode::checkReload()
}
m_sMaskFilename = "";
if (getState() != Node::NS_UNCONNECTED) {
- AVG_TRACE(Logger::ERROR, ex.getStr());
+ AVG_LOG_ERROR(ex.getStr());
} else {
- AVG_TRACE(Logger::MEMORY, ex.getStr());
+ AVG_TRACE(Logger::category::MEMORY, Logger::severity::ERROR, ex.getStr());
}
}
if (m_sMaskFilename == "") {
@@ -178,9 +167,6 @@ void RasterNode::checkReload()
VertexGrid RasterNode::getOrigVertexCoords()
{
checkDisplayAvailable("getOrigVertexCoords");
- if (!m_bBound) {
- bind();
- }
VertexGrid grid;
calcVertexGrid(grid);
return grid;
@@ -189,18 +175,12 @@ VertexGrid RasterNode::getOrigVertexCoords()
VertexGrid RasterNode::getWarpedVertexCoords()
{
checkDisplayAvailable("getWarpedVertexCoords");
- if (!m_bBound) {
- bind();
- }
return m_TileVertices;
}
void RasterNode::setWarpedVertexCoords(const VertexGrid& grid)
{
checkDisplayAvailable("setWarpedVertexCoords");
- if (!m_bBound) {
- bind();
- }
bool bGridOK = true;
IntPoint numTiles = getNumTiles();
if (grid.size() != (unsigned)(numTiles.y+1)) {
@@ -216,7 +196,6 @@ void RasterNode::setWarpedVertexCoords(const VertexGrid& grid)
"setWarpedVertexCoords() called with incorrect grid size.");
}
m_TileVertices = grid;
- m_bVertexArrayDirty = true;
}
int RasterNode::getMaxTileWidth() const
@@ -241,8 +220,15 @@ const std::string& RasterNode::getBlendModeStr() const
void RasterNode::setBlendModeStr(const string& sBlendMode)
{
+ GLContext::BlendMode blendMode = GLContext::stringToBlendMode(sBlendMode);
+ if (!GLContext::getMain()->isBlendModeSupported(blendMode)) {
+ m_sBlendMode = "blend";
+ m_BlendMode = GLContext::BLEND_BLEND;
+ throw Exception(AVG_ERR_UNSUPPORTED,
+ "Min and max blend modes are not supported in this OpenGL configuration.");
+ }
m_sBlendMode = sBlendMode;
- m_BlendMode = GLContext::stringToBlendMode(sBlendMode);
+ m_BlendMode = blendMode;
}
const UTF8String& RasterNode::getMaskHRef() const
@@ -252,36 +238,33 @@ const UTF8String& RasterNode::getMaskHRef() const
void RasterNode::setMaskHRef(const UTF8String& sHref)
{
- if (GLContext::getCurrent()) {
- checkMaskSupport(sHref);
- }
m_sMaskHref = sHref;
checkReload();
}
-const DPoint& RasterNode::getMaskPos() const
+const glm::vec2& RasterNode::getMaskPos() const
{
return m_MaskPos;
}
-void RasterNode::setMaskPos(const DPoint& pos)
+void RasterNode::setMaskPos(const glm::vec2& pos)
{
m_MaskPos = pos;
setMaskCoords();
}
-const DPoint& RasterNode::getMaskSize() const
+const glm::vec2& RasterNode::getMaskSize() const
{
return m_MaskSize;
}
-void RasterNode::setMaskSize(const DPoint& size)
+void RasterNode::setMaskSize(const glm::vec2& size)
{
m_MaskSize = size;
setMaskCoords();
}
-void RasterNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+void RasterNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
// Node isn't pickable if it's warped.
if (m_MaxTileSize == IntPoint(-1, -1)) {
@@ -289,12 +272,12 @@ void RasterNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pEleme
}
}
-DTriple RasterNode::getGamma() const
+glm::vec3 RasterNode::getGamma() const
{
return m_Gamma;
}
-void RasterNode::setGamma(const DTriple& gamma)
+void RasterNode::setGamma(const glm::vec3& gamma)
{
m_Gamma = gamma;
if (getState() == Node::NS_CANRENDER) {
@@ -302,12 +285,12 @@ void RasterNode::setGamma(const DTriple& gamma)
}
}
-DTriple RasterNode::getIntensity() const
+glm::vec3 RasterNode::getIntensity() const
{
return m_Intensity;
}
-void RasterNode::setIntensity(const DTriple& intensity)
+void RasterNode::setIntensity(const glm::vec3& intensity)
{
m_Intensity = intensity;
if (getState() == Node::NS_CANRENDER) {
@@ -315,12 +298,12 @@ void RasterNode::setIntensity(const DTriple& intensity)
}
}
-DTriple RasterNode::getContrast() const
+glm::vec3 RasterNode::getContrast() const
{
return m_Contrast;
}
-void RasterNode::setContrast(const DTriple& contrast)
+void RasterNode::setContrast(const glm::vec3& contrast)
{
m_Contrast = contrast;
if (getState() == Node::NS_CANRENDER) {
@@ -342,16 +325,35 @@ void RasterNode::setEffect(FXNodePtr pFXNode)
}
}
-void RasterNode::blt32(const DPoint& destSize, double opacity,
- GLContext::BlendMode mode, bool bPremultipliedAlpha)
+void RasterNode::calcVertexArray(const VertexArrayPtr& pVA, const Pixel32& color)
+{
+ if (isVisible() && m_pSurface->isCreated()) {
+ pVA->startSubVA(m_SubVA);
+ for (unsigned y = 0; y < m_TileVertices.size()-1; y++) {
+ for (unsigned x = 0; x < m_TileVertices[0].size()-1; x++) {
+ int curVertex = m_SubVA.getNumVerts();
+ m_SubVA.appendPos(m_TileVertices[y][x], m_TexCoords[y][x], color);
+ m_SubVA.appendPos(m_TileVertices[y][x+1], m_TexCoords[y][x+1], color);
+ m_SubVA.appendPos(m_TileVertices[y+1][x+1], m_TexCoords[y+1][x+1], color);
+ m_SubVA.appendPos(m_TileVertices[y+1][x], m_TexCoords[y+1][x], color);
+ m_SubVA.appendQuadIndexes(
+ curVertex+1, curVertex, curVertex+2, curVertex+3);
+ }
+ }
+ }
+}
+
+void RasterNode::blt32(const glm::mat4& transform, const glm::vec2& destSize,
+ float opacity, GLContext::BlendMode mode, bool bPremultipliedAlpha)
{
- blt(destSize, mode, opacity, Pixel32(255, 255, 255, 255), bPremultipliedAlpha);
+ blt(transform, destSize, mode, opacity, Pixel32(255, 255, 255, 255),
+ bPremultipliedAlpha);
}
-void RasterNode::blta8(const DPoint& destSize, double opacity,
- const Pixel32& color, GLContext::BlendMode mode)
+void RasterNode::blta8(const glm::mat4& transform, const glm::vec2& destSize,
+ float opacity, const Pixel32& color, GLContext::BlendMode mode)
{
- blt(destSize, mode, opacity, color, false);
+ blt(transform, destSize, mode, opacity, color, false);
}
GLContext::BlendMode RasterNode::getBlendMode() const
@@ -383,25 +385,17 @@ void RasterNode::setMaskCoords()
void RasterNode::calcMaskCoords()
{
- DPoint maskSize;
- DPoint mediaSize = DPoint(getMediaSize());
- if (m_MaskSize == DPoint(0,0)) {
- maskSize = DPoint(1,1);
+ glm::vec2 maskSize;
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ if (m_MaskSize == glm::vec2(0,0)) {
+ maskSize = glm::vec2(1,1);
} else {
- maskSize = DPoint(m_MaskSize.x/mediaSize.x, m_MaskSize.y/mediaSize.y);
+ maskSize = glm::vec2(m_MaskSize.x/mediaSize.x, m_MaskSize.y/mediaSize.y);
}
- DPoint maskPos = DPoint(m_MaskPos.x/mediaSize.x, m_MaskPos.y/mediaSize.y);
+ glm::vec2 maskPos = glm::vec2(m_MaskPos.x/mediaSize.x, m_MaskPos.y/mediaSize.y);
m_pSurface->setMaskCoords(maskPos, maskSize);
}
-void RasterNode::checkMaskSupport(const string& sHref)
-{
- if (!(GLContext::getCurrent()->isUsingShaders()) && sHref != "") {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "Can't use masks - unsupported on this hardware/driver combination.");
- }
-}
-
void RasterNode::downloadMask()
{
GLTexturePtr pTex(new GLTexture(m_pMaskBmp->getSize(), I8,
@@ -410,64 +404,45 @@ void RasterNode::downloadMask()
m_pSurface->setMask(pTex);
}
-void RasterNode::bind()
-{
- if (!m_bBound) {
- calcTexCoords();
- }
- m_bBound = true;
-}
-
static ProfilingZoneID FXProfilingZone("RasterNode::renderFX");
-void RasterNode::renderFX(const DPoint& destSize, const Pixel32& color,
- bool bPremultipliedAlpha)
+void RasterNode::renderFX(const glm::vec2& destSize, const Pixel32& color,
+ bool bPremultipliedAlpha, bool bForceRender)
{
- ScopeTimer Timer(FXProfilingZone);
setupFX(false);
- GLContext* pContext = GLContext::getCurrent();
- pContext->enableGLColorArray(false);
- pContext->enableTexture(true);
- if (m_pFXNode && (m_bFXDirty || m_pSurface->isDirty() || m_pFXNode->isDirty())) {
- if (!m_bBound) {
- bind();
- }
+ if (m_pFXNode && (m_bFXDirty || m_pSurface->isDirty() || m_pFXNode->isDirty() ||
+ bForceRender))
+ {
+ ScopeTimer Timer(FXProfilingZone);
+ GLContext* pContext = GLContext::getMain();
+ StandardShader::get()->setAlpha(1.0f);
m_pSurface->activate(getMediaSize());
m_pFBO->activate();
- clearGLBuffers(GL_COLOR_BUFFER_BIT);
+ clearGLBuffers(GL_COLOR_BUFFER_BIT, false);
- glColor4d(double(color.getR())/256, double(color.getG())/256,
- double(color.getB())/256, 1);
if (bPremultipliedAlpha) {
glproc::BlendColor(1.0f, 1.0f, 1.0f, 1.0f);
}
pContext->setBlendMode(GLContext::BLEND_BLEND, bPremultipliedAlpha);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
- m_pImagingProjection->activate();
- m_pImagingProjection->draw();
+ m_pImagingProjection->setColor(color);
+ m_pImagingProjection->draw(StandardShader::get()->getShader());
/*
static int i=0;
stringstream ss;
- ss << "foo" << i << ".png";
+ ss << "node" << i << ".png";
BitmapPtr pBmp = m_pFBO->getImage(0);
pBmp->save(ss.str());
- */
+*/
m_pFXNode->apply(m_pFBO->getTex());
- glPopMatrix();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "RasterNode::renderFX(): glPopMatrix");
/*
stringstream ss1;
- ss1 << "bar" << ".png";
+ ss1 << "nodefx" << i << ".png";
i++;
m_pFXNode->getImage()->save(ss1.str());
*/
- glproc::UseProgramObject(0);
m_bFXDirty = false;
m_pSurface->resetDirty();
m_pFXNode->resetDirty();
@@ -486,83 +461,71 @@ void RasterNode::checkDisplayAvailable(std::string sMsg)
}
}
+void RasterNode::newSurface()
+{
+ if (m_pSurface->isCreated()) {
+ calcVertexGrid(m_TileVertices);
+ calcTexCoords();
+ }
+}
+
void RasterNode::setupFX(bool bNewFX)
{
if (m_pSurface && m_pSurface->getSize() != IntPoint(-1, -1) && m_pFXNode) {
- if (!GLContext::getCurrent()->isUsingShaders()) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "Can't use FX - unsupported on this hardware/driver combination.");
- }
if (bNewFX || !m_pFBO || m_pFBO->getSize() != m_pSurface->getSize()) {
m_pFXNode->setSize(m_pSurface->getSize());
m_pFXNode->connect();
m_bFXDirty = true;
}
if (!m_pFBO || m_pFBO->getSize() != m_pSurface->getSize()) {
- m_pFBO = FBOPtr(new FBO(IntPoint(m_pSurface->getSize()), B8G8R8A8, 1, 1,
- false, getMipmap()));
+ PixelFormat pf = BitmapLoader::get()->getDefaultPixelFormat(true);
+ m_pFBO = FBOPtr(new FBO(IntPoint(m_pSurface->getSize()), pf, 1, 1, false,
+ getMipmap()));
GLTexturePtr pTex = m_pFBO->getTex();
+ #ifndef AVG_ENABLE_EGL
pTex->setWrapMode(GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER);
+ #endif
m_pImagingProjection = ImagingProjectionPtr(new ImagingProjection(
m_pSurface->getSize()));
}
}
}
-void RasterNode::blt(const DPoint& destSize, GLContext::BlendMode mode,
- double opacity, const Pixel32& color, bool bPremultipliedAlpha)
+void RasterNode::blt(const glm::mat4& transform, const glm::vec2& destSize,
+ GLContext::BlendMode mode, float opacity, const Pixel32& color,
+ bool bPremultipliedAlpha)
{
- if (!m_bBound) {
- bind();
- }
- GLContext* pContext = GLContext::getCurrent();
- pContext->enableGLColorArray(false);
- pContext->enableTexture(true);
- DRect destRect;
+ GLContext* pContext = GLContext::getMain();
+ FRect destRect;
+
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pContext->setBlendColor(glm::vec4(1.0f, 1.0f, 1.0f, opacity));
+ pShader->setAlpha(opacity);
if (m_pFXNode) {
- m_pFXNode->getTex()->activate(GL_TEXTURE0);
-
pContext->setBlendMode(mode, true);
- glColor4d(1.0, 1.0, 1.0, opacity);
- DRect relDestRect = m_pFXNode->getRelDestRect();
- destRect = DRect(relDestRect.tl.x*destSize.x, relDestRect.tl.y*destSize.y,
+ m_pFXNode->getTex()->activate(GL_TEXTURE0);
+ pShader->setColorModel(0);
+ pShader->disableColorspaceMatrix();
+ pShader->setGamma(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
+ pShader->setPremultipliedAlpha(true);
+ pShader->setMask(false);
+
+ FRect relDestRect = m_pFXNode->getRelDestRect();
+ destRect = FRect(relDestRect.tl.x*destSize.x, relDestRect.tl.y*destSize.y,
relDestRect.br.x*destSize.x, relDestRect.br.y*destSize.y);
} else {
m_pSurface->activate(getMediaSize(), bPremultipliedAlpha);
pContext->setBlendMode(mode, bPremultipliedAlpha);
- glColor4d(double(color.getR())/256, double(color.getG())/256,
- double(color.getB())/256, opacity);
- destRect = DRect(DPoint(0,0), destSize);
- }
- glproc::BlendColor(1.0f, 1.0f, 1.0f, float(opacity));
- glPushMatrix();
- glTranslated(destRect.tl.x, destRect.tl.y, 1);
- glScaled(destRect.size().x, destRect.size().y, 1);
-
- if (m_bVertexArrayDirty) {
- m_pVertexes->reset();
- for (unsigned y = 0; y < m_TileVertices.size()-1; y++) {
- for (unsigned x = 0; x < m_TileVertices[0].size()-1; x++) {
- int curVertex = m_pVertexes->getCurVert();
- m_pVertexes->appendPos(m_TileVertices[y][x], m_TexCoords[y][x]);
- m_pVertexes->appendPos(m_TileVertices[y][x+1], m_TexCoords[y][x+1]);
- m_pVertexes->appendPos(m_TileVertices[y+1][x+1], m_TexCoords[y+1][x+1]);
- m_pVertexes->appendPos(m_TileVertices[y+1][x], m_TexCoords[y+1][x]);
- m_pVertexes->appendQuadIndexes(
- curVertex+1, curVertex, curVertex+2, curVertex+3);
- }
- }
- m_bVertexArrayDirty = false;
+ destRect = FRect(glm::vec2(0,0), destSize);
}
+ glm::vec3 pos(destRect.tl.x, destRect.tl.y, 0);
+ glm::vec3 scaleVec(destRect.size().x, destRect.size().y, 1);
+ glm::mat4 localTransform = glm::translate(transform, pos);
+ localTransform = glm::scale(localTransform, scaleVec);
+ pShader->setTransform(localTransform);
+ pShader->activate();
- m_pVertexes->draw();
-
- glPopMatrix();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "RasterNode::blt(): glPopMatrix 2");
-
- PixelFormat pf = m_pSurface->getPixelFormat();
- AVG_TRACE(Logger::BLTS, "(" << destSize.x << ", " << destSize.y << ")"
- << ", m_pf: " << pf);
+ m_SubVA.draw();
}
IntPoint RasterNode::getNumTiles()
@@ -571,38 +534,33 @@ IntPoint RasterNode::getNumTiles()
if (m_TileSize.x == -1) {
return IntPoint(1,1);
} else {
- return IntPoint(safeCeil(double(size.x)/m_TileSize.x),
- safeCeil(double(size.y)/m_TileSize.y));
+ return IntPoint(safeCeil(float(size.x)/m_TileSize.x),
+ safeCeil(float(size.y)/m_TileSize.y));
}
}
void RasterNode::calcVertexGrid(VertexGrid& grid)
{
IntPoint numTiles = getNumTiles();
- std::vector<DPoint> TileVerticesLine(numTiles.x+1);
- grid = std::vector<std::vector<DPoint> > (numTiles.y+1, TileVerticesLine);
+ std::vector<glm::vec2> TileVerticesLine(numTiles.x+1);
+ grid = std::vector<std::vector<glm::vec2> > (numTiles.y+1, TileVerticesLine);
for (unsigned y = 0; y < grid.size(); y++) {
for (unsigned x = 0; x < grid[y].size(); x++) {
calcTileVertex(x, y, grid[y][x]);
}
}
- if (m_pVertexes) {
- delete m_pVertexes;
- }
- m_bVertexArrayDirty = true;
- m_pVertexes = new VertexArray(numTiles.x*numTiles.y*4, numTiles.x*numTiles.y*6);
}
-void RasterNode::calcTileVertex(int x, int y, DPoint& Vertex)
+void RasterNode::calcTileVertex(int x, int y, glm::vec2& Vertex)
{
IntPoint numTiles = getNumTiles();
if (x < numTiles.x) {
- Vertex.x = double(m_TileSize.x*x) / m_pSurface->getSize().x;
+ Vertex.x = float(m_TileSize.x*x) / m_pSurface->getSize().x;
} else {
Vertex.x = 1;
}
if (y < numTiles.y) {
- Vertex.y = double(m_TileSize.y*y) / m_pSurface->getSize().y;
+ Vertex.y = float(m_TileSize.y*y) / m_pSurface->getSize().y;
} else {
Vertex.y = 1;
}
@@ -610,22 +568,22 @@ void RasterNode::calcTileVertex(int x, int y, DPoint& Vertex)
void RasterNode::calcTexCoords()
{
- DPoint textureSize = DPoint(m_pSurface->getTextureSize());
- DPoint imageSize = DPoint(m_pSurface->getSize());
- DPoint texCoordExtents = DPoint(imageSize.x/textureSize.x,
+ glm::vec2 textureSize = glm::vec2(m_pSurface->getTextureSize());
+ glm::vec2 imageSize = glm::vec2(m_pSurface->getSize());
+ glm::vec2 texCoordExtents = glm::vec2(imageSize.x/textureSize.x,
imageSize.y/textureSize.y);
- DPoint texSizePerTile;
+ glm::vec2 texSizePerTile;
if (m_TileSize.x == -1) {
texSizePerTile = texCoordExtents;
} else {
- texSizePerTile = DPoint(double(m_TileSize.x)/imageSize.x*texCoordExtents.x,
- double(m_TileSize.y)/imageSize.y*texCoordExtents.y);
+ texSizePerTile = glm::vec2(float(m_TileSize.x)/imageSize.x*texCoordExtents.x,
+ float(m_TileSize.y)/imageSize.y*texCoordExtents.y);
}
IntPoint numTiles = getNumTiles();
- vector<DPoint> texCoordLine(numTiles.x+1);
- m_TexCoords = std::vector<std::vector<DPoint> >
+ vector<glm::vec2> texCoordLine(numTiles.x+1);
+ m_TexCoords = std::vector<std::vector<glm::vec2> >
(numTiles.y+1, texCoordLine);
for (unsigned y = 0; y < m_TexCoords.size(); y++) {
for (unsigned x = 0; x < m_TexCoords[y].size(); x++) {
@@ -641,6 +599,5 @@ void RasterNode::calcTexCoords()
}
}
}
- m_bVertexArrayDirty = true;
}
}
diff --git a/src/player/RasterNode.h b/src/player/RasterNode.h
index 92d9ac4..1e86e17 100644
--- a/src/player/RasterNode.h
+++ b/src/player/RasterNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,10 +27,10 @@
#include "MaterialInfo.h"
#include "../avgconfigwrapper.h"
-#include "../base/Point.h"
-#include "../base/Triple.h"
+#include "../base/GLMHelper.h"
#include "../base/UTF8String.h"
#include "../graphics/GLContext.h"
+#include "../graphics/SubVertexArray.h"
#include <string>
@@ -46,19 +46,19 @@ typedef boost::shared_ptr<GLTexture> GLTexturePtr;
class FXNode;
typedef boost::shared_ptr<FXNode> FXNodePtr;
-typedef std::vector<std::vector<DPoint> > VertexGrid;
+typedef std::vector<std::vector<glm::vec2> > VertexGrid;
class AVG_API RasterNode: public AreaNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
virtual ~RasterNode ();
virtual void connectDisplay();
virtual void setArgs(const ArgList& args);
virtual void disconnect(bool bKill);
virtual void checkReload();
-
+
// Warping support.
VertexGrid getOrigVertexCoords();
VertexGrid getWarpedVertexCoords();
@@ -75,50 +75,55 @@ class AVG_API RasterNode: public AreaNode
const UTF8String& getMaskHRef() const;
void setMaskHRef(const UTF8String& sHref);
- const DPoint& getMaskPos() const;
- void setMaskPos(const DPoint& pos);
+ const glm::vec2& getMaskPos() const;
+ void setMaskPos(const glm::vec2& pos);
- const DPoint& getMaskSize() const;
- void setMaskSize(const DPoint& size);
+ const glm::vec2& getMaskSize() const;
+ void setMaskSize(const glm::vec2& size);
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
- DTriple getGamma() const;
- void setGamma(const DTriple& gamma);
- DTriple getIntensity() const;
- void setIntensity(const DTriple& intensity);
- DTriple getContrast() const;
- void setContrast(const DTriple& contrast);
+ glm::vec3 getGamma() const;
+ void setGamma(const glm::vec3& gamma);
+ glm::vec3 getIntensity() const;
+ void setIntensity(const glm::vec3& intensity);
+ glm::vec3 getContrast() const;
+ void setContrast(const glm::vec3& contrast);
void setEffect(FXNodePtr pFXNode);
protected:
RasterNode();
- void blt32(const DPoint& destSize, double opacity, GLContext::BlendMode mode,
- bool bPremultipliedAlpha = false);
- void blta8(const DPoint& destSize, double opacity,
+
+ void calcVertexArray(const VertexArrayPtr& pVA,
+ const Pixel32& color = Pixel32(0,0,0,0));
+ void blt32(const glm::mat4& transform, const glm::vec2& destSize, float opacity,
+ GLContext::BlendMode mode, bool bPremultipliedAlpha = false);
+ void blta8(const glm::mat4& transform, const glm::vec2& destSize, float opacity,
const Pixel32& color, GLContext::BlendMode mode);
virtual OGLSurface * getSurface();
const MaterialInfo& getMaterial() const;
bool hasMask() const;
void setMaskCoords();
- void bind();
- void renderFX(const DPoint& destSize, const Pixel32& color,
- bool bPremultipliedAlpha);
+ void renderFX(const glm::vec2& destSize, const Pixel32& color,
+ bool bPremultipliedAlpha, bool bForceRender=false);
+
+ protected:
+ void newSurface();
+ void setupFX(bool bNewFX);
private:
void downloadMask();
virtual void calcMaskCoords();
- void checkMaskSupport(const std::string& sHref);
void checkDisplayAvailable(std::string sMsg);
- void setupFX(bool bNewFX);
- void blt(const DPoint& destSize, GLContext::BlendMode mode,
- double opacity, const Pixel32& color, bool bPremultipliedAlpha);
+ void blt(const glm::mat4& transform, const glm::vec2& destSize,
+ GLContext::BlendMode mode, float opacity, const Pixel32& color,
+ bool bPremultipliedAlpha);
IntPoint getNumTiles();
void calcVertexGrid(VertexGrid& grid);
- void calcTileVertex(int x, int y, DPoint& Vertex);
+ void calcTileVertex(int x, int y, glm::vec2& Vertex);
void calcTexCoords();
OGLSurface * m_pSurface;
@@ -131,20 +136,17 @@ class AVG_API RasterNode: public AreaNode
UTF8String m_sMaskHref;
std::string m_sMaskFilename;
BitmapPtr m_pMaskBmp;
- DPoint m_MaskPos;
- DPoint m_MaskSize;
+ glm::vec2 m_MaskPos;
+ glm::vec2 m_MaskSize;
- bool m_bBound;
-
IntPoint m_TileSize;
VertexGrid m_TileVertices;
- bool m_bVertexArrayDirty;
- VertexArray * m_pVertexes;
- std::vector<std::vector<DPoint> > m_TexCoords;
+ SubVertexArray m_SubVA;
+ std::vector<std::vector<glm::vec2> > m_TexCoords;
- DTriple m_Gamma;
- DTriple m_Intensity;
- DTriple m_Contrast;
+ glm::vec3 m_Gamma;
+ glm::vec3 m_Intensity;
+ glm::vec3 m_Contrast;
FBOPtr m_pFBO;
FXNodePtr m_pFXNode;
diff --git a/src/player/RectNode.cpp b/src/player/RectNode.cpp
index d7387df..980a957 100644
--- a/src/player/RectNode.cpp
+++ b/src/player/RectNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "RectNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
@@ -34,63 +34,66 @@ using namespace std;
namespace avg {
-NodeDefinition RectNode::createDefinition()
+void RectNode::registerType()
{
- double texCoords[] = {0, 0.25, 0.5, 0.75, 1};
- return NodeDefinition("rect", Node::buildNode<RectNode>)
- .extendDefinition(FilledVectorNode::createDefinition())
- .addArg(Arg<DPoint>("pos", DPoint(0,0), false, offsetof(RectNode, m_Rect.tl)))
- .addArg(Arg<DPoint>("size", DPoint(0,0)))
- .addArg(Arg<double>("angle", 0.0, false, offsetof(RectNode, m_Angle)))
- .addArg(Arg<vector<double> >("texcoords", vectorFromCArray(5, texCoords), false,
+ float texCoords[] = {0, 0.25f, 0.5f, 0.75f, 1};
+ TypeDefinition def = TypeDefinition("rect", "filledvectornode",
+ ExportedObject::buildObject<RectNode>)
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0,0), false,
+ offsetof(RectNode, m_Rect.tl)))
+ .addArg(Arg<glm::vec2>("size", glm::vec2(0,0)))
+ .addArg(Arg<float>("angle", 0.0f, false, offsetof(RectNode, m_Angle)))
+ .addArg(Arg<vector<float> >("texcoords", vectorFromCArray(5, texCoords), false,
offsetof(RectNode, m_TexCoords)))
;
+ TypeRegistry::get()->registerType(def);
}
RectNode::RectNode(const ArgList& args)
: FilledVectorNode(args)
{
args.setMembers(this);
- setSize(args.getArgVal<DPoint>("size"));
+ setSize(args.getArgVal<glm::vec2>("size"));
}
RectNode::~RectNode()
{
}
-const DPoint& RectNode::getPos() const
+const glm::vec2& RectNode::getPos() const
{
return m_Rect.tl;
}
-void RectNode::setPos(const DPoint& pt)
+void RectNode::setPos(const glm::vec2& pt)
{
- double w = m_Rect.width();
- double h = m_Rect.height();
+ float w = m_Rect.width();
+ float h = m_Rect.height();
m_Rect.tl = pt;
m_Rect.setWidth(w);
m_Rect.setHeight(h);
setDrawNeeded();
}
-DPoint RectNode::getSize() const
+glm::vec2 RectNode::getSize() const
{
return m_Rect.size();
}
-void RectNode::setSize(const DPoint& pt)
+void RectNode::setSize(const glm::vec2& pt)
{
m_Rect.setWidth(pt.x);
m_Rect.setHeight(pt.y);
+ notifySubscribers("SIZE_CHANGED", m_Rect.size());
setDrawNeeded();
}
-const vector<double>& RectNode::getTexCoords() const
+const vector<float>& RectNode::getTexCoords() const
{
return m_TexCoords;
}
-void RectNode::setTexCoords(const vector<double>& coords)
+void RectNode::setTexCoords(const vector<float>& coords)
{
if (coords.size() != 5) {
throw(Exception(AVG_ERR_OUT_OF_RANGE,
@@ -100,64 +103,76 @@ void RectNode::setTexCoords(const vector<double>& coords)
setDrawNeeded();
}
-double RectNode::getAngle() const
+float RectNode::getAngle() const
{
return m_Angle;
}
-void RectNode::setAngle(double angle)
+void RectNode::setAngle(float angle)
{
- m_Angle = fmod(angle, 2*M_PI);
+ m_Angle = fmod(angle, 2*PI);
setDrawNeeded();
}
-void RectNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+glm::vec2 RectNode::toLocal(const glm::vec2& globalPos) const
{
- DPoint pivot = m_Rect.tl+m_Rect.size()/2;
- DPoint rpos = pos.getRotatedPivot(m_Angle, pivot);
- if (rpos.x >= m_Rect.tl.x && rpos.y >= m_Rect.tl.y && rpos.x < m_Rect.br.x &&
- rpos.y < m_Rect.br.y && reactsToMouseEvents())
+ glm::vec2 localPos = globalPos - m_Rect.tl;
+ glm::vec2 pivot = m_Rect.size()/2.f;
+ return getRotatedPivot(localPos, -m_Angle, pivot);
+}
+
+glm::vec2 RectNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 pivot = m_Rect.tl + m_Rect.size()/2.f;
+ glm::vec2 globalPos = getRotatedPivot(localPos, m_Angle, pivot);
+ return globalPos + m_Rect.tl;
+}
+
+void RectNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (pos.x >= 0 && pos.y >= 0 && pos.x < m_Rect.size().x && pos.y < m_Rect.size().y
+ && reactsToMouseEvents())
{
- pElements.push_back(shared_from_this());
+ pElements.push_back(getSharedThis());
}
}
-void RectNode::calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
+void RectNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
{
- DPoint pivot = m_Rect.tl+m_Rect.size()/2;
+ glm::vec2 pivot = m_Rect.tl+m_Rect.size()/2.f;
- DPoint p1 = m_Rect.tl;
- DPoint p2(m_Rect.tl.x, m_Rect.br.y);
- DPoint p3 = m_Rect.br;
- DPoint p4(m_Rect.br.x, m_Rect.tl.y);
+ glm::vec2 p1 = m_Rect.tl;
+ glm::vec2 p2(m_Rect.tl.x, m_Rect.br.y);
+ glm::vec2 p3 = m_Rect.br;
+ glm::vec2 p4(m_Rect.br.x, m_Rect.tl.y);
- vector<DPoint> pts;
- pts.push_back(p1.getRotatedPivot(m_Angle, pivot));
- pts.push_back(p2.getRotatedPivot(m_Angle, pivot));
- pts.push_back(p3.getRotatedPivot(m_Angle, pivot));
- pts.push_back(p4.getRotatedPivot(m_Angle, pivot));
- calcPolyLine(pts, m_TexCoords, true, LJ_MITER, pVertexArray, color);
-}
-
-void RectNode::calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color)
-{
- DPoint pivot = m_Rect.tl+m_Rect.size()/2;
-
- DPoint p1 = m_Rect.tl;
- DPoint p2(m_Rect.tl.x, m_Rect.br.y);
- DPoint p3 = m_Rect.br;
- DPoint p4(m_Rect.br.x, m_Rect.tl.y);
- DPoint rp1 = p1.getRotatedPivot(m_Angle, pivot);
- DPoint rp2 = p2.getRotatedPivot(m_Angle, pivot);
- DPoint rp3 = p3.getRotatedPivot(m_Angle, pivot);
- DPoint rp4 = p4.getRotatedPivot(m_Angle, pivot);
- pVertexArray->appendPos(rp1, getFillTexCoord1(), color);
- DPoint blTexCoord = DPoint(getFillTexCoord1().x, getFillTexCoord2().y);
- pVertexArray->appendPos(rp2, blTexCoord, color);
- pVertexArray->appendPos(rp3, getFillTexCoord2(), color);
- DPoint trTexCoord = DPoint(getFillTexCoord2().x, getFillTexCoord1().y);
- pVertexArray->appendPos(rp4, trTexCoord, color);
- pVertexArray->appendQuadIndexes(1, 0, 2, 3);
+ vector<glm::vec2> pts;
+ pts.push_back(getRotatedPivot(p1, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p2, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p3, m_Angle, pivot));
+ pts.push_back(getRotatedPivot(p4, m_Angle, pivot));
+ calcPolyLine(pts, m_TexCoords, true, LJ_MITER, pVertexData, color);
+}
+
+void RectNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color)
+{
+ glm::vec2 pivot = m_Rect.tl+m_Rect.size()/2.f;
+
+ glm::vec2 p1 = m_Rect.tl;
+ glm::vec2 p2(m_Rect.tl.x, m_Rect.br.y);
+ glm::vec2 p3 = m_Rect.br;
+ glm::vec2 p4(m_Rect.br.x, m_Rect.tl.y);
+ glm::vec2 rp1 = getRotatedPivot(p1, m_Angle, pivot);
+ glm::vec2 rp2 = getRotatedPivot(p2, m_Angle, pivot);
+ glm::vec2 rp3 = getRotatedPivot(p3, m_Angle, pivot);
+ glm::vec2 rp4 = getRotatedPivot(p4, m_Angle, pivot);
+ pVertexData->appendPos(rp1, getFillTexCoord1(), color);
+ glm::vec2 blTexCoord = glm::vec2(getFillTexCoord1().x, getFillTexCoord2().y);
+ pVertexData->appendPos(rp2, blTexCoord, color);
+ pVertexData->appendPos(rp3, getFillTexCoord2(), color);
+ glm::vec2 trTexCoord = glm::vec2(getFillTexCoord2().x, getFillTexCoord1().y);
+ pVertexData->appendPos(rp4, trTexCoord, color);
+ pVertexData->appendQuadIndexes(1, 0, 2, 3);
}
}
diff --git a/src/player/RectNode.h b/src/player/RectNode.h
index 842bf35..f1a3c4e 100644
--- a/src/player/RectNode.h
+++ b/src/player/RectNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,33 +32,35 @@ namespace avg {
class AVG_API RectNode : public FilledVectorNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
RectNode(const ArgList& args);
virtual ~RectNode();
- const DPoint& getPos() const;
- void setPos(const DPoint& pt);
+ const glm::vec2& getPos() const;
+ void setPos(const glm::vec2& pt);
- DPoint getSize() const;
- void setSize(const DPoint& pt);
+ glm::vec2 getSize() const;
+ void setSize(const glm::vec2& pt);
- const std::vector<double>& getTexCoords() const;
- void setTexCoords(const std::vector<double>& coords);
+ const std::vector<float>& getTexCoords() const;
+ void setTexCoords(const std::vector<float>& coords);
- double getAngle() const;
- void setAngle(double angle);
+ float getAngle() const;
+ void setAngle(float angle);
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
+ glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ glm::vec2 toGlobal(const glm::vec2& localPos) const;
+ void getElementsByPos(const glm::vec2& pos, std::vector<NodePtr>& pElements);
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
- virtual void calcFillVertexes(VertexArrayPtr& pVertexArray, Pixel32 color);
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
+ virtual void calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color);
private:
- DRect m_Rect;
- std::vector<double> m_TexCoords;
+ FRect m_Rect;
+ std::vector<float> m_TexCoords;
- double m_Angle;
+ float m_Angle;
};
}
diff --git a/src/player/SDLDisplayEngine.cpp b/src/player/SDLDisplayEngine.cpp
index 0b6293f..74a3698 100644
--- a/src/player/SDLDisplayEngine.cpp
+++ b/src/player/SDLDisplayEngine.cpp
@@ -1,6 +1,6 @@
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -45,20 +45,19 @@
#include "../graphics/GLContext.h"
#include "../graphics/Filterflip.h"
#include "../graphics/Filterfliprgb.h"
-#include "../graphics/ShaderRegistry.h"
+#include "../graphics/Display.h"
+
+#include "../video/VideoDecoder.h"
#include "OGLSurface.h"
#include "OffscreenCanvas.h"
-#include <SDL/SDL.h>
-
#ifdef __APPLE__
#include <ApplicationServices/ApplicationServices.h>
#endif
-#ifdef linux
+
+#include <SDL/SDL.h>
#include <SDL/SDL_syswm.h>
-#include <X11/extensions/xf86vmode.h>
-#endif
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
@@ -68,6 +67,9 @@
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#endif
+#ifdef AVG_ENABLE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
#include <signal.h>
#include <iostream>
@@ -84,39 +86,43 @@ using namespace std;
namespace avg {
-double SDLDisplayEngine::s_RefreshRate = 0.0;
-
-void safeSetAttribute(SDL_GLattr attr, int value)
+void SDLDisplayEngine::initSDL()
{
- int err = SDL_GL_SetAttribute(attr, value);
+#ifdef __APPLE__
+ static bool bSDLInitialized = false;
+ if (!bSDLInitialized) {
+ CustomSDLMain();
+ bSDLInitialized = true;
+ }
+#endif
+#ifdef linux
+ // Disable all other video drivers (DirectFB, libcaca, ...) to avoid confusing
+ // error messages.
+ SDL_putenv((char*)"SDL_VIDEODRIVER=x11");
+#endif
+ int err = SDL_InitSubSystem(SDL_INIT_VIDEO);
if (err == -1) {
- throw Exception(AVG_ERR_VIDEO_GENERAL, SDL_GetError());
+ throw Exception(AVG_ERR_VIDEO_INIT_FAILED, SDL_GetError());
}
}
+void SDLDisplayEngine::quitSDL()
+{
+#ifndef _WIN32
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+#endif
+}
+
SDLDisplayEngine::SDLDisplayEngine()
: IInputDevice(EXTRACT_INPUTDEVICE_CLASSNAME(SDLDisplayEngine)),
m_WindowSize(0,0),
- m_PPMM(0),
m_pScreen(0),
- m_VBMethod(VB_NONE),
- m_VBMod(0),
- m_bMouseOverApp(true),
- m_pLastMouseEvent(new MouseEvent(Event::CURSORMOTION, false, false, false,
- IntPoint(-1, -1), MouseEvent::NO_BUTTON, DPoint(-1, -1), 0)),
- m_NumMouseButtonsDown(0)
+ m_pLastMouseEvent(new MouseEvent(Event::CURSOR_MOTION, false, false, false,
+ IntPoint(-1, -1), MouseEvent::NO_BUTTON, glm::vec2(-1, -1), 0)),
+ m_pGLContext(0)
{
-#ifdef __APPLE__
- static bool bSDLInitialized = false;
- if (!bSDLInitialized) {
- CustomSDLMain();
- bSDLInitialized = true;
- }
-#endif
- if (SDL_InitSubSystem(SDL_INIT_VIDEO)==-1) {
- AVG_TRACE(Logger::ERROR, "Can't init SDL display subsystem.");
- exit(-1);
- }
+ initSDL();
+
m_Gamma[0] = 1.0;
m_Gamma[1] = 1.0;
m_Gamma[2] = 1.0;
@@ -125,144 +131,102 @@ SDLDisplayEngine::SDLDisplayEngine()
SDLDisplayEngine::~SDLDisplayEngine()
{
-#ifndef _WIN32
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
-#endif
}
void SDLDisplayEngine::init(const DisplayParams& dp, GLConfig glConfig)
{
- calcScreenDimensions(dp.m_DotsPerMM);
+ // This "fixes" the default behaviour of SDL under x11, avoiding it
+ // to report relative mouse coordinates when going fullscreen and
+ // the mouse cursor is hidden (grabbed). So far libavg and apps based
+ // on it don't use relative coordinates.
+ setEnv("SDL_MOUSE_RELATIVE", "0");
+
+ if (m_Gamma[0] != 1.0f || m_Gamma[1] != 1.0f || m_Gamma[2] != 1.0f) {
+ internalSetGamma(1.0f, 1.0f, 1.0f);
+ }
stringstream ss;
if (dp.m_Pos.x != -1) {
ss << dp.m_Pos.x << "," << dp.m_Pos.y;
setEnv("SDL_VIDEO_WINDOW_POS", ss.str().c_str());
}
-#ifdef linux
- IntPoint oldWindowSize = m_WindowSize;
-#endif
- double aspectRatio = double(dp.m_Size.x)/double(dp.m_Size.y);
- if (dp.m_WindowSize == IntPoint(0, 0)) {
- m_WindowSize = dp.m_Size;
- } else if (dp.m_WindowSize.x == 0) {
- m_WindowSize.x = int(dp.m_WindowSize.y*aspectRatio);
- m_WindowSize.y = dp.m_WindowSize.y;
- } else {
- m_WindowSize.x = dp.m_WindowSize.x;
- m_WindowSize.y = int(dp.m_WindowSize.x/aspectRatio);
+ m_WindowSize = dp.m_WindowSize;
+ unsigned int Flags = 0;
+ if (dp.m_bFullscreen) {
+ Flags |= SDL_FULLSCREEN;
}
+ m_bIsFullscreen = dp.m_bFullscreen;
+ if (!dp.m_bHasWindowFrame) {
+ Flags |= SDL_NOFRAME;
+ }
+
+#ifndef linux
+ if (glConfig.m_bUseDebugContext) {
+ glConfig.m_bUseDebugContext = false;
+ }
switch (dp.m_BPP) {
- case 32:
- safeSetAttribute(SDL_GL_RED_SIZE, 8);
- safeSetAttribute(SDL_GL_GREEN_SIZE, 8);
- safeSetAttribute(SDL_GL_BLUE_SIZE, 8);
- safeSetAttribute(SDL_GL_BUFFER_SIZE, 32);
- break;
case 24:
- safeSetAttribute(SDL_GL_RED_SIZE, 8);
- safeSetAttribute(SDL_GL_GREEN_SIZE, 8);
- safeSetAttribute(SDL_GL_BLUE_SIZE, 8);
- safeSetAttribute(SDL_GL_BUFFER_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24);
break;
case 16:
- safeSetAttribute(SDL_GL_RED_SIZE, 5);
- safeSetAttribute(SDL_GL_GREEN_SIZE, 6);
- safeSetAttribute(SDL_GL_BLUE_SIZE, 5);
- safeSetAttribute(SDL_GL_BUFFER_SIZE, 16);
- break;
- case 15:
- safeSetAttribute(SDL_GL_RED_SIZE, 5);
- safeSetAttribute(SDL_GL_GREEN_SIZE, 5);
- safeSetAttribute(SDL_GL_BLUE_SIZE, 5);
- safeSetAttribute(SDL_GL_BUFFER_SIZE, 15);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);
break;
default:
- AVG_TRACE(Logger::ERROR, "Unsupported bpp " << dp.m_BPP <<
+ AVG_LOG_ERROR("Unsupported bpp " << dp.m_BPP <<
"in SDLDisplayEngine::init()");
exit(-1);
}
- safeSetAttribute(SDL_GL_DEPTH_SIZE, 24);
- safeSetAttribute(SDL_GL_STENCIL_SIZE, 8);
- safeSetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL , 0);
+ Flags |= SDL_OPENGL;
- unsigned int Flags = SDL_OPENGL;
- if (dp.m_bFullscreen) {
- Flags |= SDL_FULLSCREEN;
- }
- m_bIsFullscreen = dp.m_bFullscreen;
-
- if (!dp.m_bHasWindowFrame) {
- Flags |= SDL_NOFRAME;
- }
-
- bool bAllMultisampleValuesTested = false;
m_pScreen = 0;
- while (!bAllMultisampleValuesTested && !m_pScreen) {
+ while (glConfig.m_MultiSampleSamples && !m_pScreen) {
if (glConfig.m_MultiSampleSamples > 1) {
- safeSetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
- safeSetAttribute(SDL_GL_MULTISAMPLESAMPLES, glConfig.m_MultiSampleSamples);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
+ glConfig.m_MultiSampleSamples);
} else {
- safeSetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
- safeSetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
m_pScreen = SDL_SetVideoMode(m_WindowSize.x, m_WindowSize.y, dp.m_BPP, Flags);
if (!m_pScreen) {
- switch (glConfig.m_MultiSampleSamples) {
- case 1:
- bAllMultisampleValuesTested = true;
- break;
- case 2:
- glConfig.m_MultiSampleSamples = 1;
- break;
- case 4:
- glConfig.m_MultiSampleSamples = 2;
- break;
- case 8:
- glConfig.m_MultiSampleSamples = 4;
- break;
- default:
- glConfig.m_MultiSampleSamples = 8;
- break;
- }
+ glConfig.m_MultiSampleSamples = GLContext::nextMultiSampleValue(
+ glConfig.m_MultiSampleSamples);
}
}
+#else
+ // Linux version: Context created manually, not by SDL
+ m_pScreen = SDL_SetVideoMode(m_WindowSize.x, m_WindowSize.y, dp.m_BPP, Flags);
+#endif
if (!m_pScreen) {
throw Exception(AVG_ERR_UNSUPPORTED, string("Setting SDL video mode failed: ")
+ SDL_GetError() + ". (size=" + toString(m_WindowSize) + ", bpp=" +
- toString(dp.m_BPP) + ", multisamplesamples=" +
- toString(glConfig.m_MultiSampleSamples) + ").");
+ toString(dp.m_BPP) + ").");
}
- m_pGLContext = GLContextPtr(new GLContext(true, glConfig));
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ int rc = SDL_GetWMInfo(&info);
+ AVG_ASSERT(rc != -1);
+ m_pGLContext = GLContext::create(glConfig, m_WindowSize, &info);
+ GLContext::setMain(m_pGLContext);
#if defined(HAVE_XI2_1) || defined(HAVE_XI2_2)
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
m_pXIMTInputDevice = 0;
#endif
SDL_WM_SetCaption("libavg", 0);
- calcRefreshRate();
+ Display::get()->getRefreshRate();
- glEnable(GL_BLEND);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "init: glEnable(GL_BLEND)");
- glShadeModel(GL_FLAT);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "init: glShadeModel(GL_FLAT)");
- glDisable(GL_DEPTH_TEST);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "init: glDisable(GL_DEPTH_TEST)");
- glEnable(GL_STENCIL_TEST);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "init: glEnable(GL_STENCIL_TEST)");
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "init: glTexEnvf()");
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- if (!queryOGLExtension("GL_ARB_vertex_buffer_object")) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "Graphics driver lacks vertex buffer support, unable to initialize graphics.");
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
setGamma(dp.m_Gamma[0], dp.m_Gamma[1], dp.m_Gamma[2]);
showCursor(dp.m_bShowCursor);
if (dp.m_Framerate == 0) {
@@ -275,11 +239,31 @@ void SDLDisplayEngine::init(const DisplayParams& dp, GLConfig glConfig)
// SDL sets up a signal handler we really don't want.
signal(SIGSEGV, SIG_DFL);
m_pGLContext->logConfig();
+ VideoDecoder::logConfig();
SDL_EnableUNICODE(1);
- if (m_pGLContext->isUsingShaders()) {
- OGLSurface::createShader();
+}
+
+IntPoint SDLDisplayEngine::calcWindowSize(const DisplayParams& dp) const
+{
+ float aspectRatio = float(dp.m_Size.x)/float(dp.m_Size.y);
+ IntPoint windowSize;
+ if (dp.m_WindowSize == IntPoint(0, 0)) {
+ windowSize = dp.m_Size;
+ } else if (dp.m_WindowSize.x == 0) {
+ windowSize.x = int(dp.m_WindowSize.y*aspectRatio);
+ windowSize.y = dp.m_WindowSize.y;
+ } else {
+ windowSize.x = dp.m_WindowSize.x;
+ windowSize.y = int(dp.m_WindowSize.x/aspectRatio);
}
+ AVG_ASSERT(windowSize.x != 0 && windowSize.y != 0);
+ return windowSize;
+}
+
+void SDLDisplayEngine::setWindowTitle(const string& sTitle)
+{
+ SDL_WM_SetCaption(sTitle.c_str(), 0);
}
#ifdef _WIN32
@@ -288,37 +272,28 @@ void SDLDisplayEngine::init(const DisplayParams& dp, GLConfig glConfig)
void SDLDisplayEngine::teardown()
{
if (m_pScreen) {
- if (m_Gamma[0] != 1.0 || m_Gamma[1] != 1.0 || m_Gamma[2] != 1.0) {
- SDL_SetGamma(1.0, 1.0, 1.0);
- }
#ifdef linux
// Workaround for broken mouse cursor on exit under Ubuntu 8.04.
SDL_ShowCursor(SDL_ENABLE);
-// SDL_SetVideoMode(m_WindowWidth, m_WindowHeight, 24, 0);
#endif
m_pScreen = 0;
- m_pGLContext = GLContextPtr();
- }
-}
-
-double SDLDisplayEngine::getRefreshRate()
-{
- if (s_RefreshRate == 0.0) {
- calcRefreshRate();
+ if (m_pGLContext) {
+ delete m_pGLContext;
+ m_pGLContext = 0;
+ }
+ GLContext::setMain(0);
}
- return s_RefreshRate;
}
-void SDLDisplayEngine::setGamma(double red, double green, double blue)
+void SDLDisplayEngine::setGamma(float red, float green, float blue)
{
if (red > 0) {
- AVG_TRACE(Logger::CONFIG, "Setting gamma to " << red << ", " << green << ", " << blue);
- int err = SDL_SetGamma(float(red), float(green), float(blue));
+ bool bOk = internalSetGamma(red, green, blue);
m_Gamma[0] = red;
m_Gamma[1] = green;
m_Gamma[2] = blue;
- if (err == -1) {
- AVG_TRACE(Logger::WARNING, "Unable to set display gamma.");
+ if (!bOk) {
+ AVG_LOG_WARNING("Unable to set display gamma.");
}
}
}
@@ -333,32 +308,17 @@ int SDLDisplayEngine::getKeyModifierState() const
return SDL_GetModState();
}
-void SDLDisplayEngine::calcScreenDimensions(double dotsPerMM)
+bool SDLDisplayEngine::internalSetGamma(float red, float green, float blue)
{
- if (dotsPerMM != 0) {
- const SDL_VideoInfo* pInfo = SDL_GetVideoInfo();
- m_ScreenResolution = IntPoint(pInfo->current_w, pInfo->current_h);
- m_PPMM = dotsPerMM;
- }
-
- if (m_PPMM == 0) {
- const SDL_VideoInfo* pInfo = SDL_GetVideoInfo();
- m_ScreenResolution = IntPoint(pInfo->current_w, pInfo->current_h);
-#ifdef WIN32
- HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
- m_PPMM = GetDeviceCaps(hdc, LOGPIXELSX)/25.4;
+#ifdef __APPLE__
+ // Workaround for broken SDL_SetGamma for libSDL 1.2.15 under Lion
+ CGError err = CGSetDisplayTransferByFormula(kCGDirectMainDisplay, 0, 1, 1/red,
+ 0, 1, 1/green, 0, 1, 1/blue);
+ return (err == CGDisplayNoErr);
#else
- #ifdef linux
- Display * pDisplay = XOpenDisplay(0);
- DPoint displayMM(DisplayWidthMM(pDisplay,0), DisplayHeightMM(pDisplay,0));
- #elif defined __APPLE__
- CGSize size = CGDisplayScreenSize(CGMainDisplayID());
- DPoint displayMM(size.width, size.height);
- #endif
- // Non-Square pixels cause errors here. We'll fix that when it happens.
- m_PPMM = m_ScreenResolution.x/displayMM.x;
+ int err = SDL_SetGamma(float(red), float(green), float(blue));
+ return (err != -1);
#endif
- }
}
static ProfilingZoneID SwapBufferProfilingZone("Render - swap buffers");
@@ -366,9 +326,12 @@ static ProfilingZoneID SwapBufferProfilingZone("Render - swap buffers");
void SDLDisplayEngine::swapBuffers()
{
ScopeTimer timer(SwapBufferProfilingZone);
+#ifdef linux
+ m_pGLContext->swapBuffers();
+#else
SDL_GL_SwapBuffers();
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "swapBuffers()");
- AVG_TRACE(Logger::BLTS, "GL SwapBuffers");
+#endif
+ GLContext::checkError("swapBuffers()");
}
void SDLDisplayEngine::showCursor(bool bShow)
@@ -391,24 +354,35 @@ void SDLDisplayEngine::showCursor(bool bShow)
BitmapPtr SDLDisplayEngine::screenshot(int buffer)
{
- BitmapPtr pBmp (new Bitmap(m_WindowSize, B8G8R8X8, "screenshot"));
- string sTmp;
- bool bBroken = getEnv("AVG_BROKEN_READBUFFER", sTmp);
- GLenum buf = buffer;
- if (!buffer) {
- if (bBroken) {
- // Workaround for buggy GL_FRONT on some machines.
- buf = GL_BACK;
- } else {
- buf = GL_FRONT;
+ BitmapPtr pBmp;
+ glproc::BindFramebuffer(GL_FRAMEBUFFER, 0);
+ if (m_pGLContext->isGLES()) {
+ pBmp = BitmapPtr(new Bitmap(m_WindowSize, R8G8B8X8, "screenshot"));
+ glReadPixels(0, 0, m_WindowSize.x, m_WindowSize.y, GL_RGBA, GL_UNSIGNED_BYTE,
+ pBmp->getPixels());
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadPixels()");
+ } else {
+#ifndef AVG_ENABLE_EGL
+ pBmp = BitmapPtr(new Bitmap(m_WindowSize, B8G8R8X8, "screenshot"));
+ string sTmp;
+ bool bBroken = getEnv("AVG_BROKEN_READBUFFER", sTmp);
+ GLenum buf = buffer;
+ if (!buffer) {
+ if (bBroken) {
+ // Workaround for buggy GL_FRONT on some machines.
+ buf = GL_BACK;
+ } else {
+ buf = GL_FRONT;
+ }
}
+ glReadBuffer(buf);
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadBuffer()");
+ glproc::BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ glReadPixels(0, 0, m_WindowSize.x, m_WindowSize.y, GL_BGRA, GL_UNSIGNED_BYTE,
+ pBmp->getPixels());
+ GLContext::checkError("SDLDisplayEngine::screenshot:glReadPixels()");
+#endif
}
- glReadBuffer(buf);
- glproc::BindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "SDLDisplayEngine::screenshot:glReadBuffer()");
- glReadPixels(0, 0, m_WindowSize.x, m_WindowSize.y, GL_BGRA, GL_UNSIGNED_BYTE,
- pBmp->getPixels());
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "SDLDisplayEngine::screenshot:glReadPixels()");
FilterFlip().applyInPlace(pBmp);
return pBmp;
}
@@ -418,172 +392,6 @@ IntPoint SDLDisplayEngine::getSize()
return m_Size;
}
-void SDLDisplayEngine::initMacVBlank(int rate)
-{
-#ifdef __APPLE__
- CGLContextObj context = CGLGetCurrentContext();
- AVG_ASSERT (context);
-#if MAC_OS_X_VERSION_10_5
- GLint l = rate;
-#else
- long l = rate;
-#endif
- if (rate > 1) {
- AVG_TRACE(Logger::WARNING,
- "VBlank rate set to " << rate
- << " but Mac OS X only supports 1. Assuming 1.");
- l = 1;
- }
- CGLError err = CGLSetParameter(context, kCGLCPSwapInterval, &l);
- AVG_ASSERT(!err);
-#endif
-}
-
-bool SDLDisplayEngine::initVBlank(int rate)
-{
- if (rate > 0) {
-#ifdef __APPLE__
- initMacVBlank(rate);
- m_VBMethod = VB_APPLE;
-#elif defined _WIN32
- if (queryOGLExtension("WGL_EXT_swap_control")) {
- glproc::SwapIntervalEXT(rate);
- m_VBMethod = VB_WIN;
- } else {
- AVG_TRACE(Logger::WARNING,
- "Windows VBlank setup failed: OpenGL Extension not supported.");
- m_VBMethod = VB_NONE;
- }
-#else
- if (getenv("__GL_SYNC_TO_VBLANK") != 0) {
- AVG_TRACE(Logger::WARNING,
- "__GL_SYNC_TO_VBLANK set. This interferes with libavg vblank handling.");
- m_VBMethod = VB_NONE;
- } else {
- if (queryGLXExtension("GLX_SGI_swap_control")) {
- m_VBMethod = VB_SGI;
- glproc::SwapIntervalSGI(rate);
-
- } else {
- AVG_TRACE(Logger::WARNING,
- "Linux VBlank setup failed: OpenGL Extension not supported.");
- m_VBMethod = VB_NONE;
- }
- }
-#endif
- } else {
- switch (m_VBMethod) {
- case VB_APPLE:
- initMacVBlank(0);
- break;
- case VB_WIN:
-#ifdef _WIN32
- glproc::SwapIntervalEXT(0);
-#endif
- break;
- case VB_SGI:
-#ifdef linux
- if (queryGLXExtension("GLX_SGI_swap_control")) {
- glproc::SwapIntervalSGI(rate);
- }
-#endif
- break;
- default:
- break;
- }
- m_VBMethod = VB_NONE;
- }
- switch(m_VBMethod) {
- case VB_SGI:
- AVG_TRACE(Logger::CONFIG,
- " Using SGI OpenGL extension for vertical blank support.");
- break;
- case VB_APPLE:
- AVG_TRACE(Logger::CONFIG, " Using Apple GL vertical blank support.");
- break;
- case VB_WIN:
- AVG_TRACE(Logger::CONFIG, " Using Windows GL vertical blank support.");
- break;
- case VB_NONE:
- AVG_TRACE(Logger::CONFIG, " Vertical blank support disabled.");
- break;
- default:
- AVG_TRACE(Logger::WARNING, " Illegal vblank enum value.");
- }
- return m_VBMethod != VB_NONE;
-}
-
-bool SDLDisplayEngine::vbWait(int rate)
-{
- switch(m_VBMethod) {
- case VB_SGI:
- case VB_APPLE:
- case VB_WIN:
- return true;
- case VB_NONE:
- default:
- AVG_ASSERT(false);
- return false;
- }
-}
-
-void SDLDisplayEngine::calcRefreshRate()
-{
- double lastRefreshRate = s_RefreshRate;
- s_RefreshRate = 0;
-#ifdef __APPLE__
- CFDictionaryRef modeInfo = CGDisplayCurrentMode(CGMainDisplayID());
- if (modeInfo) {
- CFNumberRef value = (CFNumberRef) CFDictionaryGetValue(modeInfo,
- kCGDisplayRefreshRate);
- if (value) {
- CFNumberGetValue(value, kCFNumberIntType, &s_RefreshRate);
- if (s_RefreshRate < 1.0) {
- AVG_TRACE(Logger::CONFIG,
- "This seems to be a TFT screen, assuming 60 Hz refresh rate.");
- s_RefreshRate = 60;
- }
- } else {
- AVG_TRACE(Logger::WARNING,
- "Apple refresh rate calculation (CFDictionaryGetValue) failed");
- }
- } else {
- AVG_TRACE(Logger::WARNING,
- "Apple refresh rate calculation (CGDisplayCurrentMode) failed");
- }
-#elif defined _WIN32
- // This isn't correct for multi-monitor systems.
- HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
- s_RefreshRate = GetDeviceCaps(hDC, VREFRESH);
- if (s_RefreshRate < 2) {
- s_RefreshRate = 60;
- }
- DeleteDC(hDC);
-#else
- Display * pDisplay = XOpenDisplay(0);
- int pixelClock;
- XF86VidModeModeLine modeLine;
- bool bOK = XF86VidModeGetModeLine (pDisplay, DefaultScreen(pDisplay),
- &pixelClock, &modeLine);
- if (!bOK) {
- AVG_TRACE (Logger::WARNING,
- "Could not get current refresh rate (XF86VidModeGetModeLine failed).");
- AVG_TRACE (Logger::WARNING,
- "Defaulting to 60 Hz refresh rate.");
- }
- double HSyncRate = pixelClock*1000.0/modeLine.htotal;
- s_RefreshRate = HSyncRate/modeLine.vtotal;
- XCloseDisplay(pDisplay);
-#endif
- if (s_RefreshRate == 0 || isnan(s_RefreshRate)) {
- s_RefreshRate = 60;
- }
- if (lastRefreshRate != s_RefreshRate) {
- AVG_TRACE(Logger::CONFIG, "Vertical Refresh Rate: " << s_RefreshRate);
- }
-
-}
-
vector<long> SDLDisplayEngine::KeyCodeTranslationTable(SDLK_LAST, key::KEY_UNKNOWN);
const char * getEventTypeName(unsigned char type)
@@ -627,12 +435,14 @@ vector<EventPtr> SDLDisplayEngine::pollEvents()
SDL_Event sdlEvent;
vector<EventPtr> events;
+ int numEvents = 0;
while (SDL_PollEvent(&sdlEvent)) {
+ numEvents++;
EventPtr pNewEvent;
switch (sdlEvent.type) {
case SDL_MOUSEMOTION:
- if (m_bMouseOverApp) {
- pNewEvent = createMouseEvent(Event::CURSORMOTION, sdlEvent,
+ {
+ pNewEvent = createMouseEvent(Event::CURSOR_MOTION, sdlEvent,
MouseEvent::NO_BUTTON);
CursorEventPtr pNewCursorEvent =
boost::dynamic_pointer_cast<CursorEvent>(pNewEvent);
@@ -646,10 +456,10 @@ vector<EventPtr> SDLDisplayEngine::pollEvents()
}
break;
case SDL_MOUSEBUTTONDOWN:
- pNewEvent = createMouseButtonEvent(Event::CURSORDOWN, sdlEvent);
+ pNewEvent = createMouseButtonEvent(Event::CURSOR_DOWN, sdlEvent);
break;
case SDL_MOUSEBUTTONUP:
- pNewEvent = createMouseButtonEvent(Event::CURSORUP, sdlEvent);
+ pNewEvent = createMouseButtonEvent(Event::CURSOR_UP, sdlEvent);
break;
case SDL_JOYAXISMOTION:
// pNewEvent = createAxisEvent(sdlEvent));
@@ -661,10 +471,10 @@ vector<EventPtr> SDLDisplayEngine::pollEvents()
// pNewEvent = createButtonEvent(Event::BUTTON_UP, sdlEvent));
break;
case SDL_KEYDOWN:
- pNewEvent = createKeyEvent(Event::KEYDOWN, sdlEvent);
+ pNewEvent = createKeyEvent(Event::KEY_DOWN, sdlEvent);
break;
case SDL_KEYUP:
- pNewEvent = createKeyEvent(Event::KEYUP, sdlEvent);
+ pNewEvent = createKeyEvent(Event::KEY_UP, sdlEvent);
break;
case SDL_QUIT:
pNewEvent = EventPtr(new Event(Event::QUIT, Event::NONE));
@@ -690,6 +500,10 @@ vector<EventPtr> SDLDisplayEngine::pollEvents()
events.push_back(pNewEvent);
}
}
+ if (numEvents > 124) {
+ AVG_TRACE(Logger::category::EVENTS, Logger::severity::WARNING,
+ "SDL Event queue full, dropping events.");
+ }
return events;
}
@@ -706,13 +520,13 @@ EventPtr SDLDisplayEngine::createMouseEvent(Event::Type type, const SDL_Event& s
Uint8 buttonState = SDL_GetMouseState(&x, &y);
x = int((x*m_Size.x)/m_WindowSize.x);
y = int((y*m_Size.y)/m_WindowSize.y);
- DPoint lastMousePos = m_pLastMouseEvent->getPos();
- DPoint speed;
+ glm::vec2 lastMousePos = m_pLastMouseEvent->getPos();
+ glm::vec2 speed;
if (lastMousePos.x == -1) {
- speed = DPoint(0,0);
+ speed = glm::vec2(0,0);
} else {
- double lastFrameTime = 1000/getEffectiveFramerate();
- speed = DPoint(x-lastMousePos.x, y-lastMousePos.y)/lastFrameTime;
+ float lastFrameTime = 1000/getEffectiveFramerate();
+ speed = glm::vec2(x-lastMousePos.x, y-lastMousePos.y)/lastFrameTime;
}
MouseEventPtr pEvent(new MouseEvent(type, (buttonState & SDL_BUTTON(1)) != 0,
(buttonState & SDL_BUTTON(2)) != 0, (buttonState & SDL_BUTTON(3)) != 0,
@@ -795,7 +609,8 @@ EventPtr SDLDisplayEngine::createKeyEvent(Event::Type type, const SDL_Event& sdl
KeyEventPtr pEvent(new KeyEvent(type,
sdlEvent.key.keysym.scancode, keyCode,
- SDL_GetKeyName(sdlEvent.key.keysym.sym), sdlEvent.key.keysym.unicode, modifiers));
+ SDL_GetKeyName(sdlEvent.key.keysym.sym), sdlEvent.key.keysym.unicode,
+ modifiers));
return pEvent;
}
@@ -1047,32 +862,4 @@ bool SDLDisplayEngine::isFullscreen() const
return m_bIsFullscreen;
}
-IntPoint SDLDisplayEngine::getScreenResolution()
-{
- calcScreenDimensions();
- return m_ScreenResolution;
-}
-
-double SDLDisplayEngine::getPixelsPerMM()
-{
- calcScreenDimensions();
-
- return m_PPMM;
-}
-
-DPoint SDLDisplayEngine::getPhysicalScreenDimensions()
-{
- calcScreenDimensions();
- DPoint size;
- DPoint screenRes = DPoint(getScreenResolution());
- size.x = screenRes.x/m_PPMM;
- size.y = screenRes.y/m_PPMM;
- return size;
-}
-
-void SDLDisplayEngine::assumePixelsPerMM(double ppmm)
-{
- m_PPMM = ppmm;
-}
-
}
diff --git a/src/player/SDLDisplayEngine.h b/src/player/SDLDisplayEngine.h
index 7a824cb..90f31ed 100644
--- a/src/player/SDLDisplayEngine.h
+++ b/src/player/SDLDisplayEngine.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -44,19 +44,22 @@ class XInputMTInputDevice;
class MouseEvent;
typedef boost::shared_ptr<class MouseEvent> MouseEventPtr;
class GLContext;
-typedef boost::shared_ptr<class GLContext> GLContextPtr;
class AVG_API SDLDisplayEngine: public DisplayEngine, public IInputDevice
{
public:
+ static void initSDL();
+ static void quitSDL();
SDLDisplayEngine();
virtual ~SDLDisplayEngine();
virtual void init(const DisplayParams& dp, GLConfig glConfig);
+ IntPoint calcWindowSize(const DisplayParams& dp) const;
+
+ void setWindowTitle(const std::string& sTitle);
// From DisplayEngine
virtual void teardown();
- virtual double getRefreshRate();
- virtual void setGamma(double red, double green, double blue);
+ virtual void setGamma(float red, float green, float blue);
virtual void setMousePos(const IntPoint& pos);
virtual int getKeyModifierState() const;
@@ -71,54 +74,32 @@ class AVG_API SDLDisplayEngine: public DisplayEngine, public IInputDevice
const IntPoint& getWindowSize() const;
bool isFullscreen() const;
- IntPoint getScreenResolution();
- double getPixelsPerMM();
- DPoint getPhysicalScreenDimensions();
- void assumePixelsPerMM(double ppmm);
virtual void swapBuffers();
private:
- void initSDL(int width, int height, bool isFullscreen, int bpp);
void initTranslationTable();
- void calcScreenDimensions(double dotsPerMM=0);
+
+ bool internalSetGamma(float red, float green, float blue);
EventPtr createMouseEvent
(Event::Type Type, const SDL_Event & SDLEvent, long Button);
- EventPtr createMouseButtonEvent
- (Event::Type Type, const SDL_Event & SDLEvent);
- EventPtr createKeyEvent
- (Event::Type Type, const SDL_Event & SDLEvent);
+ EventPtr createMouseButtonEvent(Event::Type Type, const SDL_Event & SDLEvent);
+ EventPtr createKeyEvent(Event::Type Type, const SDL_Event & SDLEvent);
IntPoint m_Size;
bool m_bIsFullscreen;
IntPoint m_WindowSize;
- IntPoint m_ScreenResolution;
- double m_PPMM;
SDL_Surface * m_pScreen;
- // Vertical blank stuff.
- virtual bool initVBlank(int rate);
- void initMacVBlank(int rate);
- bool vbWait(int rate);
- enum VBMethod {VB_SGI, VB_APPLE, VB_WIN, VB_NONE};
- VBMethod m_VBMethod;
- int m_VBMod;
- int m_LastVBCount;
-
- static void calcRefreshRate();
- static double s_RefreshRate;
-
// Event handling.
- bool m_bMouseOverApp;
MouseEventPtr m_pLastMouseEvent;
- int m_NumMouseButtonsDown;
static std::vector<long> KeyCodeTranslationTable;
XInputMTInputDevice * m_pXIMTInputDevice;
- GLContextPtr m_pGLContext;
+ GLContext* m_pGLContext;
- double m_Gamma[3];
+ float m_Gamma[3];
};
typedef boost::shared_ptr<SDLDisplayEngine> SDLDisplayEnginePtr;
diff --git a/src/player/SVG.cpp b/src/player/SVG.cpp
index 2a69560..9e778fa 100644
--- a/src/player/SVG.cpp
+++ b/src/player/SVG.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -30,42 +30,40 @@
#include "../graphics/PixelFormat.h"
#include "../graphics/Filterfill.h"
+#include "../graphics/Filterfliprgb.h"
#include "../graphics/FilterUnmultiplyAlpha.h"
+#include "../graphics/BitmapLoader.h"
#include "OGLSurface.h"
#include "Player.h"
#include "ImageNode.h"
#include <glib-object.h>
+
+#ifndef RSVG_CAIRO_H
#include <librsvg/rsvg-cairo.h>
+#endif
+
#include <cairo.h>
#include <iostream>
-using namespace boost::python;
using namespace std;
namespace avg {
-bool SVG::s_RSVGInitialized = false;
-
SVG::SVG(const UTF8String& sFilename, bool bUnescapeIllustratorIDs)
: m_sFilename(sFilename),
m_bUnescapeIllustratorIDs(bUnescapeIllustratorIDs)
{
- if (!s_RSVGInitialized) {
- rsvg_init();
- s_RSVGInitialized = true;
- }
-
- GError* pErr = new GError;
+ GError* pErr = 0;
m_pRSVG = rsvg_handle_new_from_file(m_sFilename.c_str(), &pErr);
if (!m_pRSVG) {
throw Exception(AVG_ERR_INVALID_ARGS,
string("Could not open svg file: ") + m_sFilename);
+ g_error_free(pErr);
}
- delete pErr;
}
SVG::~SVG()
@@ -78,52 +76,58 @@ BitmapPtr SVG::renderElement(const UTF8String& sElementID)
return renderElement(sElementID, 1);
}
-BitmapPtr SVG::renderElement(const UTF8String& sElementID, const DPoint& size)
+BitmapPtr SVG::renderElement(const UTF8String& sElementID, const glm::vec2& size)
{
SVGElementPtr pElement = getElement(sElementID);
- DPoint elementSize = pElement->getSize();
+ glm::vec2 elementSize = pElement->getSize();
return internalRenderElement(pElement, size, elementSize);
}
-BitmapPtr SVG::renderElement(const UTF8String& sElementID, double scale)
+BitmapPtr SVG::renderElement(const UTF8String& sElementID, float scale)
{
SVGElementPtr pElement = getElement(sElementID);
- DPoint size = pElement->getSize();
- DPoint renderSize = size * scale;
+ glm::vec2 size = pElement->getSize();
+ glm::vec2 renderSize = size * scale;
return internalRenderElement(pElement, renderSize, size);
}
-NodePtr SVG::createImageNode(const UTF8String& sElementID, const dict& nodeAttrs)
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs)
{
BitmapPtr pBmp = renderElement(sElementID);
return createImageNodeFromBitmap(pBmp, nodeAttrs);
}
-NodePtr SVG::createImageNode(const UTF8String& sElementID, const dict& nodeAttrs,
- const DPoint& renderSize)
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs,
+ const glm::vec2& renderSize)
{
BitmapPtr pBmp = renderElement(sElementID, renderSize);
return createImageNodeFromBitmap(pBmp, nodeAttrs);
}
-NodePtr SVG::createImageNode(const UTF8String& sElementID, const dict& nodeAttrs,
- double scale)
+NodePtr SVG::createImageNode(const UTF8String& sElementID, const py::dict& nodeAttrs,
+ float scale)
{
BitmapPtr pBmp = renderElement(sElementID, scale);
return createImageNodeFromBitmap(pBmp, nodeAttrs);
}
-DPoint SVG::getElementSize(const UTF8String& sElementID)
+glm::vec2 SVG::getElementPos(const UTF8String& sElementID)
+{
+ SVGElementPtr pElement = getElement(sElementID);
+ return pElement->getPos();
+}
+
+glm::vec2 SVG::getElementSize(const UTF8String& sElementID)
{
SVGElementPtr pElement = getElement(sElementID);
return pElement->getSize();
}
BitmapPtr SVG::internalRenderElement(const SVGElementPtr& pElement,
- const DPoint& renderSize, const DPoint& size)
+ const glm::vec2& renderSize, const glm::vec2& size)
{
- DPoint pos = pElement->getPos();
- DPoint scale(renderSize.x/size.x, renderSize.y/size.y);
+ glm::vec2 pos = pElement->getPos();
+ glm::vec2 scale(renderSize.x/size.x, renderSize.y/size.y);
IntPoint boundingBox = IntPoint(renderSize) +
IntPoint(int(scale.x+0.5), int(scale.y+0.5));
BitmapPtr pBmp(new Bitmap(boundingBox, B8G8R8A8));
@@ -143,11 +147,15 @@ BitmapPtr SVG::internalRenderElement(const SVGElementPtr& pElement,
cairo_surface_destroy(pSurface);
cairo_destroy(pCairo);
-
+
+ if (!BitmapLoader::get()->isBlueFirst()) {
+ FilterFlipRGB().applyInPlace(pBmp);
+ }
+
return pBmp;
}
-NodePtr SVG::createImageNodeFromBitmap(BitmapPtr pBmp, const dict& nodeAttrs)
+NodePtr SVG::createImageNodeFromBitmap(BitmapPtr pBmp, const py::dict& nodeAttrs)
{
ImageNodePtr pNode = boost::dynamic_pointer_cast<ImageNode>(
Player::get()->createNode("image", nodeAttrs));
diff --git a/src/player/SVG.h b/src/player/SVG.h
index cc38620..73f0d55 100644
--- a/src/player/SVG.h
+++ b/src/player/SVG.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -48,29 +48,28 @@ public:
virtual ~SVG();
BitmapPtr renderElement(const UTF8String& sElementID);
- BitmapPtr renderElement(const UTF8String& sElementID, const DPoint& size);
- BitmapPtr renderElement(const UTF8String& sElementID, double scale);
+ BitmapPtr renderElement(const UTF8String& sElementID, const glm::vec2& size);
+ BitmapPtr renderElement(const UTF8String& sElementID, float scale);
NodePtr createImageNode(const UTF8String& sElementID,
- const boost::python::dict& nodeAttrs);
+ const py::dict& nodeAttrs);
NodePtr createImageNode(const UTF8String& sElementID,
- const boost::python::dict& nodeAttrs, const DPoint& renderSize);
+ const py::dict& nodeAttrs, const glm::vec2& renderSize);
NodePtr createImageNode(const UTF8String& sElementID,
- const boost::python::dict& nodeAttrs, double scale);
- DPoint getElementSize(const UTF8String& sElementID);
+ const py::dict& nodeAttrs, float scale);
+ glm::vec2 getElementPos(const UTF8String& sElementID);
+ glm::vec2 getElementSize(const UTF8String& sElementID);
private:
BitmapPtr internalRenderElement(const SVGElementPtr& pElement,
- const DPoint& renderSize, const DPoint& size);
+ const glm::vec2& renderSize, const glm::vec2& size);
NodePtr createImageNodeFromBitmap(BitmapPtr pBmp,
- const boost::python::dict& nodeAttrs);
+ const py::dict& nodeAttrs);
SVGElementPtr getElement(const UTF8String& sElementID);
std::map<UTF8String, SVGElementPtr> m_ElementMap;
UTF8String m_sFilename;
bool m_bUnescapeIllustratorIDs;
RsvgHandle* m_pRSVG;
-
- static bool s_RSVGInitialized;
};
}
diff --git a/src/player/SVGElement.cpp b/src/player/SVGElement.cpp
index 6531431..dc0ba28 100644
--- a/src/player/SVGElement.cpp
+++ b/src/player/SVGElement.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -36,11 +36,11 @@ SVGElement::SVGElement(RsvgHandle* pRSVG, const UTF8String& sFilename,
RsvgPositionData pos;
rsvg_handle_get_position_sub(pRSVG, &pos, m_sUnescapedID.c_str());
- m_Pos = DPoint(pos.x, pos.y);
+ m_Pos = glm::vec2(pos.x, pos.y);
RsvgDimensionData dim;
rsvg_handle_get_dimensions_sub(pRSVG, &dim, m_sUnescapedID.c_str());
- m_Size = DPoint(dim.width+1, dim.height+1);
+ m_Size = glm::vec2(dim.width+1, dim.height+1);
}
const UTF8String& SVGElement::getUnescapedID() const
@@ -48,12 +48,12 @@ const UTF8String& SVGElement::getUnescapedID() const
return m_sUnescapedID;
}
-const DPoint& SVGElement::getPos() const
+const glm::vec2& SVGElement::getPos() const
{
return m_Pos;
}
-const DPoint& SVGElement::getSize() const
+const glm::vec2& SVGElement::getSize() const
{
return m_Size;
}
@@ -66,16 +66,18 @@ UTF8String SVGElement::unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename
vector<string> sPossibleIDs;
sPossibleIDs.push_back(sResult);
string::size_type pos = sResult.find("_");
- while (pos != UTF8String::npos) {
- sResult.replace(pos, 1, "_x5F_");
- pos = sResult.find("_", pos+5);
+ if (pos != UTF8String::npos) {
+ while (pos != UTF8String::npos) {
+ sResult.replace(pos, 1, "_x5F_");
+ pos = sResult.find("_", pos+5);
+ }
+ sPossibleIDs.push_back(sResult);
}
// Illustrator adds suffixes to IDs to get rid of duplicates. Even after the
// duplicates are removed, the suffixes remain :-(.
// We handle two cases here:
// 1) If there is only one version with a suffix, we take that version.
// 2) If there are duplicate IDs, we warn.
- sPossibleIDs.push_back(sResult);
for (int i=1; i<30; ++i) {
string sTempID = sResult + "_" + toString(i) + "_";
sPossibleIDs.push_back(sTempID);
@@ -92,8 +94,7 @@ UTF8String SVGElement::unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename
throwIDNotFound(sFilename, sElementID);
}
if (numFound > 1) {
- AVG_TRACE(Logger::WARNING,
- "svg file '" << sFilename <<
+ AVG_LOG_WARNING("svg file '" << sFilename <<
"' has more than one element with id '" << sElementID << "'.");
}
} else {
diff --git a/src/player/SVGElement.h b/src/player/SVGElement.h
index 8eda90d..280df6b 100644
--- a/src/player/SVGElement.h
+++ b/src/player/SVGElement.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
#include "../api.h"
#include "../base/UTF8String.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <librsvg/rsvg.h>
#include <boost/shared_ptr.hpp>
@@ -41,8 +41,8 @@ public:
const UTF8String& sElementID, bool bUnescapeIllustratorIDs);
const UTF8String& getUnescapedID() const;
- const DPoint& getPos() const;
- const DPoint& getSize() const;
+ const glm::vec2& getPos() const;
+ const glm::vec2& getSize() const;
private:
UTF8String unescapeID(RsvgHandle* pRSVG, const UTF8String& sFilename,
@@ -50,8 +50,8 @@ private:
void throwIDNotFound(const UTF8String& sFilename, const UTF8String& sElementID);
UTF8String m_sUnescapedID;
- DPoint m_Pos;
- DPoint m_Size;
+ glm::vec2 m_Pos;
+ glm::vec2 m_Size;
};
typedef boost::shared_ptr<SVGElement> SVGElementPtr;
diff --git a/src/player/ShadowFXNode.cpp b/src/player/ShadowFXNode.cpp
index 703a901..30ef766 100644
--- a/src/player/ShadowFXNode.cpp
+++ b/src/player/ShadowFXNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"
-#include "../graphics/ShaderRegistry.h"
#include <string>
@@ -31,18 +30,15 @@ using namespace std;
namespace avg {
-ShadowFXNode::ShadowFXNode()
- : FXNode(),
- m_Offset(0,0),
- m_StdDev(1),
- m_Opacity(1),
- m_Color(255,255,255,255)
+ShadowFXNode::ShadowFXNode(glm::vec2 offset, float radius, float opacity, string sColor)
+ : FXNode(false),
+ m_Offset(offset),
+ m_StdDev(radius),
+ m_Opacity(opacity)
{
+ m_sColorName = sColor;
+ m_Color = colorStringToColor(sColor);
ObjectCounter::get()->incRef(&typeid(*this));
- if (!GLTexture::isFloatFormatSupported()) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "OpenGL configuration doesn't support Shadow (no float textures).");
- }
}
ShadowFXNode::~ShadowFXNode()
@@ -52,10 +48,6 @@ ShadowFXNode::~ShadowFXNode()
void ShadowFXNode::connect()
{
- if (!GLTexture::isFloatFormatSupported()) {
- throw Exception(AVG_ERR_UNSUPPORTED,
- "Cannot create ShadowFX: OpenGL configuration doesn't support Blur (no float textures).");
- }
FXNode::connect();
}
@@ -65,46 +57,35 @@ void ShadowFXNode::disconnect()
FXNode::disconnect();
}
-void ShadowFXNode::setParams(const DPoint& offset, double stdDev, double opacity,
- const string& sColor)
-{
- m_Offset = offset;
- m_StdDev = stdDev;
- m_Opacity = opacity;
- m_sColorName = sColor;
- m_Color = colorStringToColor(sColor);
- updateFilter();
-}
-
-void ShadowFXNode::setOffset(const DPoint& offset)
+void ShadowFXNode::setOffset(const glm::vec2& offset)
{
m_Offset = offset;
updateFilter();
}
-DPoint ShadowFXNode::getOffset() const
+glm::vec2 ShadowFXNode::getOffset() const
{
return m_Offset;
}
-void ShadowFXNode::setRadius(double radius)
+void ShadowFXNode::setRadius(float radius)
{
m_StdDev = radius;
updateFilter();
}
-double ShadowFXNode::getRadius() const
+float ShadowFXNode::getRadius() const
{
return m_StdDev;
}
-void ShadowFXNode::setOpacity(double opacity)
+void ShadowFXNode::setOpacity(float opacity)
{
m_Opacity = opacity;
updateFilter();
}
-double ShadowFXNode::getOpacity() const
+float ShadowFXNode::getOpacity() const
{
return m_Opacity;
}
diff --git a/src/player/ShadowFXNode.h b/src/player/ShadowFXNode.h
index bd5a19c..e0bd77a 100644
--- a/src/player/ShadowFXNode.h
+++ b/src/player/ShadowFXNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include "FXNode.h"
#include "../graphics/GPUShadowFilter.h"
+#include "../base/GLMHelper.h"
#include <boost/shared_ptr.hpp>
#include <string>
@@ -34,20 +35,19 @@ namespace avg {
class AVG_API ShadowFXNode: public FXNode {
public:
- ShadowFXNode();
+ ShadowFXNode(glm::vec2 offset=glm::vec2(0,0), float radius=1.f, float opacity=1.f,
+ std::string sColor="FFFFFF");
virtual ~ShadowFXNode();
virtual void connect();
virtual void disconnect();
- void setParams(const DPoint& offset, double stdDev, double opacity,
- const std::string& sColor);
- void setOffset(const DPoint& offset);
- DPoint getOffset() const;
- void setRadius(double radius);
- double getRadius() const;
- void setOpacity(double opacity);
- double getOpacity() const;
+ void setOffset(const glm::vec2& offset);
+ glm::vec2 getOffset() const;
+ void setRadius(float radius);
+ float getRadius() const;
+ void setOpacity(float opacity);
+ float getOpacity() const;
void setColor(const std::string& sColor);
std::string getColor() const;
@@ -57,9 +57,9 @@ private:
GPUShadowFilterPtr m_pFilter;
- DPoint m_Offset;
- double m_StdDev;
- double m_Opacity;
+ glm::vec2 m_Offset;
+ float m_StdDev;
+ float m_Opacity;
std::string m_sColorName;
Pixel32 m_Color;
};
diff --git a/src/player/Shape.cpp b/src/player/Shape.cpp
index f93cd6b..a40f01b 100644
--- a/src/player/Shape.cpp
+++ b/src/player/Shape.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include "../graphics/Filterfliprgb.h"
#include "../graphics/GLContext.h"
+#include "../graphics/OGLShader.h"
#include "OGLSurface.h"
@@ -58,21 +59,20 @@ void Shape::setBitmap(BitmapPtr pBmp)
if (m_pImage->getState() == Image::GPU) {
if (prevState != Image::GPU) {
// TODO: This shouldn't happen.
- m_pVertexArray = VertexArrayPtr(new VertexArray());
+ m_pVertexData = VertexDataPtr(new VertexData());
}
}
}
void Shape::moveToGPU()
{
- m_pSurface->attach();
m_pImage->moveToGPU();
- m_pVertexArray = VertexArrayPtr(new VertexArray());
+ m_pVertexData = VertexDataPtr(new VertexData());
}
void Shape::moveToCPU()
{
- m_pVertexArray = VertexArrayPtr();
+ m_pVertexData = VertexDataPtr();
m_pImage->moveToCPU();
}
@@ -86,35 +86,43 @@ bool Shape::isTextured() const
return m_pImage->getSource() != Image::NONE;
}
-VertexArrayPtr Shape::getVertexArray()
+VertexDataPtr Shape::getVertexData()
{
- return m_pVertexArray;
+ return m_pVertexData;
}
-void Shape::draw()
+void Shape::setVertexArray(const VertexArrayPtr& pVA)
+{
+ pVA->startSubVA(m_SubVA);
+ m_SubVA.appendVertexData(m_pVertexData);
+/*
+ cerr << endl;
+ cerr << "Global VA: " << endl;
+ pVA->dump();
+ cerr << "Local vertex data: " << endl;
+ m_pVertexData->dump();
+*/
+}
+
+void Shape::draw(const glm::mat4& transform, float opacity)
{
bool bIsTextured = isTextured();
- GLContext* pContext = GLContext::getCurrent();
+ GLContext* pContext = GLContext::getMain();
+ StandardShaderPtr pShader = pContext->getStandardShader();
+ pShader->setTransform(transform);
+ pShader->setAlpha(opacity);
if (bIsTextured) {
m_pSurface->activate();
} else {
- if (GLContext::getCurrent()->isUsingShaders()) {
- glproc::UseProgramObject(0);
- }
- for (int i = 1; i < 5; ++i) {
- glproc::ActiveTexture(GL_TEXTURE0 + i);
- glDisable(GL_TEXTURE_2D);
- }
- glproc::ActiveTexture(GL_TEXTURE0);
+ pShader->setUntextured();
+ pShader->activate();
}
- pContext->enableTexture(bIsTextured);
- pContext->enableGLColorArray(!bIsTextured);
- m_pVertexArray->draw();
+ m_SubVA.draw();
}
void Shape::discard()
{
- m_pVertexArray = VertexArrayPtr();
+ m_pVertexData = VertexDataPtr();
m_pImage->discard();
}
diff --git a/src/player/Shape.h b/src/player/Shape.h
index 6502aaa..4cbb390 100644
--- a/src/player/Shape.h
+++ b/src/player/Shape.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,9 +26,9 @@
#include "Image.h"
#include "MaterialInfo.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../graphics/Bitmap.h"
-#include "../graphics/VertexArray.h"
+#include "../graphics/SubVertexArray.h"
#include <boost/shared_ptr.hpp>
#include <string>
@@ -47,15 +47,17 @@ class AVG_API Shape
virtual void moveToCPU();
ImagePtr getImage();
- VertexArrayPtr getVertexArray();
- void draw();
+ VertexDataPtr getVertexData();
+ void setVertexArray(const VertexArrayPtr& pVA);
+ void draw(const glm::mat4& transform, float opacity);
void discard();
private:
bool isTextured() const;
- VertexArrayPtr m_pVertexArray;
+ VertexDataPtr m_pVertexData;
+ SubVertexArray m_SubVA;
OGLSurface * m_pSurface;
ImagePtr m_pImage;
};
diff --git a/src/player/SoundNode.cpp b/src/player/SoundNode.cpp
index 9d31597..3bb089c 100644
--- a/src/player/SoundNode.cpp
+++ b/src/player/SoundNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,18 +20,18 @@
//
#include "SoundNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Canvas.h"
#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"
+#include "../base/ObjectCounter.h"
-#include "../audio/SDLAudioEngine.h"
+#include "../audio/AudioEngine.h"
#include "../video/AsyncVideoDecoder.h"
-#include "../video/FFMpegDecoder.h"
#include <iostream>
#include <sstream>
@@ -40,33 +40,35 @@
#include <unistd.h>
#endif
-using namespace boost::python;
+using namespace boost;
using namespace std;
namespace avg {
-NodeDefinition SoundNode::createDefinition()
+void SoundNode::registerType()
{
- return NodeDefinition("sound", Node::buildNode<SoundNode>)
- .extendDefinition(AreaNode::createDefinition())
+ TypeDefinition def = TypeDefinition("sound", "areanode",
+ ExportedObject::buildObject<SoundNode>)
.addArg(Arg<UTF8String>("href", "", false, offsetof(SoundNode, m_href)))
.addArg(Arg<bool>("loop", false, false, offsetof(SoundNode, m_bLoop)))
- .addArg(Arg<double>("volume", 1.0, false, offsetof(SoundNode, m_Volume)))
+ .addArg(Arg<float>("volume", 1.0, false, offsetof(SoundNode, m_Volume)))
;
+ TypeRegistry::get()->registerType(def);
}
SoundNode::SoundNode(const ArgList& args)
: m_Filename(""),
m_pEOFCallback(0),
+ m_SeekBeforeCanRenderTime(0),
m_pDecoder(0),
m_Volume(1.0),
- m_State(Unloaded)
+ m_State(Unloaded),
+ m_AudioID(-1)
{
args.setMembers(this);
m_Filename = m_href;
initFilename(m_Filename);
- VideoDecoderPtr pSyncDecoder(new FFMpegDecoder());
- m_pDecoder = new AsyncVideoDecoder(pSyncDecoder, 8);
+ m_pDecoder = new AsyncVideoDecoder(8);
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -110,7 +112,7 @@ int SoundNode::getNumAudioChannels() const
long long SoundNode::getCurTime() const
{
exceptionIfUnloaded("getCurTime");
- return (long long)(m_pDecoder->getCurTime(SS_AUDIO)*1000);
+ return (long long)(m_pDecoder->getCurTime()*1000);
}
void SoundNode::seekToTime(long long Time)
@@ -129,13 +131,19 @@ void SoundNode::setEOFCallback(PyObject * pEOFCallback)
if (m_pEOFCallback) {
Py_DECREF(m_pEOFCallback);
}
- Py_INCREF(pEOFCallback);
- m_pEOFCallback = pEOFCallback;
+ if (pEOFCallback == Py_None) {
+ m_pEOFCallback = 0;
+ } else {
+ avgDeprecationWarning("1.8", "SoundNode.setEOFCallback()",
+ "Node.subscribe(END_OF_FILE)");
+ Py_INCREF(pEOFCallback);
+ m_pEOFCallback = pEOFCallback;
+ }
}
void SoundNode::connectDisplay()
{
- if (!SDLAudioEngine::get()) {
+ if (!AudioEngine::get()) {
throw Exception(AVG_ERR_UNSUPPORTED,
"Sound nodes can only be created if audio is not disabled.");
}
@@ -154,6 +162,7 @@ void SoundNode::connectDisplay()
void SoundNode::connect(CanvasPtr pCanvas)
{
+ checkReload();
AreaNode::connect(pCanvas);
pCanvas->registerFrameEndListener(this);
}
@@ -194,19 +203,19 @@ void SoundNode::setHRef(const UTF8String& href)
checkReload();
}
-double SoundNode::getVolume()
+float SoundNode::getVolume()
{
return m_Volume;
}
-void SoundNode::setVolume(double volume)
+void SoundNode::setVolume(float volume)
{
if (volume < 0) {
volume = 0;
}
m_Volume = volume;
- if (m_pDecoder) {
- m_pDecoder->setVolume(volume);
+ if (m_AudioID != -1) {
+ AudioEngine::get()->setSourceVolume(m_AudioID, volume);
}
}
@@ -215,13 +224,12 @@ void SoundNode::checkReload()
string fileName (m_href);
if (m_href != "") {
initFilename(fileName);
- if (fileName != m_Filename) {
- SoundState oldState = m_State;
+ if (fileName != m_Filename && m_State != Unloaded) {
changeSoundState(Unloaded);
m_Filename = fileName;
- if (oldState != Unloaded) {
- changeSoundState(Paused);
- }
+ changeSoundState(Paused);
+ } else {
+ m_Filename = fileName;
}
} else {
changeSoundState(Unloaded);
@@ -231,17 +239,12 @@ void SoundNode::checkReload()
void SoundNode::onFrameEnd()
{
- if (m_State == Playing && m_pDecoder->isEOF(SS_AUDIO)) {
- onEOF();
- }
-}
-
-int SoundNode::fillAudioBuffer(AudioBufferPtr pBuffer)
-{
if (m_State == Playing) {
- return m_pDecoder->fillAudioBuffer(pBuffer);
- } else {
- return 0;
+ m_pDecoder->updateAudioStatus();
+ }
+ if (m_State == Playing && m_pDecoder->isEOF()) {
+ NodePtr pTempThis = getSharedThis();
+ onEOF();
}
}
@@ -265,8 +268,10 @@ void SoundNode::changeSoundState(SoundState newSoundState)
}
if (newSoundState == Paused) {
m_PauseStartTime = curTime;
+ AudioEngine::get()->pauseSource(m_AudioID);
} else if (newSoundState == Playing && m_State == Paused) {
m_PauseTime += curTime-m_PauseStartTime;
+ AudioEngine::get()->playSource(m_AudioID);
}
}
m_State = newSoundState;
@@ -274,16 +279,22 @@ void SoundNode::changeSoundState(SoundState newSoundState)
void SoundNode::seek(long long destTime)
{
- m_pDecoder->seek(double(destTime)/1000);
- m_StartTime = Player::get()->getFrameTime() - destTime;
- m_PauseTime = 0;
- m_PauseStartTime = Player::get()->getFrameTime();
+ if (getState() == NS_CANRENDER) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ m_pDecoder->seek(float(destTime)/1000);
+ m_StartTime = Player::get()->getFrameTime() - destTime;
+ m_PauseTime = 0;
+ m_PauseStartTime = Player::get()->getFrameTime();
+ } else {
+ // If we get a seek command before decoding has really started, we need to defer
+ // the actual seek until the decoder is ready.
+ m_SeekBeforeCanRenderTime = destTime;
+ }
}
void SoundNode::open()
{
- m_pDecoder->setVolume(m_Volume);
- m_pDecoder->open(m_Filename, true);
+ m_pDecoder->open(m_Filename, false, true);
VideoInfo videoInfo = m_pDecoder->getVideoInfo();
if (!videoInfo.m_bHasAudio) {
throw Exception(AVG_ERR_VIDEO_GENERAL,
@@ -294,14 +305,23 @@ void SoundNode::open()
void SoundNode::startDecoding()
{
- SDLAudioEngine* pEngine = SDLAudioEngine::get();
+ AudioEngine* pEngine = AudioEngine::get();
m_pDecoder->startDecoding(false, pEngine->getParams());
- pEngine->addSource(this);
+ m_AudioID = pEngine->addSource(*m_pDecoder->getAudioMsgQ(),
+ *m_pDecoder->getAudioStatusQ());
+ pEngine->setSourceVolume(m_AudioID, m_Volume);
+ if (m_SeekBeforeCanRenderTime != 0) {
+ seek(m_SeekBeforeCanRenderTime);
+ m_SeekBeforeCanRenderTime = 0;
+ }
}
void SoundNode::close()
{
- SDLAudioEngine::get()->removeSource(this);
+ if (m_AudioID != -1) {
+ AudioEngine::get()->removeSource(m_AudioID);
+ m_AudioID = -1;
+ }
m_pDecoder->close();
}
@@ -309,7 +329,7 @@ void SoundNode::exceptionIfUnloaded(const std::string& sFuncName) const
{
if (m_State == Unloaded) {
throw Exception(AVG_ERR_VIDEO_GENERAL,
- string("SoundNode.")+sFuncName+" failed: video not loaded.");
+ string("SoundNode.")+sFuncName+" failed: sound not loaded.");
}
}
@@ -324,10 +344,11 @@ void SoundNode::onEOF()
PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist);
Py_DECREF(arglist);
if (!result) {
- throw error_already_set();
+ throw py::error_already_set();
}
Py_DECREF(result);
}
+ notifySubscribers("END_OF_FILE");
}
}
diff --git a/src/player/SoundNode.h b/src/player/SoundNode.h
index 04f927d..66f9308 100644
--- a/src/player/SoundNode.h
+++ b/src/player/SoundNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,16 +28,15 @@
#include "../base/IFrameEndListener.h"
#include "../base/UTF8String.h"
-#include "../audio/IAudioSource.h"
namespace avg {
-class VideoDecoder;
+class AsyncVideoDecoder;
-class AVG_API SoundNode : public AreaNode, IFrameEndListener, IAudioSource
+class AVG_API SoundNode : public AreaNode, IFrameEndListener
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
SoundNode(const ArgList& args);
virtual ~SoundNode();
@@ -52,8 +51,8 @@ class AVG_API SoundNode : public AreaNode, IFrameEndListener, IAudioSource
const UTF8String& getHRef() const;
void setHRef(const UTF8String& href);
- double getVolume();
- void setVolume(double volume);
+ float getVolume();
+ void setVolume(float volume);
void checkReload();
long long getDuration() const;
@@ -68,8 +67,6 @@ class AVG_API SoundNode : public AreaNode, IFrameEndListener, IAudioSource
virtual void onFrameEnd();
- virtual int fillAudioBuffer(AudioBufferPtr pBuffer);
-
private:
void seek(long long destTime);
void onEOF();
@@ -85,15 +82,16 @@ class AVG_API SoundNode : public AreaNode, IFrameEndListener, IAudioSource
std::string m_Filename;
bool m_bLoop;
PyObject * m_pEOFCallback;
- bool m_bAudioEnabled;
+ long long m_SeekBeforeCanRenderTime;
long long m_StartTime;
long long m_PauseTime;
long long m_PauseStartTime;
- VideoDecoder * m_pDecoder;
- double m_Volume;
+ AsyncVideoDecoder* m_pDecoder;
+ float m_Volume;
SoundState m_State;
+ int m_AudioID;
};
}
diff --git a/src/player/SubscriberInfo.cpp b/src/player/SubscriberInfo.cpp
new file mode 100644
index 0000000..85c0da2
--- /dev/null
+++ b/src/player/SubscriberInfo.cpp
@@ -0,0 +1,85 @@
+
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "SubscriberInfo.h"
+
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+#include "../base/ScopeTimer.h"
+
+#include <boost/python/slice.hpp>
+
+using namespace std;
+
+namespace avg {
+
+py::object SubscriberInfo::s_MethodrefModule;
+
+SubscriberInfo::SubscriberInfo(int id, const py::object& callable)
+ : m_ID(id)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+ if (s_MethodrefModule.ptr() == py::object().ptr()) {
+ s_MethodrefModule = py::import("libavg.methodref");
+ }
+ // Use the methodref module to manage the lifetime of the callables. This makes
+ // sure that we can delete bound-method callbacks when the object they are bound
+ // to disappears.
+ m_Callable = py::object(s_MethodrefModule.attr("methodref")(callable));
+}
+
+SubscriberInfo::~SubscriberInfo()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+bool SubscriberInfo::hasExpired() const
+{
+ py::object func = m_Callable();
+ return (func.ptr() == py::object().ptr());
+}
+
+static ProfilingZoneID InvokeSubscriberProfilingZone("SubscriberInfo: invoke");
+
+void SubscriberInfo::invoke(py::list args) const
+{
+ ScopeTimer timer(InvokeSubscriberProfilingZone);
+ py::object func = m_Callable();
+ py::tuple argsTuple(args);
+ py::object pyResult = func(*argsTuple);
+ if (pyResult.ptr() == 0) {
+ throw py::error_already_set();
+ }
+}
+
+int SubscriberInfo::getID() const
+{
+ return m_ID;
+}
+
+bool SubscriberInfo::isCallable(const py::object& callable) const
+{
+ bool bResult = py::call_method<bool>(m_Callable.ptr(), "isSameFunc", callable);
+ return bResult;
+}
+
+}
diff --git a/src/player/SubscriberInfo.h b/src/player/SubscriberInfo.h
new file mode 100644
index 0000000..a8dc388
--- /dev/null
+++ b/src/player/SubscriberInfo.h
@@ -0,0 +1,58 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _SubscriberInfo_H_
+#define _SubscriberInfo_H_
+
+#include "../api.h"
+
+#include "BoostPython.h"
+#include <boost/shared_ptr.hpp>
+
+// Python docs say python.h should be included before any standard headers (!)
+#include "WrapPython.h"
+
+#include <vector>
+
+namespace avg {
+
+class SubscriberInfo {
+public:
+ SubscriberInfo(int id, const py::object& callable);
+ virtual ~SubscriberInfo();
+
+ bool hasExpired() const;
+ void invoke(py::list args) const;
+ int getID() const;
+ bool isCallable(const py::object& callable) const;
+
+private:
+ int m_ID;
+ py::object m_Callable;
+ static py::object s_MethodrefModule;
+};
+
+typedef boost::shared_ptr<SubscriberInfo> SubscriberInfoPtr;
+}
+
+#endif
+
+
diff --git a/src/player/TUIOInputDevice.cpp b/src/player/TUIOInputDevice.cpp
index a722289..f6f3f08 100644
--- a/src/player/TUIOInputDevice.cpp
+++ b/src/player/TUIOInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,6 @@
#include "../base/Logger.h"
#include "../base/StringHelper.h"
#include "../base/OSHelper.h"
-#include "../base/Point.h"
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"
@@ -49,7 +48,8 @@ DWORD WINAPI TUIOInputDevice::threadFunc(LPVOID p)
};
TUIOInputDevice::TUIOInputDevice()
- : m_LastID(0)
+ : m_pSocket(0),
+ m_LastID(0)
{
}
@@ -83,8 +83,8 @@ void TUIOInputDevice::start()
if (!m_pSocket->IsBound()) {
throw Exception(AVG_ERR_MT_INIT, "TUIO event source: Socket not bound.");
}
- AVG_TRACE(Logger::CONFIG, "TUIO multitouch event source created, listening on port "
- << port);
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO,
+ "TUIO multitouch event source created, listening on port " << port);
#ifndef WIN32
pthread_create(&m_Thread, NULL, threadFunc, this);
@@ -97,7 +97,7 @@ void TUIOInputDevice::start()
void TUIOInputDevice::ProcessPacket(const char* pData, int size,
const IpEndpointName& remoteEndpoint)
{
- boost::mutex::scoped_lock lock(getMutex());
+ lock_guard lock(getMutex());
try {
ReceivedPacket packet(pData, size);
if (packet.IsBundle()) {
@@ -105,8 +105,8 @@ void TUIOInputDevice::ProcessPacket(const char* pData, int size,
} else {
processMessage(ReceivedMessage(packet), remoteEndpoint);
}
- } catch (MalformedBundleException& e) {
- AVG_TRACE(Logger::WARNING, "Malformed OSC bundle received: " << e.what());
+ } catch (osc::Exception& e) {
+ AVG_LOG_WARNING("OSC exception: " << e.what());
}
}
@@ -123,8 +123,8 @@ void TUIOInputDevice::processBundle(const ReceivedBundle& bundle,
processMessage(ReceivedMessage(*it), remoteEndpoint);
}
}
- } catch (MalformedBundleException& e) {
- AVG_TRACE(Logger::WARNING, "Malformed OSC bundle received: " << e.what());
+ } catch (osc::Exception& e) {
+ AVG_LOG_WARNING("OSC exception: " << e.what());
}
}
@@ -149,7 +149,7 @@ void TUIOInputDevice::processMessage(const ReceivedMessage& msg,
}
}
} catch (osc::Exception& e) {
- AVG_TRACE(Logger::WARNING, "Error parsing TUIO message: " << e.what()
+ AVG_LOG_WARNING("Error parsing TUIO message: " << e.what()
<< ". Message was " << msg);
}
}
@@ -161,19 +161,19 @@ void TUIOInputDevice::processSet(ReceivedMessageArgumentStream& args)
float xspeed, yspeed;
float accel;
args >> tuioID >> xpos >> ypos >> xspeed >> yspeed >> accel;
- DPoint pos(xpos, ypos);
- DPoint speed(xspeed, yspeed);
+ glm::vec2 pos(xpos, ypos);
+ glm::vec2 speed(xspeed, yspeed);
// cerr << "Set: ID: " << tuioID << ", pos: " << pos << ", speed: " << speed
// << ", accel: " << accel << endl;
TouchStatusPtr pTouchStatus = getTouchStatus(tuioID);
if (!pTouchStatus) {
// Down
m_LastID++;
- TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSORDOWN, pos, speed);
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN, pos, speed);
addTouchStatus((long)tuioID, pEvent);
} else {
// Move
- TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION, pos, speed);
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION, pos, speed);
pTouchStatus->pushEvent(pEvent);
}
}
@@ -196,20 +196,20 @@ void TUIOInputDevice::processAlive(ReceivedMessageArgumentStream& args)
TouchStatusPtr pTouchStatus = getTouchStatus(id);
TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
TouchEventPtr pUpEvent = boost::dynamic_pointer_cast<TouchEvent>(
- pOldEvent->cloneAs(Event::CURSORUP));
+ pOldEvent->cloneAs(Event::CURSOR_UP));
pTouchStatus->pushEvent(pUpEvent);
removeTouchStatus(id);
}
}
-TouchEventPtr TUIOInputDevice::createEvent(int id, Event::Type type, DPoint pos,
- DPoint speed)
+TouchEventPtr TUIOInputDevice::createEvent(int id, Event::Type type, glm::vec2 pos,
+ glm::vec2 speed)
{
- DPoint size = getWindowSize();
- IntPoint screenPos(int(pos.x*size.x+0.5), int(pos.y*size.y+0.5));
- DPoint screenSpeed(int(speed.x*size.x+0.5), int(speed.y*size.y+0.5));
+ const glm::vec2 size = getTouchArea();
+ IntPoint screenPos = getScreenPos(pos);
+ glm::vec2 screenSpeed(int(speed.x*size.x+0.5), int(speed.y*size.y+0.5));
TouchEventPtr pEvent(new TouchEvent(id, type, screenPos, Event::TOUCH));
- pEvent->setSpeed(screenSpeed/1000);
+ pEvent->setSpeed(screenSpeed/1000.f);
return pEvent;
}
diff --git a/src/player/TUIOInputDevice.h b/src/player/TUIOInputDevice.h
index 6bd99f1..7315345 100644
--- a/src/player/TUIOInputDevice.h
+++ b/src/player/TUIOInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -60,7 +60,7 @@ private:
const IpEndpointName& remoteEndpoint);
void processSet(osc::ReceivedMessageArgumentStream& args);
void processAlive(osc::ReceivedMessageArgumentStream& args);
- TouchEventPtr createEvent(int id, Event::Type type, DPoint pos, DPoint speed);
+ TouchEventPtr createEvent(int id, Event::Type type, glm::vec2 pos, glm::vec2 speed);
UdpListeningReceiveSocket* m_pSocket;
int m_LastID;
diff --git a/src/player/TestHelper.cpp b/src/player/TestHelper.cpp
index c9a3e48..342e7fd 100644
--- a/src/player/TestHelper.cpp
+++ b/src/player/TestHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -65,7 +65,7 @@ void TestHelper::fakeMouseEvent(Event::Type eventType,
}
void TestHelper::fakeTouchEvent(int id, Event::Type eventType,
- Event::Source source, const DPoint& pos, const DPoint& speed)
+ Event::Source source, const glm::vec2& pos, const glm::vec2& speed)
{
checkEventType(eventType);
// The id is modified to avoid collisions with real touch events.
@@ -73,14 +73,14 @@ void TestHelper::fakeTouchEvent(int id, Event::Type eventType,
IntPoint(pos), source, speed));
map<int, TouchStatusPtr>::iterator it = m_Touches.find(pEvent->getCursorID());
switch (pEvent->getType()) {
- case Event::CURSORDOWN: {
+ case Event::CURSOR_DOWN: {
AVG_ASSERT(it == m_Touches.end());
TouchStatusPtr pTouchStatus(new TouchStatus(pEvent));
m_Touches[pEvent->getCursorID()] = pTouchStatus;
}
break;
- case Event::CURSORMOTION:
- case Event::CURSORUP: {
+ case Event::CURSOR_MOTION:
+ case Event::CURSOR_UP: {
if (it == m_Touches.end()) {
cerr << "borked: " << pEvent->getCursorID() << ", " <<
pEvent->typeStr() << endl;
@@ -110,6 +110,11 @@ void TestHelper::dumpObjects()
cerr << ObjectCounter::get()->dump();
}
+TypeMap TestHelper::getObjectCount()
+{
+ return ObjectCounter::get()->getObjectCount();
+}
+
// From IInputDevice
std::vector<EventPtr> TestHelper::pollEvents()
{
@@ -120,7 +125,7 @@ std::vector<EventPtr> TestHelper::pollEvents()
CursorEventPtr pEvent = pTouchStatus->pollEvent();
if (pEvent) {
events.push_back(pEvent);
- if (pEvent->getType() == Event::CURSORUP) {
+ if (pEvent->getType() == Event::CURSOR_UP) {
m_Touches.erase(it++);
} else {
++it;
@@ -136,9 +141,9 @@ std::vector<EventPtr> TestHelper::pollEvents()
void TestHelper::checkEventType(Event::Type eventType)
{
- if (eventType == Event::CURSOROVER || eventType == Event::CURSOROUT) {
+ if (eventType == Event::CURSOR_OVER || eventType == Event::CURSOR_OUT) {
throw Exception(AVG_ERR_UNSUPPORTED, "TestHelper::fakeXxxEvent: Can't send "
- "CURSOROVER and CURSOROUT events directly. They are generated "
+ "CURSOR_OVER and CURSOR_OUT events directly. They are generated "
"internally.");
}
}
diff --git a/src/player/TestHelper.h b/src/player/TestHelper.h
index 0461729..f0741e9 100644
--- a/src/player/TestHelper.h
+++ b/src/player/TestHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,7 @@
#define _TestHelper_H_
#include "../api.h"
+#include "../base/ObjectCounter.h"
#include "../graphics/Bitmap.h"
#include "Event.h"
#include "IInputDevice.h"
@@ -51,11 +52,12 @@ class AVG_API TestHelper : public IInputDevice
bool rightButtonState,
int xPosition, int yPosition, int button);
void fakeTouchEvent(int id, Event::Type eventType, Event::Source source,
- const DPoint& pos, const DPoint& speed=DPoint(0, 0));
+ const glm::vec2& pos, const glm::vec2& speed=glm::vec2(0, 0));
void fakeKeyEvent(Event::Type eventType,
unsigned char scanCode, int keyCode,
const std::string& keyString, int unicode, int modifiers);
void dumpObjects();
+ TypeMap getObjectCount();
// From IInputDevice
virtual std::vector<EventPtr> pollEvents();
diff --git a/src/player/TextEngine.cpp b/src/player/TextEngine.cpp
index 9d89e36..226b0de 100644
--- a/src/player/TextEngine.cpp
+++ b/src/player/TextEngine.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -78,7 +78,6 @@ TextEngine::~TextEngine()
void TextEngine::init()
{
- g_type_init();
m_pFontMap = PANGO_FT2_FONT_MAP(pango_ft2_font_map_new());
pango_ft2_font_map_set_resolution(m_pFontMap, 72, 72);
if (m_bHint) {
@@ -88,7 +87,11 @@ void TextEngine::init()
pango_ft2_font_map_set_default_substitute(m_pFontMap, text_subst_func_nohint,
0, 0);
}
+#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,22,0)
+ m_pPangoContext = pango_font_map_create_context(PANGO_FONT_MAP(m_pFontMap));
+#else
m_pPangoContext = pango_ft2_font_map_create_context(m_pFontMap);
+#endif
pango_context_set_language(m_pPangoContext,
pango_language_from_string ("en_US"));
@@ -160,7 +163,7 @@ PangoFontDescription * TextEngine::getFontDescription(const string& sFamily,
pFamily = getFontFamily(sFamily);
} catch (Exception&) {
if (m_sFontsNotFound.find(sFamily) == m_sFontsNotFound.end()) {
- AVG_TRACE(Logger::WARNING, "Could not find font face " << sFamily <<
+ AVG_LOG_WARNING("Could not find font face " << sFamily <<
". Using sans instead.");
m_sFontsNotFound.insert(sFamily);
}
@@ -186,7 +189,7 @@ PangoFontDescription * TextEngine::getFontDescription(const string& sFamily,
pair<string, string> variant(sFamily, sVariant);
if (m_VariantsNotFound.find(variant) == m_VariantsNotFound.end()) {
m_VariantsNotFound.insert(variant);
- AVG_TRACE(Logger::WARNING, "Could not find font variant "
+ AVG_LOG_WARNING("Could not find font variant "
<< sFamily << ":" << sVariant << ". Using " <<
pango_font_face_get_face_name(pFace) << " instead.");
}
@@ -205,32 +208,41 @@ PangoFontDescription * TextEngine::getFontDescription(const string& sFamily,
void GLibLogFunc(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer unused_data)
{
+//TODO: Make this use correct AVG_LOG_LEVEL function
#ifndef WIN32
string s = "Pango ";
if (log_level & G_LOG_LEVEL_ERROR) {
- s += "error: ";
+ s += message;
+ AVG_LOG_ERROR(s);
+ return;
} else if (log_level & G_LOG_LEVEL_CRITICAL) {
- s += string("critical: ")+message;
- AVG_TRACE(Logger::ERROR, s);
+ s += message;
+ AVG_LOG_ERROR(s);
AVG_ASSERT(false);
} else if (log_level & G_LOG_LEVEL_WARNING) {
- s += "warning: ";
+ s += message;
+ AVG_LOG_WARNING(s);
+ return;
} else if (log_level & G_LOG_LEVEL_MESSAGE) {
- s += "message: ";
+ s += (string("message: ") + message);
+ AVG_LOG_INFO(s);
+ return;
} else if (log_level & G_LOG_LEVEL_INFO) {
- s += "info: ";
+ s += message;
+ AVG_LOG_INFO(s);
+ return;
} else if (log_level & G_LOG_LEVEL_DEBUG) {
- s += "debug: ";
+ s += message;
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, s);
+ return;
}
s += message;
- AVG_TRACE(Logger::WARNING, s);
+ AVG_LOG_WARNING(s);
#endif
}
void TextEngine::initFonts()
{
- g_type_init();
-
std::vector<std::string> fontConfPathPrefixList;
#ifndef WIN32
fontConfPathPrefixList.push_back("/");
diff --git a/src/player/TextEngine.h b/src/player/TextEngine.h
index 734b2a4..4fef426 100644
--- a/src/player/TextEngine.h
+++ b/src/player/TextEngine.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/player/Timeout.cpp b/src/player/Timeout.cpp
index 48f5e11..9820699 100644
--- a/src/player/Timeout.cpp
+++ b/src/player/Timeout.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,19 +21,19 @@
#include "Timeout.h"
+#include "BoostPython.h"
+
#include "../base/Exception.h"
#include "../base/ObjectCounter.h"
-#include "BoostPython.h"
-
#include <iostream>
-using namespace boost::python;
using namespace std;
namespace avg {
-int Timeout::s_LastID = 0;
+// Hack to make sure ids don't overlap with publisher/subsriber ids
+int Timeout::s_LastID = 100000;
Timeout::Timeout(int time, PyObject * pyfunc, bool isInterval, long long startTime)
: m_Interval(time),
@@ -54,17 +54,17 @@ Timeout::~Timeout()
ObjectCounter::get()->decRef(&typeid(*this));
}
-bool Timeout::IsReady(long long time) const
+bool Timeout::isReady(long long time) const
{
return m_NextTimeout <= time;
}
-bool Timeout::IsInterval() const
+bool Timeout::isInterval() const
{
return m_IsInterval;
}
-void Timeout::Fire(long long curTime)
+void Timeout::fire(long long curTime)
{
if (m_IsInterval) {
m_NextTimeout = m_Interval + curTime;
@@ -75,12 +75,12 @@ void Timeout::Fire(long long curTime)
// by a call to clearTimeout()!
Py_DECREF(arglist);
if (!result) {
- throw error_already_set();
+ throw py::error_already_set();
}
Py_DECREF(result);
}
-int Timeout::GetID() const
+int Timeout::getID() const
{
return m_ID;
}
diff --git a/src/player/Timeout.h b/src/player/Timeout.h
index 0f73a4e..9682d76 100644
--- a/src/player/Timeout.h
+++ b/src/player/Timeout.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -34,10 +34,10 @@ class AVG_API Timeout
Timeout (int time, PyObject * pyfunc, bool isInterval, long long startTime);
virtual ~Timeout ();
- bool IsReady(long long time) const;
- bool IsInterval() const;
- void Fire(long long curTime);
- int GetID() const;
+ bool isReady(long long time) const;
+ bool isInterval() const;
+ void fire(long long curTime);
+ int getID() const;
bool operator <(const Timeout& other) const;
private:
diff --git a/src/player/TouchEvent.cpp b/src/player/TouchEvent.cpp
index 17a1f52..c2541df 100644
--- a/src/player/TouchEvent.cpp
+++ b/src/player/TouchEvent.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@ using namespace std;
namespace avg {
TouchEvent::TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& pos,
- Source source, const DPoint& speed)
+ Source source, const glm::vec2& speed)
: CursorEvent(id, eventType, pos, source),
m_pBlob(pBlob),
m_bHasHandOrientation(false)
@@ -49,9 +49,9 @@ TouchEvent::TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& po
m_Area = pBlob->getArea();
m_Center = pBlob->getCenter();
m_Eccentricity = pBlob->getEccentricity();
- const DPoint& axis0 = m_pBlob->getScaledBasis(0);
- const DPoint& axis1 = m_pBlob->getScaledBasis(1);
- if (axis0.getNorm() > axis1.getNorm()) {
+ const glm::vec2& axis0 = m_pBlob->getScaledBasis(0);
+ const glm::vec2& axis1 = m_pBlob->getScaledBasis(1);
+ if (glm::length(axis0) > glm::length(axis1)) {
m_MajorAxis = axis0;
m_MinorAxis = axis1;
} else {
@@ -61,16 +61,16 @@ TouchEvent::TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& po
} else {
m_Orientation = 0;
m_Area = 20;
- m_Center = DPoint(0, 0);
+ m_Center = glm::vec2(0, 0);
m_Eccentricity = 0;
- m_MajorAxis = DPoint(5, 0);
- m_MinorAxis = DPoint(0, 5);
+ m_MajorAxis = glm::vec2(5, 0);
+ m_MinorAxis = glm::vec2(0, 5);
}
}
TouchEvent::TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
- const DPoint& speed, double orientation, double area, double eccentricity,
- DPoint majorAxis, DPoint minorAxis)
+ const glm::vec2& speed, float orientation, float area, float eccentricity,
+ glm::vec2 majorAxis, glm::vec2 minorAxis)
: CursorEvent(id, eventType, pos, source),
m_Orientation(orientation),
m_Area(area),
@@ -82,7 +82,7 @@ TouchEvent::TouchEvent(int id, Type eventType, const IntPoint& pos, Source sourc
}
TouchEvent::TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
- const DPoint& speed)
+ const glm::vec2& speed)
: CursorEvent(id, eventType, pos, source),
m_Orientation(0),
m_Area(20),
@@ -104,32 +104,32 @@ CursorEventPtr TouchEvent::cloneAs(Type eventType) const
return pClone;
}
-double TouchEvent::getOrientation() const
+float TouchEvent::getOrientation() const
{
return m_Orientation;
}
-double TouchEvent::getArea() const
+float TouchEvent::getArea() const
{
return m_Area;
}
-const DPoint & TouchEvent::getCenter() const
+const glm::vec2 & TouchEvent::getCenter() const
{
return m_Center;
}
-double TouchEvent::getEccentricity() const
+float TouchEvent::getEccentricity() const
{
return m_Eccentricity;
}
-const DPoint & TouchEvent::getMajorAxis() const
+const glm::vec2 & TouchEvent::getMajorAxis() const
{
return m_MajorAxis;
}
-const DPoint & TouchEvent::getMinorAxis() const
+const glm::vec2 & TouchEvent::getMinorAxis() const
{
return m_MinorAxis;
}
@@ -149,14 +149,14 @@ ContourSeq TouchEvent::getContour()
}
}
-double TouchEvent::getHandOrientation() const
+float TouchEvent::getHandOrientation() const
{
if (getSource() == Event::TOUCH) {
if (m_bHasHandOrientation) {
return m_HandOrientation;
} else {
- DPoint screenCenter = Player::get()->getRootNode()->getSize()/2;
- return (getPos()-screenCenter).getAngle();
+ glm::vec2 screenCenter = Player::get()->getRootNode()->getSize()/2.f;
+ return getAngle(getPos()-screenCenter);
}
} else {
throw Exception(AVG_ERR_UNSUPPORTED,
@@ -169,7 +169,7 @@ void TouchEvent::addRelatedEvent(TouchEventPtr pEvent)
m_RelatedEvents.push_back(pEvent);
if (getSource() == Event::TOUCH && m_RelatedEvents.size() == 1) {
TouchEventPtr pHandEvent = m_RelatedEvents.begin()->lock();
- m_HandOrientation = (pHandEvent->getPos()-getPos()).getAngle();
+ m_HandOrientation = getAngle(pHandEvent->getPos()-getPos());
m_bHasHandOrientation = true;
}
}
@@ -192,7 +192,7 @@ void TouchEvent::removeBlob()
void TouchEvent::trace()
{
CursorEvent::trace();
- AVG_TRACE(Logger::EVENTS2, "pos: " << getPos()
+ AVG_TRACE(Logger::category::EVENTS,Logger::severity::DEBUG, "pos: " << getPos()
<< ", ID: " << getCursorID()
<< ", Area: " << m_Area
<< ", Eccentricity: " << m_Eccentricity);
diff --git a/src/player/TouchEvent.h b/src/player/TouchEvent.h
index 95bbca4..730883a 100644
--- a/src/player/TouchEvent.h
+++ b/src/player/TouchEvent.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
#include "CursorEvent.h"
#include "../imaging/Blob.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <math.h>
#include <boost/weak_ptr.hpp>
@@ -43,25 +43,25 @@ class AVG_API TouchEvent: public CursorEvent
{
public:
TouchEvent(int id, Type eventType, BlobPtr pBlob, const IntPoint& pos,
- Source source, const DPoint& speed=DPoint(0,0));
+ Source source, const glm::vec2& speed=glm::vec2(0,0));
TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
- const DPoint& speed, double orientation, double area, double eccentricity,
- DPoint majorAxis, DPoint minorAxis);
+ const glm::vec2& speed, float orientation, float area,
+ float eccentricity, glm::vec2 majorAxis, glm::vec2 minorAxis);
TouchEvent(int id, Type eventType, const IntPoint& pos, Source source,
- const DPoint& speed=DPoint(0, 0));
+ const glm::vec2& speed=glm::vec2(0, 0));
virtual ~TouchEvent();
virtual CursorEventPtr cloneAs(Type eventType) const;
- double getOrientation() const;
- double getArea() const;
- const DPoint & getCenter() const;
- double getEccentricity() const;
- const DPoint & getMajorAxis() const;
- const DPoint & getMinorAxis() const;
+ float getOrientation() const;
+ float getArea() const;
+ const glm::vec2 & getCenter() const;
+ float getEccentricity() const;
+ const glm::vec2 & getMajorAxis() const;
+ const glm::vec2 & getMinorAxis() const;
const BlobPtr getBlob() const;
ContourSeq getContour();
- double getHandOrientation() const;
+ float getHandOrientation() const;
void addRelatedEvent(TouchEventPtr pEvent);
std::vector<TouchEventPtr> getRelatedEvents() const;
@@ -72,15 +72,15 @@ class AVG_API TouchEvent: public CursorEvent
private:
BlobPtr m_pBlob;
- double m_Orientation;
- double m_Area;
- DPoint m_Center;
- double m_Eccentricity;
- DPoint m_MajorAxis;
- DPoint m_MinorAxis;
+ float m_Orientation;
+ float m_Area;
+ glm::vec2 m_Center;
+ float m_Eccentricity;
+ glm::vec2 m_MajorAxis;
+ glm::vec2 m_MinorAxis;
std::vector<TouchEventWeakPtr> m_RelatedEvents;
bool m_bHasHandOrientation;
- double m_HandOrientation;
+ float m_HandOrientation;
};
}
diff --git a/src/player/TouchStatus.cpp b/src/player/TouchStatus.cpp
index 66d63bb..ff08bc9 100644
--- a/src/player/TouchStatus.cpp
+++ b/src/player/TouchStatus.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -53,14 +53,14 @@ void TouchStatus::pushEvent(TouchEventPtr pEvent, bool bCheckMotion)
if (m_bFirstFrame) {
// Ignore unless cursorup.
- if (pEvent->getType() == Event::CURSORUP) {
+ if (pEvent->getType() == Event::CURSOR_UP) {
// Down and up in the first frame. To avoid inconsistencies, both
// messages must be delivered. This is the only time that m_pNewEvents
// has more than one entry.
m_pNewEvents.push_back(pEvent);
}
} else {
- if (bCheckMotion && pEvent->getType() == Event::CURSORMOTION &&
+ if (bCheckMotion && pEvent->getType() == Event::CURSOR_MOTION &&
getLastEvent()->getPos() == pEvent->getPos())
{
// Ignore motion events without motion.
diff --git a/src/player/TouchStatus.h b/src/player/TouchStatus.h
index 7a4eb5a..ffe3e7f 100644
--- a/src/player/TouchStatus.h
+++ b/src/player/TouchStatus.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
#ifndef _TouchStatus_H_
#define _TouchStatus_H_
-#include "../base/Point.h"
+#include "../api.h"
#include <boost/shared_ptr.hpp>
diff --git a/src/player/TrackerCalibrator.cpp b/src/player/TrackerCalibrator.cpp
index a6a6a58..4bc13b9 100644
--- a/src/player/TrackerCalibrator.cpp
+++ b/src/player/TrackerCalibrator.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -83,7 +83,7 @@ TrackerCalibrator::TrackerCalibrator(const IntPoint& CamExtents,
m_DisplayPoints.push_back(
IntPoint(OffsetPerPoint.x*x+MIN_DIST_FROM_BORDER,
OffsetPerPoint.y*y+MIN_DIST_FROM_BORDER));
- m_CamPoints.push_back(DPoint(0,0));
+ m_CamPoints.push_back(glm::dvec2(0,0));
}
}
}
@@ -116,7 +116,7 @@ IntPoint TrackerCalibrator::getDisplayPoint()
return m_DisplayPoints[m_CurPoint];
}
-void TrackerCalibrator::setCamPoint(const DPoint& pt)
+void TrackerCalibrator::setCamPoint(const glm::vec2& pt)
{
m_CamPoints[m_CurPoint] = pt;
m_bCurPointSet = true;
@@ -140,8 +140,8 @@ DeDistortPtr TrackerCalibrator::makeTransformer()
m_DistortParams.push_back(0);
m_Angle = 0;
m_TrapezoidFactor = 0.0;
- m_DisplayOffset= DPoint(0,0);
- m_DisplayScale = DPoint(2,2);
+ m_DisplayOffset= glm::vec2(0,0);
+ m_DisplayScale = glm::vec2(2,2);
int n_p = NUM_PARAMS;
//should really match the Params enum!!!!
@@ -160,15 +160,15 @@ DeDistortPtr TrackerCalibrator::makeTransformer()
initThisFromDouble(p);
/*
for(int i=0;i<NUM_POINTS*NUM_POINTS;i++) {
- DPoint screenPoint = m_CurrentTrafo->transformBlobToScreen(
+ glm::vec2 screenPoint = m_CurrentTrafo->transformBlobToScreen(
m_CurrentTrafo->transform_point(m_CamPoints[i]));
cerr << "sample value of trafo of (cam) "
<< m_CamPoints[i]<<" : (transformed) "
<< screenPoint
<< "== (display)"
- << DPoint(m_DisplayPoints[i])
+ << glm::vec2(m_DisplayPoints[i])
<< " dist="
- << calcDist(DPoint(m_DisplayPoints[i]), screenPoint)
+ << calcDist(glm::vec2(m_DisplayPoints[i]), screenPoint)
<< endl;
}
cerr<<" DisplayScale = "<<m_DisplayScale << endl;
@@ -192,7 +192,7 @@ void TrackerCalibrator::initThisFromDouble(double *p)
m_Angle = p[ANGLE];
m_TrapezoidFactor = p[TRAPEZ];
m_CurrentTrafo = DeDistortPtr(
- new DeDistort(DPoint(m_CamExtents),
+ new DeDistort(glm::vec2(m_CamExtents),
m_DistortParams,
m_Angle,
m_TrapezoidFactor,
@@ -206,13 +206,10 @@ void TrackerCalibrator::evaluate_tracker(double *p, int m_dat, double* fvec, int
{
initThisFromDouble(p);
- for (int i=0; i<m_dat; i++){
- fvec[i] = calcDist(
- m_CurrentTrafo->transformBlobToScreen(
- m_CurrentTrafo->transform_point(m_CamPoints[i])
- ),
- DPoint(m_DisplayPoints[i])
- );
+ for (int i=0; i<m_dat; i++) {
+ glm::dvec2 resultPt = m_CurrentTrafo->transformBlobToScreen(
+ m_CurrentTrafo->transform_point(m_CamPoints[i]));
+ fvec[i] = glm::length(resultPt - glm::dvec2(m_DisplayPoints[i]));
}
*info = *info; /* to prevent a 'unused variable' warning */
/* if <parameters drifted away> { *info = -1; } */
diff --git a/src/player/TrackerCalibrator.h b/src/player/TrackerCalibrator.h
index 9b31963..93779a6 100644
--- a/src/player/TrackerCalibrator.h
+++ b/src/player/TrackerCalibrator.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,7 @@
#include "../api.h"
#include "../imaging/DeDistort.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <vector>
@@ -43,7 +43,7 @@ public:
bool nextPoint();
IntPoint getDisplayPoint();
- void setCamPoint(const DPoint& pt);
+ void setCamPoint(const glm::vec2& pt);
DeDistortPtr makeTransformer();
@@ -56,13 +56,13 @@ private:
std::vector<double> m_DistortParams;
double m_Angle;
- DPoint m_DisplayScale;
- DPoint m_DisplayOffset;
+ glm::dvec2 m_DisplayScale;
+ glm::dvec2 m_DisplayOffset;
double m_TrapezoidFactor;
DeDistortPtr m_CurrentTrafo;
unsigned int m_CurPoint;
std::vector<IntPoint> m_DisplayPoints;
- std::vector<DPoint> m_CamPoints;
+ std::vector<glm::dvec2> m_CamPoints;
IntPoint m_CamExtents;
IntPoint m_DisplayExtents;
diff --git a/src/player/TrackerInputDevice.cpp b/src/player/TrackerInputDevice.cpp
index af85784..88e6baa 100644
--- a/src/player/TrackerInputDevice.cpp
+++ b/src/player/TrackerInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -37,6 +37,8 @@
#include "../imaging/DeDistort.h"
#include "../imaging/CoordTransformer.h"
+#include "../glm/gtx/norm.hpp"
+
#include "Player.h"
#include "AVGNode.h"
@@ -69,7 +71,7 @@ TrackerInputDevice::TrackerInputDevice()
bool bFW800 = m_TrackerConfig.getBoolParam("/camera/fw800/@value");
IntPoint captureSize(m_TrackerConfig.getPointParam("/camera/size/"));
string sCaptureFormat = m_TrackerConfig.getParam("/camera/format/@value");
- double frameRate = m_TrackerConfig.getDoubleParam("/camera/framerate/@value");
+ float frameRate = m_TrackerConfig.getFloatParam("/camera/framerate/@value");
PixelFormat camPF = stringToPixelFormat(sCaptureFormat);
if (camPF == NO_PIXELFORMAT) {
@@ -77,12 +79,14 @@ TrackerInputDevice::TrackerInputDevice()
"Unknown camera pixel format "+sCaptureFormat+".");
}
- AVG_TRACE(Logger::CONFIG, "Trying to create a Tracker for " << sDriver
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Trying to create a Tracker for " << sDriver
<< " Camera: " << sDevice << " Size: " << captureSize << "format: "
<< sCaptureFormat);
m_pCamera = createCamera(sDriver, sDevice, -1, bFW800, captureSize, camPF, I8,
frameRate);
- AVG_TRACE(Logger::CONFIG, "Got Camera " << m_pCamera->getDevice() << " from driver: "
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "Got Camera " << m_pCamera->getDevice() << " from driver: "
<< m_pCamera->getDriverName());
IntPoint imgSize = m_pCamera->getImgSize();
@@ -99,15 +103,14 @@ TrackerInputDevice::TrackerInputDevice()
try {
m_DisplayROI = m_TrackerConfig.getRectParam("/transform/displayroi/");
} catch (Exception) {
- m_DisplayROI = DRect(DPoint(0,0), DPoint(m_ActiveDisplaySize));
+ m_DisplayROI = FRect(glm::vec2(0,0), glm::vec2(m_ActiveDisplaySize));
}
IntRect roi = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
if (roi.tl.x < 0 || roi.tl.y < 0 ||
roi.br.x > imgSize.x || roi.br.y > imgSize.y)
{
- AVG_TRACE(Logger::ERROR,
- "Impossible tracker configuration: Region of interest is "
+ AVG_LOG_ERROR("Impossible tracker configuration: Region of interest is "
<< roi << ", camera image size is " << imgSize << ". Aborting.");
exit(5);
}
@@ -157,8 +160,8 @@ void TrackerInputDevice::setParam(const string& sElement, const string& sValue)
m_TrackerConfig.setParam(sElement, sValue);
// Test if active area is outside camera.
- DRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
- DPoint size = m_TrackerConfig.getPointParam("/camera/size/");
+ FRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
+ glm::vec2 size = m_TrackerConfig.getPointParam("/camera/size/");
int prescale = m_TrackerConfig.getIntParam("/tracker/prescale/@value");
if (area.br.x > size.x/prescale || area.br.y > size.y/prescale ||
area.tl.x < 0 || area.tl.y < 0)
@@ -194,7 +197,7 @@ void TrackerInputDevice::saveConfig()
void TrackerInputDevice::setConfig()
{
m_pDeDistort = m_TrackerConfig.getTransform();
- DRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
+ FRect area = m_pDeDistort->getActiveBlobArea(m_DisplayROI);
createBitmaps(area);
m_pCmdQueue->pushCmd(boost::bind(&TrackerThread::setConfig, _1, m_TrackerConfig,
area, m_pBitmaps));
@@ -202,7 +205,7 @@ void TrackerInputDevice::setConfig()
void TrackerInputDevice::createBitmaps(const IntRect& area)
{
- boost::mutex::scoped_lock lock(*m_pMutex);
+ lock_guard lock(*m_pMutex);
for (int i=1; i<NUM_TRACKER_IMAGES; i++) {
switch (i) {
case TRACKER_IMG_HISTOGRAM:
@@ -226,16 +229,16 @@ void TrackerInputDevice::createBitmaps(const IntRect& area)
Bitmap * TrackerInputDevice::getImage(TrackerImageID imageID) const
{
- boost::mutex::scoped_lock lock(*m_pMutex);
+ lock_guard lock(*m_pMutex);
return new Bitmap(*m_pBitmaps[imageID]);
}
-DPoint TrackerInputDevice::getDisplayROIPos() const
+glm::vec2 TrackerInputDevice::getDisplayROIPos() const
{
return m_DisplayROI.tl;
}
-DPoint TrackerInputDevice::getDisplayROISize() const
+glm::vec2 TrackerInputDevice::getDisplayROISize() const
{
return m_DisplayROI.size();
}
@@ -259,14 +262,14 @@ void TrackerInputDevice::update(BlobVectorPtr pTrackBlobs,
// Temporary structure to be put into heap of blob distances. Used only in
// trackBlobIDs.
struct BlobDistEntry {
- BlobDistEntry(double dist, BlobPtr pNewBlob, BlobPtr pOldBlob)
+ BlobDistEntry(float dist, BlobPtr pNewBlob, BlobPtr pOldBlob)
: m_Dist(dist),
m_pNewBlob(pNewBlob),
m_pOldBlob(pOldBlob)
{
}
- double m_Dist;
+ float m_Dist;
BlobPtr m_pNewBlob;
BlobPtr m_pOldBlob;
};
@@ -300,14 +303,14 @@ void TrackerInputDevice::trackBlobIDs(BlobVectorPtr pNewBlobs, long long time,
oldBlobs.push_back((*it).first);
}
// Create a heap that contains all distances of old to new blobs < MaxDist
- double MaxDist = m_TrackerConfig.getDoubleParam(sConfigPath+"similarity/@value");
- double MaxDistSquared = MaxDist*MaxDist;
+ float MaxDist = m_TrackerConfig.getFloatParam(sConfigPath+"similarity/@value");
+ float MaxDistSquared = MaxDist*MaxDist;
priority_queue<BlobDistEntryPtr> distHeap;
for (BlobVector::iterator it = pNewBlobs->begin(); it != pNewBlobs->end(); ++it) {
BlobPtr pNewBlob = *it;
for(BlobVector::iterator it2 = oldBlobs.begin(); it2 != oldBlobs.end(); ++it2) {
BlobPtr pOldBlob = *it2;
- double distSquared = calcDistSquared(pNewBlob->getCenter(),
+ float distSquared = glm::distance2(pNewBlob->getCenter(),
pOldBlob->getEstimatedNextCenter());
if (distSquared <= MaxDistSquared) {
BlobDistEntryPtr pEntry = BlobDistEntryPtr(
@@ -368,9 +371,9 @@ TrackerCalibrator* TrackerInputDevice::startCalibration()
AVG_ASSERT(!m_pCalibrator);
m_pOldTransformer = m_TrackerConfig.getTransform();
m_OldDisplayROI = m_DisplayROI;
- m_DisplayROI = DRect(DPoint(0,0), DPoint(m_ActiveDisplaySize));
+ m_DisplayROI = FRect(glm::vec2(0,0), glm::vec2(m_ActiveDisplaySize));
m_TrackerConfig.setTransform(DeDistortPtr(new DeDistort(
- DPoint(m_pBitmaps[0]->getSize()), DPoint(m_ActiveDisplaySize))));
+ glm::vec2(m_pBitmaps[0]->getSize()), glm::vec2(m_ActiveDisplaySize))));
setConfig();
m_pCalibrator = new TrackerCalibrator(m_pBitmaps[0]->getSize(),
m_ActiveDisplaySize);
@@ -382,10 +385,9 @@ void TrackerInputDevice::endCalibration()
AVG_ASSERT(m_pCalibrator);
m_TrackerConfig.setTransform(m_pCalibrator->makeTransformer());
m_DisplayROI = m_OldDisplayROI;
- DRect area = m_TrackerConfig.getTransform()->getActiveBlobArea(m_DisplayROI);
+ FRect area = m_TrackerConfig.getTransform()->getActiveBlobArea(m_DisplayROI);
if (area.size().x*area.size().y > 1024*1024*8) {
- AVG_TRACE(Logger::WARNING, "Ignoring calibration - resulting area would be "
- << area);
+ AVG_LOG_WARNING("Ignoring calibration - resulting area would be " << area);
m_TrackerConfig.setTransform(m_pOldTransformer);
}
setConfig();
@@ -406,7 +408,7 @@ void TrackerInputDevice::abortCalibration()
vector<EventPtr> TrackerInputDevice::pollEvents()
{
- boost::mutex::scoped_lock lock(*m_pMutex);
+ lock_guard lock(*m_pMutex);
vector<EventPtr> pTouchEvents;
vector<EventPtr> pTrackEvents;
pollEventType(pTouchEvents, m_TouchEvents, CursorEvent::TOUCH);
@@ -429,7 +431,7 @@ void TrackerInputDevice::pollEventType(vector<EventPtr>& res, TouchStatusMap& Ev
pEvent = pTouchStatus->pollEvent();
if (pEvent) {
res.push_back(pEvent);
- if (pEvent->getType() == Event::CURSORUP) {
+ if (pEvent->getType() == Event::CURSOR_UP) {
Events.erase(it++);
} else {
++it;
@@ -476,12 +478,12 @@ void TrackerInputDevice::findFingertips(std::vector<EventPtr>& pTouchEvents)
TouchEventPtr pTouchEvent = boost::dynamic_pointer_cast<TouchEvent>(*it);
vector<TouchEventPtr> pTrackEvents = pTouchEvent->getRelatedEvents();
if (pTrackEvents.size() > 0) {
- double handAngle = pTouchEvent->getHandOrientation();
- double dist = pTouchEvent->getMajorAxis().getNorm()*2;
- DPoint tweakVec = DPoint::fromPolar(handAngle, dist);
- DPoint newPos = pTouchEvent->getPos()-tweakVec;
- newPos.x = max(0.0, min(newPos.x, double(m_ActiveDisplaySize.x)));
- newPos.y = max(0.0, min(newPos.y, double(m_ActiveDisplaySize.y)));
+ float handAngle = pTouchEvent->getHandOrientation();
+ float dist = glm::length(pTouchEvent->getMajorAxis())*2;
+ glm::vec2 tweakVec = fromPolar(handAngle, dist);
+ glm::vec2 newPos = pTouchEvent->getPos()-tweakVec;
+ newPos.x = max(0.0f, min(newPos.x, float(m_ActiveDisplaySize.x)));
+ newPos.y = max(0.0f, min(newPos.y, float(m_ActiveDisplaySize.y)));
pTouchEvent->setPos(newPos);
}
}
diff --git a/src/player/TrackerInputDevice.h b/src/player/TrackerInputDevice.h
index b09890b..eda8a8d 100644
--- a/src/player/TrackerInputDevice.h
+++ b/src/player/TrackerInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -62,8 +62,8 @@ class AVG_API TrackerInputDevice: public IBlobTarget, public IInputDevice
void setDebugImages(bool bImg, bool bFinger);
void saveConfig();
Bitmap * getImage(TrackerImageID imageID) const;
- DPoint getDisplayROIPos() const;
- DPoint getDisplayROISize() const;
+ glm::vec2 getDisplayROIPos() const;
+ glm::vec2 getDisplayROISize() const;
std::vector<EventPtr> pollEvents(); //main thread
@@ -95,8 +95,8 @@ class AVG_API TrackerInputDevice: public IBlobTarget, public IInputDevice
DeDistortPtr m_pDeDistort;
DeDistortPtr m_pOldTransformer;
IntPoint m_ActiveDisplaySize;
- DRect m_DisplayROI;
- DRect m_OldDisplayROI;
+ FRect m_DisplayROI;
+ FRect m_OldDisplayROI;
TrackerCalibrator * m_pCalibrator;
bool m_bFindFingertips;
diff --git a/src/player/TrackerTouchStatus.cpp b/src/player/TrackerTouchStatus.cpp
index 2377228..f52bd3b 100644
--- a/src/player/TrackerTouchStatus.cpp
+++ b/src/player/TrackerTouchStatus.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -35,8 +35,8 @@ namespace avg {
int TrackerTouchStatus::s_LastID = 0;
TrackerTouchStatus::TrackerTouchStatus(BlobPtr pFirstBlob, long long time,
- DeDistortPtr pDeDistort, const DRect& displayROI, Event::Source source)
- : TouchStatus(createEvent(source, Event::CURSORDOWN, ++s_LastID, pFirstBlob, time,
+ DeDistortPtr pDeDistort, const FRect& displayROI, Event::Source source)
+ : TouchStatus(createEvent(source, Event::CURSOR_DOWN, ++s_LastID, pFirstBlob, time,
pDeDistort, displayROI)),
m_Source(source),
m_pDeDistort(pDeDistort),
@@ -62,16 +62,16 @@ void TrackerTouchStatus::blobChanged(BlobPtr pNewBlob, long long time, bool bKee
AVG_ASSERT(m_pBlob);
AVG_ASSERT(pNewBlob);
if (!m_bGone) {
- DPoint c = pNewBlob->getCenter();
+ glm::vec2 c = pNewBlob->getCenter();
bool bPosChanged;
if (bKeepEvent) {
bPosChanged = true;
} else {
- bPosChanged = (calcDist(c, m_LastCenter) > 1);
+ bPosChanged = (glm::length(c-m_LastCenter) > 1);
}
if (bPosChanged) {
m_LastCenter = pNewBlob->getCenter();
- TouchEventPtr pEvent = createEvent(Event::CURSORMOTION, pNewBlob, time);
+ TouchEventPtr pEvent = createEvent(Event::CURSOR_MOTION, pNewBlob, time);
pushEvent(pEvent, false);
}
m_pBlob = pNewBlob;
@@ -83,7 +83,7 @@ void TrackerTouchStatus::blobChanged(BlobPtr pNewBlob, long long time, bool bKee
void TrackerTouchStatus::blobGone()
{
if (!m_bGone) {
- TouchEventPtr pEvent = createEvent(Event::CURSORUP, m_pBlob, m_LastTime+1);
+ TouchEventPtr pEvent = createEvent(Event::CURSOR_UP, m_pBlob, m_LastTime+1);
pushEvent(pEvent, false);
m_bGone = true;
}
@@ -101,11 +101,11 @@ bool TrackerTouchStatus::isStale()
TouchEventPtr TrackerTouchStatus::createEvent(Event::Source source, Event::Type type,
int id, BlobPtr pBlob, long long time, DeDistortPtr pDeDistort,
- const DRect& displayROI)
+ const FRect& displayROI)
{
- DPoint blobOffset = pDeDistort->getActiveBlobArea(displayROI).tl;
- DPoint pt = pBlob->getCenter() + blobOffset;
- DPoint screenpos = pDeDistort->transformBlobToScreen(pt);
+ glm::vec2 blobOffset = pDeDistort->getActiveBlobArea(displayROI).tl;
+ glm::vec2 pt = pBlob->getCenter() + blobOffset;
+ glm::dvec2 screenpos(pDeDistort->transformBlobToScreen(glm::dvec2(pt)));
IntPoint pos(int(screenpos.x+0.5), int(screenpos.y+0.5));
return TouchEventPtr(new TouchEvent(id, type, pBlob, pos, source));
diff --git a/src/player/TrackerTouchStatus.h b/src/player/TrackerTouchStatus.h
index 53b9e4a..5d75f5d 100644
--- a/src/player/TrackerTouchStatus.h
+++ b/src/player/TrackerTouchStatus.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,7 @@
#include "Event.h"
#include "TouchStatus.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../imaging/Blob.h"
#include "../imaging/DeDistort.h"
@@ -39,7 +39,7 @@ class AVG_API TrackerTouchStatus: public TouchStatus
{
public:
TrackerTouchStatus(BlobPtr pFirstBlob, long long time, DeDistortPtr pDeDistort,
- const DRect& displayROI, Event::Source source);
+ const FRect& displayROI, Event::Source source);
virtual ~TrackerTouchStatus();
void blobChanged(BlobPtr pNewBlob, long long time, bool bKeepEvent);
void blobGone();
@@ -49,18 +49,18 @@ class AVG_API TrackerTouchStatus: public TouchStatus
private:
TouchEventPtr createEvent(Event::Source source, Event::Type type, int id,
BlobPtr pBlob, long long time, DeDistortPtr pDeDistort,
- const DRect& displayROI);
+ const FRect& displayROI);
TouchEventPtr createEvent(Event::Type type, BlobPtr pBlob, long long time);
Event::Source m_Source;
DeDistortPtr m_pDeDistort;
- DRect m_DisplayROI;
+ FRect m_DisplayROI;
bool m_Stale;
bool m_bGone;
int m_ID;
BlobPtr m_pBlob;
long long m_LastTime;
- DPoint m_LastCenter;
+ glm::vec2 m_LastCenter;
static int s_LastID;
};
diff --git a/src/player/NodeDefinition.cpp b/src/player/TypeDefinition.cpp
index 32cfb68..f2d5ec5 100644
--- a/src/player/NodeDefinition.cpp
+++ b/src/player/TypeDefinition.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,8 @@
//
// Current versions can be found at www.libavg.de
//
-// Original author of this file is Nick Hebner (hebnern@gmail.com).
-//
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "../base/Logger.h"
@@ -29,42 +27,48 @@ using namespace std;
namespace avg {
-NodeDefinition::NodeDefinition() :
+TypeDefinition::TypeDefinition() :
m_pBuilder(0)
{
}
-NodeDefinition::NodeDefinition(const string& sName, NodeBuilder pBuilder)
+TypeDefinition::TypeDefinition(const string& sName, const string& sBaseName,
+ ObjectBuilder pBuilder)
: m_sName(sName),
m_pBuilder(pBuilder)
{
+ if (sBaseName != "") {
+ TypeDefinition baseDef = TypeRegistry::get()->getTypeDef(sBaseName);
+ m_Args.copyArgsFrom(baseDef.m_Args);
+ m_sChildren = baseDef.m_sChildren;
+ }
}
-NodeDefinition::~NodeDefinition()
+TypeDefinition::~TypeDefinition()
{
}
-const std::string& NodeDefinition::getName() const
+const std::string& TypeDefinition::getName() const
{
return m_sName;
}
-NodeBuilder NodeDefinition::getBuilder() const
+ObjectBuilder TypeDefinition::getBuilder() const
{
return m_pBuilder;
}
-const ArgList& NodeDefinition::getDefaultArgs() const
+const ArgList& TypeDefinition::getDefaultArgs() const
{
return m_Args;
}
-const string& NodeDefinition::getDTDElements() const
+const string& TypeDefinition::getDTDElements() const
{
return m_sDTDElements;
}
-string NodeDefinition::getDTDChildrenString() const
+string TypeDefinition::getDTDChildrenString() const
{
if (m_sChildren.empty()) {
return "EMPTY";
@@ -79,7 +83,7 @@ string NodeDefinition::getDTDChildrenString() const
}
}
-bool NodeDefinition::isChildAllowed(const string& sChild) const
+bool TypeDefinition::isChildAllowed(const string& sChild) const
{
for (unsigned i=0; i<m_sChildren.size(); ++i) {
if (m_sChildren[i] == sChild) {
@@ -89,34 +93,38 @@ bool NodeDefinition::isChildAllowed(const string& sChild) const
return false;
}
-bool NodeDefinition::hasChildren() const
+bool TypeDefinition::hasChildren() const
{
return !m_sChildren.empty();
}
-NodeDefinition& NodeDefinition::extendDefinition(const NodeDefinition& Def)
+bool TypeDefinition::isAbstract() const
{
- m_Args.copyArgsFrom(Def.m_Args);
- m_sChildren = Def.m_sChildren;
- return *this;
+ return m_pBuilder == 0;
}
-NodeDefinition& NodeDefinition::addArg(const ArgBase& newArg)
+TypeDefinition& TypeDefinition::addArg(const ArgBase& newArg)
{
m_Args.setArg(newArg);
return *this;
}
-NodeDefinition& NodeDefinition::addDTDElements(const string& s)
+TypeDefinition& TypeDefinition::addDTDElements(const string& s)
{
m_sDTDElements = s;
return *this;
}
-NodeDefinition& NodeDefinition::addChildren(const vector<string>& sChildren)
+TypeDefinition& TypeDefinition::addChildren(const vector<string>& sChildren)
{
m_sChildren.insert(m_sChildren.end(), sChildren.begin(), sChildren.end());
return *this;
}
+TypeDefinition& TypeDefinition::addChild(const string& sChild)
+{
+ m_sChildren.push_back(sChild);
+ return *this;
+}
+
}
diff --git a/src/player/NodeDefinition.h b/src/player/TypeDefinition.h
index aeda123..e1275f4 100644
--- a/src/player/NodeDefinition.h
+++ b/src/player/TypeDefinition.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -18,51 +18,52 @@
//
// Current versions can be found at www.libavg.de
//
-// Original author of this file is Nick Hebner (hebnern@gmail.com).
-//
-#ifndef _NodeDefinition_H_
-#define _NodeDefinition_H_
+#ifndef _TypeDefinition_H_
+#define _TypeDefinition_H_
#include "../api.h"
#include "ArgList.h"
+#include "TypeRegistry.h"
#include <map>
#include <string>
namespace avg {
-class Node;
-typedef boost::shared_ptr<Node> NodePtr;
-class NodeDefinition;
+class ExportedObject;
+typedef boost::shared_ptr<ExportedObject> ExportedObjectPtr;
+class TypeDefinition;
-typedef NodePtr (*NodeBuilder)(const ArgList& Args);
-typedef std::map<std::string, NodeDefinition> ChildMap;
+typedef ExportedObjectPtr (*ObjectBuilder)(const ArgList& Args);
+typedef std::map<std::string, TypeDefinition> ChildMap;
-class AVG_API NodeDefinition
+class AVG_API TypeDefinition
{
public:
- NodeDefinition();
- NodeDefinition(const std::string& sName, NodeBuilder pBuilder = 0);
- virtual ~NodeDefinition();
+ TypeDefinition();
+ TypeDefinition(const std::string& sName, const std::string& sBaseName="",
+ ObjectBuilder pBuilder = 0);
+ virtual ~TypeDefinition();
const std::string& getName() const;
- NodeBuilder getBuilder() const;
+ ObjectBuilder getBuilder() const;
const ArgList& getDefaultArgs() const;
const std::string& getDTDElements() const;
std::string getDTDChildrenString() const;
bool isChildAllowed(const std::string& sChild) const;
bool hasChildren() const;
+ bool isAbstract() const;
- NodeDefinition& extendDefinition(const NodeDefinition& Def);
- NodeDefinition& addArg(const ArgBase& newArg);
- NodeDefinition& addDTDElements(const std::string& s);
- NodeDefinition& addChildren(const std::vector<std::string>& sChildren);
+ TypeDefinition& addArg(const ArgBase& newArg);
+ TypeDefinition& addDTDElements(const std::string& s);
+ TypeDefinition& addChildren(const std::vector<std::string>& sChildren);
+ TypeDefinition& addChild(const std::string& sChild);
private:
std::string m_sName;
- NodeBuilder m_pBuilder;
+ ObjectBuilder m_pBuilder;
ArgList m_Args;
std::string m_sDTDElements;
std::vector<std::string> m_sChildren;
diff --git a/src/player/TypeRegistry.cpp b/src/player/TypeRegistry.cpp
new file mode 100644
index 0000000..0de3609
--- /dev/null
+++ b/src/player/TypeRegistry.cpp
@@ -0,0 +1,159 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+// Original author of this file is Nick Hebner (hebnern@gmail.com).
+//
+
+#include "TypeRegistry.h"
+#include "TypeDefinition.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Exception.h"
+
+#include <set>
+
+using namespace std;
+
+namespace avg {
+
+TypeRegistry* TypeRegistry::s_pInstance = 0;
+
+TypeRegistry::TypeRegistry()
+{
+}
+
+TypeRegistry::~TypeRegistry()
+{
+}
+
+TypeRegistry* TypeRegistry::get()
+{
+ if (!s_pInstance) {
+ s_pInstance = new TypeRegistry();
+ }
+ return s_pInstance;
+}
+
+void TypeRegistry::registerType(const TypeDefinition& def, const char* pParentNames[])
+{
+ m_TypeDefs.insert(TypeDefMap::value_type(def.getName(), def));
+
+ if (pParentNames) {
+ string sChildArray[1];
+ sChildArray[0] = def.getName();
+ vector<string> sChildren = vectorFromCArray(1, sChildArray);
+ const char **ppCurParentName = pParentNames;
+
+ while (*ppCurParentName) {
+ TypeDefinition def = getTypeDef(*ppCurParentName);
+ def.addChildren(sChildren);
+ updateDefinition(def);
+
+ ++ppCurParentName;
+ }
+ }
+}
+
+void TypeRegistry::updateDefinition(const TypeDefinition& def)
+{
+ m_TypeDefs[def.getName()] = def;
+}
+
+ExportedObjectPtr TypeRegistry::createObject(const string& sType,
+ const xmlNodePtr xmlNode)
+{
+ const TypeDefinition& def = getTypeDef(sType);
+ ArgList args(def.getDefaultArgs(), xmlNode);
+ ObjectBuilder builder = def.getBuilder();
+ ExportedObjectPtr pObj = builder(args);
+ pObj->setTypeInfo(&def);
+ return pObj;
+}
+
+ExportedObjectPtr TypeRegistry::createObject(const string& sType, const py::dict& pyDict)
+{
+ const TypeDefinition& def = getTypeDef(sType);
+ py::dict effParams;
+ effParams = pyDict;
+ ArgList args(def.getDefaultArgs(), effParams);
+ ObjectBuilder builder = def.getBuilder();
+ ExportedObjectPtr pObj = builder(args);
+ pObj->setTypeInfo(&def);
+ return pObj;
+}
+
+string TypeRegistry::getDTD() const
+{
+ if (m_TypeDefs.empty()) {
+ return string("");
+ }
+
+ stringstream ss;
+
+ for (TypeDefMap::const_iterator defIt = m_TypeDefs.begin();
+ defIt != m_TypeDefs.end(); defIt++)
+ {
+ const TypeDefinition& def = defIt->second;
+ if (!def.isAbstract()) {
+ writeTypeDTD(def, ss);
+ }
+ }
+
+ for (TypeDefMap::const_iterator defIt = m_TypeDefs.begin();
+ defIt != m_TypeDefs.end(); defIt++)
+ {
+ const TypeDefinition& def = defIt->second;
+ if (!def.isAbstract()) {
+ ss << def.getDTDElements();
+ }
+ }
+
+ return ss.str();
+}
+
+TypeDefinition& TypeRegistry::getTypeDef(const string& sType)
+{
+ TypeDefMap::iterator it = m_TypeDefs.find(sType);
+ if (it == m_TypeDefs.end()) {
+ throw (Exception (AVG_ERR_XML_NODE_UNKNOWN,
+ string("Unknown node type ") + sType + " encountered."));
+ }
+ return it->second;
+}
+
+void TypeRegistry::writeTypeDTD(const TypeDefinition& def, stringstream& ss) const
+{
+ ss << "<!ELEMENT " << def.getName() << " " << def.getDTDChildrenString() << " >\n";
+ if (!def.getDefaultArgs().getArgMap().empty()) {
+ ss << "<!ATTLIST " << def.getName();
+ for (ArgMap::const_iterator argIt = def.getDefaultArgs().getArgMap().begin();
+ argIt != def.getDefaultArgs().getArgMap().end(); argIt++)
+ {
+ string argName = argIt->first;
+ string argType = (argName == "id") ? "ID" : "CDATA";
+ string argRequired = def.getDefaultArgs().getArg(argName)->isRequired() ?
+ "#REQUIRED" : "#IMPLIED";
+ ss << "\n " << argName << " " << argType << " " << argRequired;
+ }
+ ss << " >\n";
+ }
+}
+
+}
diff --git a/src/player/NodeRegistry.h b/src/player/TypeRegistry.h
index 9aee371..3b38018 100644
--- a/src/player/NodeRegistry.h
+++ b/src/player/TypeRegistry.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,14 +21,14 @@
// Original author of this file is Nick Hebner (hebnern@gmail.com).
//
-#ifndef _NodeRegistry_H_
-#define _NodeRegistry_H_
+#ifndef _TypeRegistry_H_
+#define _TypeRegistry_H_
#include "../api.h"
#include "WrapPython.h"
#include "Node.h"
#include "ArgList.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include <map>
#include <string>
@@ -36,25 +36,28 @@
namespace avg {
-class AVG_API NodeRegistry
+class AVG_API TypeRegistry
{
public:
- NodeRegistry();
- virtual ~NodeRegistry();
+ virtual ~TypeRegistry();
+ static TypeRegistry* get();
- void registerNodeType(const NodeDefinition& def);
- void updateNodeDefinition(const NodeDefinition& def);
- const NodeDefinition& getNodeDef(const std::string& Type);
- NodePtr createNode(const std::string& Type, const xmlNodePtr xmlNode);
- NodePtr createNode(const std::string& Type, const boost::python::dict& PyDict);
+ void registerType(const TypeDefinition& def, const char* pParentNames[] = 0);
+ void updateDefinition(const TypeDefinition& def);
+ TypeDefinition& getTypeDef(const std::string& Type);
+ ExportedObjectPtr createObject(const std::string& Type, const xmlNodePtr xmlNode);
+ ExportedObjectPtr createObject(const std::string& Type, const py::dict& PyDict);
std::string getDTD() const;
private:
- void writeNodeDTD(const NodeDefinition& def, std::stringstream& ss) const;
+ TypeRegistry();
+ void writeTypeDTD(const TypeDefinition& def, std::stringstream& ss) const;
- typedef std::map<std::string, NodeDefinition> NodeDefMap;
- NodeDefMap m_NodeDefs;
+ typedef std::map<std::string, TypeDefinition> TypeDefMap;
+ TypeDefMap m_TypeDefs;
+
+ static TypeRegistry* s_pInstance;
};
}
diff --git a/src/player/VectorNode.cpp b/src/player/VectorNode.cpp
index 427d637..f484a3b 100644
--- a/src/player/VectorNode.cpp
+++ b/src/player/VectorNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "VectorNode.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "OGLSurface.h"
#include "Image.h"
@@ -37,6 +37,8 @@
#include "../graphics/VertexArray.h"
#include "../graphics/Filterfliprgb.h"
+#include "../glm/gtx/norm.hpp"
+
#include <iostream>
#include <sstream>
@@ -45,19 +47,20 @@ using namespace boost;
namespace avg {
-NodeDefinition VectorNode::createDefinition()
+void VectorNode::registerType()
{
- return NodeDefinition("vector")
- .extendDefinition(Node::createDefinition())
+ TypeDefinition def = TypeDefinition("vectornode", "node")
.addArg(Arg<string>("color", "FFFFFF", false, offsetof(VectorNode, m_sColorName)))
- .addArg(Arg<double>("strokewidth", 1, false, offsetof(VectorNode, m_StrokeWidth)))
+ .addArg(Arg<float>("strokewidth", 1, false, offsetof(VectorNode, m_StrokeWidth)))
.addArg(Arg<UTF8String>("texhref", "", false, offsetof(VectorNode, m_TexHRef)))
.addArg(Arg<string>("blendmode", "blend", false,
offsetof(VectorNode, m_sBlendMode)))
;
+ TypeRegistry::get()->registerType(def);
}
VectorNode::VectorNode(const ArgList& args)
+ : m_Transform(glm::mat4(0))
{
m_pShape = ShapePtr(createDefaultShape());
@@ -79,7 +82,6 @@ void VectorNode::connectDisplay()
m_Color = colorStringToColor(m_sColorName);
Node::connectDisplay();
m_pShape->moveToGPU();
- m_OldOpacity = -1;
setBlendModeStr(m_sBlendMode);
}
@@ -140,51 +142,44 @@ void VectorNode::setBlendModeStr(const string& sBlendMode)
static ProfilingZoneID PrerenderProfilingZone("VectorNode::prerender");
-void VectorNode::preRender()
+void VectorNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
- double curOpacity = getEffectiveOpacity();
-
- VertexArrayPtr pVA = m_pShape->getVertexArray();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
{
- if (m_bDrawNeeded || curOpacity != m_OldOpacity) {
- ScopeTimer timer(PrerenderProfilingZone);
- pVA->reset();
+ ScopeTimer timer(PrerenderProfilingZone);
+ VertexDataPtr pShapeVD = m_pShape->getVertexData();
+ if (m_bDrawNeeded) {
+ pShapeVD->reset();
Pixel32 color = getColorVal();
- color.setA((unsigned char)(curOpacity*255));
- calcVertexes(pVA, color);
- pVA->update();
+ calcVertexes(pShapeVD, color);
m_bDrawNeeded = false;
- m_OldOpacity = curOpacity;
+ }
+ if (isVisible()) {
+ m_pShape->setVertexArray(pVA);
}
}
-
}
-void VectorNode::maybeRender(const DRect& rect)
+void VectorNode::maybeRender(const glm::mat4& parentTransform)
{
AVG_ASSERT(getState() == NS_CANRENDER);
if (isVisible()) {
- if (getID() != "") {
- AVG_TRACE(Logger::BLTS, "Rendering " << getTypeStr() <<
- " with ID " << getID());
- } else {
- AVG_TRACE(Logger::BLTS, "Rendering " << getTypeStr());
- }
- GLContext::getCurrent()->setBlendMode(m_BlendMode);
- render(rect);
+ m_Transform = parentTransform;
+ GLContext::getMain()->setBlendMode(m_BlendMode);
+ render();
}
}
static ProfilingZoneID RenderProfilingZone("VectorNode::render");
-void VectorNode::render(const DRect& rect)
+void VectorNode::render()
{
ScopeTimer timer(RenderProfilingZone);
-// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- double curOpacity = getEffectiveOpacity();
- glColor4d(1.0, 1.0, 1.0, curOpacity);
- m_pShape->draw();
+ float curOpacity = getEffectiveOpacity();
+ if (curOpacity > 0.01) {
+ m_pShape->draw(m_Transform, curOpacity);
+ }
}
void VectorNode::setColor(const string& sColor)
@@ -201,7 +196,7 @@ const string& VectorNode::getColor() const
return m_sColorName;
}
-void VectorNode::setStrokeWidth(double width)
+void VectorNode::setStrokeWidth(float width)
{
if (width != m_StrokeWidth) {
m_bDrawNeeded = true;
@@ -209,7 +204,7 @@ void VectorNode::setStrokeWidth(double width)
}
}
-double VectorNode::getStrokeWidth() const
+float VectorNode::getStrokeWidth() const
{
return m_StrokeWidth;
}
@@ -259,27 +254,27 @@ bool VectorNode::isDrawNeeded()
return m_bDrawNeeded;
}
-void VectorNode::calcPolyLineCumulDist(vector<double>& cumulDists,
- const vector<DPoint>& pts, bool bIsClosed)
+void VectorNode::calcPolyLineCumulDist(vector<float>& cumulDists,
+ const vector<glm::vec2>& pts, bool bIsClosed)
{
cumulDists.clear();
cumulDists.reserve(pts.size());
if (!pts.empty()) {
- vector<double> distances;
+ vector<float> distances;
distances.reserve(pts.size());
- double totalDist = 0;
+ float totalDist = 0;
for (unsigned i = 1; i < pts.size(); ++i) {
- double dist = calcDist(pts[i], pts[i-1]);
+ float dist = glm::length(pts[i] - pts[i-1]);
distances.push_back(dist);
totalDist += dist;
}
if (bIsClosed) {
- double dist = calcDist(pts[pts.size()-1], pts[0]);
+ float dist = glm::length(pts[pts.size()-1] - pts[0]);
distances.push_back(dist);
totalDist += dist;
}
- double cumulDist = 0;
+ float cumulDist = 0;
cumulDists.push_back(0);
for (unsigned i = 0; i < distances.size(); ++i) {
cumulDist += distances[i]/totalDist;
@@ -288,8 +283,8 @@ void VectorNode::calcPolyLineCumulDist(vector<double>& cumulDists,
}
}
-void VectorNode::calcEffPolyLineTexCoords(vector<double>& effTC,
- const vector<double>& tc, const vector<double>& cumulDist)
+void VectorNode::calcEffPolyLineTexCoords(vector<float>& effTC,
+ const vector<float>& tc, const vector<float>& cumulDist)
{
if (tc.empty()) {
effTC = cumulDist;
@@ -298,39 +293,40 @@ void VectorNode::calcEffPolyLineTexCoords(vector<double>& effTC,
} else {
effTC.reserve(cumulDist.size());
effTC = tc;
- double minGivenTexCoord = tc[0];
- double maxGivenTexCoord = tc[tc.size()-1];
- double maxCumulDist = cumulDist[tc.size()-1];
+ float minGivenTexCoord = tc[0];
+ float maxGivenTexCoord = tc[tc.size()-1];
+ float maxCumulDist = cumulDist[tc.size()-1];
int baselineDist = 0;
for (unsigned i = tc.size(); i < cumulDist.size(); ++i) {
int repeatFactor = int(cumulDist[i]/maxCumulDist);
- double effCumulDist = fmod(cumulDist[i], maxCumulDist);
+ float effCumulDist = fmod(cumulDist[i], maxCumulDist);
while (cumulDist[baselineDist+1] < effCumulDist) {
baselineDist++;
}
- double ratio = (effCumulDist-cumulDist[baselineDist])/
+ float ratio = (effCumulDist-cumulDist[baselineDist])/
(cumulDist[baselineDist+1]-cumulDist[baselineDist]);
- double rawTexCoord = (1-ratio)*tc[baselineDist] +ratio*tc[baselineDist+1];
- double texCoord = rawTexCoord
+ float rawTexCoord = (1-ratio)*tc[baselineDist] +ratio*tc[baselineDist+1];
+ float texCoord = rawTexCoord
+repeatFactor*(maxGivenTexCoord-minGivenTexCoord);
effTC.push_back(texCoord);
}
}
+
}
-void VectorNode::calcPolyLine(const vector<DPoint>& origPts,
- const vector<double>& origTexCoords, bool bIsClosed, LineJoin lineJoin,
- VertexArrayPtr& pVertexArray, Pixel32 color)
+void VectorNode::calcPolyLine(const vector<glm::vec2>& origPts,
+ const vector<float>& origTexCoords, bool bIsClosed, LineJoin lineJoin,
+ const VertexDataPtr& pVertexData, Pixel32 color)
{
- vector<DPoint> pts;
+ vector<glm::vec2> pts;
pts.reserve(origPts.size());
- vector<double> texCoords;
+ vector<float> texCoords;
texCoords.reserve(origPts.size());
pts.push_back(origPts[0]);
texCoords.push_back(origTexCoords[0]);
for (unsigned i = 1; i < origPts.size(); ++i) {
- if (calcDistSquared(origPts[i], origPts[i-1]) > 0.1) {
+ if (glm::distance2(origPts[i], origPts[i-1]) > 0.1) {
pts.push_back(origPts[i]);
texCoords.push_back(origTexCoords[i]);
}
@@ -353,38 +349,38 @@ void VectorNode::calcPolyLine(const vector<DPoint>& origPts,
// First points
if (bIsClosed) {
WideLine lastLine = lines[lines.size()-1];
- DPoint pli = getLineLineIntersection(lastLine.pl0, lastLine.dir,
+ glm::vec2 pli = getLineLineIntersection(lastLine.pl0, lastLine.dir,
lines[0].pl0, lines[0].dir);
- DPoint pri = getLineLineIntersection(lastLine.pr0, lastLine.dir,
+ glm::vec2 pri = getLineLineIntersection(lastLine.pr0, lastLine.dir,
lines[0].pr0, lines[0].dir);
Triangle tri(lastLine.pl1, lines[0].pl0, pri);
if (tri.isClockwise()) {
- if (!DLineSegment(lastLine.pr0, lastLine.pr1).isPointOver(pri) &&
- !DLineSegment(lines[0].pr0, lines[0].pr1).isPointOver(pri))
+ if (!LineSegment(lastLine.pr0, lastLine.pr1).isPointOver(pri) &&
+ !LineSegment(lines[0].pr0, lines[0].pr1).isPointOver(pri))
{
pri = lines[0].pr1;
}
} else {
- if (!DLineSegment(lastLine.pl0, lastLine.pl1).isPointOver(pli) &&
- !DLineSegment(lines[0].pl0, lines[0].pl1).isPointOver(pli))
+ if (!LineSegment(lastLine.pl0, lastLine.pl1).isPointOver(pli) &&
+ !LineSegment(lines[0].pl0, lines[0].pl1).isPointOver(pli))
{
pli = lines[0].pl1;
}
}
- double curTC = texCoords[0];
+ float curTC = texCoords[0];
switch (lineJoin) {
case LJ_MITER:
- pVertexArray->appendPos(pli, DPoint(curTC,1), color);
- pVertexArray->appendPos(pri, DPoint(curTC,0), color);
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
break;
case LJ_BEVEL: {
if (tri.isClockwise()) {
- pVertexArray->appendPos(lines[0].pl0, DPoint(curTC,1), color);
- pVertexArray->appendPos(pri, DPoint(curTC,0), color);
+ pVertexData->appendPos(lines[0].pl0, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
} else {
- pVertexArray->appendPos(pli, DPoint(curTC,1), color);
- pVertexArray->appendPos(lines[0].pr0, DPoint(curTC,0), color);
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(lines[0].pr0, glm::vec2(curTC,0), color);
}
}
break;
@@ -393,8 +389,8 @@ void VectorNode::calcPolyLine(const vector<DPoint>& origPts,
break;
}
} else {
- pVertexArray->appendPos(lines[0].pl0, DPoint(texCoords[0],1), color);
- pVertexArray->appendPos(lines[0].pr0, DPoint(texCoords[0],0), color);
+ pVertexData->appendPos(lines[0].pl0, glm::vec2(texCoords[0],1), color);
+ pVertexData->appendPos(lines[0].pr0, glm::vec2(texCoords[0],0), color);
}
// All complete line segments
@@ -412,53 +408,55 @@ void VectorNode::calcPolyLine(const vector<DPoint>& origPts,
} else {
pLine2 = &(lines[i+1]);
}
- DPoint pli = getLineLineIntersection(pLine1->pl0, pLine1->dir, pLine2->pl0, pLine2->dir);
- DPoint pri = getLineLineIntersection(pLine1->pr0, pLine1->dir, pLine2->pr0, pLine2->dir);
+ glm::vec2 pli = getLineLineIntersection(pLine1->pl0, pLine1->dir, pLine2->pl0,
+ pLine2->dir);
+ glm::vec2 pri = getLineLineIntersection(pLine1->pr0, pLine1->dir, pLine2->pr0,
+ pLine2->dir);
Triangle tri(pLine1->pl1, pLine2->pl0, pri);
if (tri.isClockwise()) {
- if (!DLineSegment(pLine1->pr0, pLine1->pr1).isPointOver(pri) &&
- !DLineSegment(pLine2->pr0, pLine2->pr1).isPointOver(pri))
+ if (!LineSegment(pLine1->pr0, pLine1->pr1).isPointOver(pri) &&
+ !LineSegment(pLine2->pr0, pLine2->pr1).isPointOver(pri))
{
pri = pLine2->pr1;
}
} else {
- if (!DLineSegment(pLine1->pl0, pLine1->pl1).isPointOver(pli) &&
- !DLineSegment(pLine2->pl0, pLine2->pl1).isPointOver(pli))
+ if (!LineSegment(pLine1->pl0, pLine1->pl1).isPointOver(pli) &&
+ !LineSegment(pLine2->pl0, pLine2->pl1).isPointOver(pli))
{
pli = pLine2->pl1;
}
}
- int curVertex = pVertexArray->getCurVert();
- double curTC = texCoords[i+1];
+ int curVertex = pVertexData->getNumVerts();
+ float curTC = texCoords[i+1];
switch (lineJoin) {
case LJ_MITER:
- pVertexArray->appendPos(pli, DPoint(curTC,1), color);
- pVertexArray->appendPos(pri, DPoint(curTC,0), color);
- pVertexArray->appendQuadIndexes(
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(
curVertex-1, curVertex-2, curVertex+1, curVertex);
break;
case LJ_BEVEL:
{
- double TC0;
- double TC1;
+ float TC0;
+ float TC1;
if (tri.isClockwise()) {
calcBevelTC(*pLine1, *pLine2, true, texCoords, i+1, TC0, TC1);
- pVertexArray->appendPos(pLine1->pl1, DPoint(TC0,1), color);
- pVertexArray->appendPos(pLine2->pl0, DPoint(TC1,1), color);
- pVertexArray->appendPos(pri, DPoint(curTC,0), color);
- pVertexArray->appendQuadIndexes(
+ pVertexData->appendPos(pLine1->pl1, glm::vec2(TC0,1), color);
+ pVertexData->appendPos(pLine2->pl0, glm::vec2(TC1,1), color);
+ pVertexData->appendPos(pri, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(
curVertex-1, curVertex-2, curVertex+2, curVertex);
- pVertexArray->appendTriIndexes(
+ pVertexData->appendTriIndexes(
curVertex, curVertex+1, curVertex+2);
} else {
calcBevelTC(*pLine1, *pLine2, false, texCoords, i+1, TC0, TC1);
- pVertexArray->appendPos(pLine1->pr1, DPoint(TC0,0), color);
- pVertexArray->appendPos(pli, DPoint(curTC,1), color);
- pVertexArray->appendPos(pLine2->pr0, DPoint(TC1,0), color);
- pVertexArray->appendQuadIndexes(
+ pVertexData->appendPos(pLine1->pr1, glm::vec2(TC0,0), color);
+ pVertexData->appendPos(pli, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(pLine2->pr0, glm::vec2(TC1,0), color);
+ pVertexData->appendQuadIndexes(
curVertex-2, curVertex-1, curVertex+1, curVertex);
- pVertexArray->appendTriIndexes(
+ pVertexData->appendTriIndexes(
curVertex, curVertex+1, curVertex+2);
}
}
@@ -470,49 +468,54 @@ void VectorNode::calcPolyLine(const vector<DPoint>& origPts,
// Last segment (PolyLine only)
if (!bIsClosed) {
- int curVertex = pVertexArray->getCurVert();
- double curTC = texCoords[numPts-1];
- pVertexArray->appendPos(lines[numPts-2].pl1, DPoint(curTC,1), color);
- pVertexArray->appendPos(lines[numPts-2].pr1, DPoint(curTC,0), color);
- pVertexArray->appendQuadIndexes(curVertex-1, curVertex-2, curVertex+1, curVertex);
+ int curVertex = pVertexData->getNumVerts();
+ float curTC = texCoords[numPts-1];
+ pVertexData->appendPos(lines[numPts-2].pl1, glm::vec2(curTC,1), color);
+ pVertexData->appendPos(lines[numPts-2].pr1, glm::vec2(curTC,0), color);
+ pVertexData->appendQuadIndexes(curVertex-1, curVertex-2, curVertex+1, curVertex);
}
}
void VectorNode::calcBevelTC(const WideLine& line1, const WideLine& line2,
- bool bIsLeft, const vector<double>& texCoords, unsigned i,
- double& TC0, double& TC1)
+ bool bIsLeft, const vector<float>& texCoords, unsigned i,
+ float& TC0, float& TC1)
{
- double line1Len = line1.getLen();
- double line2Len = line2.getLen();
- double triLen;
+ float line1Len = line1.getLen();
+ float line2Len = line2.getLen();
+ float triLen;
if (bIsLeft) {
- triLen = calcDist(line1.pl1, line2.pl0);
+ triLen = glm::length(line1.pl1 - line2.pl0);
} else {
- triLen = calcDist(line1.pr1, line2.pr0);
+ triLen = glm::length(line1.pr1 - line2.pr0);
}
- double ratio0 = line1Len/(line1Len+triLen/2);
+ float ratio0 = line1Len/(line1Len+triLen/2);
TC0 = (1-ratio0)*texCoords[i-1]+ratio0*texCoords[i];
- double nextTexCoord;
+ float nextTexCoord;
if (i == texCoords.size()-1) {
nextTexCoord = texCoords[i];
} else {
nextTexCoord = texCoords[i+1];
}
- double ratio1 = line2Len/(line2Len+triLen/2);
+ float ratio1 = line2Len/(line2Len+triLen/2);
TC1 = ratio1*texCoords[i]+(1-ratio1)*nextTexCoord;
}
-int VectorNode::getNumDifferentPts(const vector<DPoint>& pts)
+int VectorNode::getNumDifferentPts(const vector<glm::vec2>& pts)
{
int numPts = pts.size();
for (unsigned i=1; i<pts.size(); ++i) {
- if (calcDistSquared(pts[i], pts[i-1])<0.1) {
+ if (glm::distance2(pts[i], pts[i-1])<0.1) {
numPts--;
}
}
return numPts;
}
+const glm::mat4& VectorNode::getTransform() const
+{
+ return m_Transform;
+}
+
Shape* VectorNode::createDefaultShape() const
{
return new Shape(MaterialInfo(GL_REPEAT, GL_CLAMP_TO_EDGE, false));
diff --git a/src/player/VectorNode.h b/src/player/VectorNode.h
index d17c7c4..4568342 100644
--- a/src/player/VectorNode.h
+++ b/src/player/VectorNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -40,7 +40,7 @@ class AVG_API VectorNode : public Node
public:
enum LineJoin {LJ_MITER, LJ_BEVEL};
- static NodeDefinition createDefinition();
+ static void registerType();
VectorNode(const ArgList& args);
virtual ~VectorNode();
@@ -56,17 +56,18 @@ class AVG_API VectorNode : public Node
const std::string& getBlendModeStr() const;
void setBlendModeStr(const std::string& sBlendMode);
- virtual void preRender();
- virtual void maybeRender(const DRect& rect);
- virtual void render(const DRect& rect);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void maybeRender(const glm::mat4& parentTransform);
+ virtual void render();
- virtual void calcVertexes(VertexArrayPtr& pVertexArray, Pixel32 color) = 0;
+ virtual void calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color) = 0;
void setColor(const std::string& sColor);
const std::string& getColor() const;
- void setStrokeWidth(double width);
- double getStrokeWidth() const;
+ void setStrokeWidth(float width);
+ float getStrokeWidth() const;
static LineJoin string2LineJoin(const std::string& s);
static std::string lineJoin2String(LineJoin lineJoin);
@@ -78,33 +79,35 @@ class AVG_API VectorNode : public Node
void setDrawNeeded();
bool isDrawNeeded();
bool hasVASizeChanged();
- void calcPolyLineCumulDist(std::vector<double>& cumulDist,
- const std::vector<DPoint>& pts, bool bIsClosed);
- void calcEffPolyLineTexCoords(std::vector<double>& effTC,
- const std::vector<double>& tc, const std::vector<double>& cumulDist);
-
- void calcPolyLine(const std::vector<DPoint>& origPts,
- const std::vector<double>& origTexCoords, bool bIsClosed, LineJoin lineJoin,
- VertexArrayPtr& pVertexArray, Pixel32 color);
+ void calcPolyLineCumulDist(std::vector<float>& cumulDist,
+ const std::vector<glm::vec2>& pts, bool bIsClosed);
+ void calcEffPolyLineTexCoords(std::vector<float>& effTC,
+ const std::vector<float>& tc, const std::vector<float>& cumulDist);
+
+ void calcPolyLine(const std::vector<glm::vec2>& origPts,
+ const std::vector<float>& origTexCoords, bool bIsClosed,
+ LineJoin lineJoin, const VertexDataPtr& pVertexData, Pixel32 color);
void calcBevelTC(const WideLine& line1, const WideLine& line2,
- bool bIsLeft, const std::vector<double>& texCoords, unsigned i,
- double& TC0, double& TC1);
- int getNumDifferentPts(const std::vector<DPoint>& pts);
+ bool bIsLeft, const std::vector<float>& texCoords, unsigned i,
+ float& TC0, float& TC1);
+ int getNumDifferentPts(const std::vector<glm::vec2>& pts);
+
+ protected:
+ const glm::mat4& getTransform() const;
private:
Shape* createDefaultShape() const;
- private:
std::string m_sColorName;
Pixel32 m_Color;
- double m_StrokeWidth;
+ float m_StrokeWidth;
UTF8String m_TexHRef;
std::string m_sBlendMode;
bool m_bDrawNeeded;
bool m_bVASizeChanged;
- double m_OldOpacity;
+ glm::mat4 m_Transform;
ShapePtr m_pShape;
GLContext::BlendMode m_BlendMode;
};
diff --git a/src/player/VersionInfo.cpp b/src/player/VersionInfo.cpp
new file mode 100644
index 0000000..3ab861b
--- /dev/null
+++ b/src/player/VersionInfo.cpp
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "VersionInfo.h"
+#include "../version.h"
+
+namespace avg {
+
+const std::string VersionInfo::getFull()
+{
+ return std::string(AVG_VERSION_FULL);
+}
+
+const std::string VersionInfo::getRelease()
+{
+ return std::string(AVG_VERSION_RELEASE);
+}
+
+const std::string VersionInfo::getBranchUrl()
+{
+ return std::string(AVG_VERSION_BRANCH_URL);
+}
+
+const std::string VersionInfo::getBuilder()
+{
+ return std::string(AVG_VERSION_BUILDER);
+}
+
+const std::string VersionInfo::getBuildTime()
+{
+ return std::string(AVG_VERSION_BUILDTIME);
+}
+
+const std::string VersionInfo::getMajor()
+{
+ return AVG_VERSION_MAJOR;
+}
+
+const std::string VersionInfo::getMinor()
+{
+ return AVG_VERSION_MINOR;
+}
+
+const std::string VersionInfo::getMicro()
+{
+ return AVG_VERSION_MICRO;
+}
+
+int VersionInfo::getRevision()
+{
+ return AVG_VERSION_REVISION;
+}
+
+}
diff --git a/src/player/VersionInfo.h b/src/player/VersionInfo.h
new file mode 100644
index 0000000..5a01e7e
--- /dev/null
+++ b/src/player/VersionInfo.h
@@ -0,0 +1,47 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _VersionInfo_H_
+#define _VersionInfo_H_
+
+#include "../api.h"
+#include <string>
+
+namespace avg {
+
+class AVG_API VersionInfo
+{
+ public:
+ const std::string getFull();
+ const std::string getRelease();
+ const std::string getBranchUrl();
+ const std::string getBuilder();
+ const std::string getBuildTime();
+ const std::string getMajor();
+ const std::string getMinor();
+ const std::string getMicro();
+ int getRevision();
+};
+
+}
+
+#endif
+
diff --git a/src/player/VideoNode.cpp b/src/player/VideoNode.cpp
index 0df4129..75b2ccc 100644
--- a/src/player/VideoNode.cpp
+++ b/src/player/VideoNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,22 +21,26 @@
#include "VideoNode.h"
#include "Player.h"
#include "OGLSurface.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Canvas.h"
#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"
+#include "../base/ObjectCounter.h"
#include "../graphics/Filterfill.h"
#include "../graphics/GLTexture.h"
#include "../graphics/TextureMover.h"
-#include "../audio/SDLAudioEngine.h"
+#include "../audio/AudioEngine.h"
#include "../video/AsyncVideoDecoder.h"
-#include "../video/FFMpegDecoder.h"
+#include "../video/SyncVideoDecoder.h"
+#ifdef AVG_ENABLE_VDPAU
+#include "../video/VDPAUDecoder.h"
+#endif
#include <iostream>
#include <sstream>
@@ -45,25 +49,28 @@
#include <unistd.h>
#endif
-using namespace boost::python;
+using namespace boost;
using namespace std;
namespace avg {
-NodeDefinition VideoNode::createDefinition()
+void VideoNode::registerType()
{
- return NodeDefinition("video", Node::buildNode<VideoNode>)
- .extendDefinition(RasterNode::createDefinition())
+ TypeDefinition def = TypeDefinition("video", "rasternode",
+ ExportedObject::buildObject<VideoNode>)
.addArg(Arg<UTF8String>("href", "", false, offsetof(VideoNode, m_href)))
.addArg(Arg<bool>("loop", false, false, offsetof(VideoNode, m_bLoop)))
.addArg(Arg<bool>("threaded", true, false, offsetof(VideoNode, m_bThreaded)))
- .addArg(Arg<double>("fps", 0.0, false, offsetof(VideoNode, m_FPS)))
+ .addArg(Arg<float>("fps", 0.0, false, offsetof(VideoNode, m_FPS)))
.addArg(Arg<int>("queuelength", 8, false,
offsetof(VideoNode, m_QueueLength)))
- .addArg(Arg<double>("volume", 1.0, false, offsetof(VideoNode, m_Volume)))
+ .addArg(Arg<float>("volume", 1.0, false, offsetof(VideoNode, m_Volume)))
.addArg(Arg<bool>("accelerated", false, false,
offsetof(VideoNode, m_bUsesHardwareAcceleration)))
+ .addArg(Arg<bool>("enablesound", true, false,
+ offsetof(VideoNode, m_bEnableSound)))
;
+ TypeRegistry::get()->registerType(def);
}
VideoNode::VideoNode(const ArgList& args)
@@ -78,7 +85,9 @@ VideoNode::VideoNode(const ArgList& args)
m_SeekBeforeCanRenderTime(0),
m_pDecoder(0),
m_Volume(1.0),
- m_bUsesHardwareAcceleration(false)
+ m_bUsesHardwareAcceleration(false),
+ m_bEnableSound(true),
+ m_AudioID(-1)
{
args.setMembers(this);
m_Filename = m_href;
@@ -88,11 +97,11 @@ VideoNode::VideoNode(const ArgList& args)
"Can't set queue length for unthreaded videos because there is no decoder queue in this case.");
}
if (m_bThreaded) {
- VideoDecoderPtr pSyncDecoder = VideoDecoderPtr(new FFMpegDecoder());
- m_pDecoder = new AsyncVideoDecoder(pSyncDecoder, m_QueueLength);
+ m_pDecoder = new AsyncVideoDecoder(m_QueueLength);
} else {
- m_pDecoder = new FFMpegDecoder();
+ m_pDecoder = new SyncVideoDecoder();
}
+
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -124,6 +133,7 @@ void VideoNode::connectDisplay()
void VideoNode::connect(CanvasPtr pCanvas)
{
pCanvas->registerFrameEndListener(this);
+ checkReload();
RasterNode::connect(pCanvas);
}
@@ -183,7 +193,7 @@ void VideoNode::seekToFrame(int frameNum)
}
exceptionIfUnloaded("seekToFrame");
if (getCurFrame() != frameNum) {
- long long destTime = (long long)(frameNum*1000.0/m_pDecoder->getNominalFPS());
+ long long destTime = (long long)(frameNum*1000.0/m_pDecoder->getStreamFPS());
seek(destTime);
}
}
@@ -200,11 +210,32 @@ long long VideoNode::getDuration() const
return (long long)(m_pDecoder->getVideoInfo().m_Duration*1000);
}
+long long VideoNode::getVideoDuration() const
+{
+ exceptionIfUnloaded("getVideoDuration");
+ return (long long)(m_pDecoder->getVideoInfo().m_VideoDuration*1000);
+}
+
+long long VideoNode::getAudioDuration() const
+{
+ exceptionIfUnloaded("getAudioDuration");
+ if (!hasAudio()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "Video has no audio track.");
+ }
+
+ return (long long)(m_pDecoder->getVideoInfo().m_AudioDuration*1000);
+}
+
int VideoNode::getBitrate() const
{
exceptionIfUnloaded("getBitrate");
return m_pDecoder->getVideoInfo().m_Bitrate;
}
+std::string VideoNode::getContainerFormat() const
+{
+ exceptionIfUnloaded("getContainerFormat");
+ return m_pDecoder->getVideoInfo().m_sContainerFormat;
+}
string VideoNode::getVideoCodec() const
{
@@ -286,6 +317,8 @@ void VideoNode::setEOFCallback(PyObject * pEOFCallback)
if (pEOFCallback == Py_None) {
m_pEOFCallback = 0;
} else {
+ avgDeprecationWarning("1.8", "VideoNode.setEOFCallback()",
+ "Node.subscribe(END_OF_FILE)");
Py_INCREF(pEOFCallback);
m_pEOFCallback = pEOFCallback;
}
@@ -308,19 +341,19 @@ void VideoNode::setHRef(const UTF8String& href)
checkReload();
}
-double VideoNode::getVolume()
+float VideoNode::getVolume()
{
return m_Volume;
}
-void VideoNode::setVolume(double Volume)
+void VideoNode::setVolume(float volume)
{
- if (Volume < 0) {
- Volume = 0;
+ if (volume < 0) {
+ volume = 0;
}
- m_Volume = Volume;
- if (m_VideoState != Unloaded && hasAudio()) {
- m_pDecoder->setVolume(Volume);
+ m_Volume = volume;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->setSourceVolume(m_AudioID, volume);
}
}
@@ -345,62 +378,65 @@ void VideoNode::checkReload()
void VideoNode::onFrameEnd()
{
+ AsyncVideoDecoder* pAsyncDecoder = dynamic_cast<AsyncVideoDecoder*>(m_pDecoder);
+ if (pAsyncDecoder && (m_VideoState == Playing || m_VideoState == Paused)) {
+ pAsyncDecoder->updateAudioStatus();
+ }
if (m_bEOFPending) {
// If the VideoNode is unlinked by python in onEOF, the following line prevents
// the object from being deleted until we return from this function.
- NodePtr pTempThis = shared_from_this();
+ NodePtr pTempThis = getSharedThis();
m_bEOFPending = false;
onEOF();
}
}
-int VideoNode::fillAudioBuffer(AudioBufferPtr pBuffer)
-{
- AVG_ASSERT(m_bThreaded);
- if (m_VideoState == Playing) {
- return m_pDecoder->fillAudioBuffer(pBuffer);
- } else {
- return 0;
- }
-}
-
-void VideoNode::changeVideoState(VideoState NewVideoState)
+void VideoNode::changeVideoState(VideoState newVideoState)
{
long long curTime = Player::get()->getFrameTime();
- if (m_VideoState == NewVideoState) {
+ if (m_VideoState == newVideoState) {
return;
}
if (m_VideoState == Unloaded) {
m_PauseStartTime = curTime;
open();
}
- if (NewVideoState == Unloaded) {
+ if (newVideoState == Unloaded) {
close();
}
if (getState() == NS_CANRENDER) {
if (m_VideoState == Unloaded) {
startDecoding();
}
- if (NewVideoState == Paused) {
+ if (newVideoState == Paused) {
m_PauseStartTime = curTime;
- } else if (NewVideoState == Playing && m_VideoState == Paused) {
+ if (m_AudioID != -1) {
+ AudioEngine::get()->pauseSource(m_AudioID);
+ }
+ } else if (newVideoState == Playing && m_VideoState == Paused) {
/*
cerr << "Play after pause:" << endl;
cerr << " getFrameTime()=" << curTime << endl;
cerr << " m_PauseStartTime=" << m_PauseStartTime << endl;
cerr << " offset=" << (1000.0/m_pDecoder->getFPS()) << endl;
*/
+ if (m_AudioID != -1) {
+ AudioEngine::get()->playSource(m_AudioID);
+ }
m_PauseTime += (curTime-m_PauseStartTime
- (long long)(1000.0/m_pDecoder->getFPS()));
}
}
- m_VideoState = NewVideoState;
+ m_VideoState = newVideoState;
}
void VideoNode::seek(long long destTime)
{
if (getState() == NS_CANRENDER) {
- m_pDecoder->seek(double(destTime)/1000.0);
+ if (m_AudioID != -1) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ }
+ m_pDecoder->seek(float(destTime)/1000.0f);
m_StartTime = Player::get()->getFrameTime() - destTime;
m_JitterCompensation = 0.5;
m_PauseTime = 0;
@@ -419,8 +455,7 @@ void VideoNode::open()
m_FramesTooLate = 0;
m_FramesInRowTooLate = 0;
m_FramesPlayed = 0;
- m_pDecoder->open(m_Filename, m_bThreaded, m_bUsesHardwareAcceleration);
- m_pDecoder->setVolume(m_Volume);
+ m_pDecoder->open(m_Filename, m_bUsesHardwareAcceleration, m_bEnableSound);
VideoInfo videoInfo = m_pDecoder->getVideoInfo();
if (!videoInfo.m_bHasVideo) {
m_pDecoder->close();
@@ -431,34 +466,38 @@ void VideoNode::open()
m_JitterCompensation = 0.5;
m_PauseTime = 0;
+ m_bSeekPending = false;
m_bFirstFrameDecoded = false;
m_bFrameAvailable = false;
m_bUsesHardwareAcceleration = videoInfo.m_bUsesVDPAU;
+ setViewport(-32767, -32767, -32767, -32767);
}
void VideoNode::startDecoding()
{
const AudioParams * pAP = 0;
- SDLAudioEngine* pAudioEngine = SDLAudioEngine::get();
+ AudioEngine* pAudioEngine = AudioEngine::get();
if (pAudioEngine) {
pAP = pAudioEngine->getParams();
}
- m_pDecoder->startDecoding(GLContext::getCurrent()->isUsingShaders(), pAP);
+ m_pDecoder->startDecoding(GLContext::getMain()->useGPUYUVConversion(), pAP);
VideoInfo videoInfo = m_pDecoder->getVideoInfo();
if (m_FPS != 0.0) {
if (videoInfo.m_bHasAudio) {
- AVG_TRACE(Logger::WARNING,
- getID() + ": Can't set FPS if video contains audio. Ignored.");
+ AVG_LOG_WARNING(getID() + ": Can't set FPS if video contains audio. Ignored.");
} else {
m_pDecoder->setFPS(m_FPS);
}
}
if (videoInfo.m_bHasAudio && pAudioEngine) {
- pAudioEngine->addSource(this);
+ AsyncVideoDecoder* pAsyncDecoder =
+ dynamic_cast<AsyncVideoDecoder*>(m_pDecoder);
+ m_AudioID = pAudioEngine->addSource(*pAsyncDecoder->getAudioMsgQ(),
+ *pAsyncDecoder->getAudioStatusQ());
+ pAudioEngine->setSourceVolume(m_AudioID, m_Volume);
}
m_bSeekPending = true;
- setViewport(-32767, -32767, -32767, -32767);
createTextures(videoInfo.m_Size);
if (m_SeekBeforeCanRenderTime != 0) {
@@ -474,8 +513,8 @@ void VideoNode::createTextures(IntPoint size)
if (pixelFormatIsPlanar(pf)) {
m_pTextures[0] = GLTexturePtr(new GLTexture(size, I8, bMipmap));
IntPoint halfSize(size.x/2, size.y/2);
- m_pTextures[1] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap));
- m_pTextures[2] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap));
+ m_pTextures[1] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap, 128));
+ m_pTextures[2] = GLTexturePtr(new GLTexture(halfSize, I8, bMipmap, 128));
if (pixelFormatHasAlpha(pf)) {
m_pTextures[3] = GLTexturePtr(new GLTexture(size, I8, bMipmap));
}
@@ -501,13 +540,15 @@ void VideoNode::createTextures(IntPoint size)
} else {
getSurface()->create(pf, m_pTextures[0]);
}
+ newSurface();
}
void VideoNode::close()
{
- SDLAudioEngine* pAudioEngine = SDLAudioEngine::get();
- if (hasAudio() && pAudioEngine) {
- pAudioEngine->removeSource(this);
+ AudioEngine* pAudioEngine = AudioEngine::get();
+ if (m_AudioID != -1) {
+ pAudioEngine->removeSource(m_AudioID);
+ m_AudioID = -1;
}
m_pDecoder->close();
if (m_FramesTooLate > 0) {
@@ -517,8 +558,9 @@ void VideoNode::close()
} else {
sID = getID();
}
- AVG_TRACE(Logger::PROFILE_VIDEO, "Missed video frames for '" << sID << "': "
- << m_FramesTooLate << " of " << m_FramesPlayed);
+ AVG_TRACE(Logger::category::PROFILE_VIDEO, Logger::severity::INFO,
+ "Missed video frames for '" << sID << "': " << m_FramesTooLate <<
+ " of " << m_FramesPlayed);
m_FramesTooLate = 0;
}
}
@@ -537,7 +579,7 @@ IntPoint VideoNode::getMediaSize()
}
}
-double VideoNode::getFPS() const
+float VideoNode::getFPS() const
{
return m_pDecoder->getFPS();
}
@@ -553,6 +595,7 @@ long long VideoNode::getNextFrameTime() const
case Unloaded:
return 0;
case Paused:
+ AVG_ASSERT(m_PauseStartTime-m_StartTime >= 0);
return m_PauseStartTime-m_StartTime;
case Playing:
{
@@ -596,10 +639,11 @@ void VideoNode::exceptionIfUnloaded(const std::string& sFuncName) const
static ProfilingZoneID PrerenderProfilingZone("VideoNode::prerender");
-void VideoNode::preRender()
+void VideoNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
ScopeTimer timer(PrerenderProfilingZone);
- Node::preRender();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
if (isVisible()) {
if (m_VideoState != Unloaded) {
if (m_VideoState == Playing) {
@@ -616,35 +660,36 @@ void VideoNode::preRender()
}
}
} else {
- if (m_bSeekPending && m_bFirstFrameDecoded && m_VideoState != Unloaded) {
+ if (m_VideoState != Unloaded && m_bSeekPending && m_bFirstFrameDecoded) {
renderFrame();
}
if (m_VideoState == Playing) {
// Throw away frames that are not visible to make sure the video
// stays in sync.
- m_pDecoder->throwAwayFrame(getNextFrameTime()/1000.0);
+ m_pDecoder->throwAwayFrame(getNextFrameTime()/1000.0f);
if (m_pDecoder->isEOF()) {
updateStatusDueToDecoderEOF();
}
}
}
+ calcVertexArray(pVA);
}
static ProfilingZoneID RenderProfilingZone("VideoNode::render");
-void VideoNode::render(const DRect& rect)
+void VideoNode::render()
{
ScopeTimer timer(RenderProfilingZone);
if (m_VideoState != Unloaded && m_bFirstFrameDecoded) {
- blt32(getSize(), getEffectiveOpacity(), getBlendMode());
+ blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode());
}
}
VideoNode::VideoAccelType VideoNode::getVideoAccelConfig()
{
#ifdef AVG_ENABLE_VDPAU
- if (VDPAU::isAvailable()) {
+ if (VDPAUDecoder::isAvailable()) {
return VDPAU;
}
#endif
@@ -653,12 +698,26 @@ VideoNode::VideoAccelType VideoNode::getVideoAccelConfig()
bool VideoNode::renderFrame()
{
- FrameAvailableCode frameAvailable = renderToSurface();
+ FrameAvailableCode frameAvailable =
+ m_pDecoder->renderToTexture(m_pTextures, getNextFrameTime()/1000.0f);
+
+ // Even with vsync, frame duration has a bit of jitter. If the video frames rendered
+ // are at the border of a frame's time, this can cause irregular display times.
+ // So, if we detect this condition, we adjust the frame time by a small fraction
+ // to move it towards the center of the time slot.
+ long long jitter = (long long)(getNextFrameTime()-m_pDecoder->getCurTime()*1000);
+ if (jitter > (long long)(0.4*(1000/m_pDecoder->getFPS()))) {
+ m_JitterCompensation += 0.05;
+ if (m_JitterCompensation > 1) {
+ m_JitterCompensation -= 1;
+ }
+ }
+
if (m_pDecoder->isEOF()) {
-// AVG_TRACE(Logger::PROFILE, "------------------ EOF -----------------");
updateStatusDueToDecoderEOF();
if (m_bLoop) {
- frameAvailable = renderToSurface();
+ frameAvailable =
+ m_pDecoder->renderToTexture(m_pTextures, getNextFrameTime()/1000.0f);
}
}
@@ -666,17 +725,16 @@ bool VideoNode::renderFrame()
case FA_NEW_FRAME:
m_FramesPlayed++;
m_FramesInRowTooLate = 0;
- bind();
m_bSeekPending = false;
setMaskCoords();
-// AVG_TRACE(Logger::PROFILE, "New frame.");
+// AVG_TRACE(Logger::category::PROFILE, "New frame.");
break;
case FA_STILL_DECODING:
{
m_FramesPlayed++;
m_FramesTooLate++;
m_FramesInRowTooLate++;
- double framerate = Player::get()->getEffectiveFramerate();
+ float framerate = Player::get()->getEffectiveFramerate();
long long frameTime = Player::get()->getFrameTime();
if (m_VideoState == Playing) {
if (m_FramesInRowTooLate > 3 && framerate != 0) {
@@ -702,50 +760,18 @@ bool VideoNode::renderFrame()
}
}
}
-// AVG_TRACE(Logger::PROFILE, "Missed video frame.");
+// AVG_TRACE(Logger::category::PROFILE, "Missed video frame.");
break;
case FA_USE_LAST_FRAME:
m_FramesInRowTooLate = 0;
m_bSeekPending = false;
-// AVG_TRACE(Logger::PROFILE, "Video frame reused.");
+// AVG_TRACE(Logger::category::PROFILE, "Video frame reused.");
break;
default:
AVG_ASSERT(false);
}
return (frameAvailable == FA_NEW_FRAME);
- return false;
-}
-
-FrameAvailableCode VideoNode::renderToSurface()
-{
- FrameAvailableCode frameAvailable;
- PixelFormat pf = m_pDecoder->getPixelFormat();
- std::vector<BitmapPtr> pBmps;
- for (unsigned i=0; i<getNumPixelFormatPlanes(pf); ++i) {
- pBmps.push_back(m_pTextures[i]->lockStreamingBmp());
- }
- if (pixelFormatIsPlanar(pf)) {
- frameAvailable = m_pDecoder->renderToBmps(pBmps, getNextFrameTime()/1000.0);
- } else {
- frameAvailable = m_pDecoder->renderToBmp(pBmps[0], getNextFrameTime()/1000.0);
- }
- for (unsigned i=0; i<getNumPixelFormatPlanes(pf); ++i) {
- m_pTextures[i]->unlockStreamingBmp(frameAvailable == FA_NEW_FRAME);
- }
-
- // Even with vsync, frame duration has a bit of jitter. If the video frames rendered
- // are at the border of a frame's time, this can cause irregular display times.
- // So, if we detect this condition, we adjust the frame time by a small fraction
- // to move it towards the center of the time slot.
- long long jitter = (long long)(getNextFrameTime()-m_pDecoder->getCurTime()*1000);
- if (jitter > (long long)(0.4*(1000/m_pDecoder->getFPS()))) {
- m_JitterCompensation += 0.05;
- if (m_JitterCompensation > 1) {
- m_JitterCompensation -= 1;
- }
- }
- return frameAvailable;
}
void VideoNode::onEOF()
@@ -755,22 +781,26 @@ void VideoNode::onEOF()
PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist);
Py_DECREF(arglist);
if (!result) {
- throw error_already_set();
+ throw py::error_already_set();
}
Py_DECREF(result);
}
+ notifySubscribers("END_OF_FILE");
}
-
void VideoNode::updateStatusDueToDecoderEOF()
{
m_bEOFPending = true;
if (m_bLoop) {
m_StartTime = Player::get()->getFrameTime();
+ m_PauseStartTime = Player::get()->getFrameTime();
m_JitterCompensation = 0.5;
m_PauseTime = 0;
m_FramesInRowTooLate = 0;
m_bFrameAvailable = false;
+ if (m_AudioID != -1) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ }
m_pDecoder->loop();
} else {
changeVideoState(Paused);
diff --git a/src/player/VideoNode.h b/src/player/VideoNode.h
index e625e03..2ae2caf 100644
--- a/src/player/VideoNode.h
+++ b/src/player/VideoNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,11 +29,10 @@
#include "Node.h"
#include "RasterNode.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../base/IFrameEndListener.h"
#include "../base/UTF8String.h"
-#include "../audio/IAudioSource.h"
#include "../video/VideoDecoder.h"
namespace avg {
@@ -42,12 +41,12 @@ class VideoDecoder;
class TextureMover;
typedef boost::shared_ptr<TextureMover> TextureMoverPtr;
-class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
+class AVG_API VideoNode: public RasterNode, IFrameEndListener
{
public:
enum VideoAccelType {NONE, VDPAU};
- static NodeDefinition createDefinition();
+ static void registerType();
VideoNode(const ArgList& args);
virtual ~VideoNode();
@@ -62,9 +61,9 @@ class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
const UTF8String& getHRef() const;
void setHRef(const UTF8String& href);
- double getVolume();
- void setVolume(double volume);
- double getFPS() const;
+ float getVolume();
+ void setVolume(float volume);
+ float getFPS() const;
int getQueueLength() const;
void checkReload();
@@ -74,7 +73,10 @@ class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
void seekToFrame(int frameNum);
std::string getStreamPixelFormat() const;
long long getDuration() const;
+ long long getVideoDuration() const;
+ long long getAudioDuration() const;
int getBitrate() const;
+ std::string getContainerFormat() const;
std::string getVideoCodec() const;
std::string getAudioCodec() const;
int getAudioSampleRate() const;
@@ -89,18 +91,17 @@ class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
void setEOFCallback(PyObject * pEOFCallback);
bool isAccelerated() const;
- virtual void render(const DRect& rect);
- virtual void preRender();
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
virtual void onFrameEnd();
- virtual int fillAudioBuffer(AudioBufferPtr pBuffer);
virtual IntPoint getMediaSize();
static VideoAccelType getVideoAccelConfig();
private:
bool renderFrame();
- FrameAvailableCode renderToSurface();
void seek(long long destTime);
void onEOF();
void updateStatusDueToDecoderEOF();
@@ -126,7 +127,7 @@ class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
std::string m_Filename;
bool m_bLoop;
bool m_bThreaded;
- double m_FPS;
+ float m_FPS;
int m_QueueLength;
bool m_bEOFPending;
PyObject * m_pEOFCallback;
@@ -139,11 +140,13 @@ class AVG_API VideoNode: public RasterNode, IFrameEndListener, IAudioSource
long long m_StartTime;
long long m_PauseTime;
long long m_PauseStartTime;
- double m_JitterCompensation;
+ float m_JitterCompensation;
VideoDecoder * m_pDecoder;
- double m_Volume;
+ float m_Volume;
bool m_bUsesHardwareAcceleration;
+ bool m_bEnableSound;
+ int m_AudioID;
GLTexturePtr m_pTextures[4];
};
diff --git a/src/player/VideoWriter.cpp b/src/player/VideoWriter.cpp
index c2c39e9..e91db38 100644
--- a/src/player/VideoWriter.cpp
+++ b/src/player/VideoWriter.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -55,7 +55,12 @@ VideoWriter::VideoWriter(CanvasPtr pCanvas, const string& sOutFileName, int fram
m_StartTime(-1),
m_bFramePending(false)
{
- m_FrameSize = m_pCanvas->getSize();
+ if (!pCanvas) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "VideoWriter needs a canvas to write to.");
+ }
+ if (GLContext::getCurrent()->isGLES()) {
+ throw Exception(AVG_ERR_UNSUPPORTED, "VideoWriter not supported under GLES.");
+ }
#ifdef WIN32
int fd = _open(m_sOutFileName.c_str(), O_RDWR | O_CREAT, _S_IREAD | _S_IWRITE);
#elif defined linux
@@ -75,10 +80,12 @@ VideoWriter::VideoWriter(CanvasPtr pCanvas, const string& sOutFileName, int fram
#endif
remove(m_sOutFileName.c_str());
CanvasPtr pMainCanvas = Player::get()->getMainCanvas();
- if (pMainCanvas != m_pCanvas) {
+ if (pMainCanvas == m_pCanvas) {
+ m_FrameSize = Player::get()->getDisplayEngine()->getWindowSize();
+ } else {
+ m_FrameSize = m_pCanvas->getSize();
m_pFBO = dynamic_pointer_cast<OffscreenCanvas>(m_pCanvas)->getFBO();
- m_pCanvas->registerPreRenderListener(this);
- if (GLContext::getCurrent()->isUsingShaders()) {
+ if (GLContext::getMain()->useGPUYUVConversion()) {
m_pFilter = GPURGB2YUVFilterPtr(new GPURGB2YUVFilter(m_FrameSize));
}
}
@@ -92,8 +99,10 @@ VideoWriter::VideoWriter(CanvasPtr pCanvas, const string& sOutFileName, int fram
VideoWriter::~VideoWriter()
{
stop();
- m_pThread->join();
- delete m_pThread;
+ if (m_pThread) {
+ m_pThread->join();
+ delete m_pThread;
+ }
}
void VideoWriter::stop()
@@ -109,9 +118,6 @@ void VideoWriter::stop()
m_pCanvas->unregisterFrameEndListener(this);
m_pCanvas->unregisterPlaybackEndListener(this);
- if (m_pFBO) {
- m_pCanvas->unregisterPreRenderListener(this);
- }
}
}
@@ -163,8 +169,12 @@ void VideoWriter::onFrameEnd()
// For MainCanvas, it simply does a screenshot onFrameEnd and sends that to the
// VideoWriterThread immediately.
// For OffscreenCanvas, an asynchronous PBO readback is started in onFrameEnd.
- // In the next frame's onPreRender, the data is read into a bitmap and sent to
+ // In the next frame's onFrameEnd, the data is read into a bitmap and sent to
// the VideoWriterThread.
+ if (m_pFBO) {
+ // Read last frame's bitmap.
+ getFrameFromPBO();
+ }
if (m_StartTime == -1) {
m_StartTime = Player::get()->getFrameTime();
}
@@ -174,7 +184,7 @@ void VideoWriter::onFrameEnd()
} else {
long long movieTime = Player::get()->getFrameTime() - m_StartTime
- m_PauseTime;
- double timePerFrame = 1000./m_FrameRate;
+ float timePerFrame = 1000.f/m_FrameRate;
int wantedFrame = int(movieTime/timePerFrame+0.1);
if (wantedFrame > m_CurFrame) {
getFrameFromFBO();
@@ -190,21 +200,13 @@ void VideoWriter::onFrameEnd()
}
}
-void VideoWriter::onPreRender()
-{
- getFrameFromPBO();
-}
-
void VideoWriter::getFrameFromFBO()
{
if (m_pFBO) {
if (m_pFilter) {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
m_pFilter->apply(m_pFBO->getTex());
FBOPtr pYUVFBO = m_pFilter->getFBO();
pYUVFBO->moveToPBO();
- glPopMatrix();
} else {
m_pFBO->moveToPBO();
}
@@ -243,6 +245,9 @@ void VideoWriter::sendFrameToEncoder(BitmapPtr pBitmap)
void VideoWriter::onPlaybackEnd()
{
stop();
+ m_pThread->join();
+ delete m_pThread;
+ m_pThread = 0;
}
void VideoWriter::writeDummyFrame()
diff --git a/src/player/VideoWriter.h b/src/player/VideoWriter.h
index c372991..ef3f724 100644
--- a/src/player/VideoWriter.h
+++ b/src/player/VideoWriter.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,8 +28,7 @@
#include "../base/IFrameEndListener.h"
#include "../base/IPlaybackEndListener.h"
-#include "../base/IPreRenderListener.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
@@ -45,8 +44,7 @@ typedef boost::shared_ptr<FBO> FBOPtr;
class GPURGB2YUVFilter;
typedef boost::shared_ptr<GPURGB2YUVFilter> GPURGB2YUVFilterPtr;
-class AVG_API VideoWriter : public IFrameEndListener, IPreRenderListener,
- IPlaybackEndListener
+class AVG_API VideoWriter : public IFrameEndListener, IPlaybackEndListener
{
public:
VideoWriter(CanvasPtr pCanvas, const std::string& sOutFileName,
@@ -62,7 +60,6 @@ class AVG_API VideoWriter : public IFrameEndListener, IPreRenderListener,
int getQMax() const;
virtual void onFrameEnd();
- virtual void onPreRender();
virtual void onPlaybackEnd();
private:
diff --git a/src/player/VideoWriterThread.cpp b/src/player/VideoWriterThread.cpp
index 3bb9a32..821df1b 100644
--- a/src/player/VideoWriterThread.cpp
+++ b/src/player/VideoWriterThread.cpp
@@ -1,7 +1,7 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,12 @@
#include "VideoWriterThread.h"
-#include "../base/ProfilingZone.h"
+#include "../base/ProfilingZoneID.h"
#include "../base/ScopeTimer.h"
#include "../base/StringHelper.h"
-#if LIBAVFORMAT_VERSION_MAJOR > 52
-#include <libavutil/mathematics.h>
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 18, 102)
+ typedef CodecID AVCodecID;
#endif
using namespace std;
@@ -35,11 +35,11 @@ using namespace std;
namespace avg {
const unsigned int VIDEO_BUFFER_SIZE = 400000;
-const ::PixelFormat STREAM_PIXEL_FORMAT = ::PIX_FMT_YUVJ420P;
+const AVPixelFormat STREAM_PIXEL_FORMAT = ::PIX_FMT_YUVJ420P;
-VideoWriterThread::VideoWriterThread(CQueue& CmdQueue, const string& sFilename,
+VideoWriterThread::VideoWriterThread(CQueue& cmdQueue, const string& sFilename,
IntPoint size, int frameRate, int qMin, int qMax)
- : WorkerThread<VideoWriterThread>(sFilename, CmdQueue, Logger::PROFILE),
+ : WorkerThread<VideoWriterThread>(sFilename, cmdQueue, Logger::category::PROFILE),
m_sFilename(sFilename),
m_Size(size),
m_FrameRate(frameRate),
@@ -53,7 +53,7 @@ VideoWriterThread::~VideoWriterThread()
{
}
-static ProfilingZoneID ProfilingZoneEncodeFrame("Encode frame");
+static ProfilingZoneID ProfilingZoneEncodeFrame("Encode frame", true);
void VideoWriterThread::encodeYUVFrame(BitmapPtr pBmp)
{
@@ -86,7 +86,11 @@ void VideoWriterThread::close()
}
if (!(m_pOutputFormat->flags & AVFMT_NOFILE)) {
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 8, 0)
+ avio_close(m_pOutputFormatContext->pb);
+#else
url_fclose(m_pOutputFormatContext->pb);
+#endif
}
av_free(m_pOutputFormatContext);
@@ -120,9 +124,9 @@ void VideoWriterThread::open()
av_register_all(); // TODO: make sure this is only done once.
// av_log_set_level(AV_LOG_DEBUG);
#if LIBAVFORMAT_VERSION_MAJOR > 52
- m_pOutputFormat = av_guess_format("mov", NULL, NULL);
+ m_pOutputFormat = av_guess_format(0, m_sFilename.c_str(), 0);
#else
- m_pOutputFormat = guess_format("mov", NULL, NULL);
+ m_pOutputFormat = guess_format(0, m_sFilename.c_str(), 0);
#endif
m_pOutputFormat->video_codec = CODEC_ID_MJPEG;
@@ -143,9 +147,7 @@ void VideoWriterThread::open()
av_set_parameters(m_pOutputFormatContext, NULL);
#endif
- double muxPreload = 0.5;
- double muxMaxDelay = 0.7;
- m_pOutputFormatContext->preload = int(muxPreload * AV_TIME_BASE);
+ float muxMaxDelay = 0.7;
m_pOutputFormatContext->max_delay = int(muxMaxDelay * AV_TIME_BASE);
// av_dump_format(m_pOutputFormatContext, 0, m_sFilename.c_str(), 1);
@@ -158,8 +160,13 @@ void VideoWriterThread::open()
}
if (!(m_pOutputFormat->flags & AVFMT_NOFILE)) {
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 8, 0)
+ int retVal = avio_open(&m_pOutputFormatContext->pb, m_sFilename.c_str(),
+ URL_WRONLY);
+#else
int retVal = url_fopen(&m_pOutputFormatContext->pb, m_sFilename.c_str(),
URL_WRONLY);
+#endif
if (retVal < 0) {
throw Exception(AVG_ERR_VIDEO_INIT_FAILED,
string("Could not open output file: '") + m_sFilename + "'");
@@ -181,10 +188,14 @@ void VideoWriterThread::open()
void VideoWriterThread::setupVideoStream()
{
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 21, 0)
+ m_pVideoStream = avformat_new_stream(m_pOutputFormatContext, 0);
+#else
m_pVideoStream = av_new_stream(m_pOutputFormatContext, 0);
+#endif
AVCodecContext* pCodecContext = m_pVideoStream->codec;
- pCodecContext->codec_id = static_cast<CodecID>(m_pOutputFormat->video_codec);
+ pCodecContext->codec_id = static_cast<AVCodecID>(m_pOutputFormat->video_codec);
pCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
/* put sample parameters */
@@ -215,11 +226,16 @@ void VideoWriterThread::openVideoCodec()
AVCodec* videoCodec = avcodec_find_encoder(m_pVideoStream->codec->codec_id);
AVG_ASSERT(videoCodec);
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 8, 0)
+ int rc = avcodec_open2(m_pVideoStream->codec, videoCodec, 0);
+
+#else
int rc = avcodec_open(m_pVideoStream->codec, videoCodec);
+#endif
AVG_ASSERT(rc == 0);
}
-AVFrame* VideoWriterThread::createFrame(::PixelFormat pixelFormat, IntPoint size)
+AVFrame* VideoWriterThread::createFrame(AVPixelFormat pixelFormat, IntPoint size)
{
AVFrame* pPicture;
@@ -233,7 +249,7 @@ AVFrame* VideoWriterThread::createFrame(::PixelFormat pixelFormat, IntPoint size
return pPicture;
}
-static ProfilingZoneID ProfilingZoneConvertImage(" Convert image");
+static ProfilingZoneID ProfilingZoneConvertImage(" Convert image", true);
void VideoWriterThread::convertRGBImage(BitmapPtr pSrcBmp)
{
@@ -284,7 +300,7 @@ void VideoWriterThread::convertYUVImage(BitmapPtr pSrcBmp)
// pUBmp->save("foo"+toString(m_FramesWritten)+".png");
}
-static ProfilingZoneID ProfilingZoneWriteFrame(" Write frame");
+static ProfilingZoneID ProfilingZoneWriteFrame(" Write frame", true);
void VideoWriterThread::writeFrame(AVFrame* pFrame)
{
@@ -299,7 +315,7 @@ void VideoWriterThread::writeFrame(AVFrame* pFrame)
AVPacket packet;
av_init_packet(&packet);
- if ((unsigned long long)(pCodecContext->coded_frame->pts) != AV_NOPTS_VALUE) {
+ if ((pCodecContext->coded_frame->pts) != (long long)AV_NOPTS_VALUE) {
packet.pts = av_rescale_q(pCodecContext->coded_frame->pts,
pCodecContext->time_base, m_pVideoStream->time_base);
}
diff --git a/src/player/VideoWriterThread.h b/src/player/VideoWriterThread.h
index 6d61c6d..4cefa1e 100644
--- a/src/player/VideoWriterThread.h
+++ b/src/player/VideoWriterThread.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@ namespace avg {
class AVG_API VideoWriterThread : public WorkerThread<VideoWriterThread> {
public:
- VideoWriterThread(CQueue& CmdQueue, const std::string& sFilename, IntPoint size,
+ VideoWriterThread(CQueue& cmdQueue, const std::string& sFilename, IntPoint size,
int frameRate, int qMin, int qMax);
virtual ~VideoWriterThread();
@@ -57,7 +57,7 @@ class AVG_API VideoWriterThread : public WorkerThread<VideoWriterThread> {
void setupVideoStream();
void openVideoCodec();
- AVFrame* createFrame(::PixelFormat pixelFormat, IntPoint size);
+ AVFrame* createFrame(AVPixelFormat pixelFormat, IntPoint size);
void convertRGBImage(BitmapPtr pSrcBmp);
void convertYUVImage(BitmapPtr pSrcBmp);
@@ -76,8 +76,6 @@ class AVG_API VideoWriterThread : public WorkerThread<VideoWriterThread> {
AVFrame* m_pConvertedFrame;
unsigned char* m_pPictureBuffer;
unsigned char* m_pVideoBuffer;
- int m_VideoBufferSize;
- PixelFormat m_StreamPixelFormat;
int m_FramesWritten;
};
diff --git a/src/player/WordsNode.cpp b/src/player/WordsNode.cpp
index be20edb..ba67720 100644
--- a/src/player/WordsNode.cpp
+++ b/src/player/WordsNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "WordsNode.h"
#include "OGLSurface.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "TextEngine.h"
#include "../base/Logger.h"
@@ -46,7 +46,7 @@ using namespace std;
namespace avg {
-NodeDefinition WordsNode::createDefinition()
+void WordsNode::registerType()
{
static const string sDTDElements =
"<!ELEMENT span (#PCDATA|span|b|big|i|s|sub|sup|small|tt|u)*>\n"
@@ -84,42 +84,50 @@ NodeDefinition WordsNode::createDefinition()
"small", "tt", "u", "br"};
vector<string> sChildren = vectorFromCArray(sizeof(sChildArray)/sizeof(*sChildArray),
sChildArray);
- return NodeDefinition("words", Node::buildNode<WordsNode>)
- .extendDefinition(RasterNode::createDefinition())
+ TypeDefinition def = TypeDefinition("words", "rasternode",
+ ExportedObject::buildObject<WordsNode>)
.addChildren(sChildren)
.addDTDElements(sDTDElements)
- .addArg(Arg<string>("font", "arial", false, offsetof(WordsNode, m_sFontName)))
- .addArg(Arg<string>("variant", "", false, offsetof(WordsNode, m_sFontVariant)))
+ .addArg(Arg<string>("font", "sans"))
+ .addArg(Arg<string>("variant", ""))
.addArg(Arg<UTF8String>("text", ""))
- .addArg(Arg<string>("color", "FFFFFF", false, offsetof(WordsNode, m_sColorName)))
- .addArg(Arg<double>("fontsize", 15, false, offsetof(WordsNode, m_FontSize)))
- .addArg(Arg<int>("indent", 0, false, offsetof(WordsNode, m_Indent)))
- .addArg(Arg<double>("linespacing", -1, false, offsetof(WordsNode, m_LineSpacing)))
+ .addArg(Arg<string>("color", "FFFFFF"))
+ .addArg(Arg<float>("aagamma", 1.0f))
+ .addArg(Arg<float>("fontsize", 15))
+ .addArg(Arg<int>("indent", 0, false))
+ .addArg(Arg<float>("linespacing", 0))
.addArg(Arg<string>("alignment", "left"))
.addArg(Arg<string>("wrapmode", "word"))
- .addArg(Arg<bool>("justify", false, false, offsetof(WordsNode, m_bJustify)))
+ .addArg(Arg<bool>("justify", false))
.addArg(Arg<bool>("rawtextmode", false, false,
offsetof(WordsNode, m_bRawTextMode)))
- .addArg(Arg<double>("letterspacing", 0, false,
- offsetof(WordsNode, m_LetterSpacing)))
- .addArg(Arg<bool>("hint", true, false, offsetof(WordsNode, m_bHint)))
+ .addArg(Arg<float>("letterspacing", 0))
+ .addArg(Arg<bool>("hint", true))
+ .addArg(Arg<FontStyle>("fontstyle", FontStyle()))
;
+ TypeRegistry::get()->registerType(def);
}
WordsNode::WordsNode(const ArgList& args)
: m_LogicalSize(0,0),
m_pFontDescription(0),
m_pLayout(0),
- m_RedrawState(FONT_CHANGED)
+ m_bRenderNeeded(true)
{
m_bParsedText = false;
-
args.setMembers(this);
- setAlignment(args.getArgVal<string>("alignment"));
- setWrapMode(args.getArgVal<string>("wrapmode"));
+
+ m_FontStyle = args.getArgVal<FontStyle>("fontstyle");
+ m_FontStyle.setDefaultedArgs(args);
+#ifdef _WIN32
+ if (m_FontStyle.getFont() == "sans") {
+ m_FontStyle.setFont("Arial");
+ m_FontStyle.setFontVariant("Regular");
+ }
+#endif
+ updateFont();
setText(args.getArgVal<UTF8String>("text"));
- m_Color = colorStringToColor(m_sColorName);
- setViewport(-32767, -32767, -32767, -32767);
+
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -146,7 +154,7 @@ void WordsNode::setTextFromNodeValue(const string& sText)
void WordsNode::connectDisplay()
{
RasterNode::connectDisplay();
- setDirty(FONT_CHANGED);
+ getSurface()->setAlphaGamma(m_FontStyle.getAAGamma());
}
void WordsNode::connect(CanvasPtr pCanvas)
@@ -160,132 +168,126 @@ void WordsNode::disconnect(bool bKill)
if (m_pFontDescription) {
pango_font_description_free(m_pFontDescription);
m_pFontDescription = 0;
- setDirty(FONT_CHANGED);
+ updateFont();
}
RasterNode::disconnect(bKill);
}
string WordsNode::getAlignment() const
{
- switch(m_Alignment) {
- case PANGO_ALIGN_LEFT:
- return "left";
- case PANGO_ALIGN_CENTER:
- return "center";
- case PANGO_ALIGN_RIGHT:
- return "right";
- default:
- AVG_ASSERT(false);
- return "";
- }
+ return m_FontStyle.getAlignment();
}
void WordsNode::setAlignment(const string& sAlign)
{
- if (sAlign == "left") {
- m_Alignment = PANGO_ALIGN_LEFT;
- } else if (sAlign == "center") {
- m_Alignment = PANGO_ALIGN_CENTER;
- } else if (sAlign == "right") {
- m_Alignment = PANGO_ALIGN_RIGHT;
- } else {
- throw(Exception(AVG_ERR_UNSUPPORTED,
- "WordsNode alignment "+sAlign+" not supported."));
- }
-
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setAlignment(sAlign);
+ updateLayout();
}
bool WordsNode::getJustify() const
{
- return m_bJustify;
+ return m_FontStyle.getJustify();
}
void WordsNode::setJustify(bool bJustify)
{
- m_bJustify = bJustify;
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setJustify(bJustify);
+ updateLayout();
}
-double WordsNode::getLetterSpacing() const
+float WordsNode::getLetterSpacing() const
{
- return m_LetterSpacing;
+ return m_FontStyle.getLetterSpacing();
}
-void WordsNode::setLetterSpacing(double letterSpacing)
+void WordsNode::setLetterSpacing(float letterSpacing)
{
- m_LetterSpacing = letterSpacing;
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setLetterSpacing(letterSpacing);
+ updateLayout();
}
bool WordsNode::getHint() const
{
- return m_bHint;
+ return m_FontStyle.getHint();
}
void WordsNode::setHint(bool bHint)
{
- setDirty(LAYOUT_CHANGED);
- m_bHint = bHint;
+ m_FontStyle.setHint(bHint);
+ updateLayout();
}
-double WordsNode::getWidth() const
+float WordsNode::getWidth() const
{
- const_cast<WordsNode*>(this)->updateLayout();
return AreaNode::getWidth();
}
-void WordsNode::setWidth(double width)
+void WordsNode::setWidth(float width)
{
- setDirty(LAYOUT_CHANGED);
AreaNode::setWidth(width);
+ updateLayout();
}
-double WordsNode::getHeight() const
+float WordsNode::getHeight() const
{
- const_cast<WordsNode*>(this)->updateLayout();
return AreaNode::getHeight();
}
-void WordsNode::setHeight(double width)
+void WordsNode::setHeight(float width)
{
- setDirty(LAYOUT_CHANGED);
AreaNode::setHeight(width);
+ updateLayout();
}
-DPoint WordsNode::getSize() const
+glm::vec2 WordsNode::getSize() const
{
- const_cast<WordsNode*>(this)->updateLayout();
return AreaNode::getSize();
}
-void WordsNode::setSize(const DPoint& pt)
+void WordsNode::setSize(const glm::vec2& pt)
{
- setDirty(LAYOUT_CHANGED);
AreaNode::setSize(pt);
+ updateLayout();
}
-void WordsNode::getElementsByPos(const DPoint& pos, vector<NodeWeakPtr>& pElements)
+glm::vec2 WordsNode::toLocal(const glm::vec2& globalPos) const
{
- updateLayout();
- DPoint relPos = pos-DPoint(m_AlignOffset, 0);
- AreaNode::getElementsByPos(relPos, pElements);
+ glm::vec2 localPos = globalPos - getRelViewport().tl - glm::vec2(m_AlignOffset, 0);
+ return getRotatedPivot(localPos, -getAngle(), getPivot());
+}
+
+glm::vec2 WordsNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 alignPos = localPos + glm::vec2(m_AlignOffset, 0);
+ glm::vec2 globalPos = getRotatedPivot(alignPos, getAngle(), getPivot());
+ return globalPos + getRelViewport().tl;
+}
+
+const FontStyle& WordsNode::getFontStyle() const
+{
+ return m_FontStyle;
+}
+
+void WordsNode::setFontStyle(const FontStyle& fontStyle)
+{
+ m_FontStyle = fontStyle;
+ updateFont();
}
const std::string& WordsNode::getFont() const
{
- return m_sFontName;
+ return m_FontStyle.getFont();
}
void WordsNode::setFont(const std::string& sName)
{
- m_sFontName = sName;
- setDirty(FONT_CHANGED);
+ m_FontStyle.setFont(sName);
+ updateFont();
}
const std::string& WordsNode::getFontVariant() const
{
- return m_sFontVariant;
+ return m_FontStyle.getFontVariant();
}
void WordsNode::addFontDir(const std::string& sDir)
@@ -296,8 +298,8 @@ void WordsNode::addFontDir(const std::string& sDir)
void WordsNode::setFontVariant(const std::string& sVariant)
{
- m_sFontVariant = sVariant;
- setDirty(FONT_CHANGED);
+ m_FontStyle.setFontVariant(sVariant);
+ updateFont();
}
const UTF8String& WordsNode::getText() const
@@ -317,59 +319,67 @@ void WordsNode::setText(const UTF8String& sText)
m_sText = m_sRawText;
if (m_bRawTextMode) {
m_bParsedText = false;
+ updateLayout();
} else {
setParsedText(sText);
}
- setDirty(LAYOUT_CHANGED);
}
}
const std::string& WordsNode::getColor() const
{
- return m_sColorName;
+ return m_FontStyle.getColor();
}
void WordsNode::setColor(const string& sColor)
{
- m_sColorName = sColor;
- m_Color = colorStringToColor(m_sColorName);
- setDirty(RENDER_NEEDED);
+ m_FontStyle.setColor(sColor);
+}
+
+float WordsNode::getAAGamma() const
+{
+ return m_FontStyle.getAAGamma();
+}
+
+void WordsNode::setAAGamma(float gamma)
+{
+ m_FontStyle.setAAGamma(gamma);
+ if (getState() == Node::NS_CANRENDER) {
+ getSurface()->setAlphaGamma(gamma);
+ }
}
-double WordsNode::getFontSize() const
+float WordsNode::getFontSize() const
{
- return m_FontSize;
+ return m_FontStyle.getFontSize();
}
-void WordsNode::setFontSize(double size)
+void WordsNode::setFontSize(float size)
{
- if (size <= 1) {
- throw Exception(AVG_ERR_INVALID_ARGS, "Words node: Font size < 1 is illegal.");
- }
- m_FontSize = size;
- setDirty(FONT_CHANGED);
+ m_FontStyle.setFontSize(size);
+ updateFont();
}
int WordsNode::getIndent() const
{
- return m_Indent;
+ return m_FontStyle.getIndent();
}
void WordsNode::setIndent(int indent)
{
- m_Indent = indent;
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setIndent(indent);
+ updateLayout();
}
-double WordsNode::getLineSpacing() const
+float WordsNode::getLineSpacing() const
{
- return m_LineSpacing;
+ return m_FontStyle.getLineSpacing();
}
-void WordsNode::setLineSpacing(double lineSpacing)
+void WordsNode::setLineSpacing(float lineSpacing)
{
- m_LineSpacing = lineSpacing;
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setLineSpacing(lineSpacing);
+ updateLayout();
}
bool WordsNode::getRawTextMode() const
@@ -387,33 +397,34 @@ void WordsNode::setRawTextMode(bool rawTextMode)
setParsedText(m_sText);
}
m_bRawTextMode = rawTextMode;
- setDirty(LAYOUT_CHANGED);
+ updateLayout();
}
}
-DPoint WordsNode::getGlyphPos(int i)
+glm::vec2 WordsNode::getGlyphPos(int i)
{
PangoRectangle rect = getGlyphRect(i);
- return DPoint(double(rect.x)/PANGO_SCALE, double(rect.y)/PANGO_SCALE);
+ return glm::vec2(float(rect.x)/PANGO_SCALE, float(rect.y)/PANGO_SCALE);
}
-DPoint WordsNode::getGlyphSize(int i)
+glm::vec2 WordsNode::getGlyphSize(int i)
{
PangoRectangle rect = getGlyphRect(i);
- return DPoint(double(rect.width)/PANGO_SCALE, double(rect.height)/PANGO_SCALE);
+ return glm::vec2(float(rect.width)/PANGO_SCALE, float(rect.height)/PANGO_SCALE);
}
int WordsNode::getNumLines()
{
- updateLayout();
- return pango_layout_get_line_count(m_pLayout);
+ if(m_sText.length() != 0) {
+ return pango_layout_get_line_count(m_pLayout);
+ }
+ return 0;
}
-PyObject* WordsNode::getCharIndexFromPos(DPoint p)
+PyObject* WordsNode::getCharIndexFromPos(glm::vec2 p)
{
int index;
int trailing;
- updateLayout();
gboolean bXyToIndex = pango_layout_xy_to_index(m_pLayout,
int(p.x*PANGO_SCALE), int(p.y*PANGO_SCALE), &index, &trailing);
if (bXyToIndex) {
@@ -426,52 +437,31 @@ PyObject* WordsNode::getCharIndexFromPos(DPoint p)
std::string WordsNode::getTextAsDisplayed()
{
- updateLayout();
return pango_layout_get_text(m_pLayout);
}
-DPoint WordsNode::getLineExtents(int line)
+glm::vec2 WordsNode::getLineExtents(int line)
{
- if(line < 0 || line >= getNumLines()) {
+ if (line < 0 || line >= getNumLines()) {
throw Exception(AVG_ERR_OUT_OF_RANGE, "WordsNode.getLineExtents: line index "
+toString(line)+" is out of range.");
}
- updateLayout();
PangoRectangle logical_rect;
PangoRectangle ink_rect;
PangoLayoutLine *layoutLine = pango_layout_get_line_readonly(m_pLayout, line);
pango_layout_line_get_pixel_extents(layoutLine, &ink_rect, &logical_rect);
- return DPoint(double(logical_rect.width), double(logical_rect.height));
+ return glm::vec2(float(logical_rect.width), float(logical_rect.height));
}
void WordsNode::setWrapMode(const string& sWrapMode)
{
- if (sWrapMode == "word") {
- m_WrapMode = PANGO_WRAP_WORD;
- } else if (sWrapMode == "char") {
- m_WrapMode = PANGO_WRAP_CHAR;
- } else if (sWrapMode == "wordchar") {
- m_WrapMode = PANGO_WRAP_WORD_CHAR;
- } else {
- throw(Exception(AVG_ERR_UNSUPPORTED,
- "WordsNode wrapping mode "+sWrapMode+" not supported."));
- }
- setDirty(LAYOUT_CHANGED);
+ m_FontStyle.setWrapMode(sWrapMode);
+ updateLayout();
}
string WordsNode::getWrapMode() const
{
- switch(m_WrapMode) {
- case PANGO_WRAP_WORD:
- return "word";
- case PANGO_WRAP_CHAR:
- return "char";
- case PANGO_WRAP_WORD_CHAR:
- return "wordchar";
- default:
- AVG_ASSERT(false);
- return "";
- }
+ return m_FontStyle.getWrapMode();
}
void WordsNode::parseString(PangoAttrList** ppAttrList, char** ppText)
@@ -497,31 +487,21 @@ void WordsNode::parseString(PangoAttrList** ppAttrList, char** ppText)
void WordsNode::calcMaskCoords()
{
- updateLayout();
-
// Calculate texture coordinates for the mask texture, normalized to
// the extents of the text.
- DPoint normMaskSize;
- DPoint normMaskPos;
- DPoint mediaSize = DPoint(getMediaSize());
- DPoint effMaskPos = getMaskPos()-DPoint(m_InkOffset);
- DPoint maskSize = getMaskSize();
- switch (m_Alignment) {
- case PANGO_ALIGN_LEFT:
- break;
- case PANGO_ALIGN_CENTER:
- effMaskPos.x -= m_AlignOffset+getSize().x/2;
- break;
- case PANGO_ALIGN_RIGHT:
- effMaskPos.x -= m_AlignOffset+getSize().x;
- break;
- }
- if (maskSize == DPoint(0,0)) {
- normMaskSize = DPoint(getSize().x/mediaSize.x, getSize().y/mediaSize.y);
- normMaskPos = DPoint(effMaskPos.x/getSize().x, effMaskPos.y/getSize().y);
+ glm::vec2 normMaskSize;
+ glm::vec2 normMaskPos;
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ glm::vec2 effMaskPos = getMaskPos()-glm::vec2(m_InkOffset);
+ glm::vec2 maskSize = getMaskSize();
+
+ if (maskSize == glm::vec2(0,0)) {
+ normMaskSize = glm::vec2(getSize().x/mediaSize.x, getSize().y/mediaSize.y);
+ normMaskPos = glm::vec2(effMaskPos.x/getSize().x, effMaskPos.y/getSize().y);
} else {
- normMaskSize = DPoint(maskSize.x/mediaSize.x, maskSize.y/mediaSize.y);
- normMaskPos = DPoint(effMaskPos.x/getMaskSize().x, effMaskPos.y/getMaskSize().y);
+ normMaskSize = glm::vec2(maskSize.x/mediaSize.x, maskSize.y/mediaSize.y);
+ normMaskPos = glm::vec2(effMaskPos.x/getMaskSize().x,
+ effMaskPos.y/getMaskSize().y);
}
/*
cerr << "calcMaskCoords" << endl;
@@ -535,126 +515,114 @@ void WordsNode::calcMaskCoords()
getSurface()->setMaskCoords(normMaskPos, normMaskSize);
}
-void WordsNode::setDirty(RedrawState newState)
-{
- if (newState < m_RedrawState) {
- m_RedrawState = newState;
- }
-}
-
static ProfilingZoneID UpdateFontProfilingZone("WordsNode: Update font");
void WordsNode::updateFont()
{
- if (m_RedrawState == FONT_CHANGED) {
+ {
ScopeTimer timer(UpdateFontProfilingZone);
if (m_pFontDescription) {
pango_font_description_free(m_pFontDescription);
}
- m_pFontDescription = TextEngine::get(m_bHint).getFontDescription(m_sFontName,
- m_sFontVariant);
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ m_pFontDescription = engine.getFontDescription(m_FontStyle.getFont(),
+ m_FontStyle.getFontVariant());
pango_font_description_set_absolute_size(m_pFontDescription,
- (int)(m_FontSize * PANGO_SCALE));
-
- m_RedrawState = LAYOUT_CHANGED;
+ (int)(m_FontStyle.getFontSize() * PANGO_SCALE));
}
+ updateLayout();
}
static ProfilingZoneID UpdateLayoutProfilingZone("WordsNode: Update layout");
void WordsNode::updateLayout()
{
- updateFont();
- if (m_RedrawState == LAYOUT_CHANGED) {
- ScopeTimer timer(UpdateLayoutProfilingZone);
+ ScopeTimer timer(UpdateLayoutProfilingZone);
- if (m_sText.length() == 0) {
- m_LogicalSize = IntPoint(0,0);
- m_RedrawState = RENDER_NEEDED;
- } else {
- PangoContext* pContext = TextEngine::get(m_bHint).getPangoContext();
- pango_context_set_font_description(pContext, m_pFontDescription);
+ if (m_sText.length() == 0) {
+ m_LogicalSize = IntPoint(0,0);
+ m_bRenderNeeded = true;
+ } else {
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ PangoContext* pContext = engine.getPangoContext();
+ pango_context_set_font_description(pContext, m_pFontDescription);
- if (m_pLayout) {
- g_object_unref(m_pLayout);
- }
- m_pLayout = pango_layout_new(pContext);
+ if (m_pLayout) {
+ g_object_unref(m_pLayout);
+ }
+ m_pLayout = pango_layout_new(pContext);
- PangoAttrList * pAttrList = 0;
+ PangoAttrList * pAttrList = 0;
#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
- PangoAttribute * pLetterSpacing = pango_attr_letter_spacing_new
- (int(m_LetterSpacing*1024));
+ PangoAttribute * pLetterSpacing = pango_attr_letter_spacing_new
+ (int(m_FontStyle.getLetterSpacing()*1024));
#endif
- if (m_bParsedText) {
- char * pText = 0;
- parseString(&pAttrList, &pText);
+ if (m_bParsedText) {
+ char * pText = 0;
+ parseString(&pAttrList, &pText);
#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
- // Workaround for pango bug.
- pango_attr_list_insert_before(pAttrList, pLetterSpacing);
+ // Workaround for pango bug.
+ pango_attr_list_insert_before(pAttrList, pLetterSpacing);
#endif
- pango_layout_set_text(m_pLayout, pText, -1);
- g_free (pText);
- } else {
- pAttrList = pango_attr_list_new();
+ pango_layout_set_text(m_pLayout, pText, -1);
+ g_free(pText);
+ } else {
+ pAttrList = pango_attr_list_new();
#if PANGO_VERSION > PANGO_VERSION_ENCODE(1,18,2)
- pango_attr_list_insert_before(pAttrList, pLetterSpacing);
+ pango_attr_list_insert_before(pAttrList, pLetterSpacing);
#endif
- pango_layout_set_text(m_pLayout, m_sText.c_str(), -1);
- }
- pango_layout_set_attributes(m_pLayout, pAttrList);
- pango_attr_list_unref(pAttrList);
-
- pango_layout_set_wrap(m_pLayout, m_WrapMode);
- pango_layout_set_alignment(m_pLayout, m_Alignment);
- pango_layout_set_justify(m_pLayout, m_bJustify);
- if (getUserSize().x != 0) {
- pango_layout_set_width(m_pLayout, int(getUserSize().x * PANGO_SCALE));
- }
- pango_layout_set_indent(m_pLayout, m_Indent * PANGO_SCALE);
- if (m_Indent < 0) {
- // For hanging indentation, we add a tabstop to support lists
- PangoTabArray* pTabs = pango_tab_array_new_with_positions(1, false,
- PANGO_TAB_LEFT, -m_Indent * PANGO_SCALE);
- pango_layout_set_tabs(m_pLayout, pTabs);
- pango_tab_array_free(pTabs);
- }
- if (m_LineSpacing != -1) {
- pango_layout_set_spacing(m_pLayout, (int)(m_LineSpacing*PANGO_SCALE));
- }
- PangoRectangle logical_rect;
- PangoRectangle ink_rect;
- pango_layout_get_pixel_extents(m_pLayout, &ink_rect, &logical_rect);
-
- /*
- cerr << getID() << endl;
- cerr << "Ink: " << ink_rect.x << ", " << ink_rect.y << ", "
- << ink_rect.width << ", " << ink_rect.height << endl;
- cerr << "Logical: " << logical_rect.x << ", " << logical_rect.y << ", "
- << logical_rect.width << ", " << logical_rect.height << endl;
- cerr << "User Size: " << getUserSize() << endl;
- */
- m_InkSize.y = ink_rect.height;
- if (getUserSize().x == 0) {
- m_InkSize.x = ink_rect.width;
- } else {
- m_InkSize.x = int(getUserSize().x);
- }
- if (m_InkSize.x == 0) {
- m_InkSize.x = 1;
- }
- if (m_InkSize.y == 0) {
- m_InkSize.y = 1;
- }
- m_LogicalSize.y = logical_rect.height;
- m_LogicalSize.x = logical_rect.width;
- m_InkOffset = IntPoint(ink_rect.x-logical_rect.x, ink_rect.y-logical_rect.y);
- if (m_LineSpacing == -1) {
- m_LineSpacing = pango_layout_get_spacing(m_pLayout)/PANGO_SCALE;
- }
- m_RedrawState = RENDER_NEEDED;
- setViewport(-32767, -32767, -32767, -32767);
+ pango_layout_set_text(m_pLayout, m_sText.c_str(), -1);
+ }
+ pango_layout_set_attributes(m_pLayout, pAttrList);
+ pango_attr_list_unref(pAttrList);
+
+ pango_layout_set_wrap(m_pLayout, m_FontStyle.getWrapModeVal());
+ pango_layout_set_alignment(m_pLayout, m_FontStyle.getAlignmentVal());
+ pango_layout_set_justify(m_pLayout, m_FontStyle.getJustify());
+ if (getUserSize().x != 0) {
+ pango_layout_set_width(m_pLayout, int(getUserSize().x * PANGO_SCALE));
+ }
+ int indent = m_FontStyle.getIndent() * PANGO_SCALE;
+ pango_layout_set_indent(m_pLayout, indent);
+ if (indent < 0) {
+ // For hanging indentation, we add a tabstop to support lists
+ PangoTabArray* pTabs = pango_tab_array_new_with_positions(1, false,
+ PANGO_TAB_LEFT, -indent);
+ pango_layout_set_tabs(m_pLayout, pTabs);
+ pango_tab_array_free(pTabs);
+ }
+ pango_layout_set_spacing(m_pLayout,
+ (int)(m_FontStyle.getLineSpacing()*PANGO_SCALE));
+ PangoRectangle logical_rect;
+ PangoRectangle ink_rect;
+ pango_layout_get_pixel_extents(m_pLayout, &ink_rect, &logical_rect);
+
+ /*
+ cerr << getID() << endl;
+ cerr << "Ink: " << ink_rect.x << ", " << ink_rect.y << ", "
+ << ink_rect.width << ", " << ink_rect.height << endl;
+ cerr << "Logical: " << logical_rect.x << ", " << logical_rect.y << ", "
+ << logical_rect.width << ", " << logical_rect.height << endl;
+ cerr << "User Size: " << getUserSize() << endl;
+ */
+ m_InkSize.y = ink_rect.height;
+ if (getUserSize().x == 0) {
+ m_InkSize.x = ink_rect.width;
+ } else {
+ m_InkSize.x = int(getUserSize().x);
+ }
+ if (m_InkSize.x == 0) {
+ m_InkSize.x = 1;
+ }
+ if (m_InkSize.y == 0) {
+ m_InkSize.y = 1;
}
+ m_LogicalSize.y = logical_rect.height;
+ m_LogicalSize.x = logical_rect.width;
+ m_InkOffset = IntPoint(ink_rect.x-logical_rect.x, ink_rect.y-logical_rect.y);
+ m_bRenderNeeded = true;
+ setViewport(-32767, -32767, -32767, -32767);
}
}
@@ -662,15 +630,16 @@ static ProfilingZoneID RenderTextProfilingZone("WordsNode: render text");
void WordsNode::renderText()
{
- AVG_ASSERT(m_RedrawState == RENDER_NEEDED || m_RedrawState == CLEAN);
-
if (!(getState() == NS_CANRENDER)) {
return;
}
- if (m_RedrawState == RENDER_NEEDED) {
+ if (m_bRenderNeeded) {
if (m_sText.length() != 0) {
ScopeTimer timer(RenderTextProfilingZone);
- int maxTexSize = GLContext::getCurrent()->getMaxTexSize();
+ TextEngine& engine = TextEngine::get(m_FontStyle.getHint());
+ PangoContext* pContext = engine.getPangoContext();
+ pango_context_set_font_description(pContext, m_pFontDescription);
+ int maxTexSize = GLContext::getMain()->getMaxTexSize();
if (m_InkSize.x > maxTexSize || m_InkSize.y > maxTexSize) {
throw Exception(AVG_ERR_UNSUPPORTED,
"WordsNode size exceeded maximum (Size="
@@ -695,7 +664,7 @@ void WordsNode::renderText()
PangoRectangle ink_rect;
pango_layout_get_pixel_extents(m_pLayout, &ink_rect, &logical_rect);
pango_ft2_render_layout(&bitmap, m_pLayout, -ink_rect.x, -ink_rect.y);
- switch (m_Alignment) {
+ switch (m_FontStyle.getAlignmentVal()) {
case PANGO_ALIGN_LEFT:
m_AlignOffset = 0;
break;
@@ -711,10 +680,9 @@ void WordsNode::renderText()
pMover->unlock();
pMover->moveToTexture(*pTex);
-
- bind();
+ newSurface();
}
- m_RedrawState = CLEAN;
+ m_bRenderNeeded = false;
}
}
@@ -722,45 +690,43 @@ void WordsNode::redraw()
{
AVG_ASSERT(m_sText.length() < 32767);
- updateLayout();
renderText();
}
-void WordsNode::preRender()
+void WordsNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity)
{
- Node::preRender();
+ Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
if (isVisible()) {
redraw();
- } else {
- updateLayout();
}
+ Pixel32 color = m_FontStyle.getColorVal();
if (m_sText.length() != 0 && isVisible()) {
- renderFX(getSize(), m_Color, false);
+ renderFX(getSize(), color, false);
}
+ calcVertexArray(pVA, color);
}
static ProfilingZoneID RenderProfilingZone("WordsNode::render");
-void WordsNode::render(const DRect& rect)
+void WordsNode::render()
{
ScopeTimer timer(RenderProfilingZone);
if (m_sText.length() != 0 && isVisible()) {
IntPoint offset = m_InkOffset + IntPoint(m_AlignOffset, 0);
- GLContext* pContext = GLContext::getCurrent();
- if (offset != IntPoint(0,0)) {
- pContext->pushTransform(DPoint(offset), 0, DPoint(0,0));
- }
- blta8(DPoint(getSurface()->getSize()), getEffectiveOpacity(), m_Color,
- getBlendMode());
- if (offset != IntPoint(0,0)) {
- pContext->popTransform();
+ glm::mat4 transform;
+ if (offset == IntPoint(0,0)) {
+ transform = getTransform();
+ } else {
+ transform = glm::translate(getTransform(), glm::vec3(offset.x, offset.y, 0));
}
+ blta8(transform, glm::vec2(getSurface()->getSize()), getEffectiveOpacity(),
+ m_FontStyle.getColorVal(), getBlendMode());
}
}
IntPoint WordsNode::getMediaSize()
{
- updateLayout();
return m_LogicalSize;
}
@@ -798,7 +764,6 @@ PangoRectangle WordsNode::getGlyphRect(int i)
throw(Exception(AVG_ERR_INVALID_ARGS,
string("getGlyphRect: Index ") + toString(i) + " out of range."));
}
- updateLayout();
const char* pText = pango_layout_get_text(m_pLayout);
char * pChar = g_utf8_offset_to_pointer(pText, i);
int byteOffset = pChar-pText;
@@ -818,16 +783,16 @@ PangoRectangle WordsNode::getGlyphRect(int i)
void WordsNode::setParsedText(const UTF8String& sText)
{
m_sText = removeExcessSpaces(sText);
- setDirty(LAYOUT_CHANGED);
// This just does a syntax check and throws an exception if appropriate.
// The results are discarded.
PangoAttrList * pAttrList = 0;
char * pText = 0;
parseString(&pAttrList, &pText);
- pango_attr_list_unref (pAttrList);
- g_free (pText);
+ pango_attr_list_unref(pAttrList);
+ g_free(pText);
m_bParsedText = true;
+ updateLayout();
}
UTF8String WordsNode::applyBR(const UTF8String& sText)
diff --git a/src/player/WordsNode.h b/src/player/WordsNode.h
index 23c225c..c189e9f 100644
--- a/src/player/WordsNode.h
+++ b/src/player/WordsNode.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "../api.h"
#include "RasterNode.h"
+#include "FontStyle.h"
#include "../graphics/Pixel32.h"
#include "../base/UTF8String.h"
@@ -37,7 +38,7 @@ namespace avg {
class AVG_API WordsNode : public RasterNode
{
public:
- static NodeDefinition createDefinition();
+ static void registerType();
WordsNode(const ArgList& args);
virtual ~WordsNode();
@@ -45,21 +46,27 @@ class AVG_API WordsNode : public RasterNode
virtual void connectDisplay();
virtual void connect(CanvasPtr pCanvas);
virtual void disconnect(bool bKill);
- virtual void preRender();
- virtual void render(const DRect& rect);
+ virtual void preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
+ float parentEffectiveOpacity);
+ virtual void render();
- virtual double getWidth() const;
- virtual void setWidth(double width);
+ virtual float getWidth() const;
+ virtual void setWidth(float width);
- virtual double getHeight() const;
- virtual void setHeight(double width);
+ virtual float getHeight() const;
+ virtual void setHeight(float width);
- virtual DPoint getSize() const;
- virtual void setSize(const DPoint& pt);
+ virtual glm::vec2 getSize() const;
+ virtual void setSize(const glm::vec2& pt);
+
+ glm::vec2 toLocal(const glm::vec2& globalPos) const;
+ glm::vec2 toGlobal(const glm::vec2& localPos) const;
- void getElementsByPos(const DPoint& pos, std::vector<NodeWeakPtr>& pElements);
void setTextFromNodeValue(const std::string& sText);
+ const FontStyle& getFontStyle() const;
+ void setFontStyle(const FontStyle& fontStyle);
+
const std::string& getFont() const;
void setFont(const std::string& sName);
@@ -72,14 +79,17 @@ class AVG_API WordsNode : public RasterNode
const std::string& getColor() const;
void setColor(const std::string& sColor);
- double getFontSize() const;
- void setFontSize(double size);
+ virtual float getAAGamma() const;
+ virtual void setAAGamma(float gamma);
+
+ float getFontSize() const;
+ void setFontSize(float size);
int getIndent() const;
void setIndent(int indent);
- double getLineSpacing() const;
- void setLineSpacing(double lineSpacing);
+ float getLineSpacing() const;
+ void setLineSpacing(float lineSpacing);
bool getRawTextMode() const;
void setRawTextMode(bool rawTextMode);
@@ -93,20 +103,20 @@ class AVG_API WordsNode : public RasterNode
bool getJustify() const;
void setJustify(bool bJustify);
- double getLetterSpacing() const;
- void setLetterSpacing(double letterSpacing);
+ float getLetterSpacing() const;
+ void setLetterSpacing(float letterSpacing);
bool getHint() const;
void setHint(bool bHint);
- DPoint getGlyphPos(int i);
- DPoint getGlyphSize(int i);
+ glm::vec2 getGlyphPos(int i);
+ glm::vec2 getGlyphSize(int i);
virtual IntPoint getMediaSize();
int getNumLines();
- PyObject* getCharIndexFromPos(DPoint p);
+ PyObject* getCharIndexFromPos(glm::vec2 p);
std::string getTextAsDisplayed();
- DPoint getLineExtents(int line);
+ glm::vec2 getLineExtents(int line);
static const std::vector<std::string>& getFontFamilies();
static const std::vector<std::string>& getFontVariants(
@@ -114,10 +124,7 @@ class AVG_API WordsNode : public RasterNode
static void addFontDir(const std::string& sDir);
private:
- enum RedrawState {FONT_CHANGED, LAYOUT_CHANGED, RENDER_NEEDED, CLEAN};
-
virtual void calcMaskCoords();
- void setDirty(RedrawState newState);
void updateFont();
void updateLayout();
void renderText();
@@ -129,21 +136,10 @@ class AVG_API WordsNode : public RasterNode
PangoRectangle getGlyphRect(int i);
// Exposed Attributes
- std::string m_sFontName;
- std::string m_sFontVariant;
+ FontStyle m_FontStyle;
UTF8String m_sText;
UTF8String m_sRawText;
- std::string m_sColorName;
- Pixel32 m_Color;
- double m_FontSize;
- int m_Indent;
- double m_LineSpacing;
- PangoAlignment m_Alignment;
- PangoWrapMode m_WrapMode;
- bool m_bJustify;
- double m_LetterSpacing;
- bool m_bHint;
-
+
bool m_bParsedText;
bool m_bRawTextMode;
IntPoint m_LogicalSize;
@@ -153,7 +149,7 @@ class AVG_API WordsNode : public RasterNode
PangoFontDescription * m_pFontDescription;
PangoLayout * m_pLayout;
- RedrawState m_RedrawState;
+ bool m_bRenderNeeded;
};
}
diff --git a/src/player/WrapPython.cpp b/src/player/WrapPython.cpp
new file mode 100644
index 0000000..e0eb9bc
--- /dev/null
+++ b/src/player/WrapPython.cpp
@@ -0,0 +1,72 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WrapPython.h"
+
+#include "../base/Logger.h"
+#include "../base/StringHelper.h"
+#include "../base/FileHelper.h"
+
+#include <frameobject.h>
+
+using namespace std;
+
+namespace avg {
+
+aquirePyGIL::aquirePyGIL()
+{
+ m_pyGilState = PyGILState_Ensure();
+}
+aquirePyGIL::~aquirePyGIL()
+{
+ PyGILState_Release(m_pyGilState);
+}
+
+void avgDeprecationWarning(const string& sVersion, const string& sOldEntryPoint,
+ const string& sNewEntryPoint)
+{
+ static vector<string> sWarningsIssued;
+ bool bWarned = false;
+ for (vector<string>::iterator it = sWarningsIssued.begin();
+ it != sWarningsIssued.end(); ++it)
+ {
+ if (*it == sOldEntryPoint) {
+ return;
+ }
+ }
+ if (!bWarned) {
+ sWarningsIssued.push_back(sOldEntryPoint);
+
+ PyFrameObject* pFrame = PyEval_GetFrame();
+ int lineNo = PyCode_Addr2Line(pFrame->f_code, pFrame->f_lasti);
+ // lineNo = PyFrame_GetLineNumber(pFrame);
+ string sFName = getFilenamePart(PyString_AS_STRING(pFrame->f_code->co_filename));
+ string sMsg = sFName + ":" + toString(lineNo) + ": ";
+ sMsg += string(sOldEntryPoint) + " deprecated since version " +
+ string(sVersion)+".";
+ if (sNewEntryPoint != string("")) {
+ sMsg += " Use "+string(sNewEntryPoint) + " instead.";
+ }
+ AVG_TRACE(Logger::category::DEPRECATION, Logger::severity::WARNING, sMsg);
+ }
+}
+
+}
diff --git a/src/player/WrapPython.h b/src/player/WrapPython.h
index b81b4eb..20ce764 100644
--- a/src/player/WrapPython.h
+++ b/src/player/WrapPython.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,9 @@
// Current versions can be found at www.libavg.de
//
+#ifndef _WrapPython_H_
+#define _WrapPython_H_
+
#include "../api.h"
#ifdef _DEBUG
@@ -47,3 +50,21 @@
# define _DEBUG
#endif
+namespace avg {
+
+class aquirePyGIL
+{
+public:
+ aquirePyGIL();
+ virtual ~aquirePyGIL();
+
+private:
+ PyGILState_STATE m_pyGilState;
+};
+
+void avgDeprecationWarning(const std::string& sVersion, const std::string& sOldEntryPoint,
+ const std::string& sNewEntryPoint);
+
+}
+
+#endif
diff --git a/src/player/XInputMTInputDevice.cpp b/src/player/XInputMTInputDevice.cpp
index 0e042c2..14145c8 100644
--- a/src/player/XInputMTInputDevice.cpp
+++ b/src/player/XInputMTInputDevice.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -43,7 +43,7 @@ using namespace std;
namespace avg {
-Display* XInputMTInputDevice::s_pDisplay = 0;
+::Display* XInputMTInputDevice::s_pDisplay = 0;
const char* cookieTypeToName(int evtype);
string xEventTypeToName(int evtype);
@@ -69,6 +69,10 @@ void XInputMTInputDevice::start()
{
Status status;
SDLDisplayEngine * pEngine = Player::get()->getDisplayEngine();
+ glm::vec2 size(pEngine->getSize());
+ glm::vec2 windowSize(pEngine->getWindowSize());
+ m_DisplayScale.x = size.x/windowSize.x;
+ m_DisplayScale.y = size.y/windowSize.y;
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
@@ -132,7 +136,8 @@ void XInputMTInputDevice::start()
pEngine->setXIMTInputDevice(this);
MultitouchInputDevice::start();
- AVG_TRACE(Logger::CONFIG, "XInput Multitouch event source created.");
+ AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
+ "XInput Multitouch event source created.");
}
void XInputMTInputDevice::handleXIEvent(const XEvent& xEvent)
@@ -148,14 +153,14 @@ void XInputMTInputDevice::handleXIEvent(const XEvent& xEvent)
{
// cerr << "TouchBegin " << xid << ", " << pos << endl;
m_LastID++;
- TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSORDOWN, pos);
+ TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN, pos);
addTouchStatus(xid, pEvent);
}
break;
case XI_TouchUpdate:
{
// cerr << "TouchUpdate " << xid << ", " << pos << endl;
- TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION, pos);
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION, pos);
TouchStatusPtr pTouchStatus = getTouchStatus(xid);
AVG_ASSERT(pTouchStatus);
pTouchStatus->pushEvent(pEvent);
@@ -166,7 +171,7 @@ void XInputMTInputDevice::handleXIEvent(const XEvent& xEvent)
// cerr << "TouchEnd " << xid << ", " << pos << endl;
TouchStatusPtr pTouchStatus = getTouchStatus(xid);
AVG_ASSERT(pTouchStatus);
- TouchEventPtr pEvent = createEvent(0, Event::CURSORUP, pos);
+ TouchEventPtr pEvent = createEvent(0, Event::CURSOR_UP, pos);
pTouchStatus->pushEvent(pEvent);
}
break;
@@ -198,7 +203,6 @@ void XInputMTInputDevice::findMTDevice()
pDevices = XIQueryDevice(s_pDisplay, XIAllDevices, &ndevices);
XITouchClassInfo* pTouchClass = 0;
- int maxTouches;
for (int i = 0; i < ndevices && !pTouchClass; ++i) {
pDevice = &pDevices[i];
// cerr << "Device " << pDevice->name << "(id: " << pDevice->deviceid << ")."
@@ -217,7 +221,6 @@ void XInputMTInputDevice::findMTDevice()
} else {
m_OldMasterDeviceID = -1;
}
- maxTouches = pTouchClass->num_touches;
break;
}
}
@@ -225,8 +228,9 @@ void XInputMTInputDevice::findMTDevice()
}
}
if (pTouchClass) {
- AVG_TRACE(Logger::CONFIG, "Using multitouch input device " << m_sDeviceName
- << ", max touches: " << maxTouches);
+ AVG_TRACE(Logger::category::CONFIG,Logger::severity::INFO,
+ "Using multitouch input device " << m_sDeviceName << ", max touches: " <<
+ pTouchClass->num_touches);
} else {
throw Exception(AVG_ERR_MT_INIT,
"XInput multitouch event source: No multitouch device found.");
@@ -236,6 +240,8 @@ void XInputMTInputDevice::findMTDevice()
TouchEventPtr XInputMTInputDevice::createEvent(int id, Event::Type type, IntPoint pos)
{
+ pos.x *= m_DisplayScale.x;
+ pos.y *= m_DisplayScale.y;
return TouchEventPtr(new TouchEvent(id, type, pos, Event::TOUCH));
}
diff --git a/src/player/XInputMTInputDevice.h b/src/player/XInputMTInputDevice.h
index af10249..d395884 100644
--- a/src/player/XInputMTInputDevice.h
+++ b/src/player/XInputMTInputDevice.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
#include "MultitouchInputDevice.h"
#include "Event.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include <X11/Xlib.h>
#include <vector>
@@ -56,7 +56,7 @@ private:
int m_LastID;
- static Display* s_pDisplay;
+ static ::Display* s_pDisplay;
void (*m_SDLLockFunc)(void);
void (*m_SDLUnlockFunc)(void);
@@ -66,6 +66,7 @@ private:
int m_DeviceID;
int m_OldMasterDeviceID;
+ glm::vec2 m_DisplayScale;
};
typedef boost::shared_ptr<XInputMTInputDevice> XInputMTInputDevicePtr;
diff --git a/src/player/testcalibrator.cpp b/src/player/testcalibrator.cpp
index 175488f..a9898f5 100644
--- a/src/player/testcalibrator.cpp
+++ b/src/player/testcalibrator.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
#include "TrackerCalibrator.h"
-#include "../base/Point.h"
+#include "../base/GLMHelper.h"
#include "../base/TestSuite.h"
#include "../base/Exception.h"
@@ -49,45 +49,46 @@ public:
bool bDone = false;
while (!bDone) {
IntPoint displayPoint(calibrator.getDisplayPoint());
- calibrator.setCamPoint(DPoint(displayPoint));
+ calibrator.setCamPoint(glm::vec2(displayPoint));
bDone = !calibrator.nextPoint();
}
pTrafo = calibrator.makeTransformer();
- TEST( calcDist(pTrafo->transformBlobToScreen( DPoint(1.00,1.00) ) , DPoint(1.00,1.00))<1);
-// cerr << "scale: " << scale << ", offset: " << offset << endl;
- TEST(checkTransform(pTrafo, DPoint(0,0), DPoint(0,0)));
- TEST(checkTransform(pTrafo, DPoint(640, 480), DPoint(640, 480)));
+ TEST(glm::length(pTrafo->transformBlobToScreen(glm::dvec2(1.00,1.00)) -
+ glm::dvec2(1.00,1.00)) < 1);
+ TEST(checkTransform(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkTransform(pTrafo, glm::dvec2(640, 480), glm::dvec2(640, 480)));
}
{
TrackerCalibrator calibrator(IntPoint(640, 480), IntPoint(1280,720));
bool bDone = false;
while (!bDone) {
IntPoint displayPoint(calibrator.getDisplayPoint());
- calibrator.setCamPoint(DPoint(displayPoint.x/2, displayPoint.y/1.5));
+ calibrator.setCamPoint(glm::vec2(displayPoint.x/2, displayPoint.y/1.5));
bDone = !calibrator.nextPoint();
}
pTrafo = calibrator.makeTransformer();
- TEST( calcDist( pTrafo->transformBlobToScreen( DPoint(1.00,1.00) ), DPoint(2.00,1.50)) <1 );
-// cerr << "scale: " << scale << ", offset: " << offset << endl;
- TEST(checkTransform(pTrafo, DPoint(0,0), DPoint(0,0)));
- TEST(checkTransform(pTrafo, DPoint(640, 480), DPoint(640, 480)));
- TEST(checkBlobToScreen(pTrafo, DPoint(0,0), DPoint(0,0)));
- TEST(checkBlobToScreen(pTrafo, DPoint(640, 480), DPoint(1280, 720)));
+ TEST(glm::length(pTrafo->transformBlobToScreen(glm::dvec2(1.00,1.00)) -
+ glm::dvec2(2.00,1.50)) < 1);
+ TEST(checkTransform(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkTransform(pTrafo, glm::dvec2(640, 480), glm::dvec2(640, 480)));
+ TEST(checkBlobToScreen(pTrafo, glm::dvec2(0,0), glm::dvec2(0,0)));
+ TEST(checkBlobToScreen(pTrafo, glm::dvec2(640, 480), glm::dvec2(1280, 720)));
}
}
- bool checkTransform(CoordTransformerPtr pTrafo, const DPoint& srcPt,
- const DPoint& destPt)
+ bool checkTransform(CoordTransformerPtr pTrafo, const glm::dvec2& srcPt,
+ const glm::dvec2& destPt)
{
- DPoint ResultPt = pTrafo->transform_point(srcPt);
+ glm::dvec2 ResultPt = pTrafo->transform_point(srcPt);
// cerr << srcPt << " -> " << ResultPt << ", expected " << destPt << endl;
return ((fabs(ResultPt.x-destPt.x) < 0.1) && (fabs(ResultPt.y-destPt.y) < 0.1));
}
bool checkBlobToScreen(DeDistortPtr pTrafo,
- const DPoint& srcPt, const DPoint& destPt)
+ const glm::dvec2& srcPt, const glm::dvec2& destPt)
{
- DPoint ResultPt = pTrafo->transformBlobToScreen(pTrafo->transform_point(srcPt));
+ glm::dvec2 ResultPt =
+ pTrafo->transformBlobToScreen(pTrafo->transform_point(srcPt));
// cerr << srcPt << " -> " << ResultPt << ", expected " << destPt << endl;
return ((fabs(ResultPt.x-destPt.x) < 1) && (fabs(ResultPt.y-destPt.y) < 1));
}
diff --git a/src/player/testplayer.cpp b/src/player/testplayer.cpp
index 342a2c4..aa0bef9 100644
--- a/src/player/testplayer.cpp
+++ b/src/player/testplayer.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,11 +25,17 @@
#include "../base/Exception.h"
#include "../base/Logger.h"
+#include "../graphics/GLConfig.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>
+#ifdef WIN32
+#include <direct.h>
+#endif
+
using namespace avg;
using namespace std;
@@ -49,11 +55,18 @@ public:
" <words text=\"foo\"/>"
" </avg>"
);
+ player.setOGLOptions(false, true, 1, GLConfig::AUTO, true);
+ GLContext::enableErrorChecks(true);
player.disablePython();
if (!getenv("AVG_CONSOLE_TEST")) {
- player.initPlayback();
+#ifdef WIN32
+ char sz[1024];
+ _getcwd(sz, 1024);
+ cerr << "Current directory: " << sz << endl;
+#endif
+ player.initPlayback("../graphics/shaders/");
player.doFrame(false);
- player.cleanup();
+ player.cleanup(false);
}
try {
throw bad_cast();