mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:17:02 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into minimum-edit-entity-filter
This commit is contained in:
commit
831d01c23a
10 changed files with 486 additions and 230 deletions
|
@ -1828,7 +1828,7 @@ void Application::initializeGL() {
|
||||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||||
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
|
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
|
||||||
if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) {
|
if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) {
|
||||||
_renderEngine->addJob<RenderForwardTask>("RenderForwardTask", items.get<RenderFetchCullSortTask::Output>());
|
_renderEngine->addJob<RenderForwardTask>("Forward", items.get<RenderFetchCullSortTask::Output>());
|
||||||
} else {
|
} else {
|
||||||
_renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", items.get<RenderFetchCullSortTask::Output>());
|
_renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", items.get<RenderFetchCullSortTask::Output>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,35 +424,25 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice,
|
||||||
adjustedAudioFormat = desiredAudioFormat;
|
adjustedAudioFormat = desiredAudioFormat;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Attempt the device sample rate in decreasing order of preference.
|
// Attempt the device sample rate and channel count in decreasing order of preference.
|
||||||
//
|
//
|
||||||
if (audioDevice.supportedSampleRates().contains(48000)) {
|
const int sampleRates[] = { 48000, 44100, 32000, 24000, 16000, 96000, 192000, 88200, 176400 };
|
||||||
adjustedAudioFormat.setSampleRate(48000);
|
const int inputChannels[] = { 1, 2, 4, 6, 8 }; // prefer mono
|
||||||
} else if (audioDevice.supportedSampleRates().contains(44100)) {
|
const int outputChannels[] = { 2, 4, 6, 8, 1 }; // prefer stereo, downmix as last resort
|
||||||
adjustedAudioFormat.setSampleRate(44100);
|
|
||||||
} else if (audioDevice.supportedSampleRates().contains(32000)) {
|
for (int channelCount : (desiredAudioFormat.channelCount() == 1 ? inputChannels : outputChannels)) {
|
||||||
adjustedAudioFormat.setSampleRate(32000);
|
for (int sampleRate : sampleRates) {
|
||||||
} else if (audioDevice.supportedSampleRates().contains(24000)) {
|
|
||||||
adjustedAudioFormat.setSampleRate(24000);
|
adjustedAudioFormat.setChannelCount(channelCount);
|
||||||
} else if (audioDevice.supportedSampleRates().contains(16000)) {
|
adjustedAudioFormat.setSampleRate(sampleRate);
|
||||||
adjustedAudioFormat.setSampleRate(16000);
|
|
||||||
} else if (audioDevice.supportedSampleRates().contains(96000)) {
|
if (audioDevice.isFormatSupported(adjustedAudioFormat)) {
|
||||||
adjustedAudioFormat.setSampleRate(96000);
|
return true;
|
||||||
} else if (audioDevice.supportedSampleRates().contains(192000)) {
|
}
|
||||||
adjustedAudioFormat.setSampleRate(192000);
|
}
|
||||||
} else if (audioDevice.supportedSampleRates().contains(88200)) {
|
|
||||||
adjustedAudioFormat.setSampleRate(88200);
|
|
||||||
} else if (audioDevice.supportedSampleRates().contains(176400)) {
|
|
||||||
adjustedAudioFormat.setSampleRate(176400);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adjustedAudioFormat != desiredAudioFormat) {
|
return false; // a supported format could not be found
|
||||||
// return the nearest in case it needs 2 channels
|
|
||||||
adjustedAudioFormat = audioDevice.nearestFormat(adjustedAudioFormat);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, unsigned int numSourceSamples,
|
bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, unsigned int numSourceSamples,
|
||||||
|
|
|
@ -555,8 +555,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
}
|
}
|
||||||
} else if (subobject.name == "Properties70") {
|
} else if (subobject.name == "Properties70") {
|
||||||
foreach (const FBXNode& subsubobject, subobject.children) {
|
foreach (const FBXNode& subsubobject, subobject.children) {
|
||||||
|
static const QVariant APPLICATION_NAME = QVariant(QByteArray("Original|ApplicationName"));
|
||||||
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
|
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
|
||||||
subsubobject.properties.at(0) == "Original|ApplicationName") {
|
subsubobject.properties.at(0) == APPLICATION_NAME) {
|
||||||
geometry.applicationName = subsubobject.properties.at(4).toString();
|
geometry.applicationName = subsubobject.properties.at(4).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,10 +572,12 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
int index = 4;
|
int index = 4;
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
if (subobject.name == propertyName) {
|
if (subobject.name == propertyName) {
|
||||||
QString subpropName = subobject.properties.at(0).toString();
|
static const QVariant UNIT_SCALE_FACTOR = QByteArray("UnitScaleFactor");
|
||||||
if (subpropName == "UnitScaleFactor") {
|
static const QVariant AMBIENT_COLOR = QByteArray("AmbientColor");
|
||||||
|
const auto& subpropName = subobject.properties.at(0);
|
||||||
|
if (subpropName == UNIT_SCALE_FACTOR) {
|
||||||
unitScaleFactor = subobject.properties.at(index).toFloat();
|
unitScaleFactor = subobject.properties.at(index).toFloat();
|
||||||
} else if (subpropName == "AmbientColor") {
|
} else if (subpropName == AMBIENT_COLOR) {
|
||||||
ambientColor = getVec3(subobject.properties, index);
|
ambientColor = getVec3(subobject.properties, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,66 +675,87 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
index = 4;
|
index = 4;
|
||||||
}
|
}
|
||||||
if (properties) {
|
if (properties) {
|
||||||
foreach (const FBXNode& property, subobject.children) {
|
static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation");
|
||||||
|
static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation");
|
||||||
|
static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling");
|
||||||
|
static const QVariant LCL_TRANSLATION = QByteArray("Lcl Translation");
|
||||||
|
static const QVariant LCL_ROTATION = QByteArray("Lcl Rotation");
|
||||||
|
static const QVariant LCL_SCALING = QByteArray("Lcl Scaling");
|
||||||
|
static const QVariant ROTATION_MAX = QByteArray("RotationMax");
|
||||||
|
static const QVariant ROTATION_MAX_X = QByteArray("RotationMaxX");
|
||||||
|
static const QVariant ROTATION_MAX_Y = QByteArray("RotationMaxY");
|
||||||
|
static const QVariant ROTATION_MAX_Z = QByteArray("RotationMaxZ");
|
||||||
|
static const QVariant ROTATION_MIN = QByteArray("RotationMin");
|
||||||
|
static const QVariant ROTATION_MIN_X = QByteArray("RotationMinX");
|
||||||
|
static const QVariant ROTATION_MIN_Y = QByteArray("RotationMinY");
|
||||||
|
static const QVariant ROTATION_MIN_Z = QByteArray("RotationMinZ");
|
||||||
|
static const QVariant ROTATION_OFFSET = QByteArray("RotationOffset");
|
||||||
|
static const QVariant ROTATION_PIVOT = QByteArray("RotationPivot");
|
||||||
|
static const QVariant SCALING_OFFSET = QByteArray("ScalingOffset");
|
||||||
|
static const QVariant SCALING_PIVOT = QByteArray("ScalingPivot");
|
||||||
|
static const QVariant PRE_ROTATION = QByteArray("PreRotation");
|
||||||
|
static const QVariant POST_ROTATION = QByteArray("PostRotation");
|
||||||
|
foreach(const FBXNode& property, subobject.children) {
|
||||||
|
const auto& childProperty = property.properties.at(0);
|
||||||
if (property.name == propertyName) {
|
if (property.name == propertyName) {
|
||||||
if (property.properties.at(0) == "Lcl Translation") {
|
if (childProperty == LCL_TRANSLATION) {
|
||||||
translation = getVec3(property.properties, index);
|
translation = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationOffset") {
|
} else if (childProperty == ROTATION_OFFSET) {
|
||||||
rotationOffset = getVec3(property.properties, index);
|
rotationOffset = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationPivot") {
|
} else if (childProperty == ROTATION_PIVOT) {
|
||||||
rotationPivot = getVec3(property.properties, index);
|
rotationPivot = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "PreRotation") {
|
} else if (childProperty == PRE_ROTATION) {
|
||||||
preRotation = getVec3(property.properties, index);
|
preRotation = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Lcl Rotation") {
|
} else if (childProperty == LCL_ROTATION) {
|
||||||
rotation = getVec3(property.properties, index);
|
rotation = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "PostRotation") {
|
} else if (childProperty == POST_ROTATION) {
|
||||||
postRotation = getVec3(property.properties, index);
|
postRotation = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "ScalingPivot") {
|
} else if (childProperty == SCALING_PIVOT) {
|
||||||
scalePivot = getVec3(property.properties, index);
|
scalePivot = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Lcl Scaling") {
|
} else if (childProperty == LCL_SCALING) {
|
||||||
scale = getVec3(property.properties, index);
|
scale = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "ScalingOffset") {
|
} else if (childProperty == SCALING_OFFSET) {
|
||||||
scaleOffset = getVec3(property.properties, index);
|
scaleOffset = getVec3(property.properties, index);
|
||||||
|
|
||||||
// NOTE: these rotation limits are stored in degrees (NOT radians)
|
// NOTE: these rotation limits are stored in degrees (NOT radians)
|
||||||
} else if (property.properties.at(0) == "RotationMin") {
|
} else if (childProperty == ROTATION_MIN) {
|
||||||
rotationMin = getVec3(property.properties, index);
|
rotationMin = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMax") {
|
} else if (childProperty == ROTATION_MAX) {
|
||||||
rotationMax = getVec3(property.properties, index);
|
rotationMax = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMinX") {
|
} else if (childProperty == ROTATION_MIN_X) {
|
||||||
rotationMinX = property.properties.at(index).toBool();
|
rotationMinX = property.properties.at(index).toBool();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMinY") {
|
} else if (childProperty == ROTATION_MIN_Y) {
|
||||||
rotationMinY = property.properties.at(index).toBool();
|
rotationMinY = property.properties.at(index).toBool();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMinZ") {
|
} else if (childProperty == ROTATION_MIN_Z) {
|
||||||
rotationMinZ = property.properties.at(index).toBool();
|
rotationMinZ = property.properties.at(index).toBool();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMaxX") {
|
} else if (childProperty == ROTATION_MAX_X) {
|
||||||
rotationMaxX = property.properties.at(index).toBool();
|
rotationMaxX = property.properties.at(index).toBool();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMaxY") {
|
} else if (childProperty == ROTATION_MAX_Y) {
|
||||||
rotationMaxY = property.properties.at(index).toBool();
|
rotationMaxY = property.properties.at(index).toBool();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "RotationMaxZ") {
|
} else if (childProperty == ROTATION_MAX_Z) {
|
||||||
rotationMaxZ = property.properties.at(index).toBool();
|
rotationMaxZ = property.properties.at(index).toBool();
|
||||||
} else if (property.properties.at(0) == "GeometricTranslation") {
|
} else if (childProperty == GEOMETRIC_TRANSLATION) {
|
||||||
geometricTranslation = getVec3(property.properties, index);
|
geometricTranslation = getVec3(property.properties, index);
|
||||||
hasGeometricOffset = true;
|
hasGeometricOffset = true;
|
||||||
} else if (property.properties.at(0) == "GeometricRotation") {
|
} else if (childProperty == GEOMETRIC_ROTATION) {
|
||||||
geometricRotation = getVec3(property.properties, index);
|
geometricRotation = getVec3(property.properties, index);
|
||||||
hasGeometricOffset = true;
|
hasGeometricOffset = true;
|
||||||
} else if (property.properties.at(0) == "GeometricScaling") {
|
} else if (childProperty == GEOMETRIC_SCALING) {
|
||||||
geometricScaling = getVec3(property.properties, index);
|
geometricScaling = getVec3(property.properties, index);
|
||||||
hasGeometricOffset = true;
|
hasGeometricOffset = true;
|
||||||
}
|
}
|
||||||
|
@ -842,20 +866,26 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
propertyName = "P";
|
propertyName = "P";
|
||||||
index = 4;
|
index = 4;
|
||||||
foreach (const FBXNode& property, subobject.children) {
|
foreach (const FBXNode& property, subobject.children) {
|
||||||
|
static const QVariant UV_SET = QByteArray("UVSet");
|
||||||
|
static const QVariant CURRENT_TEXTURE_BLEND_MODE = QByteArray("CurrentTextureBlendMode");
|
||||||
|
static const QVariant USE_MATERIAL = QByteArray("UseMaterial");
|
||||||
|
static const QVariant TRANSLATION = QByteArray("Translation");
|
||||||
|
static const QVariant ROTATION = QByteArray("Rotation");
|
||||||
|
static const QVariant SCALING = QByteArray("Scaling");
|
||||||
if (property.name == propertyName) {
|
if (property.name == propertyName) {
|
||||||
QString v = property.properties.at(0).toString();
|
QString v = property.properties.at(0).toString();
|
||||||
if (property.properties.at(0) == "UVSet") {
|
if (property.properties.at(0) == UV_SET) {
|
||||||
std::string uvName = property.properties.at(index).toString().toStdString();
|
std::string uvName = property.properties.at(index).toString().toStdString();
|
||||||
tex.assign(tex.UVSet, property.properties.at(index).toString());
|
tex.assign(tex.UVSet, property.properties.at(index).toString());
|
||||||
} else if (property.properties.at(0) == "CurrentTextureBlendMode") {
|
} else if (property.properties.at(0) == CURRENT_TEXTURE_BLEND_MODE) {
|
||||||
tex.assign<uint8_t>(tex.currentTextureBlendMode, property.properties.at(index).value<int>());
|
tex.assign<uint8_t>(tex.currentTextureBlendMode, property.properties.at(index).value<int>());
|
||||||
} else if (property.properties.at(0) == "UseMaterial") {
|
} else if (property.properties.at(0) == USE_MATERIAL) {
|
||||||
tex.assign<bool>(tex.useMaterial, property.properties.at(index).value<int>());
|
tex.assign<bool>(tex.useMaterial, property.properties.at(index).value<int>());
|
||||||
} else if (property.properties.at(0) == "Translation") {
|
} else if (property.properties.at(0) == TRANSLATION) {
|
||||||
tex.assign(tex.translation, getVec3(property.properties, index));
|
tex.assign(tex.translation, getVec3(property.properties, index));
|
||||||
} else if (property.properties.at(0) == "Rotation") {
|
} else if (property.properties.at(0) == ROTATION) {
|
||||||
tex.assign(tex.rotation, getVec3(property.properties, index));
|
tex.assign(tex.rotation, getVec3(property.properties, index));
|
||||||
} else if (property.properties.at(0) == "Scaling") {
|
} else if (property.properties.at(0) == SCALING) {
|
||||||
tex.assign(tex.scaling, getVec3(property.properties, index));
|
tex.assign(tex.scaling, getVec3(property.properties, index));
|
||||||
if (tex.scaling.x == 0.0f) {
|
if (tex.scaling.x == 0.0f) {
|
||||||
tex.scaling.x = 1.0f;
|
tex.scaling.x = 1.0f;
|
||||||
|
@ -931,87 +961,114 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
|
|
||||||
if (properties) {
|
if (properties) {
|
||||||
std::vector<std::string> unknowns;
|
std::vector<std::string> unknowns;
|
||||||
|
static const QVariant DIFFUSE_COLOR = QByteArray("DiffuseColor");
|
||||||
|
static const QVariant DIFFUSE_FACTOR = QByteArray("DiffuseFactor");
|
||||||
|
static const QVariant DIFFUSE = QByteArray("Diffuse");
|
||||||
|
static const QVariant SPECULAR_COLOR = QByteArray("SpecularColor");
|
||||||
|
static const QVariant SPECULAR_FACTOR = QByteArray("SpecularFactor");
|
||||||
|
static const QVariant SPECULAR = QByteArray("Specular");
|
||||||
|
static const QVariant EMISSIVE_COLOR = QByteArray("EmissiveColor");
|
||||||
|
static const QVariant EMISSIVE_FACTOR = QByteArray("EmissiveFactor");
|
||||||
|
static const QVariant EMISSIVE = QByteArray("Emissive");
|
||||||
|
static const QVariant AMBIENT_FACTOR = QByteArray("AmbientFactor");
|
||||||
|
static const QVariant SHININESS = QByteArray("Shininess");
|
||||||
|
static const QVariant OPACITY = QByteArray("Shininess");
|
||||||
|
static const QVariant MAYA_USE_NORMAL_MAP = QByteArray("Maya|use_normal_map");
|
||||||
|
static const QVariant MAYA_BASE_COLOR = QByteArray("Maya|base_color");
|
||||||
|
static const QVariant MAYA_USE_COLOR_MAP = QByteArray("Maya|use_color_map");
|
||||||
|
static const QVariant MAYA_ROUGHNESS = QByteArray("Maya|roughness");
|
||||||
|
static const QVariant MAYA_USE_ROUGHNESS_MAP = QByteArray("Maya|use_roughness_map");
|
||||||
|
static const QVariant MAYA_METALLIC = QByteArray("Maya|metallic");
|
||||||
|
static const QVariant MAYA_USE_METALLIC_MAP = QByteArray("Maya|use_metallic_map");
|
||||||
|
static const QVariant MAYA_EMISSIVE = QByteArray("Maya|emissive");
|
||||||
|
static const QVariant MAYA_EMISSIVE_INTENSITY = QByteArray("Maya|emissive_intensity");
|
||||||
|
static const QVariant MAYA_USE_EMISSIVE_MAP = QByteArray("Maya|use_emissive_map");
|
||||||
|
static const QVariant MAYA_USE_AO_MAP = QByteArray("Maya|use_ao_map");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach(const FBXNode& property, subobject.children) {
|
foreach(const FBXNode& property, subobject.children) {
|
||||||
if (property.name == propertyName) {
|
if (property.name == propertyName) {
|
||||||
if (property.properties.at(0) == "DiffuseColor") {
|
if (property.properties.at(0) == DIFFUSE_COLOR) {
|
||||||
material.diffuseColor = getVec3(property.properties, index);
|
material.diffuseColor = getVec3(property.properties, index);
|
||||||
} else if (property.properties.at(0) == "DiffuseFactor") {
|
} else if (property.properties.at(0) == DIFFUSE_FACTOR) {
|
||||||
material.diffuseFactor = property.properties.at(index).value<double>();
|
material.diffuseFactor = property.properties.at(index).value<double>();
|
||||||
} else if (property.properties.at(0) == "Diffuse") {
|
} else if (property.properties.at(0) == DIFFUSE) {
|
||||||
// NOTE: this is uneeded but keep it for now for debug
|
// NOTE: this is uneeded but keep it for now for debug
|
||||||
// material.diffuseColor = getVec3(property.properties, index);
|
// material.diffuseColor = getVec3(property.properties, index);
|
||||||
// material.diffuseFactor = 1.0;
|
// material.diffuseFactor = 1.0;
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "SpecularColor") {
|
} else if (property.properties.at(0) == SPECULAR_COLOR) {
|
||||||
material.specularColor = getVec3(property.properties, index);
|
material.specularColor = getVec3(property.properties, index);
|
||||||
} else if (property.properties.at(0) == "SpecularFactor") {
|
} else if (property.properties.at(0) == SPECULAR_FACTOR) {
|
||||||
material.specularFactor = property.properties.at(index).value<double>();
|
material.specularFactor = property.properties.at(index).value<double>();
|
||||||
} else if (property.properties.at(0) == "Specular") {
|
} else if (property.properties.at(0) == SPECULAR) {
|
||||||
// NOTE: this is uneeded but keep it for now for debug
|
// NOTE: this is uneeded but keep it for now for debug
|
||||||
// material.specularColor = getVec3(property.properties, index);
|
// material.specularColor = getVec3(property.properties, index);
|
||||||
// material.specularFactor = 1.0;
|
// material.specularFactor = 1.0;
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "EmissiveColor") {
|
} else if (property.properties.at(0) == EMISSIVE_COLOR) {
|
||||||
material.emissiveColor = getVec3(property.properties, index);
|
material.emissiveColor = getVec3(property.properties, index);
|
||||||
} else if (property.properties.at(0) == "EmissiveFactor") {
|
} else if (property.properties.at(0) == EMISSIVE_FACTOR) {
|
||||||
material.emissiveFactor = property.properties.at(index).value<double>();
|
material.emissiveFactor = property.properties.at(index).value<double>();
|
||||||
} else if (property.properties.at(0) == "Emissive") {
|
} else if (property.properties.at(0) == EMISSIVE) {
|
||||||
// NOTE: this is uneeded but keep it for now for debug
|
// NOTE: this is uneeded but keep it for now for debug
|
||||||
// material.emissiveColor = getVec3(property.properties, index);
|
// material.emissiveColor = getVec3(property.properties, index);
|
||||||
// material.emissiveFactor = 1.0;
|
// material.emissiveFactor = 1.0;
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "AmbientFactor") {
|
} else if (property.properties.at(0) == AMBIENT_FACTOR) {
|
||||||
material.ambientFactor = property.properties.at(index).value<double>();
|
material.ambientFactor = property.properties.at(index).value<double>();
|
||||||
// Detected just for BLender AO vs lightmap
|
// Detected just for BLender AO vs lightmap
|
||||||
} else if (property.properties.at(0) == "Shininess") {
|
} else if (property.properties.at(0) == SHININESS) {
|
||||||
material.shininess = property.properties.at(index).value<double>();
|
material.shininess = property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Opacity") {
|
} else if (property.properties.at(0) == OPACITY) {
|
||||||
material.opacity = property.properties.at(index).value<double>();
|
material.opacity = property.properties.at(index).value<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sting Ray Material Properties!!!!
|
// Sting Ray Material Properties!!!!
|
||||||
else if (property.properties.at(0) == "Maya|use_normal_map") {
|
else if (property.properties.at(0) == MAYA_USE_NORMAL_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useNormalMap = (bool)property.properties.at(index).value<double>();
|
material.useNormalMap = (bool)property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|base_color") {
|
} else if (property.properties.at(0) == MAYA_BASE_COLOR) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.diffuseColor = getVec3(property.properties, index);
|
material.diffuseColor = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|use_color_map") {
|
} else if (property.properties.at(0) == MAYA_USE_COLOR_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useAlbedoMap = (bool) property.properties.at(index).value<double>();
|
material.useAlbedoMap = (bool) property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|roughness") {
|
} else if (property.properties.at(0) == MAYA_ROUGHNESS) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.roughness = property.properties.at(index).value<double>();
|
material.roughness = property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|use_roughness_map") {
|
} else if (property.properties.at(0) == MAYA_USE_ROUGHNESS_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useRoughnessMap = (bool)property.properties.at(index).value<double>();
|
material.useRoughnessMap = (bool)property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|metallic") {
|
} else if (property.properties.at(0) == MAYA_METALLIC) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.metallic = property.properties.at(index).value<double>();
|
material.metallic = property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|use_metallic_map") {
|
} else if (property.properties.at(0) == MAYA_USE_METALLIC_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useMetallicMap = (bool)property.properties.at(index).value<double>();
|
material.useMetallicMap = (bool)property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|emissive") {
|
} else if (property.properties.at(0) == MAYA_EMISSIVE) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.emissiveColor = getVec3(property.properties, index);
|
material.emissiveColor = getVec3(property.properties, index);
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|emissive_intensity") {
|
} else if (property.properties.at(0) == MAYA_EMISSIVE_INTENSITY) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.emissiveIntensity = property.properties.at(index).value<double>();
|
material.emissiveIntensity = property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|use_emissive_map") {
|
} else if (property.properties.at(0) == MAYA_USE_EMISSIVE_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useEmissiveMap = (bool)property.properties.at(index).value<double>();
|
material.useEmissiveMap = (bool)property.properties.at(index).value<double>();
|
||||||
|
|
||||||
} else if (property.properties.at(0) == "Maya|use_ao_map") {
|
} else if (property.properties.at(0) == MAYA_USE_AO_MAP) {
|
||||||
material.isPBSMaterial = true;
|
material.isPBSMaterial = true;
|
||||||
material.useOcclusionMap = (bool)property.properties.at(index).value<double>();
|
material.useOcclusionMap = (bool)property.properties.at(index).value<double>();
|
||||||
|
|
||||||
|
@ -1116,9 +1173,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (child.name == "Connections") {
|
} else if (child.name == "Connections") {
|
||||||
|
static const QVariant OO = QByteArray("OO");
|
||||||
|
static const QVariant OP = QByteArray("OP");
|
||||||
foreach (const FBXNode& connection, child.children) {
|
foreach (const FBXNode& connection, child.children) {
|
||||||
if (connection.name == "C" || connection.name == "Connect") {
|
if (connection.name == "C" || connection.name == "Connect") {
|
||||||
if (connection.properties.at(0) == "OO") {
|
if (connection.properties.at(0) == OO) {
|
||||||
QString childID = getID(connection.properties, 1);
|
QString childID = getID(connection.properties, 1);
|
||||||
QString parentID = getID(connection.properties, 2);
|
QString parentID = getID(connection.properties, 2);
|
||||||
ooChildToParent.insert(childID, parentID);
|
ooChildToParent.insert(childID, parentID);
|
||||||
|
@ -1132,8 +1191,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
_lightmapOffset = glm::clamp((*lightIt).second.color.x, 0.f, 1.f);
|
_lightmapOffset = glm::clamp((*lightIt).second.color.x, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (connection.properties.at(0) == OP) {
|
||||||
if (connection.properties.at(0) == "OP") {
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
QByteArray type = connection.properties.at(3).toByteArray().toLower();
|
QByteArray type = connection.properties.at(3).toByteArray().toLower();
|
||||||
if (type.contains("DiffuseFactor")) {
|
if (type.contains("DiffuseFactor")) {
|
||||||
|
|
|
@ -171,7 +171,8 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
QVector<int> materials;
|
QVector<int> materials;
|
||||||
QVector<int> textures;
|
QVector<int> textures;
|
||||||
bool isMaterialPerPolygon = false;
|
bool isMaterialPerPolygon = false;
|
||||||
|
static const QVariant BY_VERTICE = QByteArray("ByVertice");
|
||||||
|
static const QVariant INDEX_TO_DIRECT = QByteArray("IndexToDirect");
|
||||||
foreach (const FBXNode& child, object.children) {
|
foreach (const FBXNode& child, object.children) {
|
||||||
if (child.name == "Vertices") {
|
if (child.name == "Vertices") {
|
||||||
data.vertices = createVec3Vector(getDoubleVector(child));
|
data.vertices = createVec3Vector(getDoubleVector(child));
|
||||||
|
@ -189,10 +190,10 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
} else if (subdata.name == "NormalsIndex") {
|
} else if (subdata.name == "NormalsIndex") {
|
||||||
data.normalIndices = getIntVector(subdata);
|
data.normalIndices = getIntVector(subdata);
|
||||||
|
|
||||||
} else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") {
|
} else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == BY_VERTICE) {
|
||||||
data.normalsByVertex = true;
|
data.normalsByVertex = true;
|
||||||
|
|
||||||
} else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == "IndexToDirect") {
|
} else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == INDEX_TO_DIRECT) {
|
||||||
indexToDirect = true;
|
indexToDirect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,10 +210,10 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
} else if (subdata.name == "ColorsIndex") {
|
} else if (subdata.name == "ColorsIndex") {
|
||||||
data.colorIndices = getIntVector(subdata);
|
data.colorIndices = getIntVector(subdata);
|
||||||
|
|
||||||
} else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") {
|
} else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == BY_VERTICE) {
|
||||||
data.colorsByVertex = true;
|
data.colorsByVertex = true;
|
||||||
|
|
||||||
} else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == "IndexToDirect") {
|
} else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == INDEX_TO_DIRECT) {
|
||||||
indexToDirect = true;
|
indexToDirect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,11 +299,12 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (child.name == "LayerElementMaterial") {
|
} else if (child.name == "LayerElementMaterial") {
|
||||||
|
static const QVariant BY_POLYGON = QByteArray("ByPolygon");
|
||||||
foreach (const FBXNode& subdata, child.children) {
|
foreach (const FBXNode& subdata, child.children) {
|
||||||
if (subdata.name == "Materials") {
|
if (subdata.name == "Materials") {
|
||||||
materials = getIntVector(subdata);
|
materials = getIntVector(subdata);
|
||||||
} else if (subdata.name == "MappingInformationType") {
|
} else if (subdata.name == "MappingInformationType") {
|
||||||
if (subdata.properties.at(0) == "ByPolygon")
|
if (subdata.properties.at(0) == BY_POLYGON)
|
||||||
isMaterialPerPolygon = true;
|
isMaterialPerPolygon = true;
|
||||||
} else {
|
} else {
|
||||||
isMaterialPerPolygon = false;
|
isMaterialPerPolygon = false;
|
||||||
|
|
|
@ -43,6 +43,28 @@ template<class T> QVariant readBinaryArray(QDataStream& in, int& position) {
|
||||||
position += sizeof(quint32) * 3;
|
position += sizeof(quint32) * 3;
|
||||||
|
|
||||||
QVector<T> values;
|
QVector<T> values;
|
||||||
|
if ((int)QSysInfo::ByteOrder == (int)in.byteOrder()) {
|
||||||
|
values.resize(arrayLength);
|
||||||
|
const unsigned int DEFLATE_ENCODING = 1;
|
||||||
|
QByteArray arrayData;
|
||||||
|
if (encoding == DEFLATE_ENCODING) {
|
||||||
|
// preface encoded data with uncompressed length
|
||||||
|
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||||
|
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
||||||
|
in.readRawData(compressed.data() + sizeof(quint32), compressedLength);
|
||||||
|
position += compressedLength;
|
||||||
|
arrayData = qUncompress(compressed);
|
||||||
|
if (arrayData.isEmpty() || arrayData.size() != (sizeof(T) * arrayLength)) { // answers empty byte array if corrupt
|
||||||
|
throw QString("corrupt fbx file");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arrayData.resize(sizeof(T) * arrayLength);
|
||||||
|
position += sizeof(T) * arrayLength;
|
||||||
|
in.readRawData(arrayData.data(), arrayData.size());
|
||||||
|
}
|
||||||
|
memcpy(&values[0], arrayData.constData(), arrayData.size());
|
||||||
|
} else {
|
||||||
|
values.reserve(arrayLength);
|
||||||
const unsigned int DEFLATE_ENCODING = 1;
|
const unsigned int DEFLATE_ENCODING = 1;
|
||||||
if (encoding == DEFLATE_ENCODING) {
|
if (encoding == DEFLATE_ENCODING) {
|
||||||
// preface encoded data with uncompressed length
|
// preface encoded data with uncompressed length
|
||||||
|
@ -70,6 +92,7 @@ template<class T> QVariant readBinaryArray(QDataStream& in, int& position) {
|
||||||
values.append(value);
|
values.append(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return QVariant::fromValue(values);
|
return QVariant::fromValue(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,16 @@
|
||||||
|
|
||||||
#include <render/drawItemBounds_vert.h>
|
#include <render/drawItemBounds_vert.h>
|
||||||
#include <render/drawItemBounds_frag.h>
|
#include <render/drawItemBounds_frag.h>
|
||||||
|
#include "nop_frag.h"
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
extern void initForwardPipelines(ShapePlumber& plumber);
|
||||||
|
|
||||||
RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) {
|
RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) {
|
||||||
|
// Prepare the ShapePipelines
|
||||||
|
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||||
|
initForwardPipelines(*shapePlumber);
|
||||||
|
|
||||||
// Extract opaques / transparents / lights / overlays
|
// Extract opaques / transparents / lights / overlays
|
||||||
const auto opaques = items[0];
|
const auto opaques = items[0];
|
||||||
const auto transparents = items[1];
|
const auto transparents = items[1];
|
||||||
|
@ -40,16 +46,19 @@ RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) {
|
||||||
|
|
||||||
const auto framebuffer = addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
const auto framebuffer = addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
||||||
|
|
||||||
|
addJob<Draw>("DrawOpaques", opaques, shapePlumber);
|
||||||
|
addJob<Stencil>("Stencil");
|
||||||
addJob<DrawBackground>("DrawBackground", background);
|
addJob<DrawBackground>("DrawBackground", background);
|
||||||
|
|
||||||
// bounds do not draw on stencil buffer, so they must come last
|
// Bounds do not draw on stencil buffer, so they must come last
|
||||||
addJob<DrawBounds>("DrawBounds", opaques);
|
addJob<DrawBounds>("DrawBounds", opaques);
|
||||||
|
|
||||||
// Blit!
|
// Blit!
|
||||||
addJob<Blit>("Blit", framebuffer);
|
addJob<Blit>("Blit", framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) {
|
void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||||
|
gpu::FramebufferPointer& framebuffer) {
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
auto framebufferSize = framebufferCache->getFrameBufferSize();
|
auto framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
|
glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
|
||||||
|
@ -89,6 +98,88 @@ void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
framebuffer = _framebuffer;
|
framebuffer = _framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Draw::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||||
|
const Inputs& items) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
// Setup projection
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||||
|
args->getViewFrustum().evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
|
// Render items
|
||||||
|
renderStateSortShapes(sceneContext, renderContext, _shapePlumber, items, -1);
|
||||||
|
});
|
||||||
|
args->_batch = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpu::PipelinePointer Stencil::getPipeline() {
|
||||||
|
if (!_stencilPipeline) {
|
||||||
|
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
|
||||||
|
auto ps = gpu::Shader::createPixel(std::string(nop_frag));
|
||||||
|
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||||
|
gpu::Shader::makeProgram(*program);
|
||||||
|
|
||||||
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||||
|
const gpu::int8 STENCIL_OPAQUE = 1;
|
||||||
|
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS,
|
||||||
|
gpu::State::STENCIL_OP_REPLACE,
|
||||||
|
gpu::State::STENCIL_OP_REPLACE,
|
||||||
|
gpu::State::STENCIL_OP_KEEP));
|
||||||
|
|
||||||
|
_stencilPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
|
return _stencilPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stencil::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
batch.enableStereo(false);
|
||||||
|
batch.setViewportTransform(args->_viewport);
|
||||||
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
|
batch.setPipeline(getPipeline());
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
});
|
||||||
|
args->_batch = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||||
|
const Inputs& background) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
args->_batch = &batch;
|
||||||
|
|
||||||
|
batch.enableSkybox(true);
|
||||||
|
batch.setViewportTransform(args->_viewport);
|
||||||
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
|
// Setup projection
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||||
|
args->getViewFrustum().evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, background);
|
||||||
|
});
|
||||||
|
args->_batch = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const gpu::PipelinePointer DrawBounds::getPipeline() {
|
const gpu::PipelinePointer DrawBounds::getPipeline() {
|
||||||
if (!_boundsPipeline) {
|
if (!_boundsPipeline) {
|
||||||
auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
|
auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
|
||||||
|
@ -112,7 +203,8 @@ const gpu::PipelinePointer DrawBounds::getPipeline() {
|
||||||
return _boundsPipeline;
|
return _boundsPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBounds::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& items) {
|
void DrawBounds::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||||
|
const Inputs& items) {
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
@ -142,26 +234,3 @@ void DrawBounds::run(const SceneContextPointer& sceneContext, const RenderContex
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& items) {
|
|
||||||
RenderArgs* args = renderContext->args;
|
|
||||||
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
|
||||||
args->_batch = &batch;
|
|
||||||
|
|
||||||
batch.enableSkybox(true);
|
|
||||||
batch.setViewportTransform(args->_viewport);
|
|
||||||
batch.setStateScissorRect(args->_viewport);
|
|
||||||
|
|
||||||
// Setup projection
|
|
||||||
glm::mat4 projMat;
|
|
||||||
Transform viewMat;
|
|
||||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
|
||||||
args->getViewFrustum().evalViewTransform(viewMat);
|
|
||||||
batch.setProjectionTransform(projMat);
|
|
||||||
batch.setViewTransform(viewMat);
|
|
||||||
|
|
||||||
renderItems(sceneContext, renderContext, items);
|
|
||||||
});
|
|
||||||
args->_batch = nullptr;
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,20 +25,62 @@ public:
|
||||||
|
|
||||||
class PrepareFramebuffer {
|
class PrepareFramebuffer {
|
||||||
public:
|
public:
|
||||||
using JobModel = render::Job::ModelO<PrepareFramebuffer, gpu::FramebufferPointer>;
|
using Inputs = gpu::FramebufferPointer;
|
||||||
|
using JobModel = render::Job::ModelO<PrepareFramebuffer, Inputs>;
|
||||||
|
|
||||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer);
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||||
|
gpu::FramebufferPointer& framebuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpu::FramebufferPointer _framebuffer;
|
gpu::FramebufferPointer _framebuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawBounds {
|
class Draw {
|
||||||
public:
|
public:
|
||||||
using Inputs = render::ItemBounds;
|
using Inputs = render::ItemBounds;
|
||||||
using JobModel = render::Job::ModelI<DrawBounds, Inputs>;
|
using JobModel = render::Job::ModelI<Draw, Inputs>;
|
||||||
|
|
||||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& items);
|
Draw(const render::ShapePlumberPointer& shapePlumber) : _shapePlumber(shapePlumber) {}
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||||
|
const Inputs& items);
|
||||||
|
|
||||||
|
private:
|
||||||
|
render::ShapePlumberPointer _shapePlumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Stencil {
|
||||||
|
public:
|
||||||
|
using JobModel = render::Job::Model<Stencil>;
|
||||||
|
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const gpu::PipelinePointer getPipeline();
|
||||||
|
gpu::PipelinePointer _stencilPipeline;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawBackground {
|
||||||
|
public:
|
||||||
|
using Inputs = render::ItemBounds;
|
||||||
|
using JobModel = render::Job::ModelI<DrawBackground, Inputs>;
|
||||||
|
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||||
|
const Inputs& background);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawBounds {
|
||||||
|
public:
|
||||||
|
class Config : public render::JobConfig {
|
||||||
|
public:
|
||||||
|
Config() : JobConfig(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Inputs = render::ItemBounds;
|
||||||
|
using JobModel = render::Job::ModelI<DrawBounds, Inputs, Config>;
|
||||||
|
|
||||||
|
void configure(const Config& configuration) {}
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||||
|
const Inputs& items);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const gpu::PipelinePointer getPipeline();
|
const gpu::PipelinePointer getPipeline();
|
||||||
|
@ -47,12 +89,4 @@ private:
|
||||||
int _scaleLocation { -1 };
|
int _scaleLocation { -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawBackground {
|
|
||||||
public:
|
|
||||||
using Inputs = render::ItemBounds;
|
|
||||||
using JobModel = render::Job::ModelI<DrawBackground, Inputs>;
|
|
||||||
|
|
||||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& background);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_RenderForwardTask_h
|
#endif // hifi_RenderForwardTask_h
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
#include <gpu/StandardShaderLib.h>
|
#include <gpu/StandardShaderLib.h>
|
||||||
|
|
||||||
|
@ -47,41 +49,17 @@
|
||||||
|
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
gpu::BufferView getDefaultMaterialBuffer() {
|
void initOverlay3DPipelines(ShapePlumber& plumber);
|
||||||
model::Material::Schema schema;
|
void initDeferredPipelines(ShapePlumber& plumber);
|
||||||
schema._albedo = vec3(1.0f);
|
void initForwardPipelines(ShapePlumber& plumber);
|
||||||
schema._opacity = 1.0f;
|
|
||||||
schema._metallic = 0.1f;
|
|
||||||
schema._roughness = 0.9f;
|
|
||||||
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
|
|
||||||
}
|
|
||||||
|
|
||||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
void addPlumberPipeline(ShapePlumber& plumber,
|
||||||
// Set a default albedo map
|
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel);
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
|
||||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
|
||||||
// Set a default normal map
|
|
||||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
|
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
|
||||||
|
|
||||||
// Set a default material
|
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch);
|
||||||
if (pipeline.locations->materialBufferUnit >= 0) {
|
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch);
|
||||||
static const gpu::BufferView OPAQUE_SCHEMA_BUFFER = getDefaultMaterialBuffer();
|
|
||||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, OPAQUE_SCHEMA_BUFFER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
|
||||||
batchSetter(pipeline, batch);
|
|
||||||
// Set the light
|
|
||||||
if (pipeline.locations->lightBufferUnit >= 0) {
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(batch,
|
|
||||||
pipeline.locations->lightBufferUnit,
|
|
||||||
pipeline.locations->lightAmbientBufferUnit,
|
|
||||||
pipeline.locations->lightAmbientMapUnit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initOverlay3DPipelines(ShapePlumber& plumber) {
|
void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||||
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
||||||
|
@ -130,50 +108,6 @@ void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initDeferredPipelines(render::ShapePlumber& plumber) {
|
void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
using Key = render::ShapeKey;
|
|
||||||
using ShaderPointer = gpu::ShaderPointer;
|
|
||||||
|
|
||||||
auto addPipeline = [&plumber](const Key& key, const ShaderPointer& vertexShader, const ShaderPointer& pixelShader) {
|
|
||||||
// These keyvalues' pipelines will be added by this lamdba in addition to the key passed
|
|
||||||
assert(!key.isWireFrame());
|
|
||||||
assert(!key.isDepthBiased());
|
|
||||||
assert(key.isCullFace());
|
|
||||||
|
|
||||||
ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
bool isCulled = (i & 1);
|
|
||||||
bool isBiased = (i & 2);
|
|
||||||
bool isWireframed = (i & 4);
|
|
||||||
|
|
||||||
ShapeKey::Builder builder(key);
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
|
||||||
|
|
||||||
// Depth test depends on transparency
|
|
||||||
state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
|
||||||
state->setBlendFunction(key.isTranslucent(),
|
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
|
||||||
|
|
||||||
if (!isCulled) {
|
|
||||||
builder.withoutCullFace();
|
|
||||||
}
|
|
||||||
state->setCullMode(isCulled ? gpu::State::CULL_BACK : gpu::State::CULL_NONE);
|
|
||||||
if (isWireframed) {
|
|
||||||
builder.withWireframe();
|
|
||||||
state->setFillMode(gpu::State::FILL_LINE);
|
|
||||||
}
|
|
||||||
if (isBiased) {
|
|
||||||
builder.withDepthBias();
|
|
||||||
state->setDepthBias(1.0f);
|
|
||||||
state->setDepthBiasSlopeScale(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
plumber.addPipeline(builder.build(), program, state,
|
|
||||||
key.isTranslucent() ? &lightBatchSetter : &batchSetter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Vertex shaders
|
// Vertex shaders
|
||||||
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
||||||
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
||||||
|
@ -198,6 +132,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
||||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||||
|
|
||||||
|
using Key = render::ShapeKey;
|
||||||
|
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3);
|
||||||
// TODO: Refactor this to use a filter
|
// TODO: Refactor this to use a filter
|
||||||
// Opaques
|
// Opaques
|
||||||
addPipeline(
|
addPipeline(
|
||||||
|
@ -281,5 +217,132 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withDepthOnly(),
|
Key::Builder().withSkinned().withDepthOnly(),
|
||||||
skinModelShadowVertex, modelShadowPixel);
|
skinModelShadowVertex, modelShadowPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initForwardPipelines(render::ShapePlumber& plumber) {
|
||||||
|
// Vertex shaders
|
||||||
|
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
||||||
|
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
||||||
|
auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
|
||||||
|
auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
|
||||||
|
|
||||||
|
// Pixel shaders
|
||||||
|
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
||||||
|
auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag));
|
||||||
|
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
||||||
|
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
||||||
|
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
||||||
|
|
||||||
|
using Key = render::ShapeKey;
|
||||||
|
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3);
|
||||||
|
// Opaques
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder(),
|
||||||
|
modelVertex, modelPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withUnlit(),
|
||||||
|
modelVertex, modelUnlitPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withTangents(),
|
||||||
|
modelNormalMapVertex, modelNormalMapPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withSpecular(),
|
||||||
|
modelVertex, modelSpecularMapPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withTangents().withSpecular(),
|
||||||
|
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
// Skinned
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withSkinned(),
|
||||||
|
skinModelVertex, modelPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withSkinned().withTangents(),
|
||||||
|
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withSkinned().withSpecular(),
|
||||||
|
skinModelVertex, modelSpecularMapPixel);
|
||||||
|
addPipeline(
|
||||||
|
Key::Builder().withSkinned().withTangents().withSpecular(),
|
||||||
|
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPlumberPipeline(ShapePlumber& plumber,
|
||||||
|
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel) {
|
||||||
|
// These key-values' pipelines are added by this functor in addition to the key passed
|
||||||
|
assert(!key.isWireFrame());
|
||||||
|
assert(!key.isDepthBiased());
|
||||||
|
assert(key.isCullFace());
|
||||||
|
|
||||||
|
gpu::ShaderPointer program = gpu::Shader::createProgram(vertex, pixel);
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
bool isCulled = (i & 1);
|
||||||
|
bool isBiased = (i & 2);
|
||||||
|
bool isWireframed = (i & 4);
|
||||||
|
|
||||||
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
|
||||||
|
// Depth test depends on transparency
|
||||||
|
state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
||||||
|
state->setBlendFunction(key.isTranslucent(),
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
|
||||||
|
ShapeKey::Builder builder(key);
|
||||||
|
if (!isCulled) {
|
||||||
|
builder.withoutCullFace();
|
||||||
|
}
|
||||||
|
state->setCullMode(isCulled ? gpu::State::CULL_BACK : gpu::State::CULL_NONE);
|
||||||
|
if (isWireframed) {
|
||||||
|
builder.withWireframe();
|
||||||
|
state->setFillMode(gpu::State::FILL_LINE);
|
||||||
|
}
|
||||||
|
if (isBiased) {
|
||||||
|
builder.withDepthBias();
|
||||||
|
state->setDepthBias(1.0f);
|
||||||
|
state->setDepthBiasSlopeScale(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
plumber.addPipeline(builder.build(), program, state,
|
||||||
|
key.isTranslucent() ? &lightBatchSetter : &batchSetter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||||
|
// Set a default albedo map
|
||||||
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
|
||||||
|
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
|
// Set a default normal map
|
||||||
|
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
|
||||||
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
|
|
||||||
|
// Set a default material
|
||||||
|
if (pipeline.locations->materialBufferUnit >= 0) {
|
||||||
|
// Create a default schema
|
||||||
|
static bool isMaterialSet = false;
|
||||||
|
static model::Material material;
|
||||||
|
if (!isMaterialSet) {
|
||||||
|
material.setAlbedo(vec3(1.0f));
|
||||||
|
material.setOpacity(1.0f);
|
||||||
|
material.setMetallic(0.1f);
|
||||||
|
material.setRoughness(0.9f);
|
||||||
|
isMaterialSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a default schema
|
||||||
|
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, material.getSchemaBuffer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||||
|
// Set the batch
|
||||||
|
batchSetter(pipeline, batch);
|
||||||
|
|
||||||
|
// Set the light
|
||||||
|
if (pipeline.locations->lightBufferUnit >= 0) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(batch,
|
||||||
|
pipeline.locations->lightBufferUnit,
|
||||||
|
pipeline.locations->lightAmbientBufferUnit,
|
||||||
|
pipeline.locations->lightAmbientMapUnit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
16
libraries/render-utils/src/nop.slf
Normal file
16
libraries/render-utils/src/nop.slf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// nop.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Zach Pomerantz on 1/3/2017.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
}
|
|
@ -371,6 +371,7 @@ protected:
|
||||||
class JobConfig : public QObject {
|
class JobConfig : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms
|
Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms
|
||||||
|
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
|
||||||
|
|
||||||
double _msCPURunTime{ 0.0 };
|
double _msCPURunTime{ 0.0 };
|
||||||
public:
|
public:
|
||||||
|
@ -380,7 +381,7 @@ public:
|
||||||
JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {}
|
JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {}
|
||||||
|
|
||||||
bool isEnabled() { return alwaysEnabled || enabled; }
|
bool isEnabled() { return alwaysEnabled || enabled; }
|
||||||
void setEnabled(bool enable) { enabled = enable; }
|
void setEnabled(bool enable) { enabled = alwaysEnabled || enable; }
|
||||||
|
|
||||||
bool alwaysEnabled{ true };
|
bool alwaysEnabled{ true };
|
||||||
bool enabled{ true };
|
bool enabled{ true };
|
||||||
|
|
Loading…
Reference in a new issue