diff --git a/src/libs/glsl/glslengine.cpp b/src/libs/glsl/glslengine.cpp index 5d8157823dd2dc3adef3d73e2eb8cec3e6138c09..ec5c40a551e750c51910c35aa679ad7e4110576b 100644 --- a/src/libs/glsl/glslengine.cpp +++ b/src/libs/glsl/glslengine.cpp @@ -147,7 +147,10 @@ const DoubleType *Engine::doubleType() const VectorType *Engine::vectorType(const Type *elementType, int dimension) { - return _vectorTypes.intern(VectorType(elementType, dimension)); + VectorType *type = const_cast<VectorType *> + (_vectorTypes.intern(VectorType(elementType, dimension))); + type->populateMembers(this); + return type; } const MatrixType *Engine::matrixType(const Type *elementType, int columns, int rows) diff --git a/src/libs/glsl/glsltypes.cpp b/src/libs/glsl/glsltypes.cpp index 3f7fd7b0f42875b180377043e1c056d820ee2c62..8d3e1964b89c7000c9fc9298c81052ba3a827ea6 100644 --- a/src/libs/glsl/glsltypes.cpp +++ b/src/libs/glsl/glsltypes.cpp @@ -29,6 +29,7 @@ #include "glsltypes.h" #include "glslsymbols.h" +#include "glslengine.h" using namespace GLSL; @@ -137,6 +138,90 @@ bool DoubleType::isLessThan(const Type *other) const return false; } +void VectorType::add(Symbol *symbol) +{ + _members.insert(symbol->name(), symbol); +} + +Symbol *VectorType::find(const QString &name) const +{ + return _members.value(name); +} + +void VectorType::populateMembers(Engine *engine) +{ + if (_members.isEmpty()) { + populateMembers(engine, "xyzw"); + populateMembers(engine, "rgba"); + populateMembers(engine, "stpq"); + } +} + +void VectorType::populateMembers(Engine *engine, const char *components) +{ + // Single component swizzles. + for (int x = 0; x < _dimension; ++x) { + const QString *name = engine->identifier(components + x, 1); + add(engine->newVariable(this, *name, _elementType)); + } + + // Two component swizzles. + const Type *vec2Type; + if (_dimension == 2) + vec2Type = this; + else + vec2Type = engine->vectorType(_elementType, 2); + for (int x = 0; x < _dimension; ++x) { + for (int y = 0; y < _dimension; ++y) { + QString name; + name += QLatin1Char(components[x]); + name += QLatin1Char(components[y]); + add(engine->newVariable + (this, *engine->identifier(name), vec2Type)); + } + } + + // Three component swizzles. + const Type *vec3Type; + if (_dimension == 3) + vec3Type = this; + else if (_dimension < 3) + return; + else + vec3Type = engine->vectorType(_elementType, 3); + for (int x = 0; x < _dimension; ++x) { + for (int y = 0; y < _dimension; ++y) { + for (int z = 0; z < _dimension; ++z) { + QString name; + name += QLatin1Char(components[x]); + name += QLatin1Char(components[y]); + name += QLatin1Char(components[z]); + add(engine->newVariable + (this, *engine->identifier(name), vec3Type)); + } + } + } + + // Four component swizzles. + if (_dimension != 4) + return; + for (int x = 0; x < _dimension; ++x) { + for (int y = 0; y < _dimension; ++y) { + for (int z = 0; z < _dimension; ++z) { + for (int w = 0; w < _dimension; ++w) { + QString name; + name += QLatin1Char(components[x]); + name += QLatin1Char(components[y]); + name += QLatin1Char(components[z]); + name += QLatin1Char(components[w]); + add(engine->newVariable + (this, *engine->identifier(name), this)); + } + } + } + } +} + bool VectorType::isEqualTo(const Type *other) const { if (other) { diff --git a/src/libs/glsl/glsltypes.h b/src/libs/glsl/glsltypes.h index 459b03181a5e0ca2c12af5cc1e75408ae34a1d93..7a2481ee6a20d9c5f6d401056a61cd66e0b0dbf1 100644 --- a/src/libs/glsl/glsltypes.h +++ b/src/libs/glsl/glsltypes.h @@ -32,6 +32,7 @@ #include "glsltype.h" #include "glslsymbol.h" #include <QtCore/QVector> +#include <QtCore/QHash> #include <QtCore/QString> namespace GLSL { @@ -98,7 +99,7 @@ public: virtual bool isLessThan(const Type *other) const; }; -class GLSL_EXPORT VectorType: public Type +class GLSL_EXPORT VectorType: public Type, public Scope { public: VectorType(const Type *elementType, int dimension) @@ -107,6 +108,10 @@ public: const Type *elementType() const { return _elementType; } int dimension() const { return _dimension; } + virtual void add(Symbol *symbol); + virtual Symbol *find(const QString &name) const; + virtual const Type *type() const { return this; } + virtual const VectorType *asVectorType() const { return this; } virtual bool isEqualTo(const Type *other) const; virtual bool isLessThan(const Type *other) const; @@ -114,6 +119,12 @@ public: private: const Type *_elementType; int _dimension; + QHash<QString, Symbol *> _members; + + friend class Engine; + + void populateMembers(Engine *engine); + void populateMembers(Engine *engine, const char *components); }; class GLSL_EXPORT MatrixType: public Type