mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 04:15:14 +02:00
Integrate the PR from ALessandro through a different Texture Type and a different TextureLoader to transform a bump map into a normal map
This commit is contained in:
parent
3614812681
commit
6a714f405c
8 changed files with 168 additions and 335 deletions
|
@ -1080,9 +1080,10 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
|
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
|
||||||
// THis is how Maya assign a texture that affect diffuse color AND transparency ?
|
// THis is how Maya assign a texture that affect diffuse color AND transparency ?
|
||||||
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
} else if (type.contains("bump") || type.contains("normal")) {
|
} else if (type.contains("bump")) {
|
||||||
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
} else if (type.contains("normal")) {
|
||||||
|
normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
} else if (type.contains("specular") || type.contains("reflection")) {
|
} else if (type.contains("specular") || type.contains("reflection")) {
|
||||||
specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,9 @@ public:
|
||||||
Transform transform;
|
Transform transform;
|
||||||
int texcoordSet;
|
int texcoordSet;
|
||||||
QString texcoordSetName;
|
QString texcoordSetName;
|
||||||
|
|
||||||
|
bool isBumpmap{ false };
|
||||||
|
|
||||||
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
|
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -394,6 +396,7 @@ public:
|
||||||
|
|
||||||
QHash<QString, QString> diffuseTextures;
|
QHash<QString, QString> diffuseTextures;
|
||||||
QHash<QString, QString> bumpTextures;
|
QHash<QString, QString> bumpTextures;
|
||||||
|
QHash<QString, QString> normalTextures;
|
||||||
QHash<QString, QString> specularTextures;
|
QHash<QString, QString> specularTextures;
|
||||||
QHash<QString, QString> emissiveTextures;
|
QHash<QString, QString> emissiveTextures;
|
||||||
QHash<QString, QString> ambientTextures;
|
QHash<QString, QString> ambientTextures;
|
||||||
|
|
|
@ -86,13 +86,21 @@ void FBXReader::consolidateFBXMaterials() {
|
||||||
|
|
||||||
FBXTexture normalTexture;
|
FBXTexture normalTexture;
|
||||||
QString bumpTextureID = bumpTextures.value(material.materialID);
|
QString bumpTextureID = bumpTextures.value(material.materialID);
|
||||||
if (!bumpTextureID.isNull()) {
|
QString normalTextureID = normalTextures.value(material.materialID);
|
||||||
normalTexture = getTexture(bumpTextureID);
|
if (!normalTextureID.isNull()) {
|
||||||
|
normalTexture = getTexture(normalTextureID);
|
||||||
|
normalTexture.isBumpmap = false;
|
||||||
|
|
||||||
|
material.normalTexture = normalTexture;
|
||||||
|
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||||
|
} else if (!bumpTextureID.isNull()) {
|
||||||
|
normalTexture = getTexture(bumpTextureID);
|
||||||
|
normalTexture.isBumpmap = true;
|
||||||
|
|
||||||
material.normalTexture = normalTexture;
|
material.normalTexture = normalTexture;
|
||||||
|
|
||||||
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FBXTexture specularTexture;
|
FBXTexture specularTexture;
|
||||||
QString specularTextureID = specularTextures.value(material.materialID);
|
QString specularTextureID = specularTextures.value(material.materialID);
|
||||||
|
|
|
@ -182,11 +182,10 @@ Texture::~Texture() {
|
||||||
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
|
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
|
||||||
Resource(url, !content.isEmpty()),
|
Resource(url, !content.isEmpty()),
|
||||||
_type(type),
|
_type(type),
|
||||||
_translucent(false),
|
|
||||||
_width(0),
|
_width(0),
|
||||||
_height(0) {
|
_height(0) {
|
||||||
|
|
||||||
_textureStorage.reset(new model::TextureStorage());
|
_textureSource.reset(new model::TextureSource());
|
||||||
|
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
_loaded = true;
|
_loaded = true;
|
||||||
|
@ -202,13 +201,12 @@ NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArr
|
||||||
|
|
||||||
NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content) :
|
NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content) :
|
||||||
Resource(url, !content.isEmpty()),
|
Resource(url, !content.isEmpty()),
|
||||||
// _type(type),
|
_type(CUSTOM_TEXTURE),
|
||||||
_textureLoader(textureLoader),
|
_textureLoader(textureLoader),
|
||||||
_translucent(false),
|
|
||||||
_width(0),
|
_width(0),
|
||||||
_height(0) {
|
_height(0) {
|
||||||
|
|
||||||
_textureStorage.reset(new model::TextureStorage());
|
_textureSource.reset(new model::TextureSource());
|
||||||
|
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
_loaded = true;
|
_loaded = true;
|
||||||
|
@ -223,11 +221,27 @@ NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& texture
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
||||||
if (_type != CUBE_TEXTURE) {
|
switch (_type) {
|
||||||
|
case CUBE_TEXTURE: {
|
||||||
return TextureLoaderFunc(model::TextureStorage::create2DTextureFromImage);
|
return TextureLoaderFunc(model::TextureSource::createCubeTextureFromImage);
|
||||||
} else {
|
break;
|
||||||
return TextureLoaderFunc(model::TextureStorage::createCubeTextureFromImage);
|
}
|
||||||
|
case BUMP_TEXTURE: {
|
||||||
|
return TextureLoaderFunc(model::TextureSource::createNormalTextureFromBumpImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CUSTOM_TEXTURE: {
|
||||||
|
return _textureLoader;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEFAULT_TEXTURE:
|
||||||
|
case NORMAL_TEXTURE:
|
||||||
|
case SPECULAR_TEXTURE:
|
||||||
|
case EMISSIVE_TEXTURE:
|
||||||
|
default: {
|
||||||
|
return TextureLoaderFunc(model::TextureSource::create2DTextureFromImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,42 +292,6 @@ void listSupportedImageFormats() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class CubeLayout {
|
|
||||||
public:
|
|
||||||
int _widthRatio = 1;
|
|
||||||
int _heightRatio = 1;
|
|
||||||
|
|
||||||
class Face {
|
|
||||||
public:
|
|
||||||
int _x = 0;
|
|
||||||
int _y = 0;
|
|
||||||
bool _horizontalMirror = false;
|
|
||||||
bool _verticalMirror = false;
|
|
||||||
|
|
||||||
Face() {}
|
|
||||||
Face(int x, int y, bool horizontalMirror, bool verticalMirror) : _x(x), _y(y), _horizontalMirror(horizontalMirror), _verticalMirror(verticalMirror) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Face _faceXPos;
|
|
||||||
Face _faceXNeg;
|
|
||||||
Face _faceYPos;
|
|
||||||
Face _faceYNeg;
|
|
||||||
Face _faceZPos;
|
|
||||||
Face _faceZNeg;
|
|
||||||
|
|
||||||
CubeLayout(int wr, int hr, Face fXP, Face fXN, Face fYP, Face fYN, Face fZP, Face fZN) :
|
|
||||||
_widthRatio(wr),
|
|
||||||
_heightRatio(hr),
|
|
||||||
_faceXPos(fXP),
|
|
||||||
_faceXNeg(fXN),
|
|
||||||
_faceYPos(fYP),
|
|
||||||
_faceYNeg(fYN),
|
|
||||||
_faceZPos(fZP),
|
|
||||||
_faceZNeg(fZN) {}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ImageReader::run() {
|
void ImageReader::run() {
|
||||||
QSharedPointer<Resource> texture = _texture.toStrongRef();
|
QSharedPointer<Resource> texture = _texture.toStrongRef();
|
||||||
if (texture.isNull()) {
|
if (texture.isNull()) {
|
||||||
|
@ -347,259 +325,25 @@ void ImageReader::run() {
|
||||||
if (ntex) {
|
if (ntex) {
|
||||||
theTexture = ntex->getTextureLoader()(image, _url.toString().toStdString());
|
theTexture = ntex->getTextureLoader()(image, _url.toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int imageArea = image.width() * image.height();
|
|
||||||
|
|
||||||
gpu::Texture* theTexture = nullptr;
|
|
||||||
|
|
||||||
if (ntex && (ntex->getType() == CUBE_TEXTURE)) {
|
|
||||||
qCDebug(gpunetwork) << "Cube map size:" << _url << image.width() << image.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
int opaquePixels = 0;
|
|
||||||
int translucentPixels = 0;
|
|
||||||
bool isTransparent = false;
|
|
||||||
int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0;
|
|
||||||
const int EIGHT_BIT_MAXIMUM = 255;
|
|
||||||
QColor averageColor(EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM);
|
|
||||||
|
|
||||||
if (!image.hasAlphaChannel()) {
|
|
||||||
if (image.format() != QImage::Format_RGB888) {
|
|
||||||
image = image.convertToFormat(QImage::Format_RGB888);
|
|
||||||
}
|
|
||||||
// int redTotal = 0, greenTotal = 0, blueTotal = 0;
|
|
||||||
for (int y = 0; y < image.height(); y++) {
|
|
||||||
for (int x = 0; x < image.width(); x++) {
|
|
||||||
QRgb rgb = image.pixel(x, y);
|
|
||||||
redTotal += qRed(rgb);
|
|
||||||
greenTotal += qGreen(rgb);
|
|
||||||
blueTotal += qBlue(rgb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (imageArea > 0) {
|
|
||||||
averageColor.setRgb(redTotal / imageArea, greenTotal / imageArea, blueTotal / imageArea);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (image.format() != QImage::Format_ARGB32) {
|
|
||||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for translucency/false transparency
|
|
||||||
// int opaquePixels = 0;
|
|
||||||
// int translucentPixels = 0;
|
|
||||||
// int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0;
|
|
||||||
for (int y = 0; y < image.height(); y++) {
|
|
||||||
for (int x = 0; x < image.width(); x++) {
|
|
||||||
QRgb rgb = image.pixel(x, y);
|
|
||||||
redTotal += qRed(rgb);
|
|
||||||
greenTotal += qGreen(rgb);
|
|
||||||
blueTotal += qBlue(rgb);
|
|
||||||
int alpha = qAlpha(rgb);
|
|
||||||
alphaTotal += alpha;
|
|
||||||
if (alpha == EIGHT_BIT_MAXIMUM) {
|
|
||||||
opaquePixels++;
|
|
||||||
} else if (alpha != 0) {
|
|
||||||
translucentPixels++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (opaquePixels == imageArea) {
|
|
||||||
qCDebug(gpunetwork) << "Image with alpha channel is completely opaque:" << _url;
|
|
||||||
image = image.convertToFormat(QImage::Format_RGB888);
|
|
||||||
}
|
|
||||||
|
|
||||||
averageColor = QColor(redTotal / imageArea,
|
|
||||||
greenTotal / imageArea, blueTotal / imageArea, alphaTotal / imageArea);
|
|
||||||
|
|
||||||
isTransparent = (translucentPixels >= imageArea / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpu::Texture* theTexture = nullptr;
|
|
||||||
if ((image.width() > 0) && (image.height() > 0)) {
|
|
||||||
|
|
||||||
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
|
||||||
bool isLinearRGB = !(_type == CUBE_TEXTURE); //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
|
||||||
|
|
||||||
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
|
||||||
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
|
||||||
if (image.hasAlphaChannel()) {
|
|
||||||
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
|
|
||||||
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_type == CUBE_TEXTURE) {
|
|
||||||
|
|
||||||
const CubeLayout CUBEMAP_LAYOUTS[] = {
|
|
||||||
// Here is the expected layout for the faces in an image with the 1/6 aspect ratio:
|
|
||||||
//
|
|
||||||
// WIDTH
|
|
||||||
// <------>
|
|
||||||
// ^ +------+
|
|
||||||
// | | |
|
|
||||||
// | | +X |
|
|
||||||
// | | |
|
|
||||||
// H +------+
|
|
||||||
// E | |
|
|
||||||
// I | -X |
|
|
||||||
// G | |
|
|
||||||
// H +------+
|
|
||||||
// T | |
|
|
||||||
// | | +Y |
|
|
||||||
// | | |
|
|
||||||
// | +------+
|
|
||||||
// | | |
|
|
||||||
// | | -Y |
|
|
||||||
// | | |
|
|
||||||
// H +------+
|
|
||||||
// E | |
|
|
||||||
// I | +Z |
|
|
||||||
// G | |
|
|
||||||
// H +------+
|
|
||||||
// T | |
|
|
||||||
// | | -Z |
|
|
||||||
// | | |
|
|
||||||
// V +------+
|
|
||||||
//
|
|
||||||
// FaceWidth = width = height / 6
|
|
||||||
{ 1, 6,
|
|
||||||
{0, 0, true, false},
|
|
||||||
{0, 1, true, false},
|
|
||||||
{0, 2, false, true},
|
|
||||||
{0, 3, false, true},
|
|
||||||
{0, 4, true, false},
|
|
||||||
{0, 5, true, false}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Here is the expected layout for the faces in an image with the 3/4 aspect ratio:
|
|
||||||
//
|
|
||||||
// <-----------WIDTH----------->
|
|
||||||
// ^ +------+------+------+------+
|
|
||||||
// | | | | | |
|
|
||||||
// | | | +Y | | |
|
|
||||||
// | | | | | |
|
|
||||||
// H +------+------+------+------+
|
|
||||||
// E | | | | |
|
|
||||||
// I | -X | -Z | +X | +Z |
|
|
||||||
// G | | | | |
|
|
||||||
// H +------+------+------+------+
|
|
||||||
// T | | | | |
|
|
||||||
// | | | -Y | | |
|
|
||||||
// | | | | | |
|
|
||||||
// V +------+------+------+------+
|
|
||||||
//
|
|
||||||
// FaceWidth = width / 4 = height / 3
|
|
||||||
{ 4, 3,
|
|
||||||
{2, 1, true, false},
|
|
||||||
{0, 1, true, false},
|
|
||||||
{1, 0, false, true},
|
|
||||||
{1, 2, false, true},
|
|
||||||
{3, 1, true, false},
|
|
||||||
{1, 1, true, false}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Here is the expected layout for the faces in an image with the 4/3 aspect ratio:
|
|
||||||
//
|
|
||||||
// <-------WIDTH-------->
|
|
||||||
// ^ +------+------+------+
|
|
||||||
// | | | | |
|
|
||||||
// | | | +Y | |
|
|
||||||
// | | | | |
|
|
||||||
// H +------+------+------+
|
|
||||||
// E | | | |
|
|
||||||
// I | -X | -Z | +X |
|
|
||||||
// G | | | |
|
|
||||||
// H +------+------+------+
|
|
||||||
// T | | | |
|
|
||||||
// | | | -Y | |
|
|
||||||
// | | | | |
|
|
||||||
// | +------+------+------+
|
|
||||||
// | | | | |
|
|
||||||
// | | | +Z! | | <+Z is upside down!
|
|
||||||
// | | | | |
|
|
||||||
// V +------+------+------+
|
|
||||||
//
|
|
||||||
// FaceWidth = width / 3 = height / 4
|
|
||||||
{ 3, 4,
|
|
||||||
{2, 1, true, false},
|
|
||||||
{0, 1, true, false},
|
|
||||||
{1, 0, false, true},
|
|
||||||
{1, 2, false, true},
|
|
||||||
{1, 3, false, true},
|
|
||||||
{1, 1, true, false}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const int NUM_CUBEMAP_LAYOUTS = sizeof(CUBEMAP_LAYOUTS) / sizeof(CubeLayout);
|
|
||||||
|
|
||||||
// Find the layout of the cubemap in the 2D image
|
|
||||||
int foundLayout = -1;
|
|
||||||
for (int i = 0; i < NUM_CUBEMAP_LAYOUTS; i++) {
|
|
||||||
if ((image.height() * CUBEMAP_LAYOUTS[i]._widthRatio) == (image.width() * CUBEMAP_LAYOUTS[i]._heightRatio)) {
|
|
||||||
foundLayout = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QImage> faces;
|
|
||||||
// If found, go extract the faces as separate images
|
|
||||||
if (foundLayout >= 0) {
|
|
||||||
auto& layout = CUBEMAP_LAYOUTS[foundLayout];
|
|
||||||
int faceWidth = image.width() / layout._widthRatio;
|
|
||||||
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceXPos._x * faceWidth, layout._faceXPos._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceXPos._horizontalMirror, layout._faceXPos._verticalMirror));
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceXNeg._x * faceWidth, layout._faceXNeg._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceXNeg._horizontalMirror, layout._faceXNeg._verticalMirror));
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceYPos._x * faceWidth, layout._faceYPos._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceYPos._horizontalMirror, layout._faceYPos._verticalMirror));
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceYNeg._x * faceWidth, layout._faceYNeg._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceYNeg._horizontalMirror, layout._faceYNeg._verticalMirror));
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceZPos._x * faceWidth, layout._faceZPos._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZPos._horizontalMirror, layout._faceZPos._verticalMirror));
|
|
||||||
faces.push_back(image.copy(QRect(layout._faceZNeg._x * faceWidth, layout._faceZNeg._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZNeg._horizontalMirror, layout._faceZNeg._verticalMirror));
|
|
||||||
} else {
|
|
||||||
qCDebug(gpunetwork) << "Failed to find a known cube map layout from this image:" << _url;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the 6 faces have been created go on and define the true Texture
|
|
||||||
if (faces.size() == gpu::Texture::NUM_FACES_PER_TYPE[gpu::Texture::TEX_CUBE]) {
|
|
||||||
theTexture = gpu::Texture::createCube(formatGPU, faces[0].width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
|
||||||
theTexture->autoGenerateMips(-1);
|
|
||||||
int f = 0;
|
|
||||||
for (auto& face : faces) {
|
|
||||||
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
|
|
||||||
f++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GEnerate irradiance while we are at it
|
|
||||||
theTexture->generateIrradiance();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
|
||||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
|
||||||
theTexture->autoGenerateMips(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
QMetaObject::invokeMethod(texture.data(), "setImage",
|
QMetaObject::invokeMethod(texture.data(), "setImage",
|
||||||
Q_ARG(const QImage&, image),
|
Q_ARG(const QImage&, image),
|
||||||
Q_ARG(void*, theTexture),
|
Q_ARG(void*, theTexture),
|
||||||
// Q_ARG(bool, isTransparent),
|
|
||||||
// Q_ARG(const QColor&, averageColor),
|
|
||||||
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::setImage(const QImage& image, void* voidTexture,/* bool translucent, const QColor& averageColor, */ int originalWidth,
|
void NetworkTexture::setImage(const QImage& image, void* voidTexture, int originalWidth,
|
||||||
int originalHeight) {
|
int originalHeight) {
|
||||||
// _translucent = translucent;
|
|
||||||
// _averageColor = averageColor;
|
|
||||||
_originalWidth = originalWidth;
|
_originalWidth = originalWidth;
|
||||||
_originalHeight = originalHeight;
|
_originalHeight = originalHeight;
|
||||||
|
|
||||||
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
||||||
|
|
||||||
// Passing ownership
|
// Passing ownership
|
||||||
// _gpuTexture.reset(texture);
|
_textureSource->resetTexture(texture);
|
||||||
_textureStorage->resetTexture(texture);
|
auto gpuTexture = _textureSource->getGPUTexture();
|
||||||
auto gpuTexture = _textureStorage->getGPUTexture();
|
|
||||||
|
|
||||||
if (gpuTexture) {
|
if (gpuTexture) {
|
||||||
_width = gpuTexture->getWidth();
|
_width = gpuTexture->getWidth();
|
||||||
|
|
|
@ -29,7 +29,7 @@ class NetworkTexture;
|
||||||
|
|
||||||
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
||||||
|
|
||||||
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE, CUBE_TEXTURE };
|
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, CUSTOM_TEXTURE };
|
||||||
|
|
||||||
/// Stores cached textures, including render-to-texture targets.
|
/// Stores cached textures, including render-to-texture targets.
|
||||||
class TextureCache : public ResourceCache, public Dependency {
|
class TextureCache : public ResourceCache, public Dependency {
|
||||||
|
@ -97,9 +97,8 @@ public:
|
||||||
Texture();
|
Texture();
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
//const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
|
const gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); }
|
||||||
const gpu::TexturePointer getGPUTexture() const { return _textureStorage->getGPUTexture(); }
|
model::TextureSourcePointer _textureSource;
|
||||||
model::TextureStoragePointer _textureStorage;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -118,18 +117,10 @@ public:
|
||||||
NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content);
|
NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content);
|
||||||
NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content);
|
NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content);
|
||||||
|
|
||||||
/// Checks whether it "looks like" this texture is translucent
|
|
||||||
/// (majority of pixels neither fully opaque or fully transparent).
|
|
||||||
// bool isTranslucent() const { return _translucent; }
|
|
||||||
|
|
||||||
/// Returns the lazily-computed average texture color.
|
|
||||||
// const QColor& getAverageColor() const { return _averageColor; }
|
|
||||||
|
|
||||||
int getOriginalWidth() const { return _originalWidth; }
|
int getOriginalWidth() const { return _originalWidth; }
|
||||||
int getOriginalHeight() const { return _originalHeight; }
|
int getOriginalHeight() const { return _originalHeight; }
|
||||||
int getWidth() const { return _width; }
|
int getWidth() const { return _width; }
|
||||||
int getHeight() const { return _height; }
|
int getHeight() const { return _height; }
|
||||||
// TextureType getType() const { return _type; }
|
|
||||||
|
|
||||||
TextureLoaderFunc getTextureLoader() const;
|
TextureLoaderFunc getTextureLoader() const;
|
||||||
|
|
||||||
|
@ -139,8 +130,7 @@ protected:
|
||||||
|
|
||||||
Q_INVOKABLE void loadContent(const QByteArray& content);
|
Q_INVOKABLE void loadContent(const QByteArray& content);
|
||||||
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
||||||
Q_INVOKABLE void setImage(const QImage& image, void* texture, /*bool translucent, const QColor& averageColor, */int originalWidth,
|
Q_INVOKABLE void setImage(const QImage& image, void* texture, int originalWidth, int originalHeight);
|
||||||
int originalHeight);
|
|
||||||
|
|
||||||
virtual void imageLoaded(const QImage& image);
|
virtual void imageLoaded(const QImage& image);
|
||||||
|
|
||||||
|
@ -148,8 +138,6 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureLoaderFunc _textureLoader;
|
TextureLoaderFunc _textureLoader;
|
||||||
bool _translucent;
|
|
||||||
QColor _averageColor;
|
|
||||||
int _originalWidth;
|
int _originalWidth;
|
||||||
int _originalHeight;
|
int _originalHeight;
|
||||||
int _width;
|
int _width;
|
||||||
|
|
|
@ -19,25 +19,25 @@
|
||||||
using namespace model;
|
using namespace model;
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
// TextureStorage
|
// TextureSource
|
||||||
TextureStorage::TextureStorage()
|
TextureSource::TextureSource()
|
||||||
{/* : Texture::Storage()//,
|
{/* : Texture::Storage()//,
|
||||||
// _gpuTexture(Texture::createFromStorage(this))*/
|
// _gpuTexture(Texture::createFromStorage(this))*/
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureStorage::~TextureStorage() {
|
TextureSource::~TextureSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureStorage::reset(const QUrl& url, const TextureUsage& usage) {
|
void TextureSource::reset(const QUrl& url, const TextureUsage& usage) {
|
||||||
_imageUrl = url;
|
_imageUrl = url;
|
||||||
_usage = usage;
|
_usage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureStorage::resetTexture(gpu::Texture* texture) {
|
void TextureSource::resetTexture(gpu::Texture* texture) {
|
||||||
_gpuTexture.reset(texture);
|
_gpuTexture.reset(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureStorage::isDefined() const {
|
bool TextureSource::isDefined() const {
|
||||||
if (_gpuTexture) {
|
if (_gpuTexture) {
|
||||||
return _gpuTexture->isDefined();
|
return _gpuTexture->isDefined();
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,21 +46,21 @@ bool TextureStorage::isDefined() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureMap::setTextureStorage(TextureStoragePointer& texStorage) {
|
void TextureMap::setTextureSource(TextureSourcePointer& texStorage) {
|
||||||
_textureStorage = texStorage;
|
_textureSource = texStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureMap::isDefined() const {
|
bool TextureMap::isDefined() const {
|
||||||
if (_textureStorage) {
|
if (_textureSource) {
|
||||||
return _textureStorage->isDefined();
|
return _textureSource->isDefined();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::TextureView TextureMap::getTextureView() const {
|
gpu::TextureView TextureMap::getTextureView() const {
|
||||||
if (_textureStorage) {
|
if (_textureSource) {
|
||||||
return gpu::TextureView(_textureStorage->getGPUTexture(), 0);
|
return gpu::TextureView(_textureSource->getGPUTexture(), 0);
|
||||||
} else {
|
} else {
|
||||||
return gpu::TextureView();
|
return gpu::TextureView();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ void TextureMap::setLightmapOffsetScale(float offset, float scale) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gpu::Texture* TextureStorage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
gpu::Texture* TextureSource::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||||
QImage image = srcImage;
|
QImage image = srcImage;
|
||||||
|
|
||||||
int imageArea = image.width() * image.height();
|
int imageArea = image.width() * image.height();
|
||||||
|
@ -145,7 +145,7 @@ gpu::Texture* TextureStorage::create2DTextureFromImage(const QImage& srcImage, c
|
||||||
if ((image.width() > 0) && (image.height() > 0)) {
|
if ((image.width() > 0) && (image.height() > 0)) {
|
||||||
|
|
||||||
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
||||||
bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
||||||
|
|
||||||
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
||||||
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
||||||
|
@ -163,6 +163,94 @@ gpu::Texture* TextureStorage::create2DTextureFromImage(const QImage& srcImage, c
|
||||||
return theTexture;
|
return theTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int clampPixelCoordinate(int coordinate, int maxCoordinate) {
|
||||||
|
return coordinate - ((int)(coordinate < 0) * coordinate) + ((int)(coordinate > maxCoordinate) * (maxCoordinate - coordinate));
|
||||||
|
}
|
||||||
|
|
||||||
|
const int RGBA_MAX = 255;
|
||||||
|
|
||||||
|
// transform -1 - 1 to 0 - 255 (from sobel value to rgb)
|
||||||
|
double mapComponent(double sobelValue) {
|
||||||
|
const double factor = RGBA_MAX / 2.0;
|
||||||
|
return (sobelValue + 1.0) * factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::Texture* TextureSource::createNormalTextureFromBumpImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||||
|
QImage image = srcImage;
|
||||||
|
|
||||||
|
// PR 5540 by AlessandroSigna
|
||||||
|
// integrated here as a specialized TextureLoader for bumpmaps
|
||||||
|
// The conversion is done using the Sobel Filter to calculate the derivatives from the grayscale image
|
||||||
|
const double pStrength = 2.0;
|
||||||
|
int width = image.width();
|
||||||
|
int height = image.height();
|
||||||
|
QImage result(width, height, image.format());
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++) {
|
||||||
|
const int iNextClamped = clampPixelCoordinate(i + 1, width - 1);
|
||||||
|
const int iPrevClamped = clampPixelCoordinate(i - 1, width - 1);
|
||||||
|
|
||||||
|
for (int j = 0; j < height; j++) {
|
||||||
|
const int jNextClamped = clampPixelCoordinate(j + 1, height - 1);
|
||||||
|
const int jPrevClamped = clampPixelCoordinate(j - 1, height - 1);
|
||||||
|
|
||||||
|
// surrounding pixels
|
||||||
|
const QRgb topLeft = image.pixel(iPrevClamped, jPrevClamped);
|
||||||
|
const QRgb top = image.pixel(iPrevClamped, j);
|
||||||
|
const QRgb topRight = image.pixel(iPrevClamped, jNextClamped);
|
||||||
|
const QRgb right = image.pixel(i, jNextClamped);
|
||||||
|
const QRgb bottomRight = image.pixel(iNextClamped, jNextClamped);
|
||||||
|
const QRgb bottom = image.pixel(iNextClamped, j);
|
||||||
|
const QRgb bottomLeft = image.pixel(iNextClamped, jPrevClamped);
|
||||||
|
const QRgb left = image.pixel(i, jPrevClamped);
|
||||||
|
|
||||||
|
// take their gray intensities
|
||||||
|
// since it's a grayscale image, the value of each component RGB is the same
|
||||||
|
const double tl = qRed(topLeft);
|
||||||
|
const double t = qRed(top);
|
||||||
|
const double tr = qRed(topRight);
|
||||||
|
const double r = qRed(right);
|
||||||
|
const double br = qRed(bottomRight);
|
||||||
|
const double b = qRed(bottom);
|
||||||
|
const double bl = qRed(bottomLeft);
|
||||||
|
const double l = qRed(left);
|
||||||
|
|
||||||
|
// apply the sobel filter
|
||||||
|
const double dX = (tr + pStrength * r + br) - (tl + pStrength * l + bl);
|
||||||
|
const double dY = (bl + pStrength * b + br) - (tl + pStrength * t + tr);
|
||||||
|
const double dZ = RGBA_MAX / pStrength;
|
||||||
|
|
||||||
|
glm::vec3 v(dX, dY, dZ);
|
||||||
|
glm::normalize(v);
|
||||||
|
|
||||||
|
// convert to rgb from the value obtained computing the filter
|
||||||
|
QRgb qRgbValue = qRgb(mapComponent(v.x), mapComponent(v.y), mapComponent(v.z));
|
||||||
|
result.setPixel(i, j, qRgbValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::Texture* theTexture = nullptr;
|
||||||
|
if ((image.width() > 0) && (image.height() > 0)) {
|
||||||
|
|
||||||
|
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
||||||
|
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
|
||||||
|
|
||||||
|
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
||||||
|
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
|
||||||
|
if (image.hasAlphaChannel()) {
|
||||||
|
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
|
||||||
|
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||||
|
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||||
|
theTexture->autoGenerateMips(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return theTexture;
|
||||||
|
}
|
||||||
|
|
||||||
class CubeLayout {
|
class CubeLayout {
|
||||||
public:
|
public:
|
||||||
int _widthRatio = 1;
|
int _widthRatio = 1;
|
||||||
|
@ -197,7 +285,7 @@ public:
|
||||||
_faceZNeg(fZN) {}
|
_faceZNeg(fZN) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
gpu::Texture* TextureStorage::createCubeTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
gpu::Texture* TextureSource::createCubeTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||||
QImage image = srcImage;
|
QImage image = srcImage;
|
||||||
|
|
||||||
int imageArea = image.width() * image.height();
|
int imageArea = image.width() * image.height();
|
||||||
|
|
|
@ -32,13 +32,13 @@ public:
|
||||||
int _environmentUsage = 0;
|
int _environmentUsage = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TextureStorage is a specialized version of the gpu::Texture::Storage
|
// TextureSource is a specialized version of the gpu::Texture::Storage
|
||||||
// It provides the mechanism to create a texture from a Url and the intended usage
|
// It provides the mechanism to create a texture from a Url and the intended usage
|
||||||
// that guides the internal format used
|
// that guides the internal format used
|
||||||
class TextureStorage {
|
class TextureSource {
|
||||||
public:
|
public:
|
||||||
TextureStorage();
|
TextureSource();
|
||||||
~TextureStorage();
|
~TextureSource();
|
||||||
|
|
||||||
const QUrl& getUrl() const { return _imageUrl; }
|
const QUrl& getUrl() const { return _imageUrl; }
|
||||||
gpu::Texture::Type getType() const { return _usage._type; }
|
gpu::Texture::Type getType() const { return _usage._type; }
|
||||||
|
@ -51,6 +51,7 @@ public:
|
||||||
bool isDefined() const;
|
bool isDefined() const;
|
||||||
|
|
||||||
static gpu::Texture* create2DTextureFromImage(const QImage& image, const std::string& srcImageName);
|
static gpu::Texture* create2DTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||||
|
static gpu::Texture* createNormalTextureFromBumpImage(const QImage& image, const std::string& srcImageName);
|
||||||
static gpu::Texture* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName);
|
static gpu::Texture* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -58,7 +59,7 @@ protected:
|
||||||
TextureUsage _usage;
|
TextureUsage _usage;
|
||||||
QUrl _imageUrl;
|
QUrl _imageUrl;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< TextureStorage > TextureStoragePointer;
|
typedef std::shared_ptr< TextureSource > TextureSourcePointer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ class TextureMap {
|
||||||
public:
|
public:
|
||||||
TextureMap() {}
|
TextureMap() {}
|
||||||
|
|
||||||
void setTextureStorage(TextureStoragePointer& texStorage);
|
void setTextureSource(TextureSourcePointer& texStorage);
|
||||||
|
|
||||||
bool isDefined() const;
|
bool isDefined() const;
|
||||||
gpu::TextureView getTextureView() const;
|
gpu::TextureView getTextureView() const;
|
||||||
|
@ -78,7 +79,7 @@ public:
|
||||||
const glm::vec2& getLightmapOffsetScale() const { return _lightmapOffsetScale; }
|
const glm::vec2& getLightmapOffsetScale() const { return _lightmapOffsetScale; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureStoragePointer _textureStorage;
|
TextureSourcePointer _textureSource;
|
||||||
|
|
||||||
Transform _texcoordTransform;
|
Transform _texcoordTransform;
|
||||||
glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
|
glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
|
||||||
|
@ -87,5 +88,5 @@ typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_model_TextureStorage_h
|
#endif // hifi_model_TextureMap_h
|
||||||
|
|
||||||
|
|
|
@ -2072,17 +2072,17 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
|
||||||
networkMaterial->diffuseTextureName = material.diffuseTexture.name;
|
networkMaterial->diffuseTextureName = material.diffuseTexture.name;
|
||||||
|
|
||||||
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
diffuseMap->setTextureStorage(networkMaterial->diffuseTexture->_textureStorage);
|
diffuseMap->setTextureSource(networkMaterial->diffuseTexture->_textureSource);
|
||||||
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
diffuseMap->setTextureTransform(material.diffuseTexture.transform);
|
||||||
|
|
||||||
material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
|
||||||
}
|
}
|
||||||
if (!material.normalTexture.filename.isEmpty()) {
|
if (!material.normalTexture.filename.isEmpty()) {
|
||||||
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), NORMAL_TEXTURE, material.normalTexture.content);
|
networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), material.normalTexture.content);
|
||||||
networkMaterial->normalTextureName = material.normalTexture.name;
|
networkMaterial->normalTextureName = material.normalTexture.name;
|
||||||
|
|
||||||
auto normalMap = model::TextureMapPointer(new model::TextureMap());
|
auto normalMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
normalMap->setTextureStorage(networkMaterial->normalTexture->_textureStorage);
|
normalMap->setTextureSource(networkMaterial->normalTexture->_textureSource);
|
||||||
|
|
||||||
material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
|
||||||
}
|
}
|
||||||
|
@ -2091,7 +2091,7 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
|
||||||
networkMaterial->specularTextureName = material.specularTexture.name;
|
networkMaterial->specularTextureName = material.specularTexture.name;
|
||||||
|
|
||||||
auto glossMap = model::TextureMapPointer(new model::TextureMap());
|
auto glossMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
glossMap->setTextureStorage(networkMaterial->specularTexture->_textureStorage);
|
glossMap->setTextureSource(networkMaterial->specularTexture->_textureSource);
|
||||||
|
|
||||||
material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
|
||||||
}
|
}
|
||||||
|
@ -2102,7 +2102,7 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
|
||||||
checkForTexcoordLightmap = true;
|
checkForTexcoordLightmap = true;
|
||||||
|
|
||||||
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
|
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
|
||||||
lightmapMap->setTextureStorage(networkMaterial->emissiveTexture->_textureStorage);
|
lightmapMap->setTextureSource(networkMaterial->emissiveTexture->_textureSource);
|
||||||
lightmapMap->setTextureTransform(material.emissiveTexture.transform);
|
lightmapMap->setTextureTransform(material.emissiveTexture.transform);
|
||||||
lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
|
lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue