|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx/shaderfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzStdfx includes
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx/shaderinterface.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx/shadingcontext.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trenderresourcemanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trenderer.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tthread.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfilepath.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfunctorinvoker.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmsgcore.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qdir></qdir>
|
|
Toshihiro Shimizu |
890ddd |
#include <qglshaderprogram></qglshaderprogram>
|
|
Toshihiro Shimizu |
890ddd |
#include <qcoreapplication></qcoreapplication>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Glew include
|
|
Toshihiro Shimizu |
890ddd |
#include <gl glew.h=""></gl>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_function_types.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_unique_ptr.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Boost includes
|
|
Toshihiro Shimizu |
890ddd |
#include <boost any.hpp=""></boost>
|
|
Toshihiro Shimizu |
890ddd |
#include <boost iterator="" transform_iterator.hpp=""></boost>
|
|
Toshihiro Shimizu |
890ddd |
#include <boost ptr_container="" ptr_vector.hpp=""></boost>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Diagnostics include
|
|
Toshihiro Shimizu |
890ddd |
//#define DIAGNOSTICS
|
|
Toshihiro Shimizu |
890ddd |
#ifdef DIAGNOSTICS
|
|
Toshihiro Shimizu |
890ddd |
#include "diagnostics.h"
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Forward Declarations
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class ShaderFxDeclaration;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local Namespace stuff
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Classes
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct ContextLocker {
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &m_ctx;
|
|
Shinya Kitaoka |
120a6e |
bool m_locked;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ContextLocker(ShadingContext &ctx) : m_ctx(ctx), m_locked(false) { relock(); }
|
|
Shinya Kitaoka |
120a6e |
~ContextLocker() {
|
|
Shinya Kitaoka |
120a6e |
if (m_locked) unlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void relock() {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_locked), m_locked = true;
|
|
Shinya Kitaoka |
120a6e |
m_ctx.makeCurrent();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void unlock() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_locked), m_locked = false;
|
|
Shinya Kitaoka |
120a6e |
m_ctx.doneCurrent();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct ProgramBinder {
|
|
Shinya Kitaoka |
120a6e |
QGLShaderProgram *m_prog;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ProgramBinder(QGLShaderProgram *prog) : m_prog(prog) { m_prog->bind(); }
|
|
Shinya Kitaoka |
120a6e |
~ProgramBinder() { m_prog->release(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct RectF {
|
|
Shinya Kitaoka |
120a6e |
GLfloat m_val[4];
|
|
Shinya Kitaoka |
120a6e |
RectF(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1) {
|
|
Shinya Kitaoka |
120a6e |
m_val[0] = x0, m_val[1] = y0, m_val[2] = x1, m_val[3] = y1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
RectF(const TRectD &rect) {
|
|
Shinya Kitaoka |
120a6e |
m_val[0] = rect.x0, m_val[1] = rect.y0, m_val[2] = rect.x1,
|
|
Shinya Kitaoka |
120a6e |
m_val[3] = rect.y1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
operator TRectD() const {
|
|
Shinya Kitaoka |
120a6e |
return TRectD(m_val[0], m_val[1], m_val[2], m_val[3]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const RectF &rect) const {
|
|
Shinya Kitaoka |
120a6e |
return (memcmp(m_val, rect.m_val, sizeof(this)) == 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct AffineF {
|
|
Shinya Kitaoka |
120a6e |
GLfloat m_val[9];
|
|
Shinya Kitaoka |
120a6e |
operator TAffine() const {
|
|
Shinya Kitaoka |
120a6e |
return TAffine(m_val[0], m_val[3], m_val[6], m_val[1], m_val[4], m_val[7]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// Observe that mat3 from GLSL stores elements column-wise; this explains the
|
|
Shinya Kitaoka |
120a6e |
// weird indexing
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Global Variables
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef std::map<qstring, *="" shaderfxdeclaration=""> FxDeclarationsMap;</qstring,>
|
|
Toshihiro Shimizu |
890ddd |
FxDeclarationsMap l_shaderFxDeclarations;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
enum Measures { NONE, PERCENT, LENGTH, ANGLE, MEASURESCOUNT };
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static const std::string l_measureNames[MEASURESCOUNT] = {"", "percentage",
|
|
Shinya Kitaoka |
120a6e |
"fxLength", "angle"};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static const TParamUIConcept::Type
|
|
Shinya Kitaoka |
120a6e |
l_conceptTypes[ShaderInterface::CONCEPTSCOUNT -
|
|
Shinya Kitaoka |
120a6e |
ShaderInterface::UI_CONCEPTS] = {
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept::RADIUS, TParamUIConcept::WIDTH,
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept::ANGLE, TParamUIConcept::POINT,
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept::POINT_2, TParamUIConcept::VECTOR,
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept::POLAR, TParamUIConcept::SIZE,
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept::QUAD, TParamUIConcept::RECT};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Functions
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool isObsolete(const TFilePath &fp, const QDateTime &lastModified) {
|
|
Shinya Kitaoka |
120a6e |
QFileInfo fInfo(QString::fromStdWString(fp.getWideString()));
|
|
Shinya Kitaoka |
120a6e |
return (lastModified != fInfo.lastModified());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TRectD tileRect(const TTile &tile) {
|
|
Shinya Kitaoka |
120a6e |
const TDimension &dim = tile.getRaster()->getSize();
|
|
Shinya Kitaoka |
120a6e |
return TRectD(tile.m_pos, TDimensionD(dim.lx, dim.ly));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void ceilRect(TRectD &rect) {
|
|
Shinya Kitaoka |
120a6e |
rect.x0 = tfloor(rect.x0), rect.y0 = tfloor(rect.y0);
|
|
Shinya Kitaoka |
120a6e |
rect.x1 = tceil(rect.x1), rect.y1 = tceil(rect.y1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Shader Fx declaration
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class ShaderFx final : public TStandardZeraryFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(ShaderFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface *m_shaderInterface; //!< Shader fx 'description'.
|
|
Shinya Kitaoka |
120a6e |
std::vector<boost::any></boost::any>
|
|
Shinya Kitaoka |
120a6e |
m_params; //!< Parameters for the shader fx. The actual parameter
|
|
Shinya Kitaoka |
120a6e |
//!< type depends on the shader interface declaration.
|
|
Shinya Kitaoka |
120a6e |
std::vector<tparamuiconcept></tparamuiconcept>
|
|
Shinya Kitaoka |
120a6e |
m_uiConcepts; //!< UI concepts related to m_params.
|
|
Shinya Kitaoka |
120a6e |
boost::ptr_vector<trasterfxport></trasterfxport>
|
|
Shinya Kitaoka |
120a6e |
m_inputPorts; //!< Input ports for the shader fx.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ShaderFx() : m_shaderInterface() {
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
} // Necessary due to TPersist inheritance, but must NOT be used
|
|
Shinya Kitaoka |
120a6e |
ShaderFx(const ShaderInterface *shaderInterface)
|
|
Shinya Kitaoka |
120a6e |
: m_shaderInterface(shaderInterface) {
|
|
Shinya Kitaoka |
120a6e |
initialize();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// void setShaderInterface(const ShaderInterface& shaderInterface);
|
|
Shinya Kitaoka |
120a6e |
void initialize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void getParamUIs(TParamUIConcept *¶ms, int &length) override;
|
|
Shinya Kitaoka |
38fd86 |
bool doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) override;
|
|
Shinya Kitaoka |
473e70 |
bool canHandle(const TRenderSettings &info, double frame) override;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
void doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &ri) override;
|
|
Shinya Kitaoka |
473e70 |
void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
QGLShaderProgram *touchShaderProgram(const ShaderInterface::ShaderData &sd,
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context,
|
|
Shinya Kitaoka |
120a6e |
int varyingsCount = 0,
|
|
Shinya Kitaoka |
120a6e |
const GLchar **varyings = 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void bindParameters(QGLShaderProgram *shaderProgram, double frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void bindWorldTransform(QGLShaderProgram *shaderProgram,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldToDst);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void getInputData(const TRectD &rect, double frame, const TRenderSettings &ri,
|
|
Shinya Kitaoka |
120a6e |
std::vector<trectd> &inputRects,</trectd>
|
|
Shinya Kitaoka |
120a6e |
std::vector<taffine> &inputAffines,</taffine>
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// ShaderFxDeclaration definition
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class ShaderFxDeclaration final : public TFxDeclaration {
|
|
Shinya Kitaoka |
120a6e |
ShaderInterface m_shaderInterface;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ShaderFxDeclaration(const ShaderInterface &shaderInterface)
|
|
Shinya Kitaoka |
120a6e |
: TFxDeclaration(
|
|
Shinya Kitaoka |
120a6e |
TFxInfo(shaderInterface.mainShader().m_name.toStdString(), false))
|
|
Shinya Kitaoka |
120a6e |
, m_shaderInterface(shaderInterface) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TPersist *create() const override { return new ShaderFx(&m_shaderInterface); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// ShadingContextManager definition
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class ShadingContextManager final : public QObject {
|
|
Shinya Kitaoka |
120a6e |
mutable QMutex m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ShadingContext m_shadingContext;
|
|
Shinya Kitaoka |
120a6e |
TAtomicVar m_activeRenderInstances;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager() {
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
The ShadingContext's QGLPixelBuffer must be destroyed *before* the global
|
|
Shinya Kitaoka |
120a6e |
QApplication
|
|
Shinya Kitaoka |
120a6e |
is. So, we will attach to a suitable parent object whose lifespan is shorter.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FYI - yes, this approach was adopted after a long and PAINFUL wrestling session
|
|
Shinya Kitaoka |
120a6e |
with Qt.
|
|
Shinya Kitaoka |
120a6e |
Suggestions are welcome as this is a tad beyond ridiculous...
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QObject *mainScopeBoundObject =
|
|
Shinya Kitaoka |
120a6e |
QCoreApplication::instance()->findChild<qobject *="">("mainScope");</qobject>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(thread() ==
|
|
Shinya Kitaoka |
120a6e |
mainScopeBoundObject
|
|
Shinya Kitaoka |
120a6e |
->thread()); // Parent object must be in the same thread,
|
|
Shinya Kitaoka |
120a6e |
setParent(mainScopeBoundObject); // otherwise reparenting fails
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static ShadingContextManager *instance() {
|
|
Shinya Kitaoka |
120a6e |
static ShadingContextManager *theManager = new ShadingContextManager;
|
|
Shinya Kitaoka |
120a6e |
return theManager;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutex *mutex() const { return &m_mutex; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const ShadingContext &shadingContext() const { return m_shadingContext; }
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &shadingContext() { return m_shadingContext; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void onRenderInstanceStart() { ++m_activeRenderInstances; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void onRenderInstanceEnd() {
|
|
Shinya Kitaoka |
120a6e |
if (--m_activeRenderInstances == 0) {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker mLocker(&m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Release the shading context's output buffer
|
|
Shinya Kitaoka |
120a6e |
::ContextLocker cLocker(m_shadingContext);
|
|
Shinya Kitaoka |
120a6e |
m_shadingContext.resize(0, 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef DIAGNOSTICS
|
|
Shinya Kitaoka |
120a6e |
DIAGNOSTICS_DUMP("ShaderLogs");
|
|
Shinya Kitaoka |
120a6e |
DIAGNOSTICS_CLEAR;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ShadingContext::Support touchSupport() {
|
|
Shinya Kitaoka |
120a6e |
struct {
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager *m_this;
|
|
Shinya Kitaoka |
120a6e |
ShadingContext::Support support() {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker mLocker(&m_this->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
::ContextLocker cLocker(m_this->m_shadingContext);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return ShadingContext::support();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} locals = {this};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static ShadingContext::Support sup = locals.support();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static bool sentMsg = false;
|
|
Shinya Kitaoka |
120a6e |
if (!sentMsg) {
|
|
Shinya Kitaoka |
120a6e |
switch (sup) {
|
|
Shinya Kitaoka |
120a6e |
case ShadingContext::NO_PIXEL_BUFFER:
|
|
Shinya Kitaoka |
120a6e |
DVGui::warning(QGLShaderProgram::tr(
|
|
Shinya Kitaoka |
120a6e |
"This system configuration does not support OpenGL Pixel Buffers. "
|
|
Shinya Kitaoka |
120a6e |
"Shader Fxs will not be able to render."));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShadingContext::NO_SHADERS:
|
|
Shinya Kitaoka |
120a6e |
DVGui::warning(QGLShaderProgram::tr(
|
|
Shinya Kitaoka |
120a6e |
"This system configuration does not support OpenGL Shader "
|
|
Shinya Kitaoka |
120a6e |
"Programs. Shader Fxs will not be able to render."));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sentMsg = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return sup;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template class DV_EXPORT_API TFxDeclarationT<shaderfx>;</shaderfx>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// ShadingContextManagerDelegate definition
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class MessageCreateContext final : public TThread::Message {
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager *man;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
MessageCreateContext(ShadingContextManager *ctx) : man(ctx) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onDeliver() override { man->onRenderInstanceEnd(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
38fd86 |
TThread::Message *clone() const override {
|
|
Shinya Kitaoka |
38fd86 |
return new MessageCreateContext(*this);
|
|
Shinya Kitaoka |
38fd86 |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class SCMDelegate final : public TRenderResourceManager {
|
|
Shinya Kitaoka |
120a6e |
T_RENDER_RESOURCE_MANAGER
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onRenderInstanceStart(unsigned long id) override {
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager::instance()->onRenderInstanceStart();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onRenderInstanceEnd(unsigned long id) override {
|
|
Shinya Kitaoka |
120a6e |
if (!TThread::isMainThread()) {
|
|
Shinya Kitaoka |
120a6e |
/* tofflinegl のときとは逆で main thread に dispatch する */
|
|
Shinya Kitaoka |
120a6e |
MessageCreateContext(ShadingContextManager::instance()).sendBlocking();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager::instance()->onRenderInstanceEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class SCMDelegateGenerator final : public TRenderResourceManagerGenerator {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
SCMDelegateGenerator() : TRenderResourceManagerGenerator(false) {
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
Again, this has to do with the manager's lifetime issue.
|
|
Shinya Kitaoka |
120a6e |
The SCM must be created in the MAIN THREAD, but NOT BEFORE the
|
|
Shinya Kitaoka |
120a6e |
QCoreApplication itself has been created. The easiest way to do so
|
|
Shinya Kitaoka |
120a6e |
is scheduling a slot to be executed as soon as event processing starts.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
d1f6c4 |
struct InstanceSCM final : public TFunctorInvoker::BaseFunctor {
|
|
Shinya Kitaoka |
473e70 |
void operator()() override { ShadingContextManager::instance(); }
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFunctorInvoker::instance()->invokeQueued(new InstanceSCM);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TRenderResourceManager *operator()() override { return new SCMDelegate; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MANAGER_FILESCOPE_DECLARATION(SCMDelegate, SCMDelegateGenerator)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Shader Fx implementation
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::initialize() {
|
|
Shinya Kitaoka |
120a6e |
struct {
|
|
Shinya Kitaoka |
120a6e |
ShaderFx *m_this;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline void addUiConcept(const ShaderInterface::Parameter &siParam,
|
|
Shinya Kitaoka |
120a6e |
const TParamP ¶m) {
|
|
Shinya Kitaoka |
120a6e |
if (siParam.m_concept.m_type >= ShaderInterface::UI_CONCEPTS &&
|
|
Shinya Kitaoka |
120a6e |
siParam.m_concept.m_type < ShaderInterface::CONCEPTSCOUNT) {
|
|
Shinya Kitaoka |
120a6e |
m_this->m_uiConcepts.push_back(TParamUIConcept());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept &uiConcept = m_this->m_uiConcepts.back();
|
|
Shinya Kitaoka |
120a6e |
uiConcept.m_type = ::l_conceptTypes[siParam.m_concept.m_type -
|
|
Shinya Kitaoka |
120a6e |
ShaderInterface::UI_CONCEPTS];
|
|
Shinya Kitaoka |
120a6e |
uiConcept.m_label = siParam.m_concept.m_label.toStdString();
|
|
Shinya Kitaoka |
120a6e |
uiConcept.m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline void addUiConcept(const ShaderInterface::ParameterConcept &concept) {
|
|
Shinya Kitaoka |
120a6e |
if (!concept.isUI() || concept.m_parameterNames.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TParamUIConcept uiConcept = {
|
|
Shinya Kitaoka |
120a6e |
::l_conceptTypes[concept.m_type - ShaderInterface::UI_CONCEPTS],
|
|
Shinya Kitaoka |
120a6e |
concept.m_label.toStdString()};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int n, nCount = int(concept.m_parameterNames.size());
|
|
Shinya Kitaoka |
120a6e |
for (n = 0; n != nCount; ++n) {
|
|
Shinya Kitaoka |
120a6e |
TParam *param = m_this->getParams()->getParam(
|
|
Shinya Kitaoka |
120a6e |
concept.m_parameterNames[n].toStdString());
|
|
Shinya Kitaoka |
120a6e |
if (!param) break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
uiConcept.m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (uiConcept.m_params.size() == concept.m_parameterNames.size())
|
|
Shinya Kitaoka |
120a6e |
m_this->m_uiConcepts.push_back(uiConcept);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} locals = {this};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(m_params.empty()); // Interfaces should not be re-set
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Allocate parameters following the specified interface
|
|
Shinya Kitaoka |
120a6e |
const std::vector<shaderinterface::parameter> &siParams =</shaderinterface::parameter>
|
|
Shinya Kitaoka |
120a6e |
m_shaderInterface->parameters();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int p, pCount = int(siParams.size());
|
|
Shinya Kitaoka |
120a6e |
m_params.reserve(pCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface::Parameter &siParam = siParams[p];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (siParam.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::BOOL: {
|
|
Shinya Kitaoka |
120a6e |
TBoolParamP param(siParam.m_default.m_bool);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tboolparamp>(&m_params.back()));</tboolparamp>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::FLOAT: {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP param(siParam.m_default.m_float);
|
|
Shinya Kitaoka |
120a6e |
param->setValueRange(siParam.m_range[0].m_float,
|
|
Shinya Kitaoka |
120a6e |
siParam.m_range[1].m_float);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
locals.addUiConcept(siParam, param);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (siParam.m_concept.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::PERCENT:
|
|
Shinya Kitaoka |
120a6e |
param->setMeasureName(l_measureNames[PERCENT]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::LENGTH:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::RADIUS_UI:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::WIDTH_UI:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::SIZE_UI:
|
|
Shinya Kitaoka |
120a6e |
param->setMeasureName(l_measureNames[LENGTH]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::ANGLE:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::ANGLE_UI:
|
|
Shinya Kitaoka |
120a6e |
param->setMeasureName(l_measureNames[ANGLE]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tdoubleparamp>(&m_params.back()));</tdoubleparamp>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::VEC2: {
|
|
Shinya Kitaoka |
120a6e |
TPointParamP param(
|
|
Shinya Kitaoka |
120a6e |
TPointD(siParam.m_default.m_vec2[0], siParam.m_default.m_vec2[1]));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
param->getX()->setValueRange(siParam.m_range[0].m_vec2[0],
|
|
Shinya Kitaoka |
120a6e |
siParam.m_range[1].m_vec2[0]);
|
|
Shinya Kitaoka |
120a6e |
param->getY()->setValueRange(siParam.m_range[0].m_vec2[1],
|
|
Shinya Kitaoka |
120a6e |
siParam.m_range[1].m_vec2[1]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
locals.addUiConcept(siParam, param);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (siParam.m_concept.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::PERCENT:
|
|
Shinya Kitaoka |
120a6e |
param->getX()->setMeasureName(l_measureNames[PERCENT]);
|
|
Shinya Kitaoka |
120a6e |
param->getY()->setMeasureName(l_measureNames[PERCENT]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::LENGTH:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::POINT:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::POINT_UI:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::VECTOR_UI:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::WIDTH_UI:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::SIZE_UI:
|
|
Shinya Kitaoka |
120a6e |
param->getX()->setMeasureName(l_measureNames[LENGTH]);
|
|
Shinya Kitaoka |
120a6e |
param->getY()->setMeasureName(l_measureNames[LENGTH]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::ANGLE:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::ANGLE_UI:
|
|
Shinya Kitaoka |
120a6e |
param->getX()->setMeasureName(l_measureNames[ANGLE]);
|
|
Shinya Kitaoka |
120a6e |
param->getY()->setMeasureName(l_measureNames[ANGLE]);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tpointparamp>(&m_params.back()));</tpointparamp>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::INT: {
|
|
Shinya Kitaoka |
120a6e |
TIntParamP param(siParam.m_default.m_int);
|
|
Shinya Kitaoka |
120a6e |
param->setValueRange(siParam.m_range[0].m_int, siParam.m_range[1].m_int);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tintparamp>(&m_params.back()));</tintparamp>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::RGBA: {
|
|
Shinya Kitaoka |
120a6e |
TPixelParamP param(
|
|
Shinya Kitaoka |
120a6e |
TPixel32(siParam.m_default.m_rgba[0], siParam.m_default.m_rgba[1],
|
|
Shinya Kitaoka |
120a6e |
siParam.m_default.m_rgba[2], siParam.m_default.m_rgba[3]));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tpixelparamp>(&m_params.back()));</tpixelparamp>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::RGB: {
|
|
Shinya Kitaoka |
120a6e |
TPixelParamP param(TPixel32(siParam.m_default.m_rgb[0],
|
|
Shinya Kitaoka |
120a6e |
siParam.m_default.m_rgb[1],
|
|
Shinya Kitaoka |
120a6e |
siParam.m_default.m_rgb[2]));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
param->enableMatte(false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_params.push_back(param);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, siParam.m_name.toStdString(),
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tpixelparamp>(&m_params.back()));</tpixelparamp>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add composite UI concepts
|
|
Shinya Kitaoka |
120a6e |
const std::vector<shaderinterface::parameterconcept> &parConcepts =</shaderinterface::parameterconcept>
|
|
Shinya Kitaoka |
120a6e |
m_shaderInterface->m_parConcepts;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int c, cCount = int(parConcepts.size());
|
|
Shinya Kitaoka |
120a6e |
for (c = 0; c != cCount; ++c) locals.addUiConcept(parConcepts[c]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add input ports
|
|
Shinya Kitaoka |
120a6e |
const std::vector<qstring> &inputPorts = m_shaderInterface->inputPorts();</qstring>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i, iCount = int(inputPorts.size());
|
|
Shinya Kitaoka |
120a6e |
m_inputPorts.reserve(iCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i != iCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
m_inputPorts.push_back(new TRasterFxPort);
|
|
Shinya Kitaoka |
120a6e |
addInputPort(inputPorts[i].toStdString(), m_inputPorts[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::getParamUIs(TParamUIConcept *¶ms, int &length) {
|
|
Shinya Kitaoka |
120a6e |
length = int(m_uiConcepts.size());
|
|
Shinya Kitaoka |
120a6e |
params = new TParamUIConcept[length];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::copy(m_uiConcepts.begin(), m_uiConcepts.end(), params);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ShaderFx::doGetBBox(double frame, TRectD &bbox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
static const ::RectF infiniteRectF(-(std::numeric_limits<glfloat>::max)(),</glfloat>
|
|
Shinya Kitaoka |
120a6e |
-(std::numeric_limits<glfloat>::max)(),</glfloat>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<glfloat>::max)(),</glfloat>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<glfloat>::max)());</glfloat>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bbox = TConsts::infiniteRectD;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface::ShaderData &sd = m_shaderInterface->bboxShader();
|
|
Shinya Kitaoka |
120a6e |
if (!sd.isValid()) return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager *manager = ShadingContextManager::instance();
|
|
Shinya Kitaoka |
120a6e |
if (manager->touchSupport() != ShadingContext::OK) return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Remember: info.m_affine MUST NOT BE CONSIDERED in doGetBBox's
|
|
Shinya Kitaoka |
120a6e |
// implementation
|
|
Shinya Kitaoka |
120a6e |
::RectF bboxF(infiniteRectF);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker mLocker(manager->mutex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ShadingContext& context = manager->shadingContext();
|
|
Shinya Kitaoka |
120a6e |
std::shared_ptr<shadingcontext> shadingContextPtr(new ShadingContext);</shadingcontext>
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context = *shadingContextPtr.get();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
::ContextLocker cLocker(context);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build the varyings data
|
|
Shinya Kitaoka |
120a6e |
QGLShaderProgram *prog = 0;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const GLchar *varyingNames[] = {"outputBBox"};
|
|
Shinya Kitaoka |
120a6e |
prog = touchShaderProgram(sd, context, 1, &varyingNames[0]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int pCount = getInputPortCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<rectf> inputBBoxes(pCount, ::RectF(TRectD()));</rectf>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort &port = m_inputPorts[p];
|
|
Shinya Kitaoka |
120a6e |
if (port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
TRectD inputBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
cLocker.unlock();
|
|
Shinya Kitaoka |
120a6e |
mLocker.unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (port->doGetBBox(frame, inputBBox, info))
|
|
Shinya Kitaoka |
120a6e |
inputBBoxes[p] = (inputBBox == TConsts::infiniteRectD)
|
|
Shinya Kitaoka |
120a6e |
? infiniteRectF
|
|
Shinya Kitaoka |
120a6e |
: ::RectF(inputBBox);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
mLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
cLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ProgramBinder progBinder(prog);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Bind uniform parameters
|
|
Shinya Kitaoka |
120a6e |
bindParameters(prog, frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
prog->setUniformValue("infiniteRect", infiniteRectF.m_val[0],
|
|
Shinya Kitaoka |
120a6e |
infiniteRectF.m_val[1], infiniteRectF.m_val[2],
|
|
Shinya Kitaoka |
120a6e |
infiniteRectF.m_val[3]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
prog->setUniformValueArray("inputBBox", inputBBoxes[0].m_val,
|
|
Shinya Kitaoka |
120a6e |
int(inputBBoxes.size()), 4);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Perform transform feedback
|
|
Shinya Kitaoka |
120a6e |
const GLsizeiptr varyingSizes[] = {sizeof(::RectF)};
|
|
Shinya Kitaoka |
120a6e |
GLvoid *bufs[] = {bboxF.m_val};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
context.transformFeedback(1, varyingSizes, bufs);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Finalize output
|
|
Shinya Kitaoka |
120a6e |
bbox = (bboxF == infiniteRectF) ? TConsts::infiniteRectD : TRectD(bboxF);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ShaderFx::canHandle(const TRenderSettings &info, double frame) {
|
|
Shinya Kitaoka |
120a6e |
return (m_shaderInterface->hwtType() == ShaderInterface::ANY)
|
|
Shinya Kitaoka |
120a6e |
? true
|
|
Shinya Kitaoka |
120a6e |
: isAlmostIsotropic(info.m_affine);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QGLShaderProgram *ShaderFx::touchShaderProgram(
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface::ShaderData &sd, ShadingContext &context,
|
|
Shinya Kitaoka |
120a6e |
int varyingsCount, const GLchar **varyings) {
|
|
Shinya Kitaoka |
120a6e |
typedef std::pair<qglshaderprogram *,="" qdatetime=""> CompiledShader;</qglshaderprogram>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
inline static void logCompilation(QGLShaderProgram *program) {
|
|
Shinya Kitaoka |
120a6e |
// Log shaders - observe that we'll look into the program's *children*,
|
|
Shinya Kitaoka |
120a6e |
// not its
|
|
Shinya Kitaoka |
120a6e |
// shaders. This is necessary as uncompiled shaders are not added to the
|
|
Shinya Kitaoka |
120a6e |
// program.
|
|
Shinya Kitaoka |
120a6e |
const QObjectList &children = program->children();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int c, cCount = children.size();
|
|
Shinya Kitaoka |
120a6e |
for (c = 0; c != cCount; ++c) {
|
|
Shinya Kitaoka |
120a6e |
if (QGLShader *shader = dynamic_cast<qglshader *="">(children[c])) {</qglshader>
|
|
Shinya Kitaoka |
120a6e |
const QString &log = shader->log();
|
|
Shinya Kitaoka |
120a6e |
if (!log.isEmpty()) DVGui::info(log);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ShaderProgram linking logs
|
|
Shinya Kitaoka |
120a6e |
const QString &log = program->log();
|
|
Shinya Kitaoka |
120a6e |
if (!log.isEmpty()) DVGui::info(log);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ShadingContext& context =
|
|
Shinya Kitaoka |
120a6e |
// ShadingContextManager::instance()->shadingContext();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
CompiledShader cs = context.shaderData(sd.m_name);
|
|
Shinya Kitaoka |
120a6e |
if (!cs.first || ::isObsolete(sd.m_path, cs.second)) {
|
|
Shinya Kitaoka |
120a6e |
cs = m_shaderInterface->makeProgram(sd, varyingsCount, varyings);
|
|
Shinya Kitaoka |
120a6e |
context.addShaderProgram(sd.m_name, cs.first, cs.second);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
locals::logCompilation(cs.first);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(cs.first);
|
|
Shinya Kitaoka |
120a6e |
return cs.first;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::bindParameters(QGLShaderProgram *program, double frame) {
|
|
Shinya Kitaoka |
120a6e |
// Bind fx parameters
|
|
Shinya Kitaoka |
120a6e |
const std::vector<shaderinterface::parameter> &siParams =</shaderinterface::parameter>
|
|
Shinya Kitaoka |
120a6e |
m_shaderInterface->parameters();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(siParams.size() == m_params.size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int p, pCount = int(siParams.size());
|
|
Shinya Kitaoka |
120a6e |
for (p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface::Parameter &siParam = siParams[p];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (siParam.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::BOOL: {
|
|
Shinya Kitaoka |
120a6e |
const TBoolParamP ¶m =
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tboolparamp>(&m_params[p]);</tboolparamp>
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue(siParam.m_name.toUtf8().data(),
|
|
Shinya Kitaoka |
120a6e |
(GLboolean)param->getValue());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::FLOAT: {
|
|
Shinya Kitaoka |
120a6e |
const TDoubleParamP ¶m =
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tdoubleparamp>(&m_params[p]);</tdoubleparamp>
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue(siParam.m_name.toUtf8().data(),
|
|
Shinya Kitaoka |
120a6e |
(GLfloat)param->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::VEC2: {
|
|
Shinya Kitaoka |
120a6e |
const TPointParamP ¶m =
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tpointparamp>(&m_params[p]);</tpointparamp>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &value = param->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue(siParam.m_name.toUtf8().data(), (GLfloat)value.x,
|
|
Shinya Kitaoka |
120a6e |
(GLfloat)value.y);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::INT: {
|
|
Shinya Kitaoka |
120a6e |
const TIntParamP ¶m =
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tintparamp>(&m_params[p]);</tintparamp>
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue(siParam.m_name.toUtf8().data(),
|
|
Shinya Kitaoka |
120a6e |
(GLint)param->getValue());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::RGBA:
|
|
Shinya Kitaoka |
120a6e |
case ShaderInterface::RGB: {
|
|
Shinya Kitaoka |
120a6e |
const TPixelParamP ¶m =
|
|
Shinya Kitaoka |
120a6e |
*boost::unsafe_any_cast<tpixelparamp>(&m_params[p]);</tpixelparamp>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 &value = param->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue(
|
|
Shinya Kitaoka |
120a6e |
siParam.m_name.toUtf8().data(), (GLfloat)value.r / 255.0f,
|
|
Shinya Kitaoka |
120a6e |
(GLfloat)value.g / 255.0f, (GLfloat)value.b / 255.0f,
|
|
Shinya Kitaoka |
120a6e |
(GLfloat)value.m / 255.0f);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::bindWorldTransform(QGLShaderProgram *program,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldToDst) {
|
|
Toshihiro Shimizu |
890ddd |
// Bind transformation affine
|
|
Toshihiro Shimizu |
890ddd |
#if QT_VERSION >= 0x050500
|
|
Shinya Kitaoka |
120a6e |
float qwToD[9] = {static_cast<float>(worldToDst.a11),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(worldToDst.a12),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(worldToDst.a13),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(worldToDst.a21),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(worldToDst.a22),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(worldToDst.a23),</float>
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
1.0f};
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
qreal qwToD[9] = {worldToDst.a11,
|
|
Shinya Kitaoka |
120a6e |
worldToDst.a12,
|
|
Shinya Kitaoka |
120a6e |
worldToDst.a13,
|
|
Shinya Kitaoka |
120a6e |
worldToDst.a21,
|
|
Shinya Kitaoka |
120a6e |
worldToDst.a22,
|
|
Shinya Kitaoka |
120a6e |
worldToDst.a23,
|
|
Shinya Kitaoka |
120a6e |
0.0,
|
|
Shinya Kitaoka |
120a6e |
0.0,
|
|
Shinya Kitaoka |
120a6e |
1.0};
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue("worldToOutput", QMatrix3x3(qwToD));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &dToW = worldToDst.inv();
|
|
Toshihiro Shimizu |
890ddd |
#if QT_VERSION >= 0x050500
|
|
Shinya Kitaoka |
120a6e |
float qdToW[9] = {static_cast<float>(dToW.a11),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(dToW.a12),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(dToW.a13),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(dToW.a21),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(dToW.a22),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(dToW.a23),</float>
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
1.0f};
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
qreal qdToW[9] = {dToW.a11, dToW.a12, dToW.a13, dToW.a21, dToW.a22,
|
|
Shinya Kitaoka |
120a6e |
dToW.a23, 0.0, 0.0, 1.0};
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValue("outputToWorld", QMatrix3x3(qdToW));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::getInputData(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &ri,
|
|
Shinya Kitaoka |
120a6e |
std::vector<trectd> &inputRects,</trectd>
|
|
Shinya Kitaoka |
120a6e |
std::vector<taffine> &inputAffines,</taffine>
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static inline void addNames(std::vector<std::string> &names,</std::string>
|
|
Shinya Kitaoka |
120a6e |
const char *prefix, int pCount) {
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p)
|
|
Shinya Kitaoka |
120a6e |
names.push_back((prefix + QString("[%1]").arg(p)).toStdString());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const ShaderInterface::ShaderData &sd = m_shaderInterface->inputPortsShader();
|
|
Shinya Kitaoka |
120a6e |
if (!sd.isValid()) {
|
|
Shinya Kitaoka |
120a6e |
inputRects.resize(getInputPortCount());
|
|
Shinya Kitaoka |
120a6e |
std::fill(inputRects.begin(), inputRects.end(), rect);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputAffines.resize(getInputPortCount());
|
|
Shinya Kitaoka |
120a6e |
std::fill(inputAffines.begin(), inputAffines.end(), ri.m_affine);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ShadingContext& context =
|
|
Shinya Kitaoka |
120a6e |
// ShadingContextManager::instance()->shadingContext();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<glfloat> buf;</glfloat>
|
|
Shinya Kitaoka |
120a6e |
int pCount = getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build the varyings data
|
|
Shinya Kitaoka |
120a6e |
QGLShaderProgram *prog = 0;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// Unsubscripted varying arrays on transform feedback seems to be
|
|
Shinya Kitaoka |
120a6e |
// unsupported
|
|
Shinya Kitaoka |
120a6e |
// on ATI cards. We have to declare EACH array name - e.g. inputRect[0],
|
|
Shinya Kitaoka |
120a6e |
// intputRect[1], etc..
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const GLchar *varyingPrefixes[] = {"inputRect", "worldToInput"};
|
|
Shinya Kitaoka |
120a6e |
const int varyingsCount = sizeof(varyingPrefixes) / sizeof(GLchar *);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::string> varyingStrings;</std::string>
|
|
Shinya Kitaoka |
120a6e |
varyingStrings.reserve(varyingsCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int v = 0; v != varyingsCount; ++v)
|
|
Shinya Kitaoka |
120a6e |
locals::addNames(varyingStrings, varyingPrefixes[v], pCount);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(__APPLE_CC__)
|
|
Shinya Kitaoka |
120a6e |
/* OSX10.8 の clang -stdlib=libc++ だと link 時 &std::string::c_str が
|
|
Shinya Kitaoka |
120a6e |
* undefined になってしまう */
|
|
Shinya Kitaoka |
120a6e |
std::vector<const *="" glchar=""> varyingNames(varyingStrings.size());</const>
|
|
Shinya Kitaoka |
120a6e |
auto conv = [](const std::string &i) { return i.c_str(); };
|
|
Shinya Kitaoka |
120a6e |
std::transform(varyingStrings.begin(), varyingStrings.end(),
|
|
Shinya Kitaoka |
120a6e |
varyingNames.begin(), conv);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
std::vector<const *="" glchar=""> varyingNames(</const>
|
|
Shinya Kitaoka |
120a6e |
boost::make_transform_iterator(varyingStrings.begin(),
|
|
Shinya Kitaoka |
120a6e |
std::mem_fun_ref(&std::string::c_str)),
|
|
Shinya Kitaoka |
120a6e |
boost::make_transform_iterator(varyingStrings.end(),
|
|
Shinya Kitaoka |
120a6e |
std::mem_fun_ref(&std::string::c_str)));
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
prog = touchShaderProgram(sd, context, int(varyingNames.size()),
|
|
Shinya Kitaoka |
120a6e |
&varyingNames[0]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ProgramBinder progBinder(prog);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build varying buffers
|
|
Shinya Kitaoka |
120a6e |
int bufFloatsCount =
|
|
Shinya Kitaoka |
120a6e |
pCount * (sizeof(RectF) + sizeof(AffineF)) / sizeof(GLfloat);
|
|
Shinya Kitaoka |
120a6e |
buf.resize(bufFloatsCount);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Bind uniform parameters
|
|
Shinya Kitaoka |
120a6e |
bindParameters(prog, frame);
|
|
Shinya Kitaoka |
120a6e |
bindWorldTransform(prog, ri.m_affine);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
prog->setUniformValue("outputRect", (GLfloat)rect.x0, (GLfloat)rect.y0,
|
|
Shinya Kitaoka |
120a6e |
(GLfloat)rect.x1, (GLfloat)rect.y1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Perform transform feedback
|
|
Shinya Kitaoka |
120a6e |
const GLsizeiptr varyingSizes[] = {
|
|
Shinya Kitaoka |
120a6e |
static_cast<glsizeiptr>(bufFloatsCount * sizeof(GLfloat))};</glsizeiptr>
|
|
Shinya Kitaoka |
120a6e |
GLvoid *bufs[] = {&buf[0]};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
context.transformFeedback(1, varyingSizes, bufs);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TRANSFORM_FEEDBACK_COUT
|
|
Shinya Kitaoka |
120a6e |
std::cout << "trFeedback: ";
|
|
Shinya Kitaoka |
120a6e |
for (int f = 0; f != bufFloatsCount; ++f) std::cout << buf[f] << " ";
|
|
Shinya Kitaoka |
120a6e |
std::cout << "\n" << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Finalize output
|
|
Shinya Kitaoka |
120a6e |
const RectF *rBufBegin(reinterpret_cast<const *="" rectf="">(&buf[0])),</const>
|
|
Shinya Kitaoka |
120a6e |
*rBufEnd(rBufBegin + pCount);
|
|
Shinya Kitaoka |
120a6e |
std::copy(rBufBegin, rBufEnd, &inputRects[0]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const AffineF *aBufBegin(reinterpret_cast<const *="" affinef="">(rBufEnd)),</const>
|
|
Shinya Kitaoka |
120a6e |
*aBufEnd(aBufBegin + pCount);
|
|
Shinya Kitaoka |
120a6e |
std::copy(aBufBegin, aBufEnd, &inputAffines[0]);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
struct TexturesStorage {
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &m_ctx;
|
|
Shinya Kitaoka |
120a6e |
std::vector<gluint> m_texIds;</gluint>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TexturesStorage(ShadingContext &ctx, int pCount) : m_ctx(ctx) {
|
|
Shinya Kitaoka |
120a6e |
m_texIds.reserve(pCount);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TexturesStorage() {
|
|
Shinya Kitaoka |
120a6e |
typedef tcg::function
|
|
Shinya Kitaoka |
120a6e |
&ShadingContext::unloadTexture>
|
|
Shinya Kitaoka |
120a6e |
UnloadFunc;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::for_each(m_texIds.begin(), m_texIds.end(),
|
|
Shinya Kitaoka |
120a6e |
tcg::bind1st(UnloadFunc(), m_ctx));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void load(const TRasterP &ras, GLuint texUnit) {
|
|
Shinya Kitaoka |
120a6e |
if (ras) m_texIds.push_back(m_ctx.loadTexture(ras, texUnit));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline static QGLFramebufferObjectFormat makeFormat(int bpp) {
|
|
Shinya Kitaoka |
120a6e |
QGLFramebufferObjectFormat fmt;
|
|
Shinya Kitaoka |
120a6e |
if (bpp == 64) fmt.setInternalTextureFormat(GL_RGBA16);
|
|
Shinya Kitaoka |
120a6e |
return fmt;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline static void touchOutputSize(ShadingContext &context,
|
|
Shinya Kitaoka |
120a6e |
const TDimension &size, int bpp) {
|
|
Shinya Kitaoka |
120a6e |
const QGLFramebufferObjectFormat &fmt = makeFormat(bpp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TDimension ¤tSize = context.size();
|
|
Shinya Kitaoka |
120a6e |
const QGLFramebufferObjectFormat ¤tFmt = context.format();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (currentSize.lx < size.lx || currentSize.ly < size.ly ||
|
|
Shinya Kitaoka |
120a6e |
currentFmt != fmt)
|
|
Shinya Kitaoka |
120a6e |
context.resize(std::max(size.lx, currentSize.lx),
|
|
Shinya Kitaoka |
120a6e |
std::max(size.ly, currentSize.ly), fmt);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager *manager = ShadingContextManager::instance();
|
|
Shinya Kitaoka |
120a6e |
if (manager->touchSupport() != ShadingContext::OK) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker mLocker(
|
|
Shinya Kitaoka |
120a6e |
manager->mutex()); // As GPU access can be considered sequential anyway,
|
|
Shinya Kitaoka |
120a6e |
// lock the full-scale mutex
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::shared_ptr<shadingcontext> shadingContextPtr(new ShadingContext);</shadingcontext>
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context = *shadingContextPtr.get();
|
|
Shinya Kitaoka |
120a6e |
// ShadingContext& context = manager->shadingContext();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int pCount = getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TRectD &tileRect = ::tileRect(tile);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<trectd> inputRects(pCount);</trectd>
|
|
Shinya Kitaoka |
120a6e |
std::vector<taffine> inputAffines(pCount);</taffine>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Calculate input tiles
|
|
Shinya Kitaoka |
120a6e |
::ContextLocker cLocker(context);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tcg::unique_ptr<ttile[]> inTiles(</ttile[]>
|
|
Shinya Kitaoka |
120a6e |
new TTile[pCount]); // NOTE: Input tiles must be STORED - they cannot
|
|
Shinya Kitaoka |
120a6e |
// be passed immediately to OpenGL, since *other shader
|
|
Shinya Kitaoka |
120a6e |
if (pCount > 0) // fxs*, with the very same host context, could lie
|
|
Shinya Kitaoka |
120a6e |
{ // inside this fx's input branches...
|
|
Shinya Kitaoka |
120a6e |
getInputData(tileRect, frame, info, inputRects, inputAffines, context);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Release context and mutex
|
|
Shinya Kitaoka |
120a6e |
cLocker.unlock();
|
|
Shinya Kitaoka |
120a6e |
mLocker.unlock();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort &port = m_inputPorts[p];
|
|
Shinya Kitaoka |
120a6e |
if (port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
// Compute input tile
|
|
Shinya Kitaoka |
120a6e |
TRectD &inRect = inputRects[p];
|
|
Shinya Kitaoka |
120a6e |
if (inRect.getLx() > 0.0 && inRect.getLy() > 0.0) {
|
|
Shinya Kitaoka |
120a6e |
::ceilRect(inRect);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings inputInfo(info);
|
|
Shinya Kitaoka |
120a6e |
inputInfo.m_affine = inputAffines[p];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TRANSFORM_FEEDBACK_COUT
|
|
Shinya Kitaoka |
120a6e |
const TAffine &inAff = inputAffines[p];
|
|
Shinya Kitaoka |
120a6e |
std::cout << "inRect " << p << ": " << inRect.x0 << " " << inRect.y0
|
|
Shinya Kitaoka |
120a6e |
<< " " << inRect.x1 << " " << inRect.y1 << "\n";
|
|
Shinya Kitaoka |
120a6e |
std::cout << "inAff " << p << ": " << inAff.a11 << " " << inAff.a12
|
|
Shinya Kitaoka |
120a6e |
<< " " << inAff.a13 << "\n";
|
|
Shinya Kitaoka |
120a6e |
std::cout << " " << inAff.a21 << " " << inAff.a22 << " "
|
|
Shinya Kitaoka |
120a6e |
<< inAff.a23 << "\n"
|
|
Shinya Kitaoka |
120a6e |
<< std::endl;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
port->allocateAndCompute(
|
|
Shinya Kitaoka |
120a6e |
inTiles[p], inRect.getP00(),
|
|
Shinya Kitaoka |
120a6e |
TDimension(tround(inRect.getLx()), tround(inRect.getLy())),
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster(), frame, inputInfo);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Load input tiles on the GPU as textures
|
|
Shinya Kitaoka |
120a6e |
mLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
cLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Input tiles are NOT supplied to OpenGL here - but rather just before
|
|
Shinya Kitaoka |
120a6e |
// drawing.
|
|
Shinya Kitaoka |
120a6e |
// It's probably beacuse a uniform integer variable must have already been
|
|
Shinya Kitaoka |
120a6e |
// bound
|
|
Shinya Kitaoka |
120a6e |
// to prepare the associated sampler variable in the linkes program...
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Perform the actual fragment shading
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
locals::touchOutputSize(context, tile.getRaster()->getSize(), info.m_bpp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QGLShaderProgram *program =
|
|
Shinya Kitaoka |
120a6e |
touchShaderProgram(m_shaderInterface->mainShader(), context);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ProgramBinder binder(program);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Bind parameters and textures
|
|
Shinya Kitaoka |
120a6e |
bindParameters(program, frame);
|
|
Shinya Kitaoka |
120a6e |
bindWorldTransform(program, TTranslation(-tile.m_pos) * info.m_affine);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Setup input data, if any
|
|
Shinya Kitaoka |
120a6e |
locals::TexturesStorage texStorage(context, pCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (pCount > 0) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<glint> inputs(pCount);</glint>
|
|
Shinya Kitaoka |
120a6e |
std::vector<qmatrix3x3> screenToInput(pCount);</qmatrix3x3>
|
|
Shinya Kitaoka |
120a6e |
std::vector<qmatrix3x3> inputToScreen(pCount);</qmatrix3x3>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
TAffine iToS(
|
|
Shinya Kitaoka |
120a6e |
TTranslation(-tile.m_pos) * // Output to Screen
|
|
Shinya Kitaoka |
120a6e |
info.m_affine * // World to Output
|
|
Shinya Kitaoka |
120a6e |
inputAffines[p].inv() * // Input to World
|
|
Shinya Kitaoka |
120a6e |
TTranslation(inputRects[p].getP00()) * // Texture to Input
|
|
Shinya Kitaoka |
120a6e |
TScale(inputRects[p].getLx(), inputRects[p].getLy())); //
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine sToI(iToS.inv());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if QT_VERSION >= 0x050500
|
|
Shinya Kitaoka |
120a6e |
float qiToS[9] = {static_cast<float>(iToS.a11),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(iToS.a12),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(iToS.a13),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(iToS.a21),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(iToS.a22),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(iToS.a23),</float>
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
1.0f};
|
|
Shinya Kitaoka |
120a6e |
float qsToI[9] = {static_cast<float>(sToI.a11),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(sToI.a12),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(sToI.a13),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(sToI.a21),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(sToI.a22),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(sToI.a23),</float>
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
0.0f,
|
|
Shinya Kitaoka |
120a6e |
1.0f};
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
qreal qiToS[9] = {iToS.a11, iToS.a12, iToS.a13, iToS.a21, iToS.a22,
|
|
Shinya Kitaoka |
120a6e |
iToS.a23, 0.0, 0.0, 1.0};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
qreal qsToI[9] = {sToI.a11, sToI.a12, sToI.a13, sToI.a21, sToI.a22,
|
|
Shinya Kitaoka |
120a6e |
sToI.a23, 0.0, 0.0, 1.0};
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
inputs[p] = p, screenToInput[p] = QMatrix3x3(qsToI),
|
|
Shinya Kitaoka |
120a6e |
inputToScreen[p] = QMatrix3x3(qiToS);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValueArray("inputImage", &inputs[0], pCount);
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValueArray("outputToInput", &screenToInput[0],
|
|
Shinya Kitaoka |
120a6e |
pCount);
|
|
Shinya Kitaoka |
120a6e |
program->setUniformValueArray("inputToOutput", &inputToScreen[0],
|
|
Shinya Kitaoka |
120a6e |
pCount);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Load textures
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p)
|
|
Shinya Kitaoka |
120a6e |
texStorage.load(inTiles[p].getRaster(), p);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef DIAGNOSTICS
|
|
Shinya Kitaoka |
120a6e |
DIAGNOSTICS_TIMER("Shader Overall Times | " +
|
|
Shinya Kitaoka |
120a6e |
m_shaderInterface->m_mainShader.m_name);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
context.draw(tile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShaderFx::doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
ShadingContextManager *manager = ShadingContextManager::instance();
|
|
Shinya Kitaoka |
120a6e |
if (manager->touchSupport() != ShadingContext::OK) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker mLocker(manager->mutex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ShadingContext& context = manager->shadingContext();
|
|
Shinya Kitaoka |
120a6e |
std::shared_ptr<shadingcontext> shadingContextPtr(new ShadingContext);</shadingcontext>
|
|
Shinya Kitaoka |
120a6e |
ShadingContext &context = *shadingContextPtr.get();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int pCount = getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
if (pCount > 0) {
|
|
Shinya Kitaoka |
120a6e |
::ContextLocker cLocker(context);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<trectd> inputRects(pCount);</trectd>
|
|
Shinya Kitaoka |
120a6e |
std::vector<taffine> inputAffines(pCount);</taffine>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
getInputData(rect, frame, info, inputRects, inputAffines, context);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p != pCount; ++p) {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort &port = m_inputPorts[p];
|
|
Shinya Kitaoka |
120a6e |
if (port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
TRectD &inRect = inputRects[p];
|
|
Shinya Kitaoka |
120a6e |
if (inRect.getLx() > 0.0 && inRect.getLy() > 0.0) {
|
|
Shinya Kitaoka |
120a6e |
::ceilRect(inRect);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings inputInfo(info);
|
|
Shinya Kitaoka |
120a6e |
inputInfo.m_affine = inputAffines[p];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
cLocker.unlock();
|
|
Shinya Kitaoka |
120a6e |
mLocker.unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
port->dryCompute(inRect, frame, inputInfo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
mLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
cLocker.relock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TPersistDeclaration *ShaderFx::getDeclaration() const {
|
|
Shinya Kitaoka |
120a6e |
FxDeclarationsMap::iterator it =
|
|
Shinya Kitaoka |
120a6e |
::l_shaderFxDeclarations.find(m_shaderInterface->mainShader().m_name);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (it == ::l_shaderFxDeclarations.end()) ? 0 : it->second;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Shader Interfaces loading function
|
|
Toshihiro Shimizu |
890ddd |
//****************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void loadShaderInterfaces(const TFilePath &shadersFolder) {
|
|
Shinya Kitaoka |
120a6e |
// Scan the shaders folder for xml (shader interface) files
|
|
Shinya Kitaoka |
120a6e |
QDir shadersDir(QString::fromStdWString(shadersFolder.getWideString()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QStringList namesFilter("*.xml");
|
|
Shinya Kitaoka |
120a6e |
QStringList files = shadersDir.entryList(namesFilter, QDir::Files,
|
|
Shinya Kitaoka |
120a6e |
QDir::Name | QDir::LocaleAware);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int f, fCount = files.size();
|
|
Shinya Kitaoka |
120a6e |
for (f = 0; f != fCount; ++f) {
|
|
Shinya Kitaoka |
120a6e |
TIStream is(shadersFolder + TFilePath(files[f].toStdWString()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Try to load a ShaderInterface instance for the file
|
|
Shinya Kitaoka |
120a6e |
ShaderInterface shaderInterface;
|
|
Shinya Kitaoka |
120a6e |
is >> shaderInterface;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (shaderInterface.isValid()) {
|
|
Shinya Kitaoka |
120a6e |
// Store a ShaderFx factory for the interface
|
|
Shinya Kitaoka |
120a6e |
::l_shaderFxDeclarations.insert(
|
|
Shinya Kitaoka |
120a6e |
std::make_pair(shaderInterface.mainShader().m_name,
|
|
Shinya Kitaoka |
120a6e |
new ShaderFxDeclaration(shaderInterface)));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|