mirror of
https://github.com/overte-org/overte.git
synced 2025-08-11 00:28:40 +02:00
commit
bc60c8ba92
9 changed files with 235 additions and 21 deletions
47
interface/resources/shaders/model_normal_specular_map.frag
Normal file
47
interface/resources/shaders/model_normal_specular_map.frag
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// model_normal_specular_map.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/6/14.
|
||||||
|
// Copyright 2014 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// the diffuse texture
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the normal map texture
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the specular map texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
|
// the interpolated tangent
|
||||||
|
varying vec4 interpolatedTangent;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||||
|
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||||
|
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||||
|
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
// compute the base color based on OpenGL lighting model
|
||||||
|
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||||
|
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||||
|
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||||
|
gl_FrontLightProduct[0].diffuse * max(0.0, dot(viewNormal, gl_LightSource[0].position)));
|
||||||
|
|
||||||
|
// compute the specular component (sans exponent)
|
||||||
|
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), viewNormal));
|
||||||
|
|
||||||
|
// modulate texture by base color and add specular contribution
|
||||||
|
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) *
|
||||||
|
gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0);
|
||||||
|
}
|
35
interface/resources/shaders/model_specular_map.frag
Normal file
35
interface/resources/shaders/model_specular_map.frag
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// model_specular_map.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/6/14.
|
||||||
|
// Copyright 2014 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// the diffuse texture
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the specular texture
|
||||||
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// compute the base color based on OpenGL lighting model
|
||||||
|
vec4 normalizedNormal = normalize(normal);
|
||||||
|
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||||
|
gl_FrontLightProduct[0].diffuse * max(0.0, dot(normalizedNormal, gl_LightSource[0].position)));
|
||||||
|
|
||||||
|
// compute the specular component (sans exponent)
|
||||||
|
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalizedNormal));
|
||||||
|
|
||||||
|
// modulate texture by base color and add specular contribution
|
||||||
|
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) *
|
||||||
|
gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0);
|
||||||
|
}
|
|
@ -443,6 +443,14 @@ bool ModelUploader::addTextures(const QString& texdir, const FBXGeometry& geomet
|
||||||
}
|
}
|
||||||
added.insert(part.normalTexture.filename);
|
added.insert(part.normalTexture.filename);
|
||||||
}
|
}
|
||||||
|
if (!part.specularTexture.filename.isEmpty() && part.specularTexture.content.isEmpty() &&
|
||||||
|
!added.contains(part.specularTexture.filename)) {
|
||||||
|
if (!addPart(texdir + "/" + part.specularTexture.filename,
|
||||||
|
QString("texture%1").arg(++_texturesCount), true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
added.insert(part.specularTexture.filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,8 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
||||||
foreach (const NetworkMesh& mesh, _meshes) {
|
foreach (const NetworkMesh& mesh, _meshes) {
|
||||||
foreach (const NetworkMeshPart& part, mesh.parts) {
|
foreach (const NetworkMeshPart& part, mesh.parts) {
|
||||||
if ((part.diffuseTexture && !part.diffuseTexture->isLoaded()) ||
|
if ((part.diffuseTexture && !part.diffuseTexture->isLoaded()) ||
|
||||||
(part.normalTexture && !part.normalTexture->isLoaded())) {
|
(part.normalTexture && !part.normalTexture->isLoaded()) ||
|
||||||
|
(part.specularTexture && !part.specularTexture->isLoaded())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,6 +417,9 @@ void NetworkGeometry::setLoadPriority(const QPointer<QObject>& owner, float prio
|
||||||
if (part.normalTexture) {
|
if (part.normalTexture) {
|
||||||
part.normalTexture->setLoadPriority(owner, priority);
|
part.normalTexture->setLoadPriority(owner, priority);
|
||||||
}
|
}
|
||||||
|
if (part.specularTexture) {
|
||||||
|
part.specularTexture->setLoadPriority(owner, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,6 +437,9 @@ void NetworkGeometry::setLoadPriorities(const QHash<QPointer<QObject>, float>& p
|
||||||
if (part.normalTexture) {
|
if (part.normalTexture) {
|
||||||
part.normalTexture->setLoadPriorities(priorities);
|
part.normalTexture->setLoadPriorities(priorities);
|
||||||
}
|
}
|
||||||
|
if (part.specularTexture) {
|
||||||
|
part.specularTexture->setLoadPriorities(priorities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,6 +457,9 @@ void NetworkGeometry::clearLoadPriority(const QPointer<QObject>& owner) {
|
||||||
if (part.normalTexture) {
|
if (part.normalTexture) {
|
||||||
part.normalTexture->clearLoadPriority(owner);
|
part.normalTexture->clearLoadPriority(owner);
|
||||||
}
|
}
|
||||||
|
if (part.specularTexture) {
|
||||||
|
part.specularTexture->clearLoadPriority(owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,6 +576,11 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
||||||
_textureBase.resolved(QUrl(part.normalTexture.filename)), true, false, part.normalTexture.content);
|
_textureBase.resolved(QUrl(part.normalTexture.filename)), true, false, part.normalTexture.content);
|
||||||
networkPart.normalTexture->setLoadPriorities(_loadPriorities);
|
networkPart.normalTexture->setLoadPriorities(_loadPriorities);
|
||||||
}
|
}
|
||||||
|
if (!part.specularTexture.filename.isEmpty()) {
|
||||||
|
networkPart.specularTexture = Application::getInstance()->getTextureCache()->getTexture(
|
||||||
|
_textureBase.resolved(QUrl(part.specularTexture.filename)), true, false, part.specularTexture.content);
|
||||||
|
networkPart.specularTexture->setLoadPriorities(_loadPriorities);
|
||||||
|
}
|
||||||
networkMesh.parts.append(networkPart);
|
networkMesh.parts.append(networkPart);
|
||||||
|
|
||||||
totalIndices += (part.quadIndices.size() + part.triangleIndices.size());
|
totalIndices += (part.quadIndices.size() + part.triangleIndices.size());
|
||||||
|
|
|
@ -124,6 +124,7 @@ public:
|
||||||
|
|
||||||
QSharedPointer<NetworkTexture> diffuseTexture;
|
QSharedPointer<NetworkTexture> diffuseTexture;
|
||||||
QSharedPointer<NetworkTexture> normalTexture;
|
QSharedPointer<NetworkTexture> normalTexture;
|
||||||
|
QSharedPointer<NetworkTexture> specularTexture;
|
||||||
|
|
||||||
bool isTranslucent() const;
|
bool isTranslucent() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,13 +56,20 @@ Model::~Model() {
|
||||||
|
|
||||||
ProgramObject Model::_program;
|
ProgramObject Model::_program;
|
||||||
ProgramObject Model::_normalMapProgram;
|
ProgramObject Model::_normalMapProgram;
|
||||||
|
ProgramObject Model::_specularMapProgram;
|
||||||
|
ProgramObject Model::_normalSpecularMapProgram;
|
||||||
ProgramObject Model::_shadowProgram;
|
ProgramObject Model::_shadowProgram;
|
||||||
ProgramObject Model::_skinProgram;
|
ProgramObject Model::_skinProgram;
|
||||||
ProgramObject Model::_skinNormalMapProgram;
|
ProgramObject Model::_skinNormalMapProgram;
|
||||||
|
ProgramObject Model::_skinSpecularMapProgram;
|
||||||
|
ProgramObject Model::_skinNormalSpecularMapProgram;
|
||||||
ProgramObject Model::_skinShadowProgram;
|
ProgramObject Model::_skinShadowProgram;
|
||||||
int Model::_normalMapTangentLocation;
|
int Model::_normalMapTangentLocation;
|
||||||
|
int Model::_normalSpecularMapTangentLocation;
|
||||||
Model::SkinLocations Model::_skinLocations;
|
Model::SkinLocations Model::_skinLocations;
|
||||||
Model::SkinLocations Model::_skinNormalMapLocations;
|
Model::SkinLocations Model::_skinNormalMapLocations;
|
||||||
|
Model::SkinLocations Model::_skinSpecularMapLocations;
|
||||||
|
Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
||||||
Model::SkinLocations Model::_skinShadowLocations;
|
Model::SkinLocations Model::_skinShadowLocations;
|
||||||
|
|
||||||
void Model::setScale(const glm::vec3& scale) {
|
void Model::setScale(const glm::vec3& scale) {
|
||||||
|
@ -92,7 +99,7 @@ void Model::setOffset(const glm::vec3& offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) {
|
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations, int specularTextureUnit) {
|
||||||
program.bind();
|
program.bind();
|
||||||
locations.clusterMatrices = program.uniformLocation("clusterMatrices");
|
locations.clusterMatrices = program.uniformLocation("clusterMatrices");
|
||||||
locations.clusterIndices = program.attributeLocation("clusterIndices");
|
locations.clusterIndices = program.attributeLocation("clusterIndices");
|
||||||
|
@ -100,6 +107,7 @@ void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locati
|
||||||
locations.tangent = program.attributeLocation("tangent");
|
locations.tangent = program.attributeLocation("tangent");
|
||||||
program.setUniformValue("diffuseMap", 0);
|
program.setUniformValue("diffuseMap", 0);
|
||||||
program.setUniformValue("normalMap", 1);
|
program.setUniformValue("normalMap", 1);
|
||||||
|
program.setUniformValue("specularMap", specularTextureUnit);
|
||||||
program.release();
|
program.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +170,10 @@ void Model::init() {
|
||||||
_program.setUniformValue("texture", 0);
|
_program.setUniformValue("texture", 0);
|
||||||
_program.release();
|
_program.release();
|
||||||
|
|
||||||
_normalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath()
|
_normalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
+ "shaders/model_normal_map.vert");
|
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||||
_normalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath()
|
_normalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
+ "shaders/model_normal_map.frag");
|
Application::resourcesPath() + "shaders/model_normal_map.frag");
|
||||||
_normalMapProgram.link();
|
_normalMapProgram.link();
|
||||||
|
|
||||||
_normalMapProgram.bind();
|
_normalMapProgram.bind();
|
||||||
|
@ -174,27 +182,65 @@ void Model::init() {
|
||||||
_normalMapTangentLocation = _normalMapProgram.attributeLocation("tangent");
|
_normalMapTangentLocation = _normalMapProgram.attributeLocation("tangent");
|
||||||
_normalMapProgram.release();
|
_normalMapProgram.release();
|
||||||
|
|
||||||
|
_specularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
|
Application::resourcesPath() + "shaders/model.vert");
|
||||||
|
_specularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
Application::resourcesPath() + "shaders/model_specular_map.frag");
|
||||||
|
_specularMapProgram.link();
|
||||||
|
|
||||||
|
_specularMapProgram.bind();
|
||||||
|
_specularMapProgram.setUniformValue("diffuseMap", 0);
|
||||||
|
_specularMapProgram.setUniformValue("specularMap", 1);
|
||||||
|
_specularMapProgram.release();
|
||||||
|
|
||||||
|
_normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
|
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||||
|
_normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
Application::resourcesPath() + "shaders/model_normal_specular_map.frag");
|
||||||
|
_normalSpecularMapProgram.link();
|
||||||
|
|
||||||
|
_normalSpecularMapProgram.bind();
|
||||||
|
_normalSpecularMapProgram.setUniformValue("diffuseMap", 0);
|
||||||
|
_normalSpecularMapProgram.setUniformValue("normalMap", 1);
|
||||||
|
_normalSpecularMapProgram.setUniformValue("specularMap", 2);
|
||||||
|
_normalSpecularMapTangentLocation = _normalMapProgram.attributeLocation("tangent");
|
||||||
|
_normalSpecularMapProgram.release();
|
||||||
|
|
||||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
|
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
|
||||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
_shadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
"shaders/model_shadow.frag");
|
Application::resourcesPath() + "shaders/model_shadow.frag");
|
||||||
_shadowProgram.link();
|
_shadowProgram.link();
|
||||||
|
|
||||||
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath()
|
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert");
|
||||||
+ "shaders/skin_model.vert");
|
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag");
|
||||||
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath()
|
|
||||||
+ "shaders/model.frag");
|
|
||||||
_skinProgram.link();
|
_skinProgram.link();
|
||||||
|
|
||||||
initSkinProgram(_skinProgram, _skinLocations);
|
initSkinProgram(_skinProgram, _skinLocations);
|
||||||
|
|
||||||
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath()
|
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
+ "shaders/skin_model_normal_map.vert");
|
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||||
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath()
|
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
+ "shaders/model_normal_map.frag");
|
Application::resourcesPath() + "shaders/model_normal_map.frag");
|
||||||
_skinNormalMapProgram.link();
|
_skinNormalMapProgram.link();
|
||||||
|
|
||||||
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
|
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
|
||||||
|
|
||||||
|
_skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
|
Application::resourcesPath() + "shaders/skin_model.vert");
|
||||||
|
_skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
Application::resourcesPath() + "shaders/model_specular_map.frag");
|
||||||
|
_skinSpecularMapProgram.link();
|
||||||
|
|
||||||
|
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
|
||||||
|
|
||||||
|
_skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
|
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||||
|
_skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
Application::resourcesPath() + "shaders/model_normal_specular_map.frag");
|
||||||
|
_skinNormalSpecularMapProgram.link();
|
||||||
|
|
||||||
|
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations, 2);
|
||||||
|
|
||||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
Application::resourcesPath() + "shaders/skin_model_shadow.vert");
|
Application::resourcesPath() + "shaders/skin_model_shadow.vert");
|
||||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
@ -1331,15 +1377,29 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) {
|
||||||
ProgramObject* program = &_program;
|
ProgramObject* program = &_program;
|
||||||
ProgramObject* skinProgram = &_skinProgram;
|
ProgramObject* skinProgram = &_skinProgram;
|
||||||
SkinLocations* skinLocations = &_skinLocations;
|
SkinLocations* skinLocations = &_skinLocations;
|
||||||
|
GLenum specularTextureUnit = 0;
|
||||||
if (mode == SHADOW_RENDER_MODE) {
|
if (mode == SHADOW_RENDER_MODE) {
|
||||||
program = &_shadowProgram;
|
program = &_shadowProgram;
|
||||||
skinProgram = &_skinShadowProgram;
|
skinProgram = &_skinShadowProgram;
|
||||||
skinLocations = &_skinShadowLocations;
|
skinLocations = &_skinShadowLocations;
|
||||||
|
|
||||||
} else if (!mesh.tangents.isEmpty()) {
|
} else if (!mesh.tangents.isEmpty()) {
|
||||||
program = &_normalMapProgram;
|
if (mesh.hasSpecularTexture()) {
|
||||||
skinProgram = &_skinNormalMapProgram;
|
program = &_normalSpecularMapProgram;
|
||||||
skinLocations = &_skinNormalMapLocations;
|
skinProgram = &_skinNormalSpecularMapProgram;
|
||||||
|
skinLocations = &_skinNormalSpecularMapLocations;
|
||||||
|
specularTextureUnit = GL_TEXTURE2;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
program = &_normalMapProgram;
|
||||||
|
skinProgram = &_skinNormalMapProgram;
|
||||||
|
skinLocations = &_skinNormalMapLocations;
|
||||||
|
}
|
||||||
|
} else if (mesh.hasSpecularTexture()) {
|
||||||
|
program = &_specularMapProgram;
|
||||||
|
skinProgram = &_skinSpecularMapProgram;
|
||||||
|
skinLocations = &_skinSpecularMapLocations;
|
||||||
|
specularTextureUnit = GL_TEXTURE1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MeshState& state = _meshStates.at(i);
|
const MeshState& state = _meshStates.at(i);
|
||||||
|
@ -1427,13 +1487,23 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) {
|
||||||
glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
|
glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
|
||||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
|
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
|
||||||
|
|
||||||
|
|
||||||
if (!mesh.tangents.isEmpty()) {
|
if (!mesh.tangents.isEmpty()) {
|
||||||
|
specularTextureUnit = GL_TEXTURE2;
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
Texture* normalMap = networkPart.normalTexture.data();
|
Texture* normalMap = networkPart.normalTexture.data();
|
||||||
glBindTexture(GL_TEXTURE_2D, !normalMap ?
|
glBindTexture(GL_TEXTURE_2D, !normalMap ?
|
||||||
Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
|
Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (specularTextureUnit) {
|
||||||
|
glActiveTexture(specularTextureUnit);
|
||||||
|
Texture* specularMap = networkPart.specularTexture.data();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, !specularMap ?
|
||||||
|
Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID());
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
|
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
|
||||||
offset += part.quadIndices.size() * sizeof(int);
|
offset += part.quadIndices.size() * sizeof(int);
|
||||||
|
@ -1456,7 +1526,13 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) {
|
||||||
|
|
||||||
activeProgram->disableAttributeArray(tangentLocation);
|
activeProgram->disableAttributeArray(tangentLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (specularTextureUnit) {
|
||||||
|
glActiveTexture(specularTextureUnit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
if (state.clusterMatrices.size() > 1) {
|
if (state.clusterMatrices.size() > 1) {
|
||||||
skinProgram->disableAttributeArray(skinLocations->clusterIndices);
|
skinProgram->disableAttributeArray(skinLocations->clusterIndices);
|
||||||
skinProgram->disableAttributeArray(skinLocations->clusterWeights);
|
skinProgram->disableAttributeArray(skinLocations->clusterWeights);
|
||||||
|
|
|
@ -318,12 +318,17 @@ private:
|
||||||
|
|
||||||
static ProgramObject _program;
|
static ProgramObject _program;
|
||||||
static ProgramObject _normalMapProgram;
|
static ProgramObject _normalMapProgram;
|
||||||
|
static ProgramObject _specularMapProgram;
|
||||||
|
static ProgramObject _normalSpecularMapProgram;
|
||||||
static ProgramObject _shadowProgram;
|
static ProgramObject _shadowProgram;
|
||||||
static ProgramObject _skinProgram;
|
static ProgramObject _skinProgram;
|
||||||
static ProgramObject _skinNormalMapProgram;
|
static ProgramObject _skinNormalMapProgram;
|
||||||
|
static ProgramObject _skinSpecularMapProgram;
|
||||||
|
static ProgramObject _skinNormalSpecularMapProgram;
|
||||||
static ProgramObject _skinShadowProgram;
|
static ProgramObject _skinShadowProgram;
|
||||||
|
|
||||||
static int _normalMapTangentLocation;
|
static int _normalMapTangentLocation;
|
||||||
|
static int _normalSpecularMapTangentLocation;
|
||||||
|
|
||||||
class SkinLocations {
|
class SkinLocations {
|
||||||
public:
|
public:
|
||||||
|
@ -335,9 +340,11 @@ private:
|
||||||
|
|
||||||
static SkinLocations _skinLocations;
|
static SkinLocations _skinLocations;
|
||||||
static SkinLocations _skinNormalMapLocations;
|
static SkinLocations _skinNormalMapLocations;
|
||||||
|
static SkinLocations _skinSpecularMapLocations;
|
||||||
|
static SkinLocations _skinNormalSpecularMapLocations;
|
||||||
static SkinLocations _skinShadowLocations;
|
static SkinLocations _skinShadowLocations;
|
||||||
|
|
||||||
static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
|
static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QPointer<Model>)
|
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||||
|
|
|
@ -54,6 +54,15 @@ void Extents::addPoint(const glm::vec3& point) {
|
||||||
maximum = glm::max(maximum, point);
|
maximum = glm::max(maximum, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FBXMesh::hasSpecularTexture() const {
|
||||||
|
foreach (const FBXMeshPart& part, parts) {
|
||||||
|
if (!part.specularTexture.filename.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList FBXGeometry::getJointNames() const {
|
QStringList FBXGeometry::getJointNames() const {
|
||||||
QStringList names;
|
QStringList names;
|
||||||
foreach (const FBXJoint& joint, joints) {
|
foreach (const FBXJoint& joint, joints) {
|
||||||
|
@ -976,6 +985,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QHash<QString, Material> materials;
|
QHash<QString, Material> materials;
|
||||||
QHash<QString, QString> diffuseTextures;
|
QHash<QString, QString> diffuseTextures;
|
||||||
QHash<QString, QString> bumpTextures;
|
QHash<QString, QString> bumpTextures;
|
||||||
|
QHash<QString, QString> specularTextures;
|
||||||
QHash<QString, QString> localRotations;
|
QHash<QString, QString> localRotations;
|
||||||
QHash<QString, QString> xComponents;
|
QHash<QString, QString> xComponents;
|
||||||
QHash<QString, QString> yComponents;
|
QHash<QString, QString> yComponents;
|
||||||
|
@ -1330,6 +1340,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
} else if (type.contains("bump") || type.contains("normal")) {
|
} else if (type.contains("bump") || type.contains("normal")) {
|
||||||
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
|
} else if (type.contains("specular")) {
|
||||||
|
specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
} else if (type == "lcl rotation") {
|
} else if (type == "lcl rotation") {
|
||||||
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||||
|
|
||||||
|
@ -1546,6 +1559,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
generateTangents = true;
|
generateTangents = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FBXTexture specularTexture;
|
||||||
|
QString specularTextureID = specularTextures.value(childID);
|
||||||
|
if (!specularTextureID.isNull()) {
|
||||||
|
specularTexture = getTexture(specularTextureID, textureFilenames, textureContent);
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
||||||
if (extracted.partMaterialTextures.at(j).first == materialIndex) {
|
if (extracted.partMaterialTextures.at(j).first == materialIndex) {
|
||||||
FBXMeshPart& part = extracted.mesh.parts[j];
|
FBXMeshPart& part = extracted.mesh.parts[j];
|
||||||
|
@ -1558,6 +1577,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
if (!normalTexture.filename.isNull()) {
|
if (!normalTexture.filename.isNull()) {
|
||||||
part.normalTexture = normalTexture;
|
part.normalTexture = normalTexture;
|
||||||
}
|
}
|
||||||
|
if (!specularTexture.filename.isNull()) {
|
||||||
|
part.specularTexture = specularTexture;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
materialIndex++;
|
materialIndex++;
|
||||||
|
|
|
@ -129,6 +129,7 @@ public:
|
||||||
|
|
||||||
FBXTexture diffuseTexture;
|
FBXTexture diffuseTexture;
|
||||||
FBXTexture normalTexture;
|
FBXTexture normalTexture;
|
||||||
|
FBXTexture specularTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A single mesh (with optional blendshapes) extracted from an FBX document.
|
/// A single mesh (with optional blendshapes) extracted from an FBX document.
|
||||||
|
@ -150,6 +151,8 @@ public:
|
||||||
bool isEye;
|
bool isEye;
|
||||||
|
|
||||||
QVector<FBXBlendshape> blendshapes;
|
QVector<FBXBlendshape> blendshapes;
|
||||||
|
|
||||||
|
bool hasSpecularTexture() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A single animation frame extracted from an FBX document.
|
/// A single animation frame extracted from an FBX document.
|
||||||
|
|
Loading…
Reference in a new issue