#pragma once
#ifndef SHADERINTERFACE_H
#define SHADERINTERFACE_H
// Glew includes
#include <GL/glew.h> // Must be included before tgl.h
// TnzBase includes
#include "tparamuiconcept.h"
// TnzCore includes
#include "tpersist.h"
#include "tfilepath.h"
#include "tgl.h"
// Qt includes
#include <QString>
#include <QDateTime>
#include <QOpenGLShader>
// STD includes
#include <vector>
#undef DVAPI
#undef DVVAR
#ifdef TNZSTDFX_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
//=========================================================
// Forward declarations
class QOpenGLShaderProgram;
//=========================================================
//**********************************************************************
// ShaderInterface declaration
//**********************************************************************
/*!
A ShaderInterface represents interface data to a GLSL shader program.
\par Rationale
OpenGL shaders are supplied as text to be compiled at run-time by a
GLSL compiler. In our case, the specified text is assumed to be stored in
one or more files on hard-disk.
\n\n
However, in order for an executable to correctly interface a GLSL
shader program, further interface data must be supplied in some form.
Interface data include the path of the GLSL shader program file and
parameters to be bound by the executable before the shader is run.
\par Usage
A ShaderInterface is loaded from an xml file. Since an interface could
be loaded incorrectly, remember to check the isValid() method to ensure
that the loading process succeeds.
A loaded ShaderInterface allows access to shader parameters and
acts as a factory object to compiled QGLShaderProgram instances.
*/
class DVAPI ShaderInterface final : public TPersist {
public: // Enums
enum ParameterConceptType {
CONCEPT_NONE,
PERCENT,
LENGTH,
ANGLE,
POINT,
RADIUS_UI,
WIDTH_UI,
ANGLE_UI,
POINT_UI,
XY_UI,
VECTOR_UI,
POLAR_UI,
SIZE_UI,
QUAD_UI,
RECT_UI,
COMPASS_UI,
COMPASS_SPIN_UI,
CONCEPTSCOUNT,
UI_CONCEPTS = RADIUS_UI
};
enum ParameterType {
PARAMETER_UNKNOWN,
BOOL,
FLOAT,
VEC2,
VEC3,
VEC4,
INT,
IVEC2,
IVEC3,
IVEC4,
RGBA,
RGB,
TYPESCOUNT
};
enum HandledWorldTransformsType { HWT_UNKNOWN, ANY, ISOTROPIC, HWTCOUNT };
public: // Sub-classes
class ParameterConcept final : public TPersist {
PERSIST_DECLARATION(ParameterConcept)
public:
ParameterConceptType m_type; //!< The concept type (typically composite)
QString m_label; //!< Name to be shown for ui concepts
std::vector<QString>
m_parameterNames; //!< The involved parameters (by name)
public:
ParameterConcept() : m_type(CONCEPT_NONE) {}
ParameterConcept(ParameterConceptType type, const QString &label)
: m_type(type), m_label(label) {}
bool isUI() const {
return m_type >= UI_CONCEPTS && m_type < CONCEPTSCOUNT;
}
protected:
void saveData(TOStream &os) override;
void loadData(TIStream &is) override;
};
union ParameterValue {
GLboolean m_bool;
GLfloat m_float;
GLfloat m_vec2[2];
GLfloat m_vec3[3];
GLfloat m_vec4[4];
GLint m_int;
GLint m_ivec2[2];
GLint m_ivec3[3];
GLint m_ivec4[4];
GLubyte m_rgba[4];
GLubyte m_rgb[3];
};
class Parameter final : public TPersist {
PERSIST_DECLARATION(Parameter)
public:
ParameterType m_type;
QString m_name;
ParameterValue m_default;
ParameterValue m_range[2];
ParameterConcept m_concept;
public:
Parameter() : m_type(PARAMETER_UNKNOWN) {}
Parameter(ParameterType type, const QString &name)
: m_type(type), m_name(name) {}
protected:
void saveData(TOStream &os) override;
void loadData(TIStream &is) override;
};
class ShaderData final : public TPersist {
PERSIST_DECLARATION(ShaderData)
public:
QString m_name; //!< A name associated to the shader action
TFilePath m_path; //!< The shader program's file path
QOpenGLShader::ShaderType m_type; //!< The shader type
public:
bool isValid() const { return !m_path.isEmpty(); }
protected:
void saveData(TOStream &os) override;
void loadData(TIStream &is) override;
};
public: // Public methods
ShaderInterface();
bool isValid() const;
const std::vector<Parameter> ¶meters() const;
const std::vector<QString> &inputPorts() const;
const ShaderData &mainShader() const;
const ShaderData &inputPortsShader() const;
const ShaderData &bboxShader() const;
HandledWorldTransformsType hwtType() const;
/*!
Returns a compiled shader program against current OpenGL context, and the
last modified date of the associated shader file.
*/
std::pair<QOpenGLShaderProgram *, QDateTime> makeProgram(
const ShaderData &sd, int varyingsCount = 0,
const GLchar **varyingNames = 0) const;
protected:
void clear();
void saveData(TOStream &os) override;
void loadData(TIStream &is) override;
private:
PERSIST_DECLARATION(ShaderInterface)
ShaderData m_mainShader; //!< Main (fragment) shader data
std::vector<Parameter> m_parameters; //!< List of parameters for the shader
std::vector<ParameterConcept>
m_parConcepts; //!< List of (composite) parameter concepts
std::vector<QString> m_ports;
ShaderData m_portsShader; //!< (Vertex) shader dedicated to input
//!< ports' geometries calculation
ShaderData m_bboxShader; //!< (Vertex) shader dedicated to extracting
//!< the fx's bbox
HandledWorldTransformsType m_hwt; //!< World transform types \a handled by
//!< associated ShaderFx instances
};
#endif // SHADERINTERFACE_H