summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation/backend/animationutils.cpp237
-rw-r--r--src/animation/backend/animationutils_p.h19
-rw-r--r--src/animation/backend/channelmapper.cpp20
-rw-r--r--src/animation/backend/channelmapper_p.h12
-rw-r--r--src/animation/backend/channelmapping.cpp6
-rw-r--r--src/animation/backend/channelmapping_p.h1
-rw-r--r--src/animation/backend/clipanimator.cpp1
-rw-r--r--src/animation/backend/clipanimator_p.h4
-rw-r--r--src/animation/backend/clipblendvalue_p.h2
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp11
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob.cpp41
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob_p.h10
-rw-r--r--src/animation/backend/skeleton.cpp9
-rw-r--r--src/animation/backend/skeleton_p.h17
-rw-r--r--src/animation/frontend/qanimationaspect.cpp1
-rw-r--r--src/animation/frontend/qblendedclipanimator.cpp2
-rw-r--r--src/core/transforms/sqt_p.h1
-rw-r--r--src/extras/3dtext/qextrudedtextgeometry.cpp4
-rw-r--r--src/extras/defaults/defaults.pri3
-rw-r--r--src/extras/defaults/qabstractcameracontroller.cpp436
-rw-r--r--src/extras/defaults/qabstractcameracontroller.h126
-rw-r--r--src/extras/defaults/qabstractcameracontroller_p.h141
-rw-r--r--src/extras/defaults/qdiffusemapmaterial.cpp4
-rw-r--r--src/extras/defaults/qdiffusespecularmapmaterial.cpp4
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller.cpp305
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller.h39
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller_p.h152
-rw-r--r--src/extras/defaults/qmetalroughmaterial.cpp30
-rw-r--r--src/extras/defaults/qmetalroughmaterial.h4
-rw-r--r--src/extras/defaults/qmetalroughmaterial_p.h3
-rw-r--r--src/extras/defaults/qnormaldiffusemapalphamaterial.cpp8
-rw-r--r--src/extras/defaults/qnormaldiffusemapmaterial.cpp4
-rw-r--r--src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp4
-rw-r--r--src/extras/defaults/qorbitcameracontroller.cpp348
-rw-r--r--src/extras/defaults/qorbitcameracontroller.h28
-rw-r--r--src/extras/defaults/qorbitcameracontroller_p.h75
-rw-r--r--src/extras/defaults/qphongalphamaterial.cpp32
-rw-r--r--src/extras/defaults/qphongalphamaterial_p.h2
-rw-r--r--src/extras/defaults/qphongmaterial.cpp5
-rw-r--r--src/extras/extras.qrc17
-rw-r--r--src/extras/geometries/qconegeometry.cpp4
-rw-r--r--src/extras/geometries/qcuboidgeometry.cpp4
-rw-r--r--src/extras/geometries/qcylindergeometry.cpp4
-rw-r--r--src/extras/geometries/qplanegeometry.cpp4
-rw-r--r--src/extras/geometries/qspheregeometry.cpp4
-rw-r--r--src/extras/geometries/qtorusgeometry.cpp4
-rw-r--r--src/extras/shaders/es2/coordinatesystems.inc87
-rw-r--r--src/extras/shaders/es2/default.vert80
-rw-r--r--src/extras/shaders/es2/diffusemap.frag15
-rw-r--r--src/extras/shaders/es2/diffusemap.vert22
-rw-r--r--src/extras/shaders/es2/diffusespecularmap.frag15
-rw-r--r--src/extras/shaders/es2/light.inc.frag185
-rw-r--r--src/extras/shaders/es2/light.inc.frag100205
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.frag23
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.vert38
-rw-r--r--src/extras/shaders/es2/normaldiffusemapalpha.frag32
-rw-r--r--src/extras/shaders/es2/normaldiffusespecularmap.frag21
-rw-r--r--src/extras/shaders/es2/pervertexcolor.frag11
-rw-r--r--src/extras/shaders/es2/pervertexcolor.vert4
-rw-r--r--src/extras/shaders/es2/phong.frag13
-rw-r--r--src/extras/shaders/es2/phong.inc.frag128
-rw-r--r--src/extras/shaders/es2/phong.inc.frag100142
-rw-r--r--src/extras/shaders/es2/phong.vert17
-rw-r--r--src/extras/shaders/es2/phongalpha.frag22
-rw-r--r--src/extras/shaders/gl3/default.vert (renamed from src/extras/shaders/gl3/metalrough.vert)13
-rw-r--r--src/extras/shaders/gl3/diffusemap.frag15
-rw-r--r--src/extras/shaders/gl3/diffusemap.vert24
-rw-r--r--src/extras/shaders/gl3/diffusespecularmap.frag15
-rw-r--r--src/extras/shaders/gl3/light.inc.frag197
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.frag23
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.vert47
-rw-r--r--src/extras/shaders/gl3/normaldiffusemapalpha.frag34
-rw-r--r--src/extras/shaders/gl3/normaldiffusespecularmap.frag24
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.frag11
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.vert4
-rw-r--r--src/extras/shaders/gl3/phong.frag13
-rw-r--r--src/extras/shaders/gl3/phong.inc.frag138
-rw-r--r--src/extras/shaders/gl3/phong.vert19
-rw-r--r--src/extras/shaders/gl3/phongalpha.frag24
-rw-r--r--src/extras/text/distancefieldtextrenderer.cpp4
-rw-r--r--src/plugins/geometryloaders/default/objgeometryloader.cpp2
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp6
-rw-r--r--src/plugins/sceneparsers/gltf/gltfimporter.cpp34
-rw-r--r--src/plugins/sceneparsers/gltfexport/gltfexporter.cpp41
-rw-r--r--src/quick3d/quick3drender/items/quick3dbuffer.cpp2
-rw-r--r--src/render/backend/renderer.cpp6
-rw-r--r--src/render/backend/renderview.cpp3
-rw-r--r--src/render/backend/renderview_p.h1
-rw-r--r--src/render/frontend/qitemmodelbuffer.cpp2
-rw-r--r--src/render/frontend/qrendersettings.cpp5
-rw-r--r--src/render/geometry/buffer.cpp6
-rw-r--r--src/render/geometry/buffer_p.h2
-rw-r--r--src/render/geometry/qbuffer.cpp17
-rw-r--r--src/render/geometry/qbuffer.h7
-rw-r--r--src/render/geometry/qbuffer_p.h1
-rw-r--r--src/render/geometry/skeleton.cpp7
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp45
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h6
-rw-r--r--src/render/materialsystem/prototypes/default.json45
-rw-r--r--src/render/texture/gltexture.cpp1
100 files changed, 2040 insertions, 2056 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index f421a8025..d05d96f38 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -48,6 +48,7 @@
#include <QtGui/qquaternion.h>
#include <QtGui/qcolor.h>
#include <QtCore/qvariant.h>
+#include <QtCore/qvarlengtharray.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <numeric>
@@ -292,13 +293,45 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
bool finalFrame)
{
QVector<Qt3DCore::QSceneChangePtr> changes;
+ QVarLengthArray<Skeleton *, 4> dirtySkeletons;
+
// Iterate over the mappings
for (const MappingData &mappingData : mappingDataVec) {
if (!mappingData.propertyName)
continue;
+
// Build the new value from the channel/fcurve evaluation results
const QVariant v = buildPropertyValue(mappingData, channelResults);
- if (v.isValid()) {
+ if (!v.isValid())
+ continue;
+
+ // TODO: Avoid wrapping joint transform components up in a variant, just
+ // to immediately unwrap them again. Refactor buildPropertyValue() to call
+ // helper functions that we can call directly here for joints.
+ if (mappingData.skeleton && mappingData.jointIndex != -1) {
+ // Remember that this skeleton is dirty. We will ask each dirty skeleton
+ // to send its set of local poses to observers below.
+ if (!dirtySkeletons.contains(mappingData.skeleton))
+ dirtySkeletons.push_back(mappingData.skeleton);
+
+ switch (mappingData.jointTransformComponent) {
+ case MappingData::Scale:
+ mappingData.skeleton->setJointScale(mappingData.jointIndex, v.value<QVector3D>());
+ break;
+
+ case MappingData::Rotation:
+ mappingData.skeleton->setJointRotation(mappingData.jointIndex, v.value<QQuaternion>());
+ break;
+
+ case MappingData::Translation:
+ mappingData.skeleton->setJointTranslation(mappingData.jointIndex, v.value<QVector3D>());
+ break;
+
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ } else {
// Construct a property update change, set target, property and delivery options
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
@@ -311,6 +344,8 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
}
}
+ for (const auto skeleton : dirtySkeletons)
+ skeleton->sendLocalPoses();
// If it's the final frame, notify the frontend that we've stopped
if (finalFrame) {
@@ -342,96 +377,118 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
return callbacks;
}
-//TODO: Remove this and use new implementation below for both the unblended
-// and blended animation cases.
-QVector<MappingData> buildPropertyMappings(Handler *handler,
- const AnimationClip *clip,
- const ChannelMapper *mapper)
+// TODO: Optimize this even more by combining the work done here with the functions:
+// buildRequiredChannelsAndTypes() and assignChannelComponentIndices(). We are
+// currently repeating the iteration over mappings and extracting/generating
+// channel names, types and joint indices.
+QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings,
+ const QVector<ChannelNameAndType> &channelNamesAndTypes,
+ const QVector<ComponentIndices> &channelComponentIndices)
{
- QVector<MappingData> mappingDataVec;
- ChannelMappingManager *mappingManager = handler->channelMappingManager();
- const QVector<Channel> &channels = clip->channels();
-
- // Iterate over the mappings in the mapper object
- const auto mappingIds = mapper->mappingIds();
- for (const Qt3DCore::QNodeId mappingId : mappingIds) {
- // Get the mapping object
- ChannelMapping *mapping = mappingManager->lookupResource(mappingId);
- Q_ASSERT(mapping);
+ // Accumulate the required number of mappings
+ int maxMappingDatas = 0;
+ for (const auto mapping : channelMappings) {
+ switch (mapping->mappingType()) {
+ case ChannelMapping::ChannelMappingType:
+ case ChannelMapping::CallbackMappingType:
+ ++maxMappingDatas;
+ break;
- // Populate the data we need, easy stuff first
- MappingData mappingData;
- mappingData.targetId = mapping->targetId();
- mappingData.propertyName = mapping->propertyName();
- mappingData.type = mapping->type();
- mappingData.callback = mapping->callback();
- mappingData.callbackFlags = mapping->callbackFlags();
-
- if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
- qWarning() << "Unknown type for node id =" << mappingData.targetId
- << "and property =" << mapping->property()
- << "and callback =" << mapping->callback();
- continue;
+ case ChannelMapping::SkeletonMappingType: {
+ Skeleton *skeleton = mapping->skeleton();
+ maxMappingDatas += 3 * skeleton->jointCount(); // S, R, T
+ break;
}
+ }
+ }
+ QVector<MappingData> mappingDataVec;
+ mappingDataVec.reserve(maxMappingDatas);
- // Now the tricky part. Mapping the channel indices onto the property type.
- // Try to find a ChannelGroup with matching name
- const QString channelName = mapping->channelName();
- int channelGroupIndex = 0;
- bool foundMatch = false;
- for (const Channel &channel : channels) {
- if (channel.name == channelName) {
- foundMatch = true;
- const int channelBaseIndex = clip->channelComponentBaseIndex(channelGroupIndex);
-
- // Within this group, match channel names with index ordering
- mappingData.channelIndices = channelComponentsToIndices(channel, mappingData.type, channelBaseIndex);
+ // Iterate over the mappings
+ for (const auto mapping : channelMappings) {
+ switch (mapping->mappingType()) {
+ case ChannelMapping::ChannelMappingType:
+ case ChannelMapping::CallbackMappingType: {
+ // Populate the data we need, easy stuff first
+ MappingData mappingData;
+ mappingData.targetId = mapping->targetId();
+ mappingData.propertyName = mapping->propertyName();
+ mappingData.type = mapping->type();
+ mappingData.callback = mapping->callback();
+ mappingData.callbackFlags = mapping->callbackFlags();
+
+ if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
+ qWarning() << "Unknown type for node id =" << mappingData.targetId
+ << "and property =" << mapping->property()
+ << "and callback =" << mapping->callback();
+ continue;
+ }
- // Store the mapping data
+ // Try to find matching channel name and type
+ const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() };
+ const int index = channelNamesAndTypes.indexOf(nameAndType);
+ if (index != -1) {
+ // We got one!
+ mappingData.channelIndices = channelComponentIndices[index];
mappingDataVec.push_back(mappingData);
-
- if (foundMatch)
- break;
}
-
- ++channelGroupIndex;
+ break;
}
- }
- return mappingDataVec;
-}
+ case ChannelMapping::SkeletonMappingType: {
+ const QVector<ChannelNameAndType> jointProperties
+ = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D) },
+ { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion) },
+ { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D) } };
+ const QHash<QString, const char *> channelNameToPropertyName
+ = { { QLatin1String("Location"), "translation" },
+ { QLatin1String("Rotation"), "rotation" },
+ { QLatin1String("Scale"), "scale" } };
+ Skeleton *skeleton = mapping->skeleton();
+ const int jointCount = skeleton->jointCount();
+ for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) {
+ // Populate the data we need, easy stuff first
+ MappingData mappingData;
+ mappingData.targetId = mapping->skeletonId();
+ mappingData.skeleton = mapping->skeleton();
-QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings,
- const QVector<ChannelNameAndType> &channelNamesAndTypes,
- const QVector<ComponentIndices> &channelComponentIndices)
-{
- QVector<MappingData> mappingDataVec;
- mappingDataVec.reserve(channelMappings.size());
+ const int propertyCount = jointProperties.size();
+ for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) {
+ // Get the name, type and index
+ ChannelNameAndType nameAndType = jointProperties[propertyIndex];
+ nameAndType.jointIndex = jointIndex;
- // Iterate over the mappings
- for (const auto mapping : channelMappings) {
- // Populate the data we need, easy stuff first
- MappingData mappingData;
- mappingData.targetId = mapping->targetId();
- mappingData.propertyName = mapping->propertyName();
- mappingData.type = mapping->type();
- mappingData.callback = mapping->callback();
- mappingData.callbackFlags = mapping->callbackFlags();
-
- if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
- qWarning() << "Unknown type for node id =" << mappingData.targetId
- << "and property =" << mapping->property()
- << "and callback =" << mapping->callback();
- continue;
+ // Try to find matching channel name and type
+ const int index = channelNamesAndTypes.indexOf(nameAndType);
+
+ // Do we have any animation data for this channel? If not, don't bother
+ // adding a mapping for it.
+ if (channelComponentIndices[index].isEmpty())
+ continue;
+
+ if (index != -1) {
+ // We got one!
+ mappingData.propertyName = channelNameToPropertyName[nameAndType.name];
+ mappingData.type = nameAndType.type;
+ mappingData.channelIndices = channelComponentIndices[index];
+ mappingData.jointIndex = jointIndex;
+
+ // Convert property name for joint transform components to
+ // an enumerated type so we can avoid the string comparisons
+ // when sending the change events after evaluation.
+ if (qstrcmp(mappingData.propertyName, "scale") == 0)
+ mappingData.jointTransformComponent = MappingData::Scale;
+ else if (qstrcmp(mappingData.propertyName, "rotation") == 0)
+ mappingData.jointTransformComponent = MappingData::Rotation;
+ else if (qstrcmp(mappingData.propertyName, "translation") == 0)
+ mappingData.jointTransformComponent = MappingData::Translation;
+
+ mappingDataVec.push_back(mappingData);
+ }
+ }
+ }
+ break;
}
-
- // Try to find matching channel name and type
- const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() };
- const int index = channelNamesAndTypes.indexOf(nameAndType);
- if (index != -1) {
- // We got one!
- mappingData.channelIndices = channelComponentIndices[index];
- mappingDataVec.push_back(mappingData);
}
}
@@ -539,6 +596,10 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
ClipBlendNodeVisitor::VisitOnlyDependencies);
auto func = [&clipIds, nodeManager] (ClipBlendNode *blendNode) {
+ // Check if this is a value node itself
+ if (blendNode->blendType() == ClipBlendNode::ValueType)
+ clipIds.append(blendNode->peerId());
+
const auto dependencyIds = blendNode->currentDependencyIds();
for (const auto dependencyId : dependencyIds) {
// Look up the blend node and if it's a value type (clip),
@@ -558,19 +619,18 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
}
ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- const QVector<ComponentIndices> &targetIndices,
+ QVector<ComponentIndices> &targetIndices,
const AnimationClip *clip)
{
Q_ASSERT(targetChannels.size() == targetIndices.size());
// Reserve enough storage for all the format indices
int indexCount = 0;
- for (const auto targetIndexVec : qAsConst(targetIndices))
+ for (const auto &targetIndexVec : qAsConst(targetIndices))
indexCount += targetIndexVec.size();
ComponentIndices format;
format.resize(indexCount);
-
// Iterate through the target channels
const int channelCount = targetChannels.size();
auto formatIt = format.begin();
@@ -579,23 +639,24 @@ ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &ta
const ChannelNameAndType &targetChannel = targetChannels[i];
const int clipChannelIndex = clip->channelIndex(targetChannel.name,
targetChannel.jointIndex);
-
- // TODO: Ensure channel in the clip has enough components to map to the type.
- // Requires some improvements to the clip data structure first.
- // TODO: I don't think we need the targetIndices, only the number of components
- // for each target channel. Check once blend tree is complete.
const int componentCount = targetIndices[i].size();
if (clipChannelIndex != -1) {
// Found a matching channel in the clip. Get the base channel
// component index and populate the format indices for this channel.
const int baseIndex = clip->channelComponentBaseIndex(clipChannelIndex);
- std::iota(formatIt, formatIt + componentCount, baseIndex);
+
+ // Within this group, match channel names with index ordering
+ const auto channelIndices = channelComponentsToIndices(clip->channels()[clipChannelIndex],
+ targetChannel.type,
+ baseIndex);
+ std::copy(channelIndices.begin(), channelIndices.end(), formatIt);
} else {
// No such channel in this clip. We'll use default values when
// mapping from the clip to the formatted clip results.
std::fill(formatIt, formatIt + componentCount, -1);
+ targetIndices[i].clear();
}
formatIt += componentCount;
diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h
index 7fcd9ead5..4bd3ee64b 100644
--- a/src/animation/backend/animationutils_p.h
+++ b/src/animation/backend/animationutils_p.h
@@ -71,9 +71,19 @@ typedef QVector<int> ComponentIndices;
struct MappingData
{
+ enum JointTransformComponent {
+ NoTransformComponent = 0,
+ Scale,
+ Rotation,
+ Translation
+ };
+
Qt3DCore::QNodeId targetId;
+ Skeleton *skeleton = nullptr;
+ int jointIndex = -1;
+ JointTransformComponent jointTransformComponent = NoTransformComponent;
const char *propertyName;
- QAnimationCallback *callback;
+ QAnimationCallback *callback = nullptr;
QAnimationCallback::Flags callbackFlags;
int type;
ComponentIndices channelIndices;
@@ -190,11 +200,6 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
const QVector<float> &channelResults);
Q_AUTOTEST_EXPORT
-QVector<MappingData> buildPropertyMappings(Handler *handler,
- const AnimationClip *clip,
- const ChannelMapper *mapper);
-
-Q_AUTOTEST_EXPORT
QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping *> &channelMappings,
const QVector<ChannelNameAndType> &channelNamesAndTypes,
const QVector<ComponentIndices> &channelComponentIndices);
@@ -222,7 +227,7 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
Q_AUTOTEST_EXPORT
ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- const QVector<ComponentIndices> &targetIndices,
+ QVector<ComponentIndices> &targetIndices,
const AnimationClip *clip);
Q_AUTOTEST_EXPORT
diff --git a/src/animation/backend/channelmapper.cpp b/src/animation/backend/channelmapper.cpp
index 0e5555096..48a1335fa 100644
--- a/src/animation/backend/channelmapper.cpp
+++ b/src/animation/backend/channelmapper.cpp
@@ -38,6 +38,7 @@
#include <Qt3DAnimation/qchannelmapper.h>
#include <Qt3DAnimation/private/qchannelmapper_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
@@ -50,6 +51,7 @@ namespace Animation {
ChannelMapper::ChannelMapper()
: BackendNode(ReadOnly)
, m_mappingIds()
+ , m_isDirty(true)
{
}
@@ -58,12 +60,15 @@ void ChannelMapper::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QChannelMapperData>>(change);
const auto &data = typedChange->data;
m_mappingIds = data.mappingIds;
+ m_isDirty = true;
}
void ChannelMapper::cleanup()
{
setEnabled(false);
m_mappingIds.clear();
+ m_mappings.clear();
+ m_isDirty = true;
}
void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -74,6 +79,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (change->propertyName() == QByteArrayLiteral("mappings")) {
m_mappingIds.push_back(change->addedNodeId());
setDirty(Handler::ChannelMappingsDirty);
+ m_isDirty = true;
}
break;
}
@@ -83,6 +89,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (change->propertyName() == QByteArrayLiteral("mappings")) {
m_mappingIds.removeOne(change->removedNodeId());
setDirty(Handler::ChannelMappingsDirty);
+ m_isDirty = true;
}
break;
}
@@ -93,6 +100,19 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QBackendNode::sceneChangeEvent(e);
}
+void ChannelMapper::updateMappings() const
+{
+ m_mappings.clear();
+ m_mappings.reserve(m_mappingIds.size());
+ const auto mappingManager = m_handler->channelMappingManager();
+ for (const auto &mappingId : m_mappingIds) {
+ const auto mapping = mappingManager->lookupResource(mappingId);
+ Q_ASSERT(mapping);
+ m_mappings.push_back(mapping);
+ }
+ m_isDirty = false;
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/channelmapper_p.h b/src/animation/backend/channelmapper_p.h
index cb1a13928..fd99c8dbd 100644
--- a/src/animation/backend/channelmapper_p.h
+++ b/src/animation/backend/channelmapper_p.h
@@ -74,10 +74,22 @@ public:
void setMappingIds(const QVector<Qt3DCore::QNodeId> &mappingIds) { m_mappingIds = mappingIds; }
QVector<Qt3DCore::QNodeId> mappingIds() const { return m_mappingIds; }
+ QVector<ChannelMapping*> mappings() const
+ {
+ if (m_isDirty)
+ updateMappings();
+ return m_mappings;
+ }
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
+ void updateMappings() const;
QVector<Qt3DCore::QNodeId> m_mappingIds;
+
+ // Cached data
+ mutable QVector<ChannelMapping*> m_mappings;
+ mutable bool m_isDirty;
};
} // namespace Animation
diff --git a/src/animation/backend/channelmapping.cpp b/src/animation/backend/channelmapping.cpp
index 417c10a1a..4c263edba 100644
--- a/src/animation/backend/channelmapping.cpp
+++ b/src/animation/backend/channelmapping.cpp
@@ -40,6 +40,7 @@
#include <Qt3DAnimation/private/qskeletonmapping_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <Qt3DAnimation/private/qchannelmappingcreatedchange_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -137,6 +138,11 @@ void ChannelMapping::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QBackendNode::sceneChangeEvent(e);
}
+Skeleton *ChannelMapping::skeleton() const
+{
+ return m_handler->skeletonManager()->lookupResource(m_skeletonId);
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/channelmapping_p.h b/src/animation/backend/channelmapping_p.h
index 92c1d1c28..82de5c7b4 100644
--- a/src/animation/backend/channelmapping_p.h
+++ b/src/animation/backend/channelmapping_p.h
@@ -101,6 +101,7 @@ public:
void setSkeletonId(Qt3DCore::QNodeId skeletonId) { m_skeletonId = skeletonId; }
Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; }
+ Skeleton *skeleton() const;
void setMappingType(MappingType mappingType) { m_mappingType = mappingType; }
MappingType mappingType() const { return m_mappingType; }
diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp
index 2f4dca63f..568e2dbb0 100644
--- a/src/animation/backend/clipanimator.cpp
+++ b/src/animation/backend/clipanimator.cpp
@@ -114,6 +114,7 @@ void ClipAnimator::cleanup()
m_clockId = Qt3DCore::QNodeId();
m_running = false;
m_loops = 1;
+ m_formatIndices.clear();
}
void ClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h
index 0f975093c..ca05afdd3 100644
--- a/src/animation/backend/clipanimator_p.h
+++ b/src/animation/backend/clipanimator_p.h
@@ -97,6 +97,9 @@ public:
void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); }
+ void setFormatIndices(const ComponentIndices &formatIndices) { m_formatIndices = formatIndices; }
+ ComponentIndices formatIndices() const { return m_formatIndices; }
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
@@ -111,6 +114,7 @@ private:
QVector<MappingData> m_mappingData;
int m_currentLoop;
+ ComponentIndices m_formatIndices;
};
} // namespace Animation
diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h
index f1bdfed3f..f0ae65589 100644
--- a/src/animation/backend/clipblendvalue_p.h
+++ b/src/animation/backend/clipblendvalue_p.h
@@ -73,7 +73,7 @@ public:
inline QVector<Qt3DCore::QNodeId> currentDependencyIds() const override
{
- return { m_clipId };
+ return {};
}
double duration() const override;
diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp
index 6dab51d63..d9600c375 100644
--- a/src/animation/backend/evaluateclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateclipanimatorjob.cpp
@@ -70,7 +70,11 @@ void EvaluateClipAnimatorJob::run()
// Prepare for evaluation (convert global time to local time ....)
const AnimatorEvaluationData animatorEvaluationData = evaluationDataForAnimator(clipAnimator, clock, globalTime);
const ClipEvaluationData preEvaluationDataForClip = evaluationDataForClip(clip, animatorEvaluationData);
- const ClipResults channelResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime);
+ const ClipResults rawClipResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime);
+
+ // Reformat the clip results into the layout used by this animator/blend tree
+ ComponentIndices format = clipAnimator->formatIndices();
+ ClipResults formattedClipResults = formatClipResults(rawClipResults, format);
if (preEvaluationDataForClip.isFinalFrame)
clipAnimator->setRunning(false);
@@ -80,14 +84,15 @@ void EvaluateClipAnimatorJob::run()
// Prepare property changes (if finalFrame it also prepares the change for the running property for the frontend)
const QVector<Qt3DCore::QSceneChangePtr> changes = preparePropertyChanges(clipAnimator->peerId(),
clipAnimator->mappingData(),
- channelResults,
+ formattedClipResults,
preEvaluationDataForClip.isFinalFrame);
// Send the property changes
clipAnimator->sendPropertyChanges(changes);
// Trigger callbacks either on this thread or by notifying the gui thread.
- const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(), channelResults);
+ const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(),
+ formattedClipResults);
clipAnimator->sendCallbacks(callbacks);
}
diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp
index a8349eb91..16b84359e 100644
--- a/src/animation/backend/findrunningclipanimatorsjob.cpp
+++ b/src/animation/backend/findrunningclipanimatorsjob.cpp
@@ -62,24 +62,39 @@ void FindRunningClipAnimatorsJob::run()
Q_ASSERT(m_handler);
ClipAnimatorManager *clipAnimatorManager = m_handler->clipAnimatorManager();
- for (const auto clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) {
+ for (const auto &clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) {
ClipAnimator *clipAnimator = clipAnimatorManager->data(clipAnimatorHandle);
Q_ASSERT(clipAnimator);
const bool canRun = clipAnimator->canRun();
m_handler->setClipAnimatorRunning(clipAnimatorHandle, canRun);
- // The clip animator needs to know how to map fcurve values through to
- // properties on QNodes. Now we know this animator can run, build the mapping
- // table.
- // TODO: Should be possible to parallelise this with the fcurve evaluation as
- // sending the property change events doesn't happen until after evaluation
- if (canRun) {
- const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId());
- const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId());
- Q_ASSERT(clip && mapper);
- const QVector<MappingData> mappingData = buildPropertyMappings(m_handler, clip, mapper);
- clipAnimator->setMappingData(mappingData);
- }
+ if (!canRun)
+ continue;
+
+ // The clip animator needs to know how to map fcurve values through to properties on QNodes.
+ // Now we know this animator can run, build the mapping table. Even though this could be
+ // done a little simpler in the non-blended case, we follow the same code path as the
+ // blended clip animator for consistency and ease of maintenance.
+ const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId());
+ Q_ASSERT(mapper);
+ const QVector<ChannelMapping *> channelMappings = mapper->mappings();
+
+ const QVector<ChannelNameAndType> channelNamesAndTypes
+ = buildRequiredChannelsAndTypes(m_handler, mapper);
+ QVector<ComponentIndices> channelComponentIndices
+ = assignChannelComponentIndices(channelNamesAndTypes);
+
+ const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId());
+ Q_ASSERT(clip);
+ const ComponentIndices formatIndices = generateClipFormatIndices(channelNamesAndTypes,
+ channelComponentIndices,
+ clip);
+ clipAnimator->setFormatIndices(formatIndices);
+
+ const QVector<MappingData> mappingData = buildPropertyMappings(channelMappings,
+ channelNamesAndTypes,
+ channelComponentIndices);
+ clipAnimator->setMappingData(mappingData);
}
qCDebug(Jobs) << "Running clip animators =" << m_handler->runningClipAnimators();
diff --git a/src/animation/backend/findrunningclipanimatorsjob_p.h b/src/animation/backend/findrunningclipanimatorsjob_p.h
index 6c81ee914..f0e30e80c 100644
--- a/src/animation/backend/findrunningclipanimatorsjob_p.h
+++ b/src/animation/backend/findrunningclipanimatorsjob_p.h
@@ -52,6 +52,10 @@
#include <Qt3DAnimation/private/handle_types_p.h>
#include <QtCore/qvector.h>
+#if defined(QT_BUILD_INTERNAL)
+class tst_FindRunningClipAnimatorsJob;
+#endif
+
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
@@ -59,7 +63,7 @@ namespace Animation {
class Handler;
-class FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob
+class Q_AUTOTEST_EXPORT FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob
{
public:
FindRunningClipAnimatorsJob();
@@ -75,6 +79,10 @@ protected:
private:
QVector<HClipAnimator> m_clipAnimatorHandles;
Handler *m_handler;
+
+#if defined(QT_BUILD_INTERNAL)
+ friend class ::tst_FindRunningClipAnimatorsJob;
+#endif
};
} // namespace Animation
diff --git a/src/animation/backend/skeleton.cpp b/src/animation/backend/skeleton.cpp
index a920e2473..dcfaf55e7 100644
--- a/src/animation/backend/skeleton.cpp
+++ b/src/animation/backend/skeleton.cpp
@@ -96,6 +96,15 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Skeleton::sendLocalPoses()
+{
+ auto e = QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::BackendNodes);
+ e->setPropertyName("localPoses");
+ e->setValue(QVariant::fromValue(m_jointLocalPoses));
+ notifyObservers(e);
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h
index 19da98261..e26e276d9 100644
--- a/src/animation/backend/skeleton_p.h
+++ b/src/animation/backend/skeleton_p.h
@@ -66,6 +66,23 @@ public:
int jointCount() const { return m_jointLocalPoses.size(); }
+ void setJointScale(int jointIndex, const QVector3D &scale)
+ {
+ m_jointLocalPoses[jointIndex].scale = scale;
+ }
+
+ void setJointRotation(int jointIndex, const QQuaternion &rotation)
+ {
+ m_jointLocalPoses[jointIndex].rotation = rotation;
+ }
+
+ void setJointTranslation(int jointIndex, const QVector3D &translation)
+ {
+ m_jointLocalPoses[jointIndex].translation = translation;
+ }
+
+ void sendLocalPoses();
+
#if defined(QT_BUILD_INTERNAL)
void setJointCount(int jointCount)
{
diff --git a/src/animation/frontend/qanimationaspect.cpp b/src/animation/frontend/qanimationaspect.cpp
index 14a0c4f8c..9b23a7b1d 100644
--- a/src/animation/frontend/qanimationaspect.cpp
+++ b/src/animation/frontend/qanimationaspect.cpp
@@ -95,6 +95,7 @@ QAnimationAspect::QAnimationAspect(QAnimationAspectPrivate &dd, QObject *parent)
Q_D(QAnimationAspect);
qRegisterMetaType<Qt3DAnimation::QAnimationClipLoader*>();
qRegisterMetaType<Qt3DAnimation::QChannelMapper*>();
+ qRegisterMetaType<QVector<Qt3DCore::Sqt>>();
registerBackendType<QAbstractAnimationClip>(
QSharedPointer<Animation::NodeFunctor<Animation::AnimationClip, Animation::AnimationClipLoaderManager>>::create(d->m_handler.data(),
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp
index 93cc27f50..785c810d3 100644
--- a/src/animation/frontend/qblendedclipanimator.cpp
+++ b/src/animation/frontend/qblendedclipanimator.cpp
@@ -40,6 +40,7 @@
#include "qblendedclipanimator_p.h"
#include <Qt3DAnimation/qabstractclipblendnode.h>
#include <Qt3DAnimation/qchannelmapper.h>
+#include <Qt3DAnimation/qclock.h>
QT_BEGIN_NAMESPACE
@@ -312,6 +313,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChan
Q_D(const QBlendedClipAnimator);
data.blendTreeRootId = Qt3DCore::qIdForNode(d->m_blendTreeRoot);
data.mapperId = Qt3DCore::qIdForNode(d->m_mapper);
+ data.clockId = Qt3DCore::qIdForNode(d->m_clock);
data.running = d->m_running;
data.loops = d->m_loops;
return creationChange;
diff --git a/src/core/transforms/sqt_p.h b/src/core/transforms/sqt_p.h
index 262e3a645..5fdefccc8 100644
--- a/src/core/transforms/sqt_p.h
+++ b/src/core/transforms/sqt_p.h
@@ -101,6 +101,7 @@ struct JointNamesAndLocalPoses
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QVector<Qt3DCore::Sqt>)
Q_DECLARE_METATYPE(Qt3DCore::JointNamesAndLocalPoses)
#endif // QT3DCORE_SQT_P_H
diff --git a/src/extras/3dtext/qextrudedtextgeometry.cpp b/src/extras/3dtext/qextrudedtextgeometry.cpp
index c4c4ba77f..4a81ae44a 100644
--- a/src/extras/3dtext/qextrudedtextgeometry.cpp
+++ b/src/extras/3dtext/qextrudedtextgeometry.cpp
@@ -166,8 +166,8 @@ void QExtrudedTextGeometryPrivate::init()
m_positionAttribute = new Qt3DRender::QAttribute(q);
m_normalAttribute = new Qt3DRender::QAttribute(q);
m_indexAttribute = new Qt3DRender::QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
const quint32 elementSize = 3 + 3;
const quint32 stride = elementSize * sizeof(float);
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
index d3fd122ae..2575de1a3 100644
--- a/src/extras/defaults/defaults.pri
+++ b/src/extras/defaults/defaults.pri
@@ -25,6 +25,8 @@ HEADERS += \
$$PWD/qphongalphamaterial_p.h \
$$PWD/qt3dwindow.h \
$$PWD/qt3dwindow_p.h \
+ $$PWD/qabstractcameracontroller.h \
+ $$PWD/qabstractcameracontroller_p.h \
$$PWD/qfirstpersoncameracontroller.h \
$$PWD/qfirstpersoncameracontroller_p.h \
$$PWD/qorbitcameracontroller.h \
@@ -58,6 +60,7 @@ SOURCES += \
$$PWD/qgoochmaterial.cpp \
$$PWD/qphongalphamaterial.cpp \
$$PWD/qt3dwindow.cpp \
+ $$PWD/qabstractcameracontroller.cpp \
$$PWD/qfirstpersoncameracontroller.cpp \
$$PWD/qorbitcameracontroller.cpp \
$$PWD/qabstractspritesheet.cpp \
diff --git a/src/extras/defaults/qabstractcameracontroller.cpp b/src/extras/defaults/qabstractcameracontroller.cpp
new file mode 100644
index 000000000..8bf57f5fa
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractcameracontroller.h"
+#include "qabstractcameracontroller_p.h"
+
+#include <Qt3DRender/QCamera>
+#include <Qt3DInput/QAxis>
+#include <Qt3DInput/QAnalogAxisInput>
+#include <Qt3DInput/QButtonAxisInput>
+#include <Qt3DInput/QAction>
+#include <Qt3DInput/QActionInput>
+#include <Qt3DInput/QLogicalDevice>
+#include <Qt3DInput/QKeyboardDevice>
+#include <Qt3DInput/QMouseDevice>
+#include <Qt3DInput/QMouseEvent>
+#include <Qt3DLogic/QFrameAction>
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QAbstractCameraControllerPrivate::QAbstractCameraControllerPrivate()
+ : Qt3DCore::QEntityPrivate()
+ , m_camera(nullptr)
+ , m_leftMouseButtonAction(new Qt3DInput::QAction())
+ , m_middleMouseButtonAction(new Qt3DInput::QAction())
+ , m_rightMouseButtonAction(new Qt3DInput::QAction())
+ , m_altButtonAction(new Qt3DInput::QAction())
+ , m_shiftButtonAction(new Qt3DInput::QAction())
+ , m_rxAxis(new Qt3DInput::QAxis())
+ , m_ryAxis(new Qt3DInput::QAxis())
+ , m_txAxis(new Qt3DInput::QAxis())
+ , m_tyAxis(new Qt3DInput::QAxis())
+ , m_tzAxis(new Qt3DInput::QAxis())
+ , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_middleMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_rightMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_altButtonInput(new Qt3DInput::QActionInput())
+ , m_shiftButtonInput(new Qt3DInput::QActionInput())
+ , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
+ , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
+ , m_mouseDevice(new Qt3DInput::QMouseDevice())
+ , m_logicalDevice(new Qt3DInput::QLogicalDevice())
+ , m_frameAction(new Qt3DLogic::QFrameAction())
+ , m_linearSpeed(10.0f)
+ , m_lookSpeed(180.0f)
+ , m_acceleration(-1.0f)
+ , m_deceleration(-1.0f)
+ , m_sceneUp(0.0f, 1.0f, 0.0f)
+{}
+
+void QAbstractCameraControllerPrivate::init()
+{
+ //// Actions
+
+ // Left Mouse Button Action
+ m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
+ m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
+
+ // Middle Mouse Button Action
+ m_middleMouseButtonInput->setButtons(QVector<int>() << Qt::MiddleButton);
+ m_middleMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_middleMouseButtonAction->addInput(m_middleMouseButtonInput);
+
+ // Right Mouse Button Action
+ m_rightMouseButtonInput->setButtons(QVector<int>() << Qt::RightButton);
+ m_rightMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_rightMouseButtonAction->addInput(m_rightMouseButtonInput);
+
+ // Alt Button Action
+ m_altButtonInput->setButtons(QVector<int>() << Qt::Key_Alt);
+ m_altButtonInput->setSourceDevice(m_keyboardDevice);
+ m_altButtonAction->addInput(m_altButtonInput);
+
+ // Shift Button Action
+ m_shiftButtonInput->setButtons(QVector<int>() << Qt::Key_Shift);
+ m_shiftButtonInput->setSourceDevice(m_keyboardDevice);
+ m_shiftButtonAction->addInput(m_shiftButtonInput);
+
+ //// Axes
+
+ // Mouse X
+ m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
+ m_mouseRxInput->setSourceDevice(m_mouseDevice);
+ m_rxAxis->addInput(m_mouseRxInput);
+
+ // Mouse Y
+ m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
+ m_mouseRyInput->setSourceDevice(m_mouseDevice);
+ m_ryAxis->addInput(m_mouseRyInput);
+
+ // Mouse Wheel X
+ m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
+ m_mouseTzXInput->setSourceDevice(m_mouseDevice);
+ m_tzAxis->addInput(m_mouseTzXInput);
+
+ // Mouse Wheel Y
+ m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
+ m_mouseTzYInput->setSourceDevice(m_mouseDevice);
+ m_tzAxis->addInput(m_mouseTzYInput);
+
+ // Keyboard Pos Tx
+ m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
+ m_keyboardTxPosInput->setScale(1.0f);
+ m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
+ m_txAxis->addInput(m_keyboardTxPosInput);
+
+ // Keyboard Pos Tz
+ m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
+ m_keyboardTzPosInput->setScale(1.0f);
+ m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
+ m_tzAxis->addInput(m_keyboardTzPosInput);
+
+ // Keyboard Pos Ty
+ m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_Up);
+ m_keyboardTyPosInput->setScale(1.0f);
+ m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
+ m_tyAxis->addInput(m_keyboardTyPosInput);
+
+ // Keyboard Neg Tx
+ m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
+ m_keyboardTxNegInput->setScale(-1.0f);
+ m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
+ m_txAxis->addInput(m_keyboardTxNegInput);
+
+ // Keyboard Neg Tz
+ m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
+ m_keyboardTzNegInput->setScale(-1.0f);
+ m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
+ m_tzAxis->addInput(m_keyboardTzNegInput);
+
+ // Keyboard Neg Ty
+ m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_Down);
+ m_keyboardTyNegInput->setScale(-1.0f);
+ m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
+ m_tyAxis->addInput(m_keyboardTyNegInput);
+
+ //// Logical Device
+
+ m_logicalDevice->addAction(m_leftMouseButtonAction);
+ m_logicalDevice->addAction(m_middleMouseButtonAction);
+ m_logicalDevice->addAction(m_rightMouseButtonAction);
+ m_logicalDevice->addAction(m_altButtonAction);
+ m_logicalDevice->addAction(m_shiftButtonAction);
+ m_logicalDevice->addAxis(m_rxAxis);
+ m_logicalDevice->addAxis(m_ryAxis);
+ m_logicalDevice->addAxis(m_txAxis);
+ m_logicalDevice->addAxis(m_tyAxis);
+ m_logicalDevice->addAxis(m_tzAxis);
+
+ applyInputAccelerations();
+
+ Q_Q(QAbstractCameraController);
+ //// FrameAction
+
+ // Disable the logical device when the entity is disabled
+ QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
+ m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
+
+ q->addComponent(m_frameAction);
+ q->addComponent(m_logicalDevice);
+}
+
+void QAbstractCameraControllerPrivate::applyInputAccelerations()
+{
+ const auto inputs = {
+ m_keyboardTxPosInput,
+ m_keyboardTyPosInput,
+ m_keyboardTzPosInput,
+ m_keyboardTxNegInput,
+ m_keyboardTyNegInput,
+ m_keyboardTzNegInput
+ };
+
+ for (auto input : inputs) {
+ input->setAcceleration(m_acceleration);
+ input->setDeceleration(m_deceleration);
+ }
+}
+
+/*!
+ \class QAbstractCameraController
+
+ \brief The QAbstractCameraController class provides basic
+ functionality for camera controllers.
+
+ \inmodule Qt3DExtras
+ \since 5.10
+
+ QAbstractCameraController sets up and handles input from keyboard,
+ mouse, and other devices. QAbstractCameraController is an abstract
+ class and cannot itself be instantiated. It provides a standard
+ interface for camera controllers.
+
+ Derived classes need only implement the frameActionTriggered()
+ method to move the camera.
+*/
+
+/*!
+ \fn void QAbstractCameraController::moveCamera(const InputState &state, float dt) = 0
+
+ This method is called whenever a frame action is triggered. Derived
+ classes must override this method to implement the camera movement
+ specific to the controller.
+
+ In the base class this is a pure virtual function.
+*/
+
+QAbstractCameraController::QAbstractCameraController(Qt3DCore::QNode *parent)
+ : QAbstractCameraController(*new QAbstractCameraControllerPrivate, parent)
+{
+}
+
+/*! \internal
+ */
+QAbstractCameraController::QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
+ : Qt3DCore::QEntity(dd, parent)
+{
+ Q_D(QAbstractCameraController);
+ d->init();
+
+ QObject::connect(d->m_frameAction, &Qt3DLogic::QFrameAction::triggered,
+ this, [=] (float dt) {
+ InputState state;
+
+ state.rxAxisValue = d->m_rxAxis->value();
+ state.ryAxisValue = d->m_ryAxis->value();
+ state.txAxisValue = d->m_txAxis->value();
+ state.tyAxisValue = d->m_tyAxis->value();
+ state.tzAxisValue = d->m_tzAxis->value();
+
+ state.leftMouseButtonActive = d->m_leftMouseButtonAction->isActive();
+ state.middleMouseButtonActive = d->m_middleMouseButtonAction->isActive();
+ state.rightMouseButtonActive = d->m_rightMouseButtonAction->isActive();
+
+ state.altKeyActive = d->m_altButtonAction->isActive();
+ state.shiftKeyActive = d->m_shiftButtonAction->isActive();
+
+ moveCamera(state, dt);
+ });
+}
+
+QAbstractCameraController::~QAbstractCameraController()
+{
+}
+
+/*!
+ \property QAbstractCameraController::camera
+
+ Holds the currently controlled camera.
+*/
+Qt3DRender::QCamera *QAbstractCameraController::camera() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_camera;
+}
+
+/*!
+ \property QAbstractCameraController::linearSpeed
+
+ Holds the current linear speed of the camera controller. Linear speed determines the
+ movement speed of the camera.
+
+ The default is 10.0.
+*/
+float QAbstractCameraController::linearSpeed() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_linearSpeed;
+}
+
+/*!
+ \property QAbstractCameraController::lookSpeed
+
+ Holds the current look speed of the camera controller. The look speed determines the turn rate
+ of the camera pan and tilt.
+
+ The default is 180.0.
+*/
+float QAbstractCameraController::lookSpeed() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_lookSpeed;
+}
+
+/*!
+ \property QAbstractCameraController::acceleration
+
+ Holds the current acceleration of the camera controller.
+*/
+float QAbstractCameraController::acceleration() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_acceleration;
+}
+
+/*!
+ \property QAbstractCameraController::deceleration
+
+ Holds the current deceleration of the camera controller.
+*/
+float QAbstractCameraController::deceleration() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_deceleration;
+}
+
+void QAbstractCameraController::setCamera(Qt3DRender::QCamera *camera)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_camera != camera) {
+
+ if (d->m_camera)
+ d->unregisterDestructionHelper(d->m_camera);
+
+ if (camera && !camera->parent())
+ camera->setParent(this);
+
+ d->m_camera = camera;
+
+ // Ensures proper bookkeeping
+ if (d->m_camera)
+ d->registerDestructionHelper(d->m_camera, &QAbstractCameraController::setCamera, d->m_camera);
+
+ emit cameraChanged();
+ }
+}
+
+void QAbstractCameraController::setLinearSpeed(float linearSpeed)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_linearSpeed != linearSpeed) {
+ d->m_linearSpeed = linearSpeed;
+ emit linearSpeedChanged();
+ }
+}
+
+void QAbstractCameraController::setLookSpeed(float lookSpeed)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_lookSpeed != lookSpeed) {
+ d->m_lookSpeed = lookSpeed;
+ emit lookSpeedChanged();
+ }
+}
+
+void QAbstractCameraController::setAcceleration(float acceleration)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_acceleration != acceleration) {
+ d->m_acceleration = acceleration;
+ d->applyInputAccelerations();
+ emit accelerationChanged(acceleration);
+ }
+}
+
+void QAbstractCameraController::setDeceleration(float deceleration)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_deceleration != deceleration) {
+ d->m_deceleration = deceleration;
+ d->applyInputAccelerations();
+ emit decelerationChanged(deceleration);
+ }
+}
+
+/*!
+ Provides access to the keyboard device.
+*/
+
+Qt3DInput::QKeyboardDevice *QAbstractCameraController::keyboardDevice() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_keyboardDevice;
+}
+
+/*!
+ Provides access to the mouse device.
+*/
+
+Qt3DInput::QMouseDevice *QAbstractCameraController::mouseDevice() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_mouseDevice;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#include "moc_qabstractcameracontroller.cpp"
diff --git a/src/extras/defaults/qabstractcameracontroller.h b/src/extras/defaults/qabstractcameracontroller.h
new file mode 100644
index 000000000..f13079f5f
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
+#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
+
+#include <Qt3DCore/QEntity>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DInput {
+class QKeyboardDevice;
+class QMouseDevice;
+}
+
+namespace Qt3DRender {
+class QCamera;
+}
+
+namespace Qt3DExtras {
+
+class QAbstractCameraControllerPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QAbstractCameraController : public Qt3DCore::QEntity
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
+ Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
+ Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
+ Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
+ Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged)
+
+public:
+ ~QAbstractCameraController();
+
+ Qt3DRender::QCamera *camera() const;
+ float linearSpeed() const;
+ float lookSpeed() const;
+
+ float acceleration() const;
+ float deceleration() const;
+
+ void setCamera(Qt3DRender::QCamera *camera);
+ void setLinearSpeed(float linearSpeed);
+ void setLookSpeed(float lookSpeed);
+
+ void setAcceleration(float acceleration);
+ void setDeceleration(float deceleration);
+
+Q_SIGNALS:
+ void cameraChanged();
+ void linearSpeedChanged();
+ void lookSpeedChanged();
+
+ void accelerationChanged(float acceleration);
+ void decelerationChanged(float deceleration);
+
+protected:
+ explicit QAbstractCameraController(Qt3DCore::QNode *parent = nullptr);
+ QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+ Qt3DInput::QKeyboardDevice *keyboardDevice() const;
+ Qt3DInput::QMouseDevice *mouseDevice() const;
+
+ struct InputState
+ {
+ float rxAxisValue;
+ float ryAxisValue;
+ float txAxisValue;
+ float tyAxisValue;
+ float tzAxisValue;
+
+ bool leftMouseButtonActive;
+ bool middleMouseButtonActive;
+ bool rightMouseButtonActive;
+
+ bool altKeyActive;
+ bool shiftKeyActive;
+ };
+
+private:
+ virtual void moveCamera(const InputState &state, float dt) = 0;
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractCameraController)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
diff --git a/src/extras/defaults/qabstractcameracontroller_p.h b/src/extras/defaults/qabstractcameracontroller_p.h
new file mode 100644
index 000000000..00424a55b
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
+#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DExtras/qabstractcameracontroller.h>
+#include <QtGui/QVector3D>
+
+#include <Qt3DCore/private/qentity_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+class QCamera;
+}
+
+namespace Qt3DLogic {
+class QFrameAction;
+}
+
+namespace Qt3DInput {
+class QKeyboardDevice;
+class QMouseDevice;
+class QLogicalDevice;
+class QAction;
+class QActionInput;
+class QAxis;
+class QAnalogAxisInput;
+class QButtonAxisInput;
+class QAxisActionHandler;
+}
+
+namespace Qt3DExtras {
+
+class QAbstractCameraControllerPrivate : public Qt3DCore::QEntityPrivate
+{
+public:
+ QAbstractCameraControllerPrivate();
+
+ void init();
+ void applyInputAccelerations();
+
+ Qt3DRender::QCamera *m_camera;
+
+ Qt3DInput::QAction *m_leftMouseButtonAction;
+ Qt3DInput::QAction *m_middleMouseButtonAction;
+ Qt3DInput::QAction *m_rightMouseButtonAction;
+ Qt3DInput::QAction *m_altButtonAction;
+ Qt3DInput::QAction *m_shiftButtonAction;
+
+ Qt3DInput::QAxis *m_rxAxis;
+ Qt3DInput::QAxis *m_ryAxis;
+ Qt3DInput::QAxis *m_txAxis;
+ Qt3DInput::QAxis *m_tyAxis;
+ Qt3DInput::QAxis *m_tzAxis;
+
+ Qt3DInput::QActionInput *m_leftMouseButtonInput;
+ Qt3DInput::QActionInput *m_middleMouseButtonInput;
+ Qt3DInput::QActionInput *m_rightMouseButtonInput;
+ Qt3DInput::QActionInput *m_altButtonInput;
+ Qt3DInput::QActionInput *m_shiftButtonInput;
+
+ Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
+
+ Qt3DInput::QKeyboardDevice *m_keyboardDevice;
+ Qt3DInput::QMouseDevice *m_mouseDevice;
+
+ Qt3DInput::QLogicalDevice *m_logicalDevice;
+
+ Qt3DLogic::QFrameAction *m_frameAction;
+
+ float m_linearSpeed;
+ float m_lookSpeed;
+
+ float m_acceleration;
+ float m_deceleration;
+
+ QVector3D m_sceneUp;
+
+ Q_DECLARE_PUBLIC(QAbstractCameraController)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
diff --git a/src/extras/defaults/qdiffusemapmaterial.cpp b/src/extras/defaults/qdiffusemapmaterial.cpp
index a6da98a2e..930fbbd1f 100644
--- a/src/extras/defaults/qdiffusemapmaterial.cpp
+++ b/src/extras/defaults/qdiffusemapmaterial.cpp
@@ -98,9 +98,9 @@ void QDiffuseMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_diffuseMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_diffuseMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.frag"))));
- m_diffuseMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_diffuseMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.frag"))));
m_diffuseMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.cpp b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
index 615ee6305..2e98bc8e7 100644
--- a/src/extras/defaults/qdiffusespecularmapmaterial.cpp
+++ b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
@@ -105,9 +105,9 @@ void QDiffuseSpecularMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
- m_diffuseSpecularMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseSpecularMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_diffuseSpecularMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusespecularmap.frag"))));
- m_diffuseSpecularMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseSpecularMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_diffuseSpecularMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusespecularmap.frag"))));
m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp
index 5321bfcf2..2ad997d05 100644
--- a/src/extras/defaults/qfirstpersoncameracontroller.cpp
+++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp
@@ -35,188 +35,13 @@
****************************************************************************/
#include "qfirstpersoncameracontroller.h"
-#include "qfirstpersoncameracontroller_p.h"
-#include <Qt3DInput/QAction>
-#include <Qt3DInput/QActionInput>
-#include <Qt3DInput/QAnalogAxisInput>
-#include <Qt3DInput/QAxis>
-#include <Qt3DInput/QButtonAxisInput>
-#include <Qt3DLogic/QFrameAction>
-#include <Qt3DInput/QKeyboardDevice>
-#include <Qt3DInput/QLogicalDevice>
-#include <Qt3DInput/QMouseDevice>
-#include <Qt3DInput/QMouseEvent>
#include <Qt3DRender/QCamera>
QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
-QFirstPersonCameraControllerPrivate::QFirstPersonCameraControllerPrivate()
- : Qt3DCore::QEntityPrivate()
- , m_camera(nullptr)
- , m_leftMouseButtonAction(new Qt3DInput::QAction())
- , m_fineMotionAction(new Qt3DInput::QAction())
- , m_rxAxis(new Qt3DInput::QAxis())
- , m_ryAxis(new Qt3DInput::QAxis())
- , m_txAxis(new Qt3DInput::QAxis())
- , m_tyAxis(new Qt3DInput::QAxis())
- , m_tzAxis(new Qt3DInput::QAxis())
- , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
- , m_fineMotionKeyInput(new Qt3DInput::QActionInput())
- , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
- , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
- , m_mouseDevice(new Qt3DInput::QMouseDevice())
- , m_logicalDevice(new Qt3DInput::QLogicalDevice())
- , m_frameAction(new Qt3DLogic::QFrameAction())
- , m_linearSpeed(10.0f)
- , m_lookSpeed(180.0f)
- , m_acceleration(-1.0f)
- , m_deceleration(-1.0f)
- , m_firstPersonUp(QVector3D(0.0f, 1.0f, 0.0f))
-{}
-
-void QFirstPersonCameraControllerPrivate::init()
-{
- //// Actions
-
- // Left Mouse Button Action
- m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
- m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
-
- // Fine Motion Action
- m_fineMotionKeyInput->setButtons(QVector<int>() << Qt::Key_Shift);
- m_fineMotionKeyInput->setSourceDevice(m_keyboardDevice);
- m_fineMotionAction->addInput(m_fineMotionKeyInput);
-
- //// Axes
-
- // Mouse X
- m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
- m_mouseRxInput->setSourceDevice(m_mouseDevice);
- m_rxAxis->addInput(m_mouseRxInput);
-
- // Mouse Y
- m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
- m_mouseRyInput->setSourceDevice(m_mouseDevice);
- m_ryAxis->addInput(m_mouseRyInput);
-
- // Mouse Wheel X
- m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
- m_mouseTzXInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzXInput);
-
- // Mouse Wheel Y
- m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
- m_mouseTzYInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzYInput);
-
- // Keyboard Pos Tx
- m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
- m_keyboardTxPosInput->setScale(1.0f);
- m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxPosInput);
-
- // Keyboard Pos Ty
- m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
- m_keyboardTyPosInput->setScale(1.0f);
- m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyPosInput);
-
- // Keyboard Pos Tz
- m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_Up);
- m_keyboardTzPosInput->setScale(1.0f);
- m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzPosInput);
-
- // Keyboard Neg Tx
- m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
- m_keyboardTxNegInput->setScale(-1.0f);
- m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxNegInput);
-
- // Keyboard Neg Ty
- m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
- m_keyboardTyNegInput->setScale(-1.0f);
- m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyNegInput);
-
- // Keyboard Neg Tz
- m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_Down);
- m_keyboardTzNegInput->setScale(-1.0f);
- m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzNegInput);
-
- //// Logical Device
-
- m_logicalDevice->addAction(m_fineMotionAction);
- m_logicalDevice->addAction(m_leftMouseButtonAction);
- m_logicalDevice->addAxis(m_rxAxis);
- m_logicalDevice->addAxis(m_ryAxis);
- m_logicalDevice->addAxis(m_txAxis);
- m_logicalDevice->addAxis(m_tyAxis);
- m_logicalDevice->addAxis(m_tzAxis);
-
- applyAccelerations();
-
- Q_Q(QFirstPersonCameraController);
- //// FrameAction
-
- QObject::connect(m_frameAction, SIGNAL(triggered(float)),
- q, SLOT(_q_onTriggered(float)));
-
- // Disable the logical device when the entity is disabled
- QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
- m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
-
- q->addComponent(m_frameAction);
- q->addComponent(m_logicalDevice);
-}
-
-void QFirstPersonCameraControllerPrivate::applyAccelerations()
-{
- const auto inputs = {
- m_keyboardTxPosInput,
- m_keyboardTyPosInput,
- m_keyboardTzPosInput,
- m_keyboardTxNegInput,
- m_keyboardTyNegInput,
- m_keyboardTzNegInput
- };
-
- for (auto input : inputs) {
- input->setAcceleration(m_acceleration);
- input->setDeceleration(m_deceleration);
- }
-}
-
-void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt)
-{
- if (m_camera != nullptr) {
- m_camera->translate(QVector3D(m_txAxis->value() * m_linearSpeed,
- m_tyAxis->value() * m_linearSpeed,
- m_tzAxis->value() * m_linearSpeed) * dt);
- if (m_leftMouseButtonAction->isActive()) {
- float lookSpeed = m_lookSpeed;
- if (m_fineMotionAction->isActive())
- lookSpeed *= 0.2f;
- m_camera->pan(m_rxAxis->value() * lookSpeed * dt, m_firstPersonUp);
- m_camera->tilt(m_ryAxis->value() * lookSpeed * dt);
- }
- }
-}
-
/*!
\class Qt3DExtras::QFirstPersonCameraController
\brief The QFirstPersonCameraController class allows controlling the scene camera
@@ -251,129 +76,35 @@ void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt)
*/
QFirstPersonCameraController::QFirstPersonCameraController(Qt3DCore::QNode *parent)
- : Qt3DCore::QEntity(*new QFirstPersonCameraControllerPrivate, parent)
+ : QAbstractCameraController(parent)
{
- Q_D(QFirstPersonCameraController);
- d->init();
}
QFirstPersonCameraController::~QFirstPersonCameraController()
{
}
-/*!
- \property QFirstPersonCameraController::camera
-
- Holds the currently controlled camera.
-*/
-Qt3DRender::QCamera *QFirstPersonCameraController::camera() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_camera;
-}
-
-/*!
- \property QFirstPersonCameraController::linearSpeed
- Holds the current linear speed of the camera controller. Linear speed determines the
- movement speed of the camera.
-*/
-float QFirstPersonCameraController::linearSpeed() const
+void QFirstPersonCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
{
- Q_D(const QFirstPersonCameraController);
- return d->m_linearSpeed;
-}
-
-/*!
- \property QFirstPersonCameraController::lookSpeed
-
- Holds the current look speed of the camera controller. The look speed determines the turn rate
- of the camera pan and tilt.
-*/
-float QFirstPersonCameraController::lookSpeed() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_lookSpeed;
-}
-
-/*!
- \property QFirstPersonCameraController::acceleration
-
- Holds the current acceleration of the camera controller.
-*/
-float QFirstPersonCameraController::acceleration() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_acceleration;
-}
-
-/*!
- \property QFirstPersonCameraController::deceleration
-
- Holds the current deceleration of the camera controller.
-*/
-float QFirstPersonCameraController::deceleration() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_deceleration;
-}
-
-void QFirstPersonCameraController::setCamera(Qt3DRender::QCamera *camera)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_camera != camera) {
-
- if (d->m_camera)
- d->unregisterDestructionHelper(d->m_camera);
-
- if (camera && !camera->parent())
- camera->setParent(this);
-
- d->m_camera = camera;
-
- // Ensures proper bookkeeping
- if (d->m_camera)
- d->registerDestructionHelper(d->m_camera, &QFirstPersonCameraController::setCamera, d->m_camera);
-
- emit cameraChanged();
- }
-}
-
-void QFirstPersonCameraController::setLinearSpeed(float linearSpeed)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_linearSpeed != linearSpeed) {
- d->m_linearSpeed = linearSpeed;
- emit linearSpeedChanged();
- }
-}
-
-void QFirstPersonCameraController::setLookSpeed(float lookSpeed)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_lookSpeed != lookSpeed) {
- d->m_lookSpeed = lookSpeed;
- emit lookSpeedChanged();
- }
-}
+ Qt3DRender::QCamera *theCamera = camera();
+
+ if (theCamera == nullptr)
+ return;
+
+ theCamera->translate(QVector3D(state.txAxisValue * linearSpeed(),
+ state.tyAxisValue * linearSpeed(),
+ state.tzAxisValue * linearSpeed()) * dt);
+ if (state.leftMouseButtonActive) {
+ float theLookSpeed = lookSpeed();
+ if (state.shiftKeyActive) {
+ theLookSpeed *= 0.2f;
+ }
-void QFirstPersonCameraController::setAcceleration(float acceleration)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_acceleration != acceleration) {
- d->m_acceleration = acceleration;
- d->applyAccelerations();
- emit accelerationChanged(acceleration);
- }
-}
+ const QVector3D upVector(0.0f, 1.0f, 0.0f);
-void QFirstPersonCameraController::setDeceleration(float deceleration)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_deceleration != deceleration) {
- d->m_deceleration = deceleration;
- d->applyAccelerations();
- emit decelerationChanged(deceleration);
+ theCamera->pan(state.rxAxisValue * theLookSpeed * dt, upVector);
+ theCamera->tilt(state.ryAxisValue * theLookSpeed * dt);
}
}
diff --git a/src/extras/defaults/qfirstpersoncameracontroller.h b/src/extras/defaults/qfirstpersoncameracontroller.h
index 3f7a6acc4..60edf7cb8 100644
--- a/src/extras/defaults/qfirstpersoncameracontroller.h
+++ b/src/extras/defaults/qfirstpersoncameracontroller.h
@@ -37,53 +37,22 @@
#ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H
#define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H
-#include <Qt3DExtras/qt3dextras_global.h>
-#include <Qt3DCore/QEntity>
+#include <Qt3DExtras/qabstractcameracontroller.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
namespace Qt3DExtras {
-class QFirstPersonCameraControllerPrivate;
-
-class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public Qt3DCore::QEntity
+class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public QAbstractCameraController
{
Q_OBJECT
- Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
- Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
- Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
- Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
- Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged)
+
public:
explicit QFirstPersonCameraController(Qt3DCore::QNode *parent = nullptr);
~QFirstPersonCameraController();
- Qt3DRender::QCamera *camera() const;
- float linearSpeed() const;
- float lookSpeed() const;
- float acceleration() const;
- float deceleration() const;
-
- void setCamera(Qt3DRender::QCamera *camera);
- void setLinearSpeed(float linearSpeed);
- void setLookSpeed(float lookSpeed);
- void setAcceleration(float acceleration);
- void setDeceleration(float deceleration);
-
-Q_SIGNALS:
- void cameraChanged();
- void linearSpeedChanged();
- void lookSpeedChanged();
- void accelerationChanged(float acceleration);
- void decelerationChanged(float deceleration);
-
private:
- Q_DECLARE_PRIVATE(QFirstPersonCameraController)
- Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float))
+ void moveCamera(const QAbstractCameraController::InputState &state, float dt) override;
};
} // Qt3DExtras
diff --git a/src/extras/defaults/qfirstpersoncameracontroller_p.h b/src/extras/defaults/qfirstpersoncameracontroller_p.h
deleted file mode 100644
index 48a7c7998..000000000
--- a/src/extras/defaults/qfirstpersoncameracontroller_p.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H
-#define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H
-
-#include <Qt3DExtras/qfirstpersoncameracontroller.h>
-#include <QtGui/QVector3D>
-
-#include <Qt3DCore/private/qentity_p.h>
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-class QCamera;
-}
-
-namespace Qt3DLogic {
-class QFrameAction;
-}
-
-namespace Qt3DInput {
-
-class QKeyboardDevice;
-class QMouseDevice;
-class QLogicalDevice;
-class QAction;
-class QActionInput;
-class QAxis;
-class QAnalogAxisInput;
-class QButtonAxisInput;
-class QAxisActionHandler;
-
-}
-
-namespace Qt3DExtras {
-
-class QFirstPersonCameraControllerPrivate : public Qt3DCore::QEntityPrivate
-{
-public:
- QFirstPersonCameraControllerPrivate();
-
- void init();
- void applyAccelerations();
-
- Qt3DRender::QCamera *m_camera;
-
- Qt3DInput::QAction *m_leftMouseButtonAction;
- Qt3DInput::QAction *m_fineMotionAction;
-
- Qt3DInput::QAxis *m_rxAxis;
- Qt3DInput::QAxis *m_ryAxis;
- Qt3DInput::QAxis *m_txAxis;
- Qt3DInput::QAxis *m_tyAxis;
- Qt3DInput::QAxis *m_tzAxis;
-
- Qt3DInput::QActionInput *m_leftMouseButtonInput;
- Qt3DInput::QActionInput *m_fineMotionKeyInput;
-
- Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
- Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
-
- Qt3DInput::QKeyboardDevice *m_keyboardDevice;
- Qt3DInput::QMouseDevice *m_mouseDevice;
-
- Qt3DInput::QLogicalDevice *m_logicalDevice;
-
- Qt3DLogic::QFrameAction *m_frameAction;
-
- float m_linearSpeed;
- float m_lookSpeed;
- float m_acceleration;
- float m_deceleration;
- QVector3D m_firstPersonUp;
-
- void _q_onTriggered(float);
-
- Q_DECLARE_PUBLIC(QFirstPersonCameraController)
-};
-
-} // Qt3DInput
-
-QT_END_NAMESPACE
-
-#endif // QT3DINPUT_QFIRSTPERSONCAMERACONTROLLER_P_H
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp
index c3d59d9de..ac6117101 100644
--- a/src/extras/defaults/qmetalroughmaterial.cpp
+++ b/src/extras/defaults/qmetalroughmaterial.cpp
@@ -71,6 +71,7 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
, m_roughnessMapParameter(new QParameter(QStringLiteral("roughnessMap"), QVariant()))
, m_ambientOcclusionMapParameter(new QParameter(QStringLiteral("ambientOcclusionMap"), QVariant()))
, m_normalMapParameter(new QParameter(QStringLiteral("normalMap"), QVariant()))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
, m_environmentIrradianceParameter(new QParameter(QStringLiteral("envLight.irradiance"), m_environmentIrradianceTexture))
, m_environmentSpecularParameter(new QParameter(QStringLiteral("envLight.specular"), m_environmentSpecularTexture))
, m_metalRoughEffect(new QEffect())
@@ -107,8 +108,10 @@ void QMetalRoughMaterialPrivate::init()
q, &QMetalRoughMaterial::roughnessChanged);
QObject::connect(m_normalMapParameter, &Qt3DRender::QParameter::valueChanged,
q, &QMetalRoughMaterial::roughnessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleTextureScaleChanged);
- m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert"))));
+ m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_metalRoughGL3ShaderBuilder->setParent(q);
m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader);
@@ -136,6 +139,7 @@ void QMetalRoughMaterialPrivate::init()
m_metalRoughEffect->addParameter(m_baseColorParameter);
m_metalRoughEffect->addParameter(m_metalnessParameter);
m_metalRoughEffect->addParameter(m_roughnessParameter);
+ m_metalRoughEffect->addParameter(m_textureScaleParameter);
// Note that even though those parameters are not exposed in the API,
// they need to be kept around for now due to a bug in some drivers/GPUs
@@ -149,6 +153,12 @@ void QMetalRoughMaterialPrivate::init()
q->setEffect(m_metalRoughEffect);
}
+void QMetalRoughMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
/*!
\class Qt3DExtras::QMetalRoughMaterial
\brief The QMetalRoughMaterial provides a default implementation of PBR
@@ -249,6 +259,18 @@ QVariant QMetalRoughMaterial::normal() const
return d->m_normalMapParameter->value();
}
+/*!
+ \property QMetalRoughMaterial::textureScale
+
+ Holds the current texture scale. It is applied as a multiplier to texture
+ coordinates at render time. Defaults to 1.0.
+*/
+float QMetalRoughMaterial::textureScale() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
void QMetalRoughMaterial::setBaseColor(const QVariant &baseColor)
{
Q_D(QMetalRoughMaterial);
@@ -348,6 +370,12 @@ void QMetalRoughMaterial::setNormal(const QVariant &normal)
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
}
+void QMetalRoughMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
} // namespace Qt3DExtras
QT_END_NAMESPACE
diff --git a/src/extras/defaults/qmetalroughmaterial.h b/src/extras/defaults/qmetalroughmaterial.h
index 6da00ec08..400437338 100644
--- a/src/extras/defaults/qmetalroughmaterial.h
+++ b/src/extras/defaults/qmetalroughmaterial.h
@@ -62,6 +62,7 @@ class QT3DEXTRASSHARED_EXPORT QMetalRoughMaterial : public Qt3DRender::QMaterial
Q_PROPERTY(QVariant roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged)
Q_PROPERTY(QVariant ambientOcclusion READ ambientOcclusion WRITE setAmbientOcclusion NOTIFY ambientOcclusionChanged REVISION 10)
Q_PROPERTY(QVariant normal READ normal WRITE setNormal NOTIFY normalChanged REVISION 10)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged REVISION 10)
public:
explicit QMetalRoughMaterial(Qt3DCore::QNode *parent = nullptr);
@@ -72,6 +73,7 @@ public:
QVariant roughness() const;
QVariant ambientOcclusion() const;
QVariant normal() const;
+ float textureScale() const;
public Q_SLOTS:
void setBaseColor(const QVariant &baseColor);
@@ -79,6 +81,7 @@ public Q_SLOTS:
void setRoughness(const QVariant &roughness);
void setAmbientOcclusion(const QVariant &ambientOcclusion);
void setNormal(const QVariant &normal);
+ void setTextureScale(float textureScale);
Q_SIGNALS:
void baseColorChanged(const QVariant &baseColor);
@@ -86,6 +89,7 @@ Q_SIGNALS:
void roughnessChanged(const QVariant &roughness);
void ambientOcclusionChanged(const QVariant &ambientOcclusion);
void normalChanged(const QVariant &normal);
+ void textureScaleChanged(float textureScale);
protected:
explicit QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h
index 8d6cbfcad..838474490 100644
--- a/src/extras/defaults/qmetalroughmaterial_p.h
+++ b/src/extras/defaults/qmetalroughmaterial_p.h
@@ -79,6 +79,8 @@ public:
void init();
+ void handleTextureScaleChanged(const QVariant &var);
+
Qt3DRender::QAbstractTexture *m_environmentIrradianceTexture;
Qt3DRender::QAbstractTexture *m_environmentSpecularTexture;
Qt3DRender::QParameter *m_baseColorParameter;
@@ -89,6 +91,7 @@ public:
Qt3DRender::QParameter *m_roughnessMapParameter;
Qt3DRender::QParameter *m_ambientOcclusionMapParameter;
Qt3DRender::QParameter *m_normalMapParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
Qt3DRender::QParameter *m_environmentIrradianceParameter;
Qt3DRender::QParameter *m_environmentSpecularParameter;
Qt3DRender::QEffect *m_metalRoughEffect;
diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
index eb6398341..dd8288683 100644
--- a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
@@ -82,10 +82,10 @@ void QNormalDiffuseMapAlphaMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
- m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemapalpha.frag"))));
- m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
- m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemapalpha.frag"))));
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
+ m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.frag"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
+ m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.frag"))));
m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_normalDiffuseGL3Technique->graphicsApiFilter()->setMajorVersion(3);
diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.cpp b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
index 35cea095a..ec3bd0a22 100644
--- a/src/extras/defaults/qnormaldiffusemapmaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
@@ -107,9 +107,9 @@ void QNormalDiffuseMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.frag"))));
- m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.frag"))));
m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
index c6f8ced9c..eaa1491a0 100644
--- a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
@@ -115,9 +115,9 @@ void QNormalDiffuseSpecularMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_normalDiffuseSpecularGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusespecularmap.frag"))));
- m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_normalDiffuseSpecularGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusespecularmap.frag"))));
m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp
index 565a75ea1..03e9a290b 100644
--- a/src/extras/defaults/qorbitcameracontroller.cpp
+++ b/src/extras/defaults/qorbitcameracontroller.cpp
@@ -38,22 +38,15 @@
#include "qorbitcameracontroller_p.h"
#include <Qt3DRender/QCamera>
-#include <Qt3DInput/QAxis>
-#include <Qt3DInput/QAnalogAxisInput>
-#include <Qt3DInput/QButtonAxisInput>
-#include <Qt3DInput/QAction>
-#include <Qt3DInput/QActionInput>
-#include <Qt3DInput/QLogicalDevice>
-#include <Qt3DInput/QKeyboardDevice>
-#include <Qt3DInput/QMouseDevice>
-#include <Qt3DInput/QMouseEvent>
-#include <Qt3DLogic/QFrameAction>
-#include <QtCore/QtGlobal>
QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
+QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
+ : m_zoomInLimit(2.0f)
+{}
+
/*!
\class Qt3DExtras::QOrbitCameraController
\brief The QOrbitCameraController class allows controlling the scene camera along orbital path.
@@ -99,251 +92,20 @@ namespace Qt3DExtras {
\endtable
*/
-QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
- : Qt3DCore::QEntityPrivate()
- , m_camera(nullptr)
- , m_leftMouseButtonAction(new Qt3DInput::QAction())
- , m_rightMouseButtonAction(new Qt3DInput::QAction())
- , m_altButtonAction(new Qt3DInput::QAction())
- , m_shiftButtonAction(new Qt3DInput::QAction())
- , m_rxAxis(new Qt3DInput::QAxis())
- , m_ryAxis(new Qt3DInput::QAxis())
- , m_txAxis(new Qt3DInput::QAxis())
- , m_tyAxis(new Qt3DInput::QAxis())
- , m_tzAxis(new Qt3DInput::QAxis())
- , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
- , m_rightMouseButtonInput(new Qt3DInput::QActionInput())
- , m_altButtonInput(new Qt3DInput::QActionInput())
- , m_shiftButtonInput(new Qt3DInput::QActionInput())
- , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
- , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
- , m_mouseDevice(new Qt3DInput::QMouseDevice())
- , m_logicalDevice(new Qt3DInput::QLogicalDevice())
- , m_frameAction(new Qt3DLogic::QFrameAction())
- , m_linearSpeed(10.0f)
- , m_lookSpeed(180.0f)
- , m_zoomInLimit(2.0f)
- , m_cameraUp(QVector3D(0.0f, 1.0f, 0.0f))
-{}
-
-void QOrbitCameraControllerPrivate::init()
-{
- //// Actions
-
- // Left Mouse Button Action
- m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
- m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
-
- // Right Mouse Button Action
- m_rightMouseButtonInput->setButtons(QVector<int>() << Qt::RightButton);
- m_rightMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_rightMouseButtonAction->addInput(m_rightMouseButtonInput);
-
- // Alt Button Action
- m_altButtonInput->setButtons(QVector<int>() << Qt::Key_Alt);
- m_altButtonInput->setSourceDevice(m_keyboardDevice);
- m_altButtonAction->addInput(m_altButtonInput);
-
- // Shift Button Action
- m_shiftButtonInput->setButtons(QVector<int>() << Qt::Key_Shift);
- m_shiftButtonInput->setSourceDevice(m_keyboardDevice);
- m_shiftButtonAction->addInput(m_shiftButtonInput);
-
- //// Axes
-
- // Mouse X
- m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
- m_mouseRxInput->setSourceDevice(m_mouseDevice);
- m_rxAxis->addInput(m_mouseRxInput);
-
- // Mouse Y
- m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
- m_mouseRyInput->setSourceDevice(m_mouseDevice);
- m_ryAxis->addInput(m_mouseRyInput);
-
- // Mouse Wheel X
- m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
- m_mouseTzXInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzXInput);
-
- // Mouse Wheel Y
- m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
- m_mouseTzYInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzYInput);
-
- // Keyboard Pos Tx
- m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
- m_keyboardTxPosInput->setScale(1.0f);
- m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxPosInput);
-
- // Keyboard Pos Tz
- m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
- m_keyboardTzPosInput->setScale(1.0f);
- m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzPosInput);
-
- // Keyboard Pos Ty
- m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_Up);
- m_keyboardTyPosInput->setScale(1.0f);
- m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyPosInput);
-
- // Keyboard Neg Tx
- m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
- m_keyboardTxNegInput->setScale(-1.0f);
- m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxNegInput);
-
- // Keyboard Neg Tz
- m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
- m_keyboardTzNegInput->setScale(-1.0f);
- m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzNegInput);
-
- // Keyboard Neg Ty
- m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_Down);
- m_keyboardTyNegInput->setScale(-1.0f);
- m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyNegInput);
-
- //// Logical Device
-
- m_logicalDevice->addAction(m_leftMouseButtonAction);
- m_logicalDevice->addAction(m_rightMouseButtonAction);
- m_logicalDevice->addAction(m_altButtonAction);
- m_logicalDevice->addAction(m_shiftButtonAction);
- m_logicalDevice->addAxis(m_rxAxis);
- m_logicalDevice->addAxis(m_ryAxis);
- m_logicalDevice->addAxis(m_txAxis);
- m_logicalDevice->addAxis(m_tyAxis);
- m_logicalDevice->addAxis(m_tzAxis);
-
- Q_Q(QOrbitCameraController);
- //// FrameAction
-
- QObject::connect(m_frameAction, SIGNAL(triggered(float)),
- q, SLOT(_q_onTriggered(float)));
-
- // Disable the logical device when the entity is disabled
- QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
- m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
-
- q->addComponent(m_frameAction);
- q->addComponent(m_logicalDevice);
-}
-
-float clampInputs(float input1, float input2)
-{
- float axisValue = input1 + input2;
- return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
-}
-
-float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
-{
- return (secondPoint - firstPoint).lengthSquared();
-}
-
-void QOrbitCameraControllerPrivate::_q_onTriggered(float dt)
-{
- if (m_camera != nullptr) {
- // Mouse input
- if (m_leftMouseButtonAction->isActive()) {
- if (m_rightMouseButtonAction->isActive()) {
- if ( zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) {
- // Dolly up to limit
- m_camera->translate(QVector3D(0, 0, m_ryAxis->value()), m_camera->DontTranslateViewCenter);
- } else {
- m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter);
- }
- } else {
- // Translate
- m_camera->translate(QVector3D(clampInputs(m_rxAxis->value(), m_txAxis->value()) * m_linearSpeed,
- clampInputs(m_ryAxis->value(), m_tyAxis->value()) * m_linearSpeed,
- 0) * dt);
- }
- return;
- }
- else if (m_rightMouseButtonAction->isActive()) {
- // Orbit
- m_camera->panAboutViewCenter((m_rxAxis->value() * m_lookSpeed) * dt, m_cameraUp);
- m_camera->tiltAboutViewCenter((m_ryAxis->value() * m_lookSpeed) * dt);
- }
- // Keyboard Input
- if (m_altButtonAction->isActive()) {
- // Orbit
- m_camera->panAboutViewCenter((m_txAxis->value() * m_lookSpeed) * dt, m_cameraUp);
- m_camera->tiltAboutViewCenter((m_tyAxis->value() * m_lookSpeed) * dt);
- } else if (m_shiftButtonAction->isActive()) {
- if (zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) {
- // Dolly
- m_camera->translate(QVector3D(0, 0, m_tyAxis->value()), m_camera->DontTranslateViewCenter);
- } else {
- m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter);
- }
- } else {
- // Translate
- m_camera->translate(QVector3D(clampInputs(m_leftMouseButtonAction->isActive() ? m_rxAxis->value() : 0, m_txAxis->value()) * m_linearSpeed,
- clampInputs(m_leftMouseButtonAction->isActive() ? m_ryAxis->value() : 0, m_tyAxis->value()) * m_linearSpeed,
- m_tzAxis->value() * m_linearSpeed) * dt);
- }
- }
-}
-
QOrbitCameraController::QOrbitCameraController(Qt3DCore::QNode *parent)
- : Qt3DCore::QEntity(*new QOrbitCameraControllerPrivate, parent)
+ : QOrbitCameraController(*new QOrbitCameraControllerPrivate, parent)
{
- Q_D(QOrbitCameraController);
- d->init();
}
-QOrbitCameraController::~QOrbitCameraController()
+/*! \internal
+ */
+QOrbitCameraController::QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
+ : QAbstractCameraController(dd, parent)
{
}
-/*!
- \property QOrbitCameraController::camera
-
- Holds the currently controlled camera.
-*/
-Qt3DRender::QCamera *QOrbitCameraController::camera() const
-{
- Q_D(const QOrbitCameraController);
- return d->m_camera;
-}
-
-/*!
- \property QOrbitCameraController::linearSpeed
-
- Holds the current linear speed of the camera controller. Linear speed determines the
- movement speed of the camera.
-*/
-float QOrbitCameraController::linearSpeed() const
-{
- Q_D(const QOrbitCameraController);
- return d->m_linearSpeed;
-}
-
-/*!
- \property QOrbitCameraController::lookSpeed
-
- Holds the current look speed of the camera controller. The look speed determines the turn rate
- of the camera pan and tilt.
-*/
-float QOrbitCameraController::lookSpeed() const
+QOrbitCameraController::~QOrbitCameraController()
{
- Q_D(const QOrbitCameraController);
- return d->m_lookSpeed;
}
/*!
@@ -358,51 +120,77 @@ float QOrbitCameraController::zoomInLimit() const
return d->m_zoomInLimit;
}
-void QOrbitCameraController::setCamera(Qt3DRender::QCamera *camera)
+void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
{
Q_D(QOrbitCameraController);
- if (d->m_camera != camera) {
-
- if (d->m_camera)
- d->unregisterDestructionHelper(d->m_camera);
-
- if (camera && !camera->parent())
- camera->setParent(this);
-
- d->m_camera = camera;
-
- // Ensures proper bookkeeping
- if (d->m_camera)
- d->registerDestructionHelper(d->m_camera, &QOrbitCameraController::setCamera, d->m_camera);
-
- emit cameraChanged();
+ if (d->m_zoomInLimit != zoomInLimit) {
+ d->m_zoomInLimit = zoomInLimit;
+ emit zoomInLimitChanged();
}
}
-void QOrbitCameraController::setLinearSpeed(float linearSpeed)
+inline float clampInputs(float input1, float input2)
{
- Q_D(QOrbitCameraController);
- if (d->m_linearSpeed != linearSpeed) {
- d->m_linearSpeed = linearSpeed;
- emit linearSpeedChanged();
- }
+ float axisValue = input1 + input2;
+ return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
}
-void QOrbitCameraController::setLookSpeed(float lookSpeed)
+inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
{
- Q_D(QOrbitCameraController);
- if (d->m_lookSpeed != lookSpeed) {
- d->m_lookSpeed = lookSpeed;
- emit lookSpeedChanged();
- }
+ return (secondPoint - firstPoint).lengthSquared();
}
-void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
+void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
{
Q_D(QOrbitCameraController);
- if (d->m_zoomInLimit != zoomInLimit) {
- d->m_zoomInLimit = zoomInLimit;
- emit zoomInLimitChanged();
+
+ Qt3DRender::QCamera *theCamera = camera();
+
+ if (theCamera == nullptr)
+ return;
+
+ const QVector3D upVector(0.0f, 1.0f, 0.0f);
+
+ // Mouse input
+ if (state.leftMouseButtonActive) {
+ if (state.rightMouseButtonActive) {
+ if ( zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
+ // Dolly up to limit
+ theCamera->translate(QVector3D(0, 0, state.ryAxisValue), theCamera->DontTranslateViewCenter);
+ } else {
+ theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter);
+ }
+ } else {
+ // Translate
+ theCamera->translate(QVector3D(clampInputs(state.rxAxisValue, state.txAxisValue) * linearSpeed(),
+ clampInputs(state.ryAxisValue, state.tyAxisValue) * linearSpeed(),
+ 0) * dt);
+ }
+ return;
+ }
+ else if (state.rightMouseButtonActive) {
+ // Orbit
+ theCamera->panAboutViewCenter((state.rxAxisValue * lookSpeed()) * dt, upVector);
+ theCamera->tiltAboutViewCenter((state.ryAxisValue * lookSpeed()) * dt);
+ }
+
+ // Keyboard Input
+ if (state.altKeyActive) {
+ // Orbit
+ theCamera->panAboutViewCenter((state.txAxisValue * lookSpeed()) * dt, upVector);
+ theCamera->tiltAboutViewCenter((state.tyAxisValue * lookSpeed()) * dt);
+ } else if (state.shiftKeyActive) {
+ if (zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
+ // Dolly
+ theCamera->translate(QVector3D(0, 0, state.tyAxisValue), theCamera->DontTranslateViewCenter);
+ } else {
+ theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter);
+ }
+ } else {
+ // Translate
+ theCamera->translate(QVector3D(clampInputs(state.leftMouseButtonActive ? state.rxAxisValue : 0, state.txAxisValue) * linearSpeed(),
+ clampInputs(state.leftMouseButtonActive ? state.ryAxisValue : 0, state.tyAxisValue) * linearSpeed(),
+ state.tzAxisValue * linearSpeed()) * dt);
}
}
diff --git a/src/extras/defaults/qorbitcameracontroller.h b/src/extras/defaults/qorbitcameracontroller.h
index 7cb8b3eb7..684bfddf1 100644
--- a/src/extras/defaults/qorbitcameracontroller.h
+++ b/src/extras/defaults/qorbitcameracontroller.h
@@ -37,50 +37,38 @@
#ifndef QT3DEXTRAS_QORBITCAMERACONTROLLER_H
#define QT3DEXTRAS_QORBITCAMERACONTROLLER_H
-#include <Qt3DCore/QEntity>
-#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DExtras/qabstractcameracontroller.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
namespace Qt3DExtras {
class QOrbitCameraControllerPrivate;
-class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public Qt3DCore::QEntity
+class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public QAbstractCameraController
{
Q_OBJECT
- Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
- Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
- Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
Q_PROPERTY(float zoomInLimit READ zoomInLimit WRITE setZoomInLimit NOTIFY zoomInLimitChanged)
public:
explicit QOrbitCameraController(Qt3DCore::QNode *parent = nullptr);
~QOrbitCameraController();
- Qt3DRender::QCamera *camera() const;
- float linearSpeed() const;
- float lookSpeed() const;
float zoomInLimit() const;
- void setCamera(Qt3DRender::QCamera *camera);
- void setLinearSpeed(float linearSpeed);
- void setLookSpeed(float lookSpeed);
void setZoomInLimit(float zoomInLimit);
Q_SIGNALS:
- void cameraChanged();
- void linearSpeedChanged();
- void lookSpeedChanged();
void zoomInLimitChanged();
+protected:
+ QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ void moveCamera(const QAbstractCameraController::InputState &state, float dt) override;
+
private:
Q_DECLARE_PRIVATE(QOrbitCameraController)
- Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float))
};
} // Qt3DExtras
diff --git a/src/extras/defaults/qorbitcameracontroller_p.h b/src/extras/defaults/qorbitcameracontroller_p.h
index 8105d4375..1e4e3d4d2 100644
--- a/src/extras/defaults/qorbitcameracontroller_p.h
+++ b/src/extras/defaults/qorbitcameracontroller_p.h
@@ -48,88 +48,25 @@
// We mean it.
//
-#include <Qt3DExtras/qorbitcameracontroller.h>
-#include <QtGui/QVector3D>
-
-#include <Qt3DCore/private/qentity_p.h>
+#include <Qt3DExtras/private/qabstractcameracontroller_p.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
-namespace Qt3DLogic {
-class QFrameAction;
-}
-
-namespace Qt3DInput {
-
-class QKeyboardDevice;
-class QMouseDevice;
-class QLogicalDevice;
-class QAction;
-class QActionInput;
-class QAxis;
-class QAnalogAxisInput;
-class QButtonAxisInput;
-class QAxisActionHandler;
-
-}
-
namespace Qt3DExtras {
-class QOrbitCameraControllerPrivate : public Qt3DCore::QEntityPrivate
+class QOrbitCameraControllerPrivate : public QAbstractCameraControllerPrivate
{
+ Q_DECLARE_PUBLIC(QOrbitCameraController)
+
public:
QOrbitCameraControllerPrivate();
void init();
- Qt3DRender::QCamera *m_camera;
-
- Qt3DInput::QAction *m_leftMouseButtonAction;
- Qt3DInput::QAction *m_rightMouseButtonAction;
- Qt3DInput::QAction *m_altButtonAction;
- Qt3DInput::QAction *m_shiftButtonAction;
-
- Qt3DInput::QAxis *m_rxAxis;
- Qt3DInput::QAxis *m_ryAxis;
- Qt3DInput::QAxis *m_txAxis;
- Qt3DInput::QAxis *m_tyAxis;
- Qt3DInput::QAxis *m_tzAxis;
-
- Qt3DInput::QActionInput *m_leftMouseButtonInput;
- Qt3DInput::QActionInput *m_rightMouseButtonInput;
- Qt3DInput::QActionInput *m_altButtonInput;
- Qt3DInput::QActionInput *m_shiftButtonInput;
-
- Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
- Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
-
- Qt3DInput::QKeyboardDevice *m_keyboardDevice;
- Qt3DInput::QMouseDevice *m_mouseDevice;
-
- Qt3DInput::QLogicalDevice *m_logicalDevice;
-
- Qt3DLogic::QFrameAction *m_frameAction;
-
- float m_linearSpeed;
- float m_lookSpeed;
float m_zoomInLimit;
- QVector3D m_cameraUp;
- void _q_onTriggered(float);
-
- Q_DECLARE_PUBLIC(QOrbitCameraController)
+private:
+ QOrbitCameraController *q_ptr;
};
} // namespace Qt3DExtras
diff --git a/src/extras/defaults/qphongalphamaterial.cpp b/src/extras/defaults/qphongalphamaterial.cpp
index d7f054d71..fd8c52525 100644
--- a/src/extras/defaults/qphongalphamaterial.cpp
+++ b/src/extras/defaults/qphongalphamaterial.cpp
@@ -65,10 +65,9 @@ QPhongAlphaMaterialPrivate::QPhongAlphaMaterialPrivate()
: QMaterialPrivate()
, m_phongEffect(new QEffect())
, m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
- , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 0.5f)))
, m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
, m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
- , m_alphaParameter(new QParameter(QStringLiteral("alpha"), 0.5f))
, m_phongAlphaGL3Technique(new QTechnique())
, m_phongAlphaGL2Technique(new QTechnique())
, m_phongAlphaES2Technique(new QTechnique())
@@ -95,13 +94,11 @@ void QPhongAlphaMaterialPrivate::init()
this, &QPhongAlphaMaterialPrivate::handleSpecularChanged);
connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
this, &QPhongAlphaMaterialPrivate::handleShininessChanged);
- connect(m_alphaParameter, &Qt3DRender::QParameter::valueChanged,
- this, &QPhongAlphaMaterialPrivate::handleAlphaChanged);
- m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
- m_phongAlphaGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phongalpha.frag"))));
- m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
- m_phongAlphaGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phongalpha.frag"))));
+ m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
+ m_phongAlphaGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
+ m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
+ m_phongAlphaGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
m_phongAlphaGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_phongAlphaGL3Technique->graphicsApiFilter()->setMajorVersion(3);
@@ -159,7 +156,6 @@ void QPhongAlphaMaterialPrivate::init()
m_phongEffect->addParameter(m_diffuseParameter);
m_phongEffect->addParameter(m_specularParameter);
m_phongEffect->addParameter(m_shininessParameter);
- m_phongEffect->addParameter(m_alphaParameter);
q->setEffect(m_phongEffect);
}
@@ -174,6 +170,7 @@ void QPhongAlphaMaterialPrivate::handleDiffuseChanged(const QVariant &var)
{
Q_Q(QPhongAlphaMaterial);
emit q->diffuseChanged(var.value<QColor>());
+ emit q->alphaChanged(var.value<QColor>().alphaF());
}
void QPhongAlphaMaterialPrivate::handleSpecularChanged(const QVariant &var)
@@ -188,12 +185,6 @@ void QPhongAlphaMaterialPrivate::handleShininessChanged(const QVariant &var)
emit q->shininessChanged(var.toFloat());
}
-void QPhongAlphaMaterialPrivate::handleAlphaChanged(const QVariant &var)
-{
- Q_Q(QPhongAlphaMaterial);
- emit q->alphaChanged(var.toFloat());
-}
-
/*!
\class Qt3DExtras::QPhongAlphaMaterial
@@ -301,7 +292,7 @@ float QPhongAlphaMaterial::shininess() const
float QPhongAlphaMaterial::alpha() const
{
Q_D(const QPhongAlphaMaterial);
- return d->m_alphaParameter->value().toFloat();
+ return d->m_diffuseParameter->value().value<QColor>().alphaF();
}
/*!
@@ -378,7 +369,10 @@ void QPhongAlphaMaterial::setAmbient(const QColor &ambient)
void QPhongAlphaMaterial::setDiffuse(const QColor &diffuse)
{
Q_D(QPhongAlphaMaterial);
- d->m_diffuseParameter->setValue(diffuse);
+ QColor currentDiffuse = d->m_diffuseParameter->value().value<QColor>();
+ QColor newDiffuse = diffuse;
+ newDiffuse.setAlphaF(currentDiffuse.alphaF());
+ d->m_diffuseParameter->setValue(newDiffuse);
}
void QPhongAlphaMaterial::setSpecular(const QColor &specular)
@@ -396,7 +390,9 @@ void QPhongAlphaMaterial::setShininess(float shininess)
void QPhongAlphaMaterial::setAlpha(float alpha)
{
Q_D(QPhongAlphaMaterial);
- d->m_alphaParameter->setValue(alpha);
+ QColor diffuse = d->m_diffuseParameter->value().value<QColor>();
+ diffuse.setAlphaF(alpha);
+ d->m_diffuseParameter->setValue(diffuse);
}
void QPhongAlphaMaterial::setSourceRgbArg(QBlendEquationArguments::Blending sourceRgbArg)
diff --git a/src/extras/defaults/qphongalphamaterial_p.h b/src/extras/defaults/qphongalphamaterial_p.h
index 623eca0ea..84e2eead3 100644
--- a/src/extras/defaults/qphongalphamaterial_p.h
+++ b/src/extras/defaults/qphongalphamaterial_p.h
@@ -84,14 +84,12 @@ public:
void handleDiffuseChanged(const QVariant &var);
void handleSpecularChanged(const QVariant &var);
void handleShininessChanged(const QVariant &var);
- void handleAlphaChanged(const QVariant &var);
Qt3DRender::QEffect *m_phongEffect;
Qt3DRender::QParameter *m_ambientParameter;
Qt3DRender::QParameter *m_diffuseParameter;
Qt3DRender::QParameter *m_specularParameter;
Qt3DRender::QParameter *m_shininessParameter;
- Qt3DRender::QParameter *m_alphaParameter;
Qt3DRender::QTechnique *m_phongAlphaGL3Technique;
Qt3DRender::QTechnique *m_phongAlphaGL2Technique;
Qt3DRender::QTechnique *m_phongAlphaES2Technique;
diff --git a/src/extras/defaults/qphongmaterial.cpp b/src/extras/defaults/qphongmaterial.cpp
index 449eb7351..25dbf3c85 100644
--- a/src/extras/defaults/qphongmaterial.cpp
+++ b/src/extras/defaults/qphongmaterial.cpp
@@ -89,10 +89,9 @@ void QPhongMaterialPrivate::init()
connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
this, &QPhongMaterialPrivate::handleShininessChanged);
-
- m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
+ m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
- m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
+ m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index ce959af93..f3619fdb7 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -4,26 +4,24 @@
<file>shaders/gl3/light.inc.frag</file>
<file>shaders/es2/light.inc.frag</file>
<file>shaders/es2/light.inc.frag100</file>
+ <file>shaders/gl3/phong.inc.frag</file>
+ <file>shaders/es2/phong.inc.frag</file>
+ <file>shaders/es2/phong.inc.frag100</file>
<file>shaders/gl3/metalrough.inc.frag</file>
<file>shaders/gl3/coordinatesystems.inc</file>
- <file>shaders/gl3/phong.vert</file>
+ <file>shaders/es2/coordinatesystems.inc</file>
<file>shaders/gl3/phong.frag</file>
- <file>shaders/es2/phong.vert</file>
<file>shaders/es2/phong.frag</file>
<file>shaders/gl3/normaldiffusespecularmap.frag</file>
- <file>shaders/gl3/diffusemap.vert</file>
<file>shaders/gl3/diffusemap.frag</file>
<file>shaders/es2/normaldiffusespecularmap.frag</file>
- <file>shaders/es2/diffusemap.vert</file>
<file>shaders/es2/diffusemap.frag</file>
- <file>shaders/es2/normaldiffusemap.vert</file>
<file>shaders/es2/normaldiffusemap.frag</file>
- <file>shaders/es2/normaldiffusemapalpha.frag</file>
<file>shaders/gl3/normaldiffusemap.frag</file>
- <file>shaders/gl3/normaldiffusemap.vert</file>
- <file>shaders/gl3/normaldiffusemapalpha.frag</file>
<file>shaders/es2/diffusespecularmap.frag</file>
<file>shaders/gl3/diffusespecularmap.frag</file>
+ <file>shaders/gl3/default.vert</file>
+ <file>shaders/es2/default.vert</file>
<file>shaders/gl3/pervertexcolor.frag</file>
<file>shaders/gl3/pervertexcolor.vert</file>
<file>shaders/es2/pervertexcolor.frag</file>
@@ -36,13 +34,10 @@
<file>shaders/gl3/gooch.frag</file>
<file>shaders/es2/gooch.frag</file>
<file>shaders/es2/gooch.vert</file>
- <file>shaders/gl3/phongalpha.frag</file>
- <file>shaders/es2/phongalpha.frag</file>
<file>shaders/gl3/unlittexture.vert</file>
<file>shaders/gl3/unlittexture.frag</file>
<file>shaders/es2/unlittexture.frag</file>
<file>shaders/es2/unlittexture.vert</file>
- <file>shaders/gl3/metalrough.vert</file>
<file>shaders/gl3/distancefieldtext.vert</file>
<file>shaders/gl3/distancefieldtext.frag</file>
<file>shaders/es2/distancefieldtext.frag</file>
diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp
index d1a6917f5..a80e2a78a 100644
--- a/src/extras/geometries/qconegeometry.cpp
+++ b/src/extras/geometries/qconegeometry.cpp
@@ -368,8 +368,8 @@ void QConeGeometryPrivate::init()
m_normalAttribute = new QAttribute(q);
m_texCoordAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal
const quint32 elementSize = 3 + 2 + 3;
diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp
index a8899989c..9e6747c1e 100644
--- a/src/extras/geometries/qcuboidgeometry.cpp
+++ b/src/extras/geometries/qcuboidgeometry.cpp
@@ -497,8 +497,8 @@ void QCuboidGeometryPrivate::init()
m_texCoordAttribute = new Qt3DRender::QAttribute(q);
m_tangentAttribute = new Qt3DRender::QAttribute(q);
m_indexAttribute = new Qt3DRender::QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos vec2 tex vec3 normal vec4 tangent
const quint32 stride = (3 + 2 + 3 + 4) * sizeof(float);
diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp
index a6eb01d41..c86b76d24 100644
--- a/src/extras/geometries/qcylindergeometry.cpp
+++ b/src/extras/geometries/qcylindergeometry.cpp
@@ -299,8 +299,8 @@ void QCylinderGeometryPrivate::init()
m_normalAttribute = new QAttribute(q);
m_texCoordAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal
const quint32 elementSize = 3 + 2 + 3;
diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp
index c6318e199..225726342 100644
--- a/src/extras/geometries/qplanegeometry.cpp
+++ b/src/extras/geometries/qplanegeometry.cpp
@@ -509,8 +509,8 @@ void QPlaneGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
const int nVerts = m_meshResolution.width() * m_meshResolution.height();
const int stride = (3 + 2 + 3 + 4) * sizeof(float);
diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp
index 92844335c..1a3b50553 100644
--- a/src/extras/geometries/qspheregeometry.cpp
+++ b/src/extras/geometries/qspheregeometry.cpp
@@ -254,8 +254,8 @@ void QSphereGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal, vec4 tangent
const quint32 elementSize = 3 + 2 + 3 + 4;
diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp
index ef14ee50d..726b81c62 100644
--- a/src/extras/geometries/qtorusgeometry.cpp
+++ b/src/extras/geometries/qtorusgeometry.cpp
@@ -243,8 +243,8 @@ void QTorusGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal, vec4 tangent
const quint32 elementSize = 3 + 2 + 3 + 4;
const quint32 stride = elementSize * sizeof(float);
diff --git a/src/extras/shaders/es2/coordinatesystems.inc b/src/extras/shaders/es2/coordinatesystems.inc
new file mode 100644
index 000000000..5f6ee40f5
--- /dev/null
+++ b/src/extras/shaders/es2/coordinatesystems.inc
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define FP highp
+
+FP mat3 transpose(const in FP mat3 inputMatrix)
+{
+ FP vec3 i0 = inputMatrix[0];
+ FP vec3 i1 = inputMatrix[1];
+ FP vec3 i2 = inputMatrix[2];
+
+ FP mat3 outputMatrix = mat3(
+ vec3(i0.x, i1.x, i2.x),
+ vec3(i0.y, i1.y, i2.y),
+ vec3(i0.z, i1.z, i2.z)
+ );
+
+ return outputMatrix;
+}
+
+FP mat3 calcWorldSpaceToTangentSpaceMatrix(const in FP vec3 wNormal, const in FP vec4 wTangent)
+{
+ // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
+ // This allows to build the tangentMatrix below by simply transposing the
+ // tangent -> eyespace matrix (which would now be orthogonal)
+ FP vec3 wFixedTangent = normalize(wTangent.xyz - dot(wTangent.xyz, wNormal) * wNormal);
+
+ // Calculate binormal vector. No "real" need to renormalize it,
+ // as built by crossing two normal vectors.
+ // To orient the binormal correctly, use the fourth coordinate of the tangent,
+ // which is +1 for a right hand system, and -1 for a left hand system.
+ FP vec3 wBinormal = cross(wNormal, wFixedTangent.xyz) * wTangent.w;
+
+ // Construct matrix to transform from world space to tangent space
+ // This is the transpose of the tangentToWorld transformation matrix
+ FP mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal);
+ FP mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix);
+ return worldToTangentMatrix;
+}
+
diff --git a/src/extras/shaders/es2/default.vert b/src/extras/shaders/es2/default.vert
new file mode 100644
index 000000000..810f658bc
--- /dev/null
+++ b/src/extras/shaders/es2/default.vert
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec4 vertexTangent;
+attribute vec2 vertexTexCoord;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+varying vec4 worldTangent;
+varying vec2 texCoord;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+
+uniform float texCoordScale;
+
+void main()
+{
+ // Pass through texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
+
+ // Transform position, normal, and tangent to world coords
+ worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
+
+ // Calculate vertex position in clip coordinates
+ gl_Position = modelViewProjection * vec4(vertexPosition, 1.0);
+}
diff --git a/src/extras/shaders/es2/diffusemap.frag b/src/extras/shaders/es2/diffusemap.frag
index 7d06d8e2c..6ac9bd5a3 100644
--- a/src/extras/shaders/es2/diffusemap.frag
+++ b/src/extras/shaders/es2/diffusemap.frag
@@ -1,7 +1,7 @@
#define FP highp
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -12,14 +12,11 @@ varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
varying FP vec2 texCoord;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
-
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/diffusemap.vert b/src/extras/shaders/es2/diffusemap.vert
deleted file mode 100644
index 13798279e..000000000
--- a/src/extras/shaders/es2/diffusemap.vert
+++ /dev/null
@@ -1,22 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-attribute vec2 vertexTexCoord;
-
-varying vec3 worldPosition;
-varying vec3 worldNormal;
-varying vec2 texCoord;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- texCoord = vertexTexCoord * texCoordScale;
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/diffusespecularmap.frag b/src/extras/shaders/es2/diffusespecularmap.frag
index 4d776772c..99183aaf4 100644
--- a/src/extras/shaders/es2/diffusespecularmap.frag
+++ b/src/extras/shaders/es2/diffusespecularmap.frag
@@ -1,7 +1,7 @@
#define FP highp
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -13,15 +13,12 @@ varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
varying FP vec2 texCoord;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
- FP vec3 specularTextureColor = texture2D( specularTexture, texCoord ).rgb;
-
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag
index 57a30036f..167ff306e 100644
--- a/src/extras/shaders/es2/light.inc.frag
+++ b/src/extras/shaders/es2/light.inc.frag
@@ -1,3 +1,5 @@
+#define FP highp
+
const int MAX_LIGHTS = 8;
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
@@ -13,186 +15,3 @@ struct Light {
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) );
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s, ts;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if ( dot(snormal, s) < 0.0 )
- att = 0.0;
- else {
- ts = normalize( tangentMatrix * s );
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- }
- } else {
- if ( dot(snormal, -light.direction) > 0.0 )
- s = normalize( tangentMatrix * -light.direction );
- else
- att = 0.0;
- }
-
- FP float diffuse = max( dot( ts, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -ts, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
- }
-}
-
-void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -light.direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
- }
-}
-
-void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -light.direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- }
-}
diff --git a/src/extras/shaders/es2/light.inc.frag100 b/src/extras/shaders/es2/light.inc.frag100
index b4988ad82..8680ee423 100644
--- a/src/extras/shaders/es2/light.inc.frag100
+++ b/src/extras/shaders/es2/light.inc.frag100
@@ -1,3 +1,5 @@
+#define FP highp
+
const int MAX_LIGHTS = 2; // RPi: cannot use more than two as we run out of uniforms
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
@@ -13,206 +15,3 @@ struct Light {
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[0].position - vpos );
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += att * specular;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[1].position - vpos );
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
- specularColor += att * specular;
-}
-
-void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += att * specular;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = lights[1].position - vpos;
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
- specularColor += att * specular;
-}
-
-void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = lights[1].position - vpos;
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
-}
diff --git a/src/extras/shaders/es2/normaldiffusemap.frag b/src/extras/shaders/es2/normaldiffusemap.frag
index c69aa8b81..0bf4c5630 100644
--- a/src/extras/shaders/es2/normaldiffusemap.frag
+++ b/src/extras/shaders/es2/normaldiffusemap.frag
@@ -1,31 +1,34 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/es2/normaldiffusemap.vert b/src/extras/shaders/es2/normaldiffusemap.vert
deleted file mode 100644
index ecc689f69..000000000
--- a/src/extras/shaders/es2/normaldiffusemap.vert
+++ /dev/null
@@ -1,38 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-attribute vec2 vertexTexCoord;
-attribute vec4 vertexTangent;
-
-varying vec3 worldPosition;
-varying vec2 texCoord;
-varying mat3 tangentMatrix;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 projectionMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- // Pass through texture coordinates
- texCoord = vertexTexCoord * texCoordScale;
-
- // Transform position, normal, and tangent to world coords
- vec3 normal = normalize( modelNormalMatrix * vertexNormal );
- vec3 tangent = normalize( modelNormalMatrix * vertexTangent.xyz );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- // Calculate binormal vector
- vec3 binormal = normalize( cross( normal, tangent ) );
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3 (
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z );
-
- // Calculate vertex position in clip coordinates
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/normaldiffusemapalpha.frag b/src/extras/shaders/es2/normaldiffusemapalpha.frag
deleted file mode 100644
index 98acbf01d..000000000
--- a/src/extras/shaders/es2/normaldiffusemapalpha.frag
+++ /dev/null
@@ -1,32 +0,0 @@
-#define FP highp
-
-varying FP vec3 worldPosition;
-varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
-
-uniform sampler2D diffuseTexture;
-uniform sampler2D normalTexture;
-
-// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
-uniform FP float shininess; // Specular shininess factor
-
-uniform FP vec3 eyePosition;
-
-#pragma include light.inc.frag
-
-void main()
-{
- // Sample the textures at the interpolated texCoords
- FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
-
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
-
- // Combine spec with ambient+diffuse for final fragment color
- // Use the alpha from the diffuse texture (for alpha to coverage)
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
-}
diff --git a/src/extras/shaders/es2/normaldiffusespecularmap.frag b/src/extras/shaders/es2/normaldiffusespecularmap.frag
index b30c1bd5f..0541c8902 100644
--- a/src/extras/shaders/es2/normaldiffusespecularmap.frag
+++ b/src/extras/shaders/es2/normaldiffusespecularmap.frag
@@ -1,32 +1,35 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + specularTextureColor.rgb * specularColor, 1.0 );
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/es2/pervertexcolor.frag b/src/extras/shaders/es2/pervertexcolor.frag
index ab429d942..a2f0e8bf2 100644
--- a/src/extras/shaders/es2/pervertexcolor.frag
+++ b/src/extras/shaders/es2/pervertexcolor.frag
@@ -2,13 +2,14 @@
varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
-varying FP vec3 color;
+varying FP vec4 color;
-#pragma include light.inc.frag
+uniform FP vec3 eyePosition;
+
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseColor;
- adModel(worldPosition, worldNormal, diffuseColor);
- gl_FragColor = vec4( color + color * diffuseColor, 1.0 );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(color, color, vec4(0.0), 0.0, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/pervertexcolor.vert b/src/extras/shaders/es2/pervertexcolor.vert
index 7fc3e649f..bfa2e615a 100644
--- a/src/extras/shaders/es2/pervertexcolor.vert
+++ b/src/extras/shaders/es2/pervertexcolor.vert
@@ -1,10 +1,10 @@
attribute vec3 vertexPosition;
attribute vec3 vertexNormal;
-attribute vec3 vertexColor;
+attribute vec4 vertexColor;
varying vec3 worldPosition;
varying vec3 worldNormal;
-varying vec3 color;
+varying vec4 color;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
diff --git a/src/extras/shaders/es2/phong.frag b/src/extras/shaders/es2/phong.frag
index c00f89db0..6b8ab7111 100644
--- a/src/extras/shaders/es2/phong.frag
+++ b/src/extras/shaders/es2/phong.frag
@@ -1,8 +1,8 @@
#define FP highp
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 kd; // Diffuse reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 kd; // Diffuse reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -10,11 +10,10 @@ uniform FP vec3 eyePosition;
varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, kd, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/phong.inc.frag b/src/extras/shaders/es2/phong.inc.frag
new file mode 100644
index 000000000..9d17b68b5
--- /dev/null
+++ b/src/extras/shaders/es2/phong.inc.frag
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 vview, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ FP vec3 s;
+ Light light;
+ for (int i = 0; i < lightCount; ++i) {
+ if (i == 0)
+ light = lights[0];
+ else if (i == 1)
+ light = lights[1];
+ else if (i == 2)
+ light = lights[2];
+ else if (i == 3)
+ light = lights[3];
+ else if (i == 4)
+ light = lights[4];
+ else if (i == 5)
+ light = lights[5];
+ else if (i == 6)
+ light = lights[6];
+ else if (i == 7)
+ light = lights[7];
+
+ FP float att = 1.0;
+ if ( light.type != TYPE_DIRECTIONAL ) {
+ s = light.position - vpos;
+ if (length( light.attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( light.type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -light.direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * light.intensity * diffuse * light.color;
+ specularColor += att * light.intensity * specular * light.color;
+ }
+}
+
+FP vec4 phongFunction(const in FP vec4 ambient,
+ const in FP vec4 diffuse,
+ const in FP vec4 specular,
+ const in FP float shininess,
+ const in FP vec3 worldPosition,
+ const in FP vec3 worldView,
+ const in FP vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ FP vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/es2/phong.inc.frag100 b/src/extras/shaders/es2/phong.inc.frag100
new file mode 100644
index 000000000..507d8eaf5
--- /dev/null
+++ b/src/extras/shaders/es2/phong.inc.frag100
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 vview, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[0].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[0].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += att * specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[1].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[1].direction );
+ }
+
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += att * specular;
+}
+
+FP vec4 phongFunction(const in FP vec4 ambient,
+ const in FP vec4 diffuse,
+ const in FP vec4 specular,
+ const in FP float shininess,
+ const in FP vec3 worldPosition,
+ const in FP vec3 worldView,
+ const in FP vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ FP vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/es2/phong.vert b/src/extras/shaders/es2/phong.vert
deleted file mode 100644
index 2b4c51b14..000000000
--- a/src/extras/shaders/es2/phong.vert
+++ /dev/null
@@ -1,17 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-
-varying vec3 worldPosition;
-varying vec3 worldNormal;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 modelViewProjection;
-
-void main()
-{
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/phongalpha.frag b/src/extras/shaders/es2/phongalpha.frag
deleted file mode 100644
index c5ec43049..000000000
--- a/src/extras/shaders/es2/phongalpha.frag
+++ /dev/null
@@ -1,22 +0,0 @@
-#define FP highp
-
-// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 kd; // Diffuse reflectivity
-uniform FP vec3 ks; // Specular reflectivity
-uniform FP float shininess; // Specular shininess factor
-uniform FP float alpha;
-
-uniform FP vec3 eyePosition;
-
-varying FP vec3 worldPosition;
-varying FP vec3 worldNormal;
-
-#pragma include light.inc.frag
-
-void main()
-{
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
-}
diff --git a/src/extras/shaders/gl3/metalrough.vert b/src/extras/shaders/gl3/default.vert
index 6d3a60ef6..f97cd099d 100644
--- a/src/extras/shaders/gl3/metalrough.vert
+++ b/src/extras/shaders/gl3/default.vert
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#version 150
+#version 150 core
in vec3 vertexPosition;
in vec3 vertexNormal;
@@ -62,12 +62,14 @@ out vec2 texCoord;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
+uniform mat4 modelViewProjection;
+
+uniform float texCoordScale;
void main()
{
- // Pass the texture coordinates through
- texCoord = vertexTexCoord;
+ // Pass through scaled texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
// Transform position, normal, and tangent to world space
worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
@@ -75,5 +77,6 @@ void main()
worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
worldTangent.w = vertexTangent.w;
- gl_Position = mvp * vec4(vertexPosition, 1.0);
+ // Calculate vertex position in clip coordinates
+ gl_Position = modelViewProjection * vec4(vertexPosition, 1.0);
}
diff --git a/src/extras/shaders/gl3/diffusemap.frag b/src/extras/shaders/gl3/diffusemap.frag
index 7810fdb68..34fef5a43 100644
--- a/src/extras/shaders/gl3/diffusemap.frag
+++ b/src/extras/shaders/gl3/diffusemap.frag
@@ -1,7 +1,7 @@
#version 150 core
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -14,14 +14,11 @@ in vec2 texCoord;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
-
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/diffusemap.vert b/src/extras/shaders/gl3/diffusemap.vert
deleted file mode 100644
index 439be6e99..000000000
--- a/src/extras/shaders/gl3/diffusemap.vert
+++ /dev/null
@@ -1,24 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-in vec2 vertexTexCoord;
-
-out vec3 worldPosition;
-out vec3 worldNormal;
-out vec2 texCoord;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- texCoord = vertexTexCoord * texCoordScale;
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/gl3/diffusespecularmap.frag b/src/extras/shaders/gl3/diffusespecularmap.frag
index fb809393a..8673a5121 100644
--- a/src/extras/shaders/gl3/diffusespecularmap.frag
+++ b/src/extras/shaders/gl3/diffusespecularmap.frag
@@ -1,7 +1,7 @@
#version 150 core
// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
+uniform vec4 ka; // Ambient reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -15,15 +15,12 @@ in vec2 texCoord;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
- vec3 specularTextureColor = texture( specularTexture, texCoord ).rgb;
-
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec4 specularTextureColor = texture( specularTexture, texCoord );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/light.inc.frag b/src/extras/shaders/gl3/light.inc.frag
index ce5c581cf..0b642638f 100644
--- a/src/extras/shaders/gl3/light.inc.frag
+++ b/src/extras/shaders/gl3/light.inc.frag
@@ -23,200 +23,3 @@ struct EnvironmentLight {
};
uniform EnvironmentLight envLight;
uniform int envLightCount = 0;
-
-void adsModelNormalMapped(const in vec3 worldPos,
- const in vec3 tsNormal,
- const in vec3 worldEye,
- const in float shininess,
- const in mat3 tangentMatrix,
- out vec3 diffuseColor,
- out vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- // We perform all work in tangent space, so we convert quantities from world space
- vec3 tsPos = tangentMatrix * worldPos;
- vec3 n = normalize(tsNormal);
- vec3 v = normalize(tangentMatrix * (worldEye - worldPos));
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Transform the light position from world to tangent space
- vec3 tsLightPos = tangentMatrix * lights[i].position;
- vec3 sUnnormalized = tsLightPos - tsPos;
- s = normalize(sUnnormalized); // Light direction in tangent space
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space, convert to tangent space
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- vec3 tsLightDirection = tangentMatrix * lights[i].direction;
- if (degrees(acos(dot(-s, tsLightDirection))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space, convert to tangent space
- s = normalize(tangentMatrix * -lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Calculate the specular factor
- float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- float normFactor = (shininess + 2.0) / 2.0;
- vec3 r = reflect(-s, n); // Reflection direction in tangent space
- specular = normFactor * pow(max(dot(r, v), 0.0), shininess);
- }
-
- // Accumulate the diffuse and specular contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- specularColor += att * lights[i].intensity * specular * lights[i].color;
- }
-}
-
-void adsModel(const in vec3 worldPos,
- const in vec3 worldNormal,
- const in vec3 worldEye,
- const in float shininess,
- out vec3 diffuseColor,
- out vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- // We perform all work in world space
- vec3 n = normalize(worldNormal);
- vec3 v = normalize(worldEye - worldPos);
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Light position is already in world space
- vec3 sUnnormalized = lights[i].position - worldPos;
- s = normalize(sUnnormalized); // Light direction
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space already
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space already
- s = normalize(-lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Calculate the specular factor
- float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- float normFactor = (shininess + 2.0) / 2.0;
- vec3 r = reflect(-s, n); // Reflection direction in world space
- specular = normFactor * pow(max(dot(r, v), 0.0), shininess);
- }
-
- // Accumulate the diffuse and specular contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- specularColor += att * lights[i].intensity * specular * lights[i].color;
- }
-}
-
-void adModel(const in vec3 worldPos,
- const in vec3 worldNormal,
- out vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- // We perform all work in world space
- vec3 n = normalize(worldNormal);
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Light position is already in world space
- vec3 sUnnormalized = lights[i].position - worldPos;
- s = normalize(sUnnormalized); // Light direction
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space already
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space already
- s = normalize(-lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Accumulate the diffuse contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- }
-}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.frag b/src/extras/shaders/gl3/normaldiffusemap.frag
index a99a7ed73..bac776738 100644
--- a/src/extras/shaders/gl3/normaldiffusemap.frag
+++ b/src/extras/shaders/gl3/normaldiffusemap.frag
@@ -1,33 +1,36 @@
#version 150 core
in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
in vec2 texCoord;
-in mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ vec3 tNormal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+ vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.vert b/src/extras/shaders/gl3/normaldiffusemap.vert
deleted file mode 100644
index 8da443e8d..000000000
--- a/src/extras/shaders/gl3/normaldiffusemap.vert
+++ /dev/null
@@ -1,47 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-in vec2 vertexTexCoord;
-in vec4 vertexTangent;
-
-out vec3 worldPosition;
-out vec2 texCoord;
-out mat3 tangentMatrix;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- // Pass through scaled texture coordinates
- texCoord = vertexTexCoord * texCoordScale;
-
- // Transform position, normal, and tangent to world coords
- worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
- vec3 normal = normalize(modelNormalMatrix * vertexNormal);
- vec3 tangent = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
-
- // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
- // This allows to build the tangentMatrix below by simply transposing the
- // tangent -> world space matrix (which would now be orthogonal)
- tangent = normalize(tangent - dot(tangent, normal) * normal);
-
- // Calculate binormal vector. No "real" need to renormalize it,
- // as built by crossing two normal vectors.
- // To orient the binormal correctly, use the fourth coordinate of the tangent,
- // which is +1 for a right hand system, and -1 for a left hand system.
- vec3 binormal = cross(normal, tangent) * vertexTangent.w;
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3(
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z);
-
- // Calculate vertex position in clip coordinates
- gl_Position = mvp * vec4(vertexPosition, 1.0);
-}
diff --git a/src/extras/shaders/gl3/normaldiffusemapalpha.frag b/src/extras/shaders/gl3/normaldiffusemapalpha.frag
deleted file mode 100644
index ce5cf0e90..000000000
--- a/src/extras/shaders/gl3/normaldiffusemapalpha.frag
+++ /dev/null
@@ -1,34 +0,0 @@
-#version 150 core
-
-in vec3 worldPosition;
-in vec2 texCoord;
-in mat3 tangentMatrix;
-
-uniform sampler2D diffuseTexture;
-uniform sampler2D normalTexture;
-
-// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
-uniform float shininess; // Specular shininess factor
-
-uniform vec3 eyePosition;
-
-out vec4 fragColor;
-
-#pragma include light.inc.frag
-
-void main()
-{
- // Sample the textures at the interpolated texCoords
- vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
-
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
-
- // Combine spec with ambient+diffuse for final fragment color
- // Use the alpha from the diffuse texture (for alpha to coverage)
- fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
-}
diff --git a/src/extras/shaders/gl3/normaldiffusespecularmap.frag b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
index b60cfe84c..d96b9e747 100644
--- a/src/extras/shaders/gl3/normaldiffusespecularmap.frag
+++ b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
@@ -1,8 +1,9 @@
#version 150 core
in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
in vec2 texCoord;
-in mat3 tangentMatrix;
out vec4 fragColor;
@@ -10,26 +11,25 @@ uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
uniform sampler2D normalTexture;
-uniform vec3 ka; // Ambient reflectivity
+uniform vec4 ka; // Ambient reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
vec4 specularTextureColor = texture( specularTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ vec3 tNormal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition,
- shininess, tangentMatrix,
- diffuseColor, specularColor);
+ mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- fragColor = vec4((ka + diffuseColor) * diffuseTextureColor.rgb
- + specularColor * specularTextureColor.rgb, 1.0);
+ vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/gl3/pervertexcolor.frag b/src/extras/shaders/gl3/pervertexcolor.frag
index b5ed5a33d..40fc066d6 100644
--- a/src/extras/shaders/gl3/pervertexcolor.frag
+++ b/src/extras/shaders/gl3/pervertexcolor.frag
@@ -2,15 +2,16 @@
in vec3 worldPosition;
in vec3 worldNormal;
-in vec3 color;
+in vec4 color;
out vec4 fragColor;
-#pragma include light.inc.frag
+uniform vec3 eyePosition;
+
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseColor;
- adModel(worldPosition, worldNormal, diffuseColor);
- fragColor = vec4( color + color * diffuseColor, 1.0 );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(color, color, vec4(0.0), 0.0, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/pervertexcolor.vert b/src/extras/shaders/gl3/pervertexcolor.vert
index 87713a520..1d721e945 100644
--- a/src/extras/shaders/gl3/pervertexcolor.vert
+++ b/src/extras/shaders/gl3/pervertexcolor.vert
@@ -2,11 +2,11 @@
in vec3 vertexPosition;
in vec3 vertexNormal;
-in vec3 vertexColor;
+in vec4 vertexColor;
out vec3 worldPosition;
out vec3 worldNormal;
-out vec3 color;
+out vec4 color;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
diff --git a/src/extras/shaders/gl3/phong.frag b/src/extras/shaders/gl3/phong.frag
index a4d7e0969..3652672b5 100644
--- a/src/extras/shaders/gl3/phong.frag
+++ b/src/extras/shaders/gl3/phong.frag
@@ -1,8 +1,8 @@
#version 150 core
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 kd; // Diffuse reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 kd; // Diffuse reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -12,11 +12,10 @@ in vec3 worldNormal;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, kd, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/phong.inc.frag b/src/extras/shaders/gl3/phong.inc.frag
new file mode 100644
index 000000000..47a6ecd4a
--- /dev/null
+++ b/src/extras/shaders/gl3/phong.inc.frag
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in vec3 worldPos,
+ const in vec3 worldNormal,
+ const in vec3 worldView,
+ const in float shininess,
+ out vec3 diffuseColor,
+ out vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ // We perform all work in world space
+ vec3 n = normalize(worldNormal);
+ vec3 s = vec3(0.0);
+
+ for (int i = 0; i < lightCount; ++i) {
+ float att = 1.0;
+ float sDotN = 0.0;
+
+ if (lights[i].type != TYPE_DIRECTIONAL) {
+ // Point and Spot lights
+
+ // Light position is already in world space
+ vec3 sUnnormalized = lights[i].position - worldPos;
+ s = normalize(sUnnormalized); // Light direction
+
+ // Calculate the attenuation factor
+ sDotN = dot(s, n);
+ if (sDotN > 0.0) {
+ if (lights[i].constantAttenuation != 0.0
+ || lights[i].linearAttenuation != 0.0
+ || lights[i].quadraticAttenuation != 0.0) {
+ float dist = length(sUnnormalized);
+ att = 1.0 / (lights[i].constantAttenuation +
+ lights[i].linearAttenuation * dist +
+ lights[i].quadraticAttenuation * dist * dist);
+ }
+
+ // The light direction is in world space already
+ if (lights[i].type == TYPE_SPOT) {
+ // Check if fragment is inside or outside of the spot light cone
+ if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
+ sDotN = 0.0;
+ }
+ }
+ } else {
+ // Directional lights
+ // The light direction is in world space already
+ s = normalize(-lights[i].direction);
+ sDotN = dot(s, n);
+ }
+
+ // Calculate the diffuse factor
+ float diffuse = max(sDotN, 0.0);
+
+ // Calculate the specular factor
+ float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ float normFactor = (shininess + 2.0) / 2.0;
+ vec3 r = reflect(-s, n); // Reflection direction in world space
+ specular = normFactor * pow(max(dot(r, worldView), 0.0), shininess);
+ }
+
+ // Accumulate the diffuse and specular contributions
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+vec4 phongFunction(const in vec4 ambient,
+ const in vec4 diffuse,
+ const in vec4 specular,
+ const in float shininess,
+ const in vec3 worldPosition,
+ const in vec3 worldView,
+ const in vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/gl3/phong.vert b/src/extras/shaders/gl3/phong.vert
deleted file mode 100644
index cdb3c70e9..000000000
--- a/src/extras/shaders/gl3/phong.vert
+++ /dev/null
@@ -1,19 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-
-out vec3 worldPosition;
-out vec3 worldNormal;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 modelViewProjection;
-
-void main()
-{
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/gl3/phongalpha.frag b/src/extras/shaders/gl3/phongalpha.frag
deleted file mode 100644
index cb019e9aa..000000000
--- a/src/extras/shaders/gl3/phongalpha.frag
+++ /dev/null
@@ -1,24 +0,0 @@
-#version 150 core
-
-// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 kd; // Diffuse reflectivity
-uniform vec3 ks; // Specular reflectivity
-uniform float shininess; // Specular shininess factor
-uniform float alpha;
-
-uniform vec3 eyePosition;
-
-in vec3 worldPosition;
-in vec3 worldNormal;
-
-out vec4 fragColor;
-
-#pragma include light.inc.frag
-
-void main()
-{
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
-}
diff --git a/src/extras/text/distancefieldtextrenderer.cpp b/src/extras/text/distancefieldtextrenderer.cpp
index 9f390e8da..4cf9c0b4a 100644
--- a/src/extras/text/distancefieldtextrenderer.cpp
+++ b/src/extras/text/distancefieldtextrenderer.cpp
@@ -80,8 +80,8 @@ void DistanceFieldTextRendererPrivate::init()
m_geometry = new Qt3DRender::QGeometry(m_renderer);
m_renderer->setGeometry(m_geometry);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, m_geometry);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, m_geometry);
+ m_vertexBuffer = new Qt3DRender::QBuffer(m_geometry);
+ m_indexBuffer = new Qt3DRender::QBuffer(m_geometry);
m_positionAttr = new Qt3DRender::QAttribute(m_geometry);
m_positionAttr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp
index b1fb1f931..7184e2f69 100644
--- a/src/plugins/geometryloaders/default/objgeometryloader.cpp
+++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp
@@ -144,7 +144,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
++normalsOffset;
}
}
- } else if (!skipping && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) {
+ } else if (!skipping && tokens.size() >= 4 && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) {
// Process face
++faceCount;
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index a1558b7e2..3a06c7807 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -403,8 +403,8 @@ void AssimpImporter::setSource(const QUrl &source)
}
/*!
- * Sets the \a source used by the parser to load the asset file.
- * If the file is valid, this will trigger parsing of the file.
+ * Sets the \a basePath used by the parser to load the asset file.
+ * If the file specified in \a data is valid, this will trigger parsing of the file.
*/
void AssimpImporter::setData(const QByteArray &data, const QString &basePath)
{
@@ -412,7 +412,7 @@ void AssimpImporter::setData(const QByteArray &data, const QString &basePath)
}
/*!
- * Returns \c true if the extension of \a source is supported by
+ * Returns \c true if the extension in QStringList \a extensions is supported by
* the assimp parser.
*/
bool AssimpImporter::areFileTypesSupported(const QStringList &extensions) const
diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
index a94a4f307..4419bd708 100644
--- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp
+++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
@@ -268,11 +268,23 @@ GLTFImporter::~GLTFImporter()
}
+/*!
+ \class Qt3DRender::GLTFImporter
+ \inmodule Qt3DRender
+ \brief Handles importing of gltf files
+*/
+/*!
+ Set the base \a path for importing scenes.
+*/
void GLTFImporter::setBasePath(const QString& path)
{
m_basePath = path;
}
+/*!
+ Set a \a json document as the file used for importing a scene.
+ Returns true if the operation is successful.
+*/
bool GLTFImporter::setJSON(const QJsonDocument &json )
{
if ( !json.isObject() ) {
@@ -286,7 +298,8 @@ bool GLTFImporter::setJSON(const QJsonDocument &json )
}
/*!
- * Sets the \a path used by the parser to load the scene file.
+ * Sets the path based on parameter \a source. The path is
+ * used by the parser to load the scene file.
* If the file is valid, parsing is automatically triggered.
*/
void GLTFImporter::setSource(const QUrl &source)
@@ -314,8 +327,9 @@ void GLTFImporter::setSource(const QUrl &source)
}
/*!
- * Sets the \a path used by the parser to load the scene file.
- * If the file is valid, parsing is automatically triggered.
+ * Sets the \a basePath used by the parser to load the scene file.
+ * If the file derived from \a data is valid, parsing is automatically
+ * triggered.
*/
void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
{
@@ -332,7 +346,7 @@ void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
}
/*!
- * Returns true if the extensions are supported by the
+ * Returns true if the \a extensions are supported by the
* GLTF parser.
*/
bool GLTFImporter::areFileTypesSupported(const QStringList &extensions) const
@@ -340,6 +354,9 @@ bool GLTFImporter::areFileTypesSupported(const QStringList &extensions) const
return GLTFImporter::isGLTFSupported(extensions);
}
+/*!
+ Imports the node specified in \a id from the GLTF file.
+*/
Qt3DCore::QEntity* GLTFImporter::node(const QString &id)
{
QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
@@ -507,6 +524,9 @@ Qt3DCore::QEntity* GLTFImporter::node(const QString &id)
return result;
}
+/*!
+ Imports the scene specified in parameter \a id.
+*/
Qt3DCore::QEntity* GLTFImporter::scene(const QString &id)
{
parse();
@@ -1656,6 +1676,9 @@ void GLTFImporter::processJSONRenderPass(const QString &id, const QJsonObject &j
m_renderPasses[id] = pass;
}
+/*!
+ Loads raw data from the GLTF file into the buffer.
+*/
void GLTFImporter::loadBufferData()
{
for (auto &bufferData : m_bufferDatas) {
@@ -1665,6 +1688,9 @@ void GLTFImporter::loadBufferData()
}
}
+/*!
+ Removes all data from the buffer.
+*/
void GLTFImporter::unloadBufferData()
{
for (const auto &bufferData : qAsConst(m_bufferDatas)) {
diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
index 7921fce64..ba100e095 100644
--- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
+++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
@@ -266,6 +266,13 @@ GLTFExporter::~GLTFExporter()
{
}
+/*!
+ \class Qt3DRender::GLTFExporter
+ \inmodule Qt3DRender
+ \brief Manages the export of a 3D scene to the GLTF format.
+
+ Handles the export of a 3D scene to the GLTF format.
+*/
// sceneRoot : The root entity that contains the exported scene. If the sceneRoot doesn't have
// any exportable components, it is not exported itself. This is because importing a
// scene creates an empty top level entity to hold the scene.
@@ -278,6 +285,23 @@ GLTFExporter::~GLTFExporter()
// "binaryJson" (bool): Generates a binary JSON file, which is more efficient to parse.
// "compactJson" (bool): Removes unnecessary whitespace from the generated JSON file.
// Ignored if "binaryJson" option is true.
+
+/*!
+ Exports the scene to the GLTF format
+
+ \a sceneRoot is the root entity that will be exported.
+ If the sceneRoot does not have any exportable components, it is not exported itself.
+
+ \a outDir is the directory in which the scene export is created.
+
+ \a exportName is the name of the directory created in \c outDir that will hold
+ the exported scene.
+
+ \a options contain the export options.
+
+ Returns true if the export was carried out successfully.
+*/
+
bool GLTFExporter::exportScene(QEntity *sceneRoot, const QString &outDir,
const QString &exportName, const QVariantHash &options)
{
@@ -643,18 +667,23 @@ void GLTFExporter::parseMaterials()
for (auto param : parameters) {
if (param->value().type() == QVariant::Color) {
QColor color = param->value().value<QColor>();
- if (param->name() == MATERIAL_AMBIENT_COLOR)
+ if (param->name() == MATERIAL_AMBIENT_COLOR) {
matInfo.colors.insert(QStringLiteral("ambient"), color);
- else if (param->name() == MATERIAL_DIFFUSE_COLOR)
+ } else if (param->name() == MATERIAL_DIFFUSE_COLOR) {
+ if (matInfo.type == MaterialInfo::TypePhongAlpha) {
+ matInfo.values.insert(QStringLiteral("transparency"), float(color.alphaF()));
+ color.setAlphaF(1.0f);
+ }
matInfo.colors.insert(QStringLiteral("diffuse"), color);
- else if (param->name() == MATERIAL_SPECULAR_COLOR)
+ } else if (param->name() == MATERIAL_SPECULAR_COLOR) {
matInfo.colors.insert(QStringLiteral("specular"), color);
- else if (param->name() == MATERIAL_COOL_COLOR) // Custom Qt3D gooch
+ } else if (param->name() == MATERIAL_COOL_COLOR) { // Custom Qt3D gooch
matInfo.colors.insert(QStringLiteral("cool"), color);
- else if (param->name() == MATERIAL_WARM_COLOR) // Custom Qt3D gooch
+ } else if (param->name() == MATERIAL_WARM_COLOR) { // Custom Qt3D gooch
matInfo.colors.insert(QStringLiteral("warm"), color);
- else
+ } else {
matInfo.colors.insert(param->name(), color);
+ }
} else if (param->value().canConvert<QAbstractTexture *>()) {
const QString urlString = textureVariantToUrl(param->value());
if (param->name() == MATERIAL_DIFFUSE_TEXTURE)
diff --git a/src/quick3d/quick3drender/items/quick3dbuffer.cpp b/src/quick3d/quick3drender/items/quick3dbuffer.cpp
index 362e60328..9ff349118 100644
--- a/src/quick3d/quick3drender/items/quick3dbuffer.cpp
+++ b/src/quick3d/quick3drender/items/quick3dbuffer.cpp
@@ -61,7 +61,7 @@ const int jsValueTypeId = qMetaTypeId<QJSValue>();
}
Quick3DBuffer::Quick3DBuffer(Qt3DCore::QNode *parent)
- : Qt3DRender::QBuffer(QBuffer::VertexBuffer, parent)
+ : Qt3DRender::QBuffer(parent)
, m_engine(nullptr)
, m_v4engine(nullptr)
{
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index da4ad0ae0..1ba178a3a 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -64,6 +64,7 @@
#include <Qt3DRender/private/renderqueue_p.h>
#include <Qt3DRender/private/shader_p.h>
#include <Qt3DRender/private/buffer_p.h>
+#include <Qt3DRender/private/glbuffer_p.h>
#include <Qt3DRender/private/renderstateset_p.h>
#include <Qt3DRender/private/technique_p.h>
#include <Qt3DRender/private/renderthread_p.h>
@@ -1078,8 +1079,9 @@ void Renderer::updateGLResources()
for (HBuffer handle: dirtyBufferHandles) {
Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
// Forces creation if it doesn't exit
+ // Also note the binding point doesn't really matter here, we just upload data
if (!m_graphicsContext->hasGLBufferForBuffer(buffer))
- m_graphicsContext->glBufferForRenderBuffer(buffer);
+ m_graphicsContext->glBufferForRenderBuffer(buffer, GLBuffer::ArrayBuffer);
// Update the glBuffer data
m_graphicsContext->updateBuffer(buffer);
buffer->unsetDirty();
@@ -1604,7 +1606,7 @@ void Renderer::performDraw(RenderCommand *command)
}
// Get GLBuffer from Buffer;
- GLBuffer *indirectDrawGLBuffer = m_graphicsContext->glBufferForRenderBuffer(indirectDrawBuffer);
+ GLBuffer *indirectDrawGLBuffer = m_graphicsContext->glBufferForRenderBuffer(indirectDrawBuffer, GLBuffer::DrawIndirectBuffer);
if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) {
qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve GLBuffer";
return;
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 962480f2f..07311824e 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -129,6 +129,7 @@ RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniform
setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix);
+ setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio);
setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure);
setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma);
setters.insert(StringToInt::lookupId(QLatin1String("time")), Time);
@@ -200,6 +201,8 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
return UniformValue(viewportMatrix.inverted());
}
+ case AspectRatio:
+ return float(m_surfaceSize.width()) / float(m_surfaceSize.height());
case Exposure:
return UniformValue(m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f);
case Gamma:
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index bc68e2a63..8c733fc3a 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -342,6 +342,7 @@ private:
ModelViewNormalMatrix,
ViewportMatrix,
InverseViewportMatrix,
+ AspectRatio,
Time,
Exposure,
Gamma,
diff --git a/src/render/frontend/qitemmodelbuffer.cpp b/src/render/frontend/qitemmodelbuffer.cpp
index 3941ac2fd..82215204a 100644
--- a/src/render/frontend/qitemmodelbuffer.cpp
+++ b/src/render/frontend/qitemmodelbuffer.cpp
@@ -223,7 +223,7 @@ QBuffer *QItemModelBuffer::buffer()
m_attributes.clear();
m_itemStride = 0;
- m_buffer = new QBuffer(QBuffer::VertexBuffer);
+ m_buffer = new QBuffer;
// assume model will change
m_buffer->setUsage(QBuffer::DynamicDraw);
diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp
index 4212897ab..23f88eb10 100644
--- a/src/render/frontend/qrendersettings.cpp
+++ b/src/render/frontend/qrendersettings.cpp
@@ -217,8 +217,11 @@ void QRenderSettings::setActiveFrameGraph(QFrameGraphNode *activeFrameGraph)
if (d->m_activeFrameGraph && activeFrameGraph) {
Qt3DRender::QRenderSurfaceSelector *oldSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(d->m_activeFrameGraph);
Qt3DRender::QRenderSurfaceSelector *newSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(activeFrameGraph);
- if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface())
+ if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface()) {
+ newSurfaceSelector->setExternalRenderTargetSize(oldSurfaceSelector->externalRenderTargetSize());
+ newSurfaceSelector->setSurfacePixelRatio(oldSurfaceSelector->surfacePixelRatio());
newSurfaceSelector->setSurface(oldSurfaceSelector->surface());
+ }
}
if (d->m_activeFrameGraph)
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index 666b5006d..3658ef335 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -51,7 +51,6 @@ namespace Render {
Buffer::Buffer()
: BackendNode(QBackendNode::ReadWrite)
- , m_type(QBuffer::VertexBuffer)
, m_usage(QBuffer::StaticDraw)
, m_bufferDirty(false)
, m_syncData(false)
@@ -68,7 +67,6 @@ Buffer::~Buffer()
void Buffer::cleanup()
{
- m_type = QBuffer::VertexBuffer;
m_usage = QBuffer::StaticDraw;
m_data.clear();
m_bufferUpdates.clear();
@@ -120,7 +118,6 @@ void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBufferData>>(change);
const auto &data = typedChange->data;
m_data = data.data;
- m_type = data.type;
m_usage = data.usage;
m_syncData = data.syncData;
m_access = data.access;
@@ -164,9 +161,6 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>();
m_bufferUpdates.push_back(updateData);
m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("type")) {
- m_type = static_cast<QBuffer::BufferType>(propertyChange->value().value<int>());
- m_bufferDirty = true;
} else if (propertyName == QByteArrayLiteral("usage")) {
m_usage = static_cast<QBuffer::UsageType>(propertyChange->value().value<int>());
m_bufferDirty = true;
diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h
index 690d1eab6..9a171599d 100644
--- a/src/render/geometry/buffer_p.h
+++ b/src/render/geometry/buffer_p.h
@@ -78,7 +78,6 @@ public:
void setManager(BufferManager *manager);
void executeFunctor();
void updateDataFromGPUToCPU(QByteArray data);
- inline QBuffer::BufferType type() const { return m_type; }
inline QBuffer::UsageType usage() const { return m_usage; }
inline QByteArray data() const { return m_data; }
inline QVector<Qt3DRender::QBufferUpdate> &pendingBufferUpdates() { return m_bufferUpdates; }
@@ -92,7 +91,6 @@ private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void forceDataUpload();
- QBuffer::BufferType m_type;
QBuffer::UsageType m_usage;
QByteArray m_data;
QVector<Qt3DRender::QBufferUpdate> m_bufferUpdates;
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index 3d524d60f..fe065929d 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -77,6 +77,8 @@ QBufferPrivate::QBufferPrivate()
* \qmlproperty QBuffer::BufferType Buffer::type
*
* Holds the buffer type.
+ *
+ * \deprecated
*/
/*!
@@ -220,6 +222,8 @@ QBufferPrivate::QBufferPrivate()
* GL_SHADER_STORAGE_BUFFER
* \value DrawIndirectBuffer
* GL_DRAW_INDIRECT_BUFFER
+ *
+ * \deprecated
*/
/*!
@@ -253,7 +257,17 @@ QBufferPrivate::QBufferPrivate()
*/
/*!
+ * Constructs a new QBuffer with \a parent.
+ */
+QBuffer::QBuffer(QNode *parent)
+ : QNode(*new QBufferPrivate(), parent)
+{
+}
+
+/*!
* Constructs a new QBuffer of buffer type \a ty with \a parent.
+ *
+ * \deprecated
*/
QBuffer::QBuffer(QBuffer::BufferType ty, QNode *parent)
: QNode(*new QBufferPrivate(), parent)
@@ -360,6 +374,8 @@ void QBuffer::setUsage(QBuffer::UsageType usage)
* \property QBuffer::type
*
* Holds the buffer type.
+ *
+ * \deprecated
*/
QBuffer::BufferType QBuffer::type() const
{
@@ -448,7 +464,6 @@ Qt3DCore::QNodeCreatedChangeBasePtr QBuffer::createNodeCreationChange() const
auto &data = creationChange->data;
Q_D(const QBuffer);
data.data = d->m_data;
- data.type = d->m_type;
data.usage = d->m_usage;
data.functor = d->m_functor;
data.syncData = d->m_syncData;
diff --git a/src/render/geometry/qbuffer.h b/src/render/geometry/qbuffer.h
index 1aa4bcc06..09fe54e10 100644
--- a/src/render/geometry/qbuffer.h
+++ b/src/render/geometry/qbuffer.h
@@ -95,11 +95,12 @@ public:
};
Q_ENUM(AccessType) // LCOV_EXCL_LINE
- explicit QBuffer(BufferType ty = QBuffer::VertexBuffer, Qt3DCore::QNode *parent = nullptr);
+ explicit QBuffer(Qt3DCore::QNode *parent = nullptr);
+ QT_DEPRECATED explicit QBuffer(BufferType ty, Qt3DCore::QNode *parent = nullptr);
~QBuffer();
UsageType usage() const;
- BufferType type() const;
+ QT_DEPRECATED BufferType type() const;
bool isSyncData() const;
AccessType accessType() const;
@@ -112,7 +113,7 @@ public:
Q_INVOKABLE void updateData(int offset, const QByteArray &bytes);
public Q_SLOTS:
- void setType(BufferType type);
+ QT_DEPRECATED void setType(BufferType type);
void setUsage(UsageType usage);
void setSyncData(bool syncData);
void setAccessType(AccessType access);
diff --git a/src/render/geometry/qbuffer_p.h b/src/render/geometry/qbuffer_p.h
index a722675ab..a342518e0 100644
--- a/src/render/geometry/qbuffer_p.h
+++ b/src/render/geometry/qbuffer_p.h
@@ -80,7 +80,6 @@ public:
struct QBufferData
{
QByteArray data;
- QBuffer::BufferType type;
QBuffer::UsageType usage;
QBufferDataGeneratorPtr functor;
bool syncData;
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index 485069e2a..075936f37 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -118,7 +118,12 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
switch (e->type()) {
case Qt3DCore::PropertyUpdated: {
const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("source")) {
+ if (change->propertyName() == QByteArrayLiteral("localPoses")) {
+ // When the animation aspect sends us a new set of local poses, all we
+ // need to do is copy them into place. The existing jobs will then update
+ // the skinning matrix palette.
+ m_skeletonData.localPoses = change->value().value<QVector<Qt3DCore::Sqt>>();
+ } else if (change->propertyName() == QByteArrayLiteral("source")) {
Q_ASSERT(m_dataType == File);
const auto source = change->value().toUrl();
if (source != m_source) {
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 11132c5ed..814429504 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -120,22 +120,14 @@ static void logOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage)
namespace {
-GLBuffer::Type bufferTypeToGLBufferType(QBuffer::BufferType type)
+GLBuffer::Type attributeTypeToGLBufferType(QAttribute::AttributeType type)
{
switch (type) {
- case QBuffer::VertexBuffer:
+ case QAttribute::VertexAttribute:
return GLBuffer::ArrayBuffer;
- case QBuffer::IndexBuffer:
+ case QAttribute::IndexAttribute:
return GLBuffer::IndexBuffer;
- case QBuffer::PixelPackBuffer:
- return GLBuffer::PixelPackBuffer;
- case QBuffer::PixelUnpackBuffer:
- return GLBuffer::PixelUnpackBuffer;
- case QBuffer::UniformBuffer:
- return GLBuffer::UniformBuffer;
- case QBuffer::ShaderStorageBuffer:
- return GLBuffer::ShaderStorageBuffer;
- case QBuffer::DrawIndirectBuffer:
+ case QAttribute::DrawIndirectAttribute:
return GLBuffer::DrawIndirectBuffer;
default:
Q_UNREACHABLE();
@@ -1220,7 +1212,7 @@ void GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
int ssboIndex = 0;
for (const BlockToSSBO b : blockToSSBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
- GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer);
+ GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer, GLBuffer::ShaderStorageBuffer);
bindShaderStorageBlock(shader->programId(), b.m_blockIndex, ssboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
@@ -1240,7 +1232,7 @@ void GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
int uboIndex = 0;
for (const BlockToUBO &b : blockToUBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
- GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer);
+ GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer, GLBuffer::UniformBuffer);
bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
@@ -1287,7 +1279,7 @@ void GraphicsContext::enableAttribute(const VAOVertexAttribute &attr)
// Bind buffer within the current VAO
GLBuffer *buf = m_renderer->nodeManagers()->glBufferManager()->data(attr.bufferHandle);
Q_ASSERT(buf);
- bindGLBuffer(buf, attr.bufferType);
+ bindGLBuffer(buf, attr.attributeType);
// Don't use QOpenGLShaderProgram::setAttributeBuffer() because of QTBUG-43199.
// Use the introspection data and set the attribute explicitly
@@ -1437,7 +1429,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
const GLint attributeDataType = glDataTypeFromAttributeDataType(attribute->vertexBaseType());
const HGLBuffer glBufferHandle = m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId());
Q_ASSERT(!glBufferHandle.isNull());
- const GLBuffer::Type bufferType = bufferTypeToGLBufferType(buffer->type());
+ const GLBuffer::Type attributeType = attributeTypeToGLBufferType(attribute->attributeType());
int typeSize = 0;
int attrCount = 0;
@@ -1457,7 +1449,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
for (int i = 0; i < attrCount; i++) {
VAOVertexAttribute attr;
attr.bufferHandle = glBufferHandle;
- attr.bufferType = bufferType;
+ attr.attributeType = attributeType;
attr.location = location + i;
attr.dataType = attributeDataType;
attr.byteOffset = attribute->byteOffset() + (i * attrCount * typeSize);
@@ -1476,9 +1468,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
void GraphicsContext::specifyIndices(Buffer *buffer)
{
- Q_ASSERT(buffer->type() == QBuffer::IndexBuffer);
-
- GLBuffer *buf = glBufferForRenderBuffer(buffer);
+ GLBuffer *buf = glBufferForRenderBuffer(buffer, GLBuffer::IndexBuffer);
if (!bindGLBuffer(buf, GLBuffer::IndexBuffer))
qCWarning(Backend) << Q_FUNC_INFO << "binding index buffer failed";
@@ -1585,14 +1575,14 @@ void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers)
m_glHelper->memoryBarrier(barriers);
}
-GLBuffer *GraphicsContext::glBufferForRenderBuffer(Buffer *buf)
+GLBuffer *GraphicsContext::glBufferForRenderBuffer(Buffer *buf, GLBuffer::Type type)
{
if (!m_renderBufferHash.contains(buf->peerId()))
- m_renderBufferHash.insert(buf->peerId(), createGLBufferFor(buf));
+ m_renderBufferHash.insert(buf->peerId(), createGLBufferFor(buf, type));
return m_renderer->nodeManagers()->glBufferManager()->data(m_renderBufferHash.value(buf->peerId()));
}
-HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
+HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer, GLBuffer::Type type)
{
GLBuffer *b = m_renderer->nodeManagers()->glBufferManager()->getOrCreateResource(buffer->peerId());
// b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(buffer->usage()));
@@ -1600,7 +1590,7 @@ HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
if (!b->create(this))
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed";
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, type))
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed";
return m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId());
@@ -1621,7 +1611,7 @@ bool GraphicsContext::bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type)
void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer)
{
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're uploading, the type doesn't matter here
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
// If the buffer is dirty (hence being called here)
// there are two possible cases
@@ -1663,15 +1653,14 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel
if (releaseBuffer) {
b->release(this);
- if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer)
- m_boundArrayBuffer = nullptr;
+ m_boundArrayBuffer = nullptr;
}
qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size();
}
QByteArray GraphicsContext::downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b)
{
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're downloading, the type doesn't matter here
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
QByteArray data = b->download(this, buffer->data().size());
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index 21ec90c58..1b9438a6f 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -188,7 +188,7 @@ public:
* @param buf
* @return
*/
- GLBuffer *glBufferForRenderBuffer(Buffer *buf);
+ GLBuffer *glBufferForRenderBuffer(Buffer *buf, GLBuffer::Type type);
/**
* @brief activateTexture - make a texture active on a hardware unit
@@ -270,7 +270,7 @@ private:
void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments);
void activateDrawBuffers(const AttachmentPack &attachments);
- HGLBuffer createGLBufferFor(Buffer *buffer);
+ HGLBuffer createGLBufferFor(Buffer *buffer, GLBuffer::Type type);
void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false);
QByteArray downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b);
bool bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type);
@@ -331,7 +331,7 @@ private:
struct VAOVertexAttribute
{
HGLBuffer bufferHandle;
- GLBuffer::Type bufferType;
+ GLBuffer::Type attributeType;
int location;
GLint dataType;
uint byteOffset;
diff --git a/src/render/materialsystem/prototypes/default.json b/src/render/materialsystem/prototypes/default.json
index 429c435f4..9f16b0f53 100644
--- a/src/render/materialsystem/prototypes/default.json
+++ b/src/render/materialsystem/prototypes/default.json
@@ -107,7 +107,7 @@
"major": 2,
"minor": 0
},
- "substitution": "gl_fragColor = $fragColor;"
+ "substitution": "gl_FragColor = $fragColor;"
},
{
"format": {
@@ -377,6 +377,15 @@
"rules": [
{
"format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp mat3 $matrix = calcWorldSpaceToTangentSpaceMatrix($worldNormal, $worldTangent);",
+ "headerSnippets": [ "#pragma include :/shaders/es2/coordinatesystems.inc" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 0
@@ -386,6 +395,40 @@
}
]
},
+ "phongFunction": {
+ "inputs": [
+ "ambient",
+ "diffuse",
+ "specular",
+ "shininess",
+ "worldPosition",
+ "worldView",
+ "worldNormal"
+ ],
+ "outputs": [
+ "outputColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $outputColor = phongFunction($ambient, $diffuse, $specular, $shininess, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/es2/phong.inc.frag" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $outputColor = phongFunction($ambient, $diffuse, $specular, $shininess, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/gl3/phong.inc.frag" ]
+ }
+ ]
+ },
"metalRoughFunction": {
"inputs": [
"baseColor",
diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp
index 2a35a6f7e..11cc1544f 100644
--- a/src/render/texture/gltexture.cpp
+++ b/src/render/texture/gltexture.cpp
@@ -208,6 +208,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture()
// need to (re-)upload texture data?
if (needUpload && !texturedDataInvalid) {
uploadGLTextureData();
+ setDirtyFlag(TextureData, false);
}
// need to set texture parameters?