mirror of
https://github.com/lubosz/overte.git
synced 2025-04-13 21:06:32 +02:00
First version of the lighmap working
This commit is contained in:
parent
7daff18101
commit
87471df7a1
11 changed files with 468 additions and 300 deletions
|
@ -11,6 +11,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
|
@ -22,7 +26,7 @@ void main(void) {
|
|||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.f, 1.f);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the tangent vector
|
||||
attribute vec3 tangent;
|
||||
|
||||
|
@ -29,7 +33,7 @@ void main(void) {
|
|||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.f, 1.f);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
const int MAX_CLUSTERS = 128;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
uniform mat4 clusterMatrices[MAX_CLUSTERS];
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
attribute vec4 clusterIndices;
|
||||
attribute vec4 clusterWeights;
|
||||
|
@ -38,7 +40,7 @@ void main(void) {
|
|||
gl_FrontColor = gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.f, 1.f);
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * position;
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
const int MAX_CLUSTERS = 128;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
uniform mat4 clusterMatrices[MAX_CLUSTERS];
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the tangent vector
|
||||
attribute vec3 tangent;
|
||||
|
@ -46,7 +48,7 @@ void main(void) {
|
|||
gl_FrontColor = gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.f, 1.f);
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * interpolatedPosition;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
TANGENT,
|
||||
SKIN_CLUSTER_INDEX,
|
||||
SKIN_CLUSTER_WEIGHT,
|
||||
TEXCOORD1,
|
||||
|
||||
NUM_INPUT_SLOTS,
|
||||
};
|
||||
|
|
|
@ -964,7 +964,8 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
int tangentsOffset = normalsOffset + mesh.normals.size() * sizeof(glm::vec3);
|
||||
int colorsOffset = tangentsOffset + mesh.tangents.size() * sizeof(glm::vec3);
|
||||
int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3);
|
||||
int clusterIndicesOffset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2);
|
||||
int texCoords1Offset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2);
|
||||
int clusterIndicesOffset = texCoords1Offset + mesh.texCoords1.size() * sizeof(glm::vec2);
|
||||
int clusterWeightsOffset = clusterIndicesOffset + mesh.clusterIndices.size() * sizeof(glm::vec4);
|
||||
|
||||
networkMesh._vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4));
|
||||
|
@ -977,6 +978,8 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
networkMesh._vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Resource::Byte*) mesh.colors.constData());
|
||||
networkMesh._vertexBuffer->setSubData(texCoordsOffset,
|
||||
mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords.constData());
|
||||
networkMesh._vertexBuffer->setSubData(texCoords1Offset,
|
||||
mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Resource::Byte*) mesh.texCoords1.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterIndicesOffset,
|
||||
mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Resource::Byte*) mesh.clusterIndices.constData());
|
||||
networkMesh._vertexBuffer->setSubData(clusterWeightsOffset,
|
||||
|
@ -989,6 +992,7 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
if (mesh.tangents.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, tangentsOffset, sizeof(glm::vec3));
|
||||
if (mesh.colors.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, colorsOffset, sizeof(glm::vec3));
|
||||
if (mesh.texCoords.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, texCoordsOffset, sizeof(glm::vec2));
|
||||
if (mesh.texCoords1.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, texCoords1Offset, sizeof(glm::vec2));
|
||||
if (mesh.clusterIndices.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4));
|
||||
if (mesh.clusterWeights.size()) networkMesh._vertexStream->addBuffer(networkMesh._vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4));
|
||||
|
||||
|
@ -999,6 +1003,7 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
|||
if (mesh.tangents.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||
if (mesh.colors.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
|
||||
if (mesh.texCoords.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
|
||||
if (mesh.texCoords1.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
|
||||
if (mesh.clusterIndices.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
|
||||
if (mesh.clusterWeights.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW));
|
||||
}
|
||||
|
|
|
@ -70,10 +70,10 @@ ProgramObject Model::_specularMapProgram;
|
|||
ProgramObject Model::_normalSpecularMapProgram;
|
||||
ProgramObject Model::_translucentProgram;
|
||||
|
||||
ProgramObject Model::_emissiveProgram;
|
||||
ProgramObject Model::_emissiveNormalMapProgram;
|
||||
ProgramObject Model::_emissiveSpecularMapProgram;
|
||||
ProgramObject Model::_emissiveNormalSpecularMapProgram;
|
||||
ProgramObject Model::_lightmapProgram;
|
||||
ProgramObject Model::_lightmapNormalMapProgram;
|
||||
ProgramObject Model::_lightmapSpecularMapProgram;
|
||||
ProgramObject Model::_lightmapNormalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_shadowProgram;
|
||||
|
||||
|
@ -83,11 +83,6 @@ ProgramObject Model::_skinSpecularMapProgram;
|
|||
ProgramObject Model::_skinNormalSpecularMapProgram;
|
||||
ProgramObject Model::_skinTranslucentProgram;
|
||||
|
||||
ProgramObject Model::_skinEmissiveProgram;
|
||||
ProgramObject Model::_skinEmissiveNormalMapProgram;
|
||||
ProgramObject Model::_skinEmissiveSpecularMapProgram;
|
||||
ProgramObject Model::_skinEmissiveNormalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_skinShadowProgram;
|
||||
|
||||
Model::Locations Model::_locations;
|
||||
|
@ -96,10 +91,10 @@ Model::Locations Model::_specularMapLocations;
|
|||
Model::Locations Model::_normalSpecularMapLocations;
|
||||
Model::Locations Model::_translucentLocations;
|
||||
|
||||
Model::Locations Model::_emissiveLocations;
|
||||
Model::Locations Model::_emissiveNormalMapLocations;
|
||||
Model::Locations Model::_emissiveSpecularMapLocations;
|
||||
Model::Locations Model::_emissiveNormalSpecularMapLocations;
|
||||
Model::Locations Model::_lightmapLocations;
|
||||
Model::Locations Model::_lightmapNormalMapLocations;
|
||||
Model::Locations Model::_lightmapSpecularMapLocations;
|
||||
Model::Locations Model::_lightmapNormalSpecularMapLocations;
|
||||
|
||||
Model::SkinLocations Model::_skinLocations;
|
||||
Model::SkinLocations Model::_skinNormalMapLocations;
|
||||
|
@ -108,11 +103,6 @@ Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
|||
Model::SkinLocations Model::_skinShadowLocations;
|
||||
Model::SkinLocations Model::_skinTranslucentLocations;
|
||||
|
||||
Model::SkinLocations Model::_skinEmissiveLocations;
|
||||
Model::SkinLocations Model::_skinEmissiveNormalMapLocations;
|
||||
Model::SkinLocations Model::_skinEmissiveSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinEmissiveNormalSpecularMapLocations;
|
||||
|
||||
void Model::setScale(const glm::vec3& scale) {
|
||||
setScaleInternal(scale);
|
||||
// if anyone sets scale manually, then we are no longer scaled to fit
|
||||
|
@ -160,17 +150,40 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, int
|
|||
|
||||
glBindAttribLocation(program.programId(), gpu::Stream::TANGENT, "tangent");
|
||||
|
||||
glBindAttribLocation(program.programId(), gpu::Stream::TEXCOORD1, "texcoord1");
|
||||
|
||||
glLinkProgram(program.programId());
|
||||
|
||||
locations.tangent = program.attributeLocation("tangent");
|
||||
|
||||
locations.alphaThreshold = program.uniformLocation("alphaThreshold");
|
||||
|
||||
locations.texcoordMatrices = program.uniformLocation("texcoordMatrices");
|
||||
|
||||
|
||||
program.setUniformValue("diffuseMap", 0);
|
||||
|
||||
program.setUniformValue("normalMap", 1);
|
||||
|
||||
program.setUniformValue("specularMap", specularTextureUnit);
|
||||
int loc = program.uniformLocation("specularMap");
|
||||
if (loc >= 0) {
|
||||
program.setUniformValue("specularMap", 2);
|
||||
locations.specularTextureUnit = 2;
|
||||
} else {
|
||||
locations.specularTextureUnit = -1;
|
||||
}
|
||||
|
||||
loc = program.uniformLocation("emissiveMap");
|
||||
if (loc >= 0) {
|
||||
program.setUniformValue("emissiveMap", 3);
|
||||
locations.emissiveTextureUnit = 3;
|
||||
} else {
|
||||
locations.emissiveTextureUnit = -1;
|
||||
}
|
||||
|
||||
if (!program.isLinked()) {
|
||||
program.release();
|
||||
}
|
||||
|
||||
program.release();
|
||||
|
||||
|
@ -289,37 +302,37 @@ void Model::init() {
|
|||
|
||||
initProgram(_translucentProgram, _translucentLocations);
|
||||
|
||||
// Emissive
|
||||
_emissiveProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert");
|
||||
_emissiveProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_emissive.frag");
|
||||
_emissiveProgram.link();
|
||||
// Lightmap
|
||||
_lightmapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_lightmap.vert");
|
||||
_lightmapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_lightmap.frag");
|
||||
_lightmapProgram.link();
|
||||
|
||||
initProgram(_emissiveProgram, _emissiveLocations);
|
||||
initProgram(_lightmapProgram, _lightmapLocations);
|
||||
|
||||
_emissiveNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_emissiveNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_normal_map.frag");
|
||||
_emissiveNormalMapProgram.link();
|
||||
_lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
|
||||
_lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_lightmap_normal_map.frag");
|
||||
_lightmapNormalMapProgram.link();
|
||||
|
||||
initProgram(_emissiveNormalMapProgram, _emissiveNormalMapLocations);
|
||||
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
|
||||
|
||||
_emissiveSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model.vert");
|
||||
_emissiveSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_specular_map.frag");
|
||||
_emissiveSpecularMapProgram.link();
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_lightmap.vert");
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_lightmap_specular_map.frag");
|
||||
_lightmapSpecularMapProgram.link();
|
||||
|
||||
initProgram(_emissiveSpecularMapProgram, _emissiveSpecularMapLocations);
|
||||
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
|
||||
|
||||
_emissiveNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_emissiveNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_normal_specular_map.frag");
|
||||
_emissiveNormalSpecularMapProgram.link();
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_lightmap_normal_specular_map.frag");
|
||||
_lightmapNormalSpecularMapProgram.link();
|
||||
|
||||
initProgram(_emissiveNormalSpecularMapProgram, _emissiveNormalSpecularMapLocations, 2);
|
||||
// end emissive
|
||||
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations, 2);
|
||||
// end lightmap
|
||||
|
||||
|
||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
|
||||
|
@ -374,36 +387,6 @@ void Model::init() {
|
|||
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
||||
|
||||
|
||||
_skinEmissiveProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinEmissiveProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_emissive.frag");
|
||||
_skinEmissiveProgram.link();
|
||||
|
||||
initSkinProgram(_skinEmissiveProgram, _skinEmissiveLocations);
|
||||
|
||||
_skinEmissiveNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinEmissiveNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_normal_map.frag");
|
||||
_skinEmissiveNormalMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinEmissiveNormalMapProgram, _skinEmissiveNormalMapLocations);
|
||||
|
||||
_skinEmissiveSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinEmissiveSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_specular_map.frag");
|
||||
_skinEmissiveSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinEmissiveSpecularMapProgram, _skinEmissiveSpecularMapLocations);
|
||||
|
||||
_skinEmissiveNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinEmissiveNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_emissive_normal_specular_map.frag");
|
||||
_skinEmissiveNormalSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinEmissiveNormalSpecularMapProgram, _skinEmissiveNormalSpecularMapLocations, 2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,13 +699,9 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, true, args);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
//Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
||||
|
@ -1666,13 +1645,9 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args);
|
||||
*/
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, true, args);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
//Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
||||
|
@ -1793,15 +1768,10 @@ void Model::segregateMeshGroups() {
|
|||
_meshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_meshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_meshesOpaqueEmissiveTangents.clear();
|
||||
_meshesOpaqueEmissive.clear();
|
||||
_meshesOpaqueEmissiveTangentsSpecular.clear();
|
||||
_meshesOpaqueEmissiveSpecular.clear();
|
||||
|
||||
_meshesOpaqueEmissiveTangentsSkinned.clear();
|
||||
_meshesOpaqueEmissiveSkinned.clear();
|
||||
_meshesOpaqueEmissiveTangentsSpecularSkinned.clear();
|
||||
_meshesOpaqueEmissiveSpecularSkinned.clear();
|
||||
_meshesOpaqueLightmapTangents.clear();
|
||||
_meshesOpaqueLightmap.clear();
|
||||
_meshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_meshesOpaqueLightmapSpecular.clear();
|
||||
|
||||
_unsortedMeshesTranslucentTangents.clear();
|
||||
_unsortedMeshesTranslucent.clear();
|
||||
|
@ -1823,15 +1793,10 @@ void Model::segregateMeshGroups() {
|
|||
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangents.clear();
|
||||
_unsortedMeshesOpaqueEmissive.clear();
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSpecular.clear();
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangents.clear();
|
||||
_unsortedMeshesOpaqueLightmap.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueLightmapSpecular.clear();
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||
|
@ -1846,7 +1811,7 @@ void Model::segregateMeshGroups() {
|
|||
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
|
||||
bool hasTangents = !mesh.tangents.isEmpty();
|
||||
bool hasSpecular = mesh.hasSpecularTexture();
|
||||
bool hasEmissive = mesh.hasEmissiveTexture();
|
||||
bool haslightmap = mesh.hasEmissiveTexture();
|
||||
bool isSkinned = state.clusterMatrices.size() > 1;
|
||||
QString materialID;
|
||||
|
||||
|
@ -1865,7 +1830,7 @@ void Model::segregateMeshGroups() {
|
|||
qDebug() << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||
}
|
||||
|
||||
if ( !hasEmissive) {
|
||||
if ( !haslightmap) {
|
||||
if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucent.insertMulti(materialID, i);
|
||||
|
@ -1935,35 +1900,20 @@ void Model::segregateMeshGroups() {
|
|||
} else {
|
||||
if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissive.insertMulti(materialID, i);
|
||||
_unsortedMeshesOpaqueLightmap.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangents.insertMulti(materialID, i);
|
||||
_unsortedMeshesOpaqueLightmapTangents.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecular.insertMulti(materialID, i);
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveSpecular.insertMulti(materialID, i);
|
||||
_unsortedMeshesOpaqueLightmapSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecularSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveSpecularSkinned.insertMulti(materialID, i);
|
||||
} else {
|
||||
qDebug() << "unexpected!!! this mesh didn't fall into any or our groups???";
|
||||
}
|
||||
|
@ -2034,36 +1984,20 @@ void Model::segregateMeshGroups() {
|
|||
_meshesOpaqueSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissive) {
|
||||
_meshesOpaqueEmissive.append(i);
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmap) {
|
||||
_meshesOpaqueLightmap.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveTangents) {
|
||||
_meshesOpaqueEmissiveTangents.append(i);
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapTangents) {
|
||||
_meshesOpaqueLightmapTangents.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveTangentsSpecular) {
|
||||
_meshesOpaqueEmissiveTangentsSpecular.append(i);
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapTangentsSpecular) {
|
||||
_meshesOpaqueLightmapTangentsSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveSpecular) {
|
||||
_meshesOpaqueEmissiveSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveSkinned) {
|
||||
_meshesOpaqueEmissiveSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveTangentsSkinned) {
|
||||
_meshesOpaqueEmissiveTangentsSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveTangentsSpecularSkinned) {
|
||||
_meshesOpaqueEmissiveTangentsSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueEmissiveSpecularSkinned) {
|
||||
_meshesOpaqueEmissiveSpecularSkinned.append(i);
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapSpecular) {
|
||||
_meshesOpaqueLightmapSpecular.append(i);
|
||||
}
|
||||
|
||||
_unsortedMeshesTranslucentTangents.clear();
|
||||
|
@ -2086,20 +2020,15 @@ void Model::segregateMeshGroups() {
|
|||
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangents.clear();
|
||||
_unsortedMeshesOpaqueEmissive.clear();
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSpecular.clear();
|
||||
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueEmissiveSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangents.clear();
|
||||
_unsortedMeshesOpaqueLightmap.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueLightmapSpecular.clear();
|
||||
|
||||
_meshGroupsKnown = true;
|
||||
}
|
||||
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned) {
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
// depending on which parameters we were called with, pick the correct mesh group to render
|
||||
|
@ -2121,39 +2050,31 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
|
|||
} else if (translucent && !hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesTranslucentSpecularSkinned;
|
||||
|
||||
} else if (!translucent && !hasEmissive && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaque;
|
||||
} else if (!translucent && !hasEmissive && hasTangents && !hasSpecular && !isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueTangents;
|
||||
} else if (!translucent && !hasEmissive && hasTangents && hasSpecular && !isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSpecular;
|
||||
} else if (!translucent && !hasEmissive && !hasTangents && hasSpecular && !isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueSpecular;
|
||||
} else if (!translucent && !hasEmissive && hasTangents && !hasSpecular && isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSkinned;
|
||||
} else if (!translucent && !hasEmissive && !hasTangents && !hasSpecular && isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueSkinned;
|
||||
} else if (!translucent && !hasEmissive && hasTangents && hasSpecular && isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSpecularSkinned;
|
||||
} else if (!translucent && !hasEmissive && !hasTangents && hasSpecular && isSkinned) {
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueSpecularSkinned;
|
||||
|
||||
} else if (!translucent && hasEmissive && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissive;
|
||||
} else if (!translucent && hasEmissive && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveTangents;
|
||||
} else if (!translucent && hasEmissive && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveTangentsSpecular;
|
||||
} else if (!translucent && hasEmissive && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveSpecular;
|
||||
} else if (!translucent && hasEmissive && hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveTangentsSkinned;
|
||||
} else if (!translucent && hasEmissive && !hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveSkinned;
|
||||
} else if (!translucent && hasEmissive && hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveTangentsSpecularSkinned;
|
||||
} else if (!translucent && hasEmissive && !hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueEmissiveSpecularSkinned;
|
||||
} else if (!translucent && hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmap;
|
||||
} else if (!translucent && hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapTangents;
|
||||
} else if (!translucent && hasLightmap && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapTangentsSpecular;
|
||||
} else if (!translucent && hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapSpecular;
|
||||
|
||||
} else {
|
||||
qDebug() << "unexpected!!! this mesh didn't fall into any or our groups???";
|
||||
|
@ -2162,15 +2083,13 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
|
|||
}
|
||||
|
||||
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
SkinLocations*& skinLocations, GLenum& specularTextureUnit, GLenum& emissiveTextureUnit) {
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
Locations*& locations, SkinLocations*& skinLocations) {
|
||||
|
||||
ProgramObject* program = &_program;
|
||||
Locations* locations = &_locations;
|
||||
locations = &_locations;
|
||||
ProgramObject* skinProgram = &_skinProgram;
|
||||
skinLocations = &_skinLocations;
|
||||
specularTextureUnit = 0;
|
||||
emissiveTextureUnit = 0;
|
||||
if (mode == SHADOW_RENDER_MODE) {
|
||||
program = &_shadowProgram;
|
||||
skinProgram = &_skinShadowProgram;
|
||||
|
@ -2181,35 +2100,29 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
skinProgram = &_skinTranslucentProgram;
|
||||
skinLocations = &_skinTranslucentLocations;
|
||||
|
||||
} else if (hasEmissive) {
|
||||
} else if (hasLightmap) {
|
||||
if (hasTangents) {
|
||||
if (hasSpecular) {
|
||||
program = &_emissiveNormalSpecularMapProgram;
|
||||
locations = &_emissiveNormalSpecularMapLocations;
|
||||
skinProgram = &_skinEmissiveNormalSpecularMapProgram;
|
||||
skinLocations = &_skinEmissiveNormalSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE2;
|
||||
emissiveTextureUnit = GL_TEXTURE3;
|
||||
program = &_lightmapNormalSpecularMapProgram;
|
||||
locations = &_lightmapNormalSpecularMapLocations;
|
||||
skinProgram = NULL;
|
||||
skinLocations = NULL;
|
||||
} else {
|
||||
program = &_emissiveNormalMapProgram;
|
||||
locations = &_emissiveNormalMapLocations;
|
||||
skinProgram = &_skinEmissiveNormalMapProgram;
|
||||
skinLocations = &_skinEmissiveNormalMapLocations;
|
||||
emissiveTextureUnit = GL_TEXTURE3;
|
||||
program = &_lightmapNormalMapProgram;
|
||||
locations = &_lightmapNormalMapLocations;
|
||||
skinProgram = NULL;
|
||||
skinLocations = NULL;
|
||||
}
|
||||
} else if (hasSpecular) {
|
||||
program = &_emissiveSpecularMapProgram;
|
||||
locations = &_emissiveSpecularMapLocations;
|
||||
skinProgram = &_skinEmissiveSpecularMapProgram;
|
||||
skinLocations = &_skinEmissiveSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE1;
|
||||
emissiveTextureUnit = GL_TEXTURE3;
|
||||
program = &_lightmapSpecularMapProgram;
|
||||
locations = &_lightmapSpecularMapLocations;
|
||||
skinProgram = NULL;
|
||||
skinLocations = NULL;
|
||||
} else {
|
||||
program = &_emissiveProgram;
|
||||
locations = &_emissiveLocations;
|
||||
skinProgram = &_skinEmissiveProgram;
|
||||
skinLocations = &_skinEmissiveLocations;
|
||||
emissiveTextureUnit = GL_TEXTURE3;
|
||||
program = &_lightmapProgram;
|
||||
locations = &_lightmapLocations;
|
||||
skinProgram = NULL;
|
||||
skinLocations = NULL;
|
||||
}
|
||||
} else {
|
||||
if (hasTangents) {
|
||||
|
@ -2218,7 +2131,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
locations = &_normalSpecularMapLocations;
|
||||
skinProgram = &_skinNormalSpecularMapProgram;
|
||||
skinLocations = &_skinNormalSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE2;
|
||||
} else {
|
||||
program = &_normalMapProgram;
|
||||
locations = &_normalMapLocations;
|
||||
|
@ -2230,7 +2142,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
locations = &_specularMapLocations;
|
||||
skinProgram = &_skinSpecularMapProgram;
|
||||
skinLocations = &_skinSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2240,6 +2151,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
if (isSkinned) {
|
||||
activeProgram = skinProgram;
|
||||
activeLocations = skinLocations;
|
||||
locations = skinLocations;
|
||||
}
|
||||
// This code replace the "bind()" on the QGLProgram
|
||||
if (!activeProgram->isLinked()) {
|
||||
|
@ -2251,27 +2163,26 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
}
|
||||
|
||||
int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
bool pickProgramsNeeded = true;
|
||||
Locations* locations;
|
||||
SkinLocations* skinLocations;
|
||||
GLenum specularTextureUnit;
|
||||
GLenum emissiveTextureUnit;
|
||||
|
||||
foreach(Model* model, _modelsInScene) {
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasEmissive, hasTangents, hasSpecular, isSkinned);
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
if (whichList) {
|
||||
QVector<int>& list = *whichList;
|
||||
if (list.size() > 0) {
|
||||
if (pickProgramsNeeded) {
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasEmissive, hasTangents, hasSpecular, isSkinned, args, skinLocations, specularTextureUnit, emissiveTextureUnit);
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
|
||||
pickProgramsNeeded = false;
|
||||
}
|
||||
model->setupBatchTransform(batch);
|
||||
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, skinLocations, specularTextureUnit, emissiveTextureUnit);
|
||||
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
|
||||
GLBATCH(glPopMatrix)();
|
||||
}
|
||||
}
|
||||
|
@ -2284,12 +2195,12 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
}
|
||||
|
||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasEmissive, hasTangents, hasSpecular, isSkinned);
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
if (!whichList) {
|
||||
qDebug() << "unexpected!!! we don't know which list of meshes to render...";
|
||||
|
@ -2302,11 +2213,10 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
return 0;
|
||||
}
|
||||
|
||||
Locations* locations;
|
||||
SkinLocations* skinLocations;
|
||||
GLenum specularTextureUnit;
|
||||
GLenum emissiveTextureUnit;
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasEmissive, hasTangents, hasSpecular, isSkinned, args, skinLocations, specularTextureUnit, emissiveTextureUnit);
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, skinLocations, specularTextureUnit, emissiveTextureUnit);
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
|
||||
GLBATCH(glUseProgram)(0);
|
||||
|
||||
return meshPartsRendered;
|
||||
|
@ -2314,7 +2224,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
|
||||
|
||||
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
|
||||
SkinLocations* skinLocations, GLenum specularTextureUnit, GLenum emissiveTextureUnit) {
|
||||
Locations* locations, SkinLocations* skinLocations) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts);
|
||||
bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts);
|
||||
|
@ -2431,7 +2341,7 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
|
||||
GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular);
|
||||
GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, (part.shininess > 128.0f ? 128.0f: part.shininess));
|
||||
|
||||
|
||||
Texture* diffuseMap = networkPart.diffuseTexture.data();
|
||||
if (mesh.isEye && diffuseMap) {
|
||||
diffuseMap = (_dilatedTextures[i][j] =
|
||||
|
@ -2439,7 +2349,18 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
}
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !diffuseMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
|
||||
|
||||
|
||||
if (locations->texcoordMatrices >= 0) {
|
||||
glm::mat4 texcoordTransform[2];
|
||||
if (!part.diffuseTexture.transform.isIdentity()) {
|
||||
part.diffuseTexture.transform.getMatrix(texcoordTransform[0]);
|
||||
}
|
||||
if (!part.emissiveTexture.transform.isIdentity()) {
|
||||
part.emissiveTexture.transform.getMatrix(texcoordTransform[1]);
|
||||
}
|
||||
GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);
|
||||
}
|
||||
|
||||
if (!mesh.tangents.isEmpty()) {
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE1);
|
||||
Texture* normalMap = networkPart.normalTexture.data();
|
||||
|
@ -2448,19 +2369,20 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (specularTextureUnit) {
|
||||
GLBATCH(glActiveTexture)(specularTextureUnit);
|
||||
if (locations->specularTextureUnit >= 0) {
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->specularTextureUnit);
|
||||
Texture* specularMap = networkPart.specularTexture.data();
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !specularMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID());
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (emissiveTextureUnit) {
|
||||
GLBATCH(glActiveTexture)(emissiveTextureUnit);
|
||||
if (locations->emissiveTextureUnit >= 0) {
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit);
|
||||
Texture* emissiveMap = networkPart.emissiveTexture.data();
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID());
|
||||
// GLBATCH(glBindTexture)(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getWhiteTextureID());
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
|
@ -2498,14 +2420,14 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (specularTextureUnit) {
|
||||
GLBATCH(glActiveTexture)(specularTextureUnit);
|
||||
if (locations->specularTextureUnit >= 0) {
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->specularTextureUnit);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (emissiveTextureUnit) {
|
||||
GLBATCH(glActiveTexture)(emissiveTextureUnit);
|
||||
if (locations->emissiveTextureUnit >= 0) {
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit);
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
|
|
@ -304,10 +304,10 @@ private:
|
|||
static ProgramObject _normalSpecularMapProgram;
|
||||
static ProgramObject _translucentProgram;
|
||||
|
||||
static ProgramObject _emissiveProgram;
|
||||
static ProgramObject _emissiveNormalMapProgram;
|
||||
static ProgramObject _emissiveSpecularMapProgram;
|
||||
static ProgramObject _emissiveNormalSpecularMapProgram;
|
||||
static ProgramObject _lightmapProgram;
|
||||
static ProgramObject _lightmapNormalMapProgram;
|
||||
static ProgramObject _lightmapSpecularMapProgram;
|
||||
static ProgramObject _lightmapNormalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _shadowProgram;
|
||||
|
||||
|
@ -317,11 +317,6 @@ private:
|
|||
static ProgramObject _skinNormalSpecularMapProgram;
|
||||
static ProgramObject _skinTranslucentProgram;
|
||||
|
||||
static ProgramObject _skinEmissiveProgram;
|
||||
static ProgramObject _skinEmissiveNormalMapProgram;
|
||||
static ProgramObject _skinEmissiveSpecularMapProgram;
|
||||
static ProgramObject _skinEmissiveNormalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _skinShadowProgram;
|
||||
|
||||
static int _normalMapTangentLocation;
|
||||
|
@ -331,6 +326,9 @@ private:
|
|||
public:
|
||||
int tangent;
|
||||
int alphaThreshold;
|
||||
int texcoordMatrices;
|
||||
int specularTextureUnit;
|
||||
int emissiveTextureUnit;
|
||||
};
|
||||
|
||||
static Locations _locations;
|
||||
|
@ -339,10 +337,10 @@ private:
|
|||
static Locations _normalSpecularMapLocations;
|
||||
static Locations _translucentLocations;
|
||||
|
||||
static Locations _emissiveLocations;
|
||||
static Locations _emissiveNormalMapLocations;
|
||||
static Locations _emissiveSpecularMapLocations;
|
||||
static Locations _emissiveNormalSpecularMapLocations;
|
||||
static Locations _lightmapLocations;
|
||||
static Locations _lightmapNormalMapLocations;
|
||||
static Locations _lightmapSpecularMapLocations;
|
||||
static Locations _lightmapNormalSpecularMapLocations;
|
||||
|
||||
static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1);
|
||||
|
||||
|
@ -350,7 +348,7 @@ private:
|
|||
public:
|
||||
int clusterMatrices;
|
||||
int clusterIndices;
|
||||
int clusterWeights;
|
||||
int clusterWeights;
|
||||
};
|
||||
|
||||
static SkinLocations _skinLocations;
|
||||
|
@ -360,11 +358,6 @@ private:
|
|||
static SkinLocations _skinShadowLocations;
|
||||
static SkinLocations _skinTranslucentLocations;
|
||||
|
||||
static SkinLocations _skinEmissiveLocations;
|
||||
static SkinLocations _skinEmissiveNormalMapLocations;
|
||||
static SkinLocations _skinEmissiveSpecularMapLocations;
|
||||
static SkinLocations _skinEmissiveNormalSpecularMapLocations;
|
||||
|
||||
static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1);
|
||||
|
||||
QVector<AABox> _calculatedMeshBoxes;
|
||||
|
@ -396,15 +389,10 @@ private:
|
|||
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecularSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueSpecularSkinned;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissive;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveTangents;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveTangentsSpecular;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveSpecular;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveTangentsSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveTangentsSpecularSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueEmissiveSpecularSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmap;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangents;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangentsSpecular;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapSpecular;
|
||||
|
||||
QVector<int> _meshesTranslucent;
|
||||
QVector<int> _meshesTranslucentTangents;
|
||||
|
@ -426,15 +414,11 @@ private:
|
|||
QVector<int> _meshesOpaqueTangentsSpecularSkinned;
|
||||
QVector<int> _meshesOpaqueSpecularSkinned;
|
||||
|
||||
QVector<int> _meshesOpaqueEmissive;
|
||||
QVector<int> _meshesOpaqueEmissiveTangents;
|
||||
QVector<int> _meshesOpaqueEmissiveTangentsSpecular;
|
||||
QVector<int> _meshesOpaqueEmissiveSpecular;
|
||||
QVector<int> _meshesOpaqueLightmap;
|
||||
QVector<int> _meshesOpaqueLightmapTangents;
|
||||
QVector<int> _meshesOpaqueLightmapTangentsSpecular;
|
||||
QVector<int> _meshesOpaqueLightmapSpecular;
|
||||
|
||||
QVector<int> _meshesOpaqueEmissiveSkinned;
|
||||
QVector<int> _meshesOpaqueEmissiveTangentsSkinned;
|
||||
QVector<int> _meshesOpaqueEmissiveTangentsSpecularSkinned;
|
||||
QVector<int> _meshesOpaqueEmissiveSpecularSkinned;
|
||||
|
||||
// Scene rendering support
|
||||
static QVector<Model*> _modelsInScene;
|
||||
|
@ -447,19 +431,19 @@ private:
|
|||
void renderSetup(RenderArgs* args);
|
||||
bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
|
||||
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL);
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL);
|
||||
void setupBatchTransform(gpu::Batch& batch);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||
|
||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
RenderArgs* args, SkinLocations* skinLocations, GLenum specularTextureUnit, GLenum emissiveTextureUnit);
|
||||
RenderArgs* args, Locations* locations, SkinLocations* skinLocations);
|
||||
|
||||
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
SkinLocations*& skinLocations, GLenum& specularTextureUnit, GLenum& emissiveTextureUnit);
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
Locations*& locations, SkinLocations*& skinLocations);
|
||||
|
||||
static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasEmissive, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args);
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -32,6 +32,48 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
struct TextureParam {
|
||||
glm::vec2 UVTranslation;
|
||||
glm::vec2 UVScaling;
|
||||
glm::vec4 cropping;
|
||||
std::string UVSet;
|
||||
|
||||
glm::vec3 translation;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scaling;
|
||||
uint8_t alphaSource;
|
||||
uint8_t currentTextureBlendMode;
|
||||
bool useMaterial;
|
||||
|
||||
template <typename T>
|
||||
bool assign(T& ref, const T& v) {
|
||||
if (ref == v) {
|
||||
return false;
|
||||
} else {
|
||||
ref = v;
|
||||
isDefault = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isDefault;
|
||||
|
||||
TextureParam() :
|
||||
UVTranslation(0.0f),
|
||||
UVScaling(1.0f),
|
||||
cropping(0.0f),
|
||||
UVSet("map1"),
|
||||
translation(0.0f),
|
||||
rotation(0.0f),
|
||||
scaling(1.0f),
|
||||
alphaSource(0),
|
||||
currentTextureBlendMode(0),
|
||||
useMaterial(true),
|
||||
isDefault(true)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
bool FBXMesh::hasSpecularTexture() const {
|
||||
foreach (const FBXMeshPart& part, parts) {
|
||||
if (!part.specularTexture.filename.isEmpty()) {
|
||||
|
@ -718,6 +760,7 @@ class Vertex {
|
|||
public:
|
||||
int originalIndex;
|
||||
glm::vec2 texCoord;
|
||||
glm::vec2 texCoord1;
|
||||
};
|
||||
|
||||
uint qHash(const Vertex& vertex, uint seed = 0) {
|
||||
|
@ -725,7 +768,7 @@ uint qHash(const Vertex& vertex, uint seed = 0) {
|
|||
}
|
||||
|
||||
bool operator==(const Vertex& v1, const Vertex& v2) {
|
||||
return v1.originalIndex == v2.originalIndex && v1.texCoord == v2.texCoord;
|
||||
return v1.originalIndex == v2.originalIndex && v1.texCoord == v2.texCoord && v1.texCoord1 == v2.texCoord1;
|
||||
}
|
||||
|
||||
class ExtractedMesh {
|
||||
|
@ -734,6 +777,16 @@ public:
|
|||
QMultiHash<int, int> newIndices;
|
||||
QVector<QHash<int, int> > blendshapeIndexMaps;
|
||||
QVector<QPair<int, int> > partMaterialTextures;
|
||||
QHash<QString, int> texcoordSetMap;
|
||||
std::map<std::string, int> texcoordSetMap2;
|
||||
};
|
||||
|
||||
class AttributeData {
|
||||
public:
|
||||
QVector<glm::vec2> texCoords;
|
||||
QVector<int> texCoordIndices;
|
||||
std::string name;
|
||||
int index;
|
||||
};
|
||||
|
||||
class MeshData {
|
||||
|
@ -748,6 +801,8 @@ public:
|
|||
QVector<int> texCoordIndices;
|
||||
|
||||
QHash<Vertex, int> indices;
|
||||
|
||||
std::vector<AttributeData> attributes;
|
||||
};
|
||||
|
||||
void appendIndex(MeshData& data, QVector<int>& indices, int index) {
|
||||
|
@ -789,6 +844,20 @@ void appendIndex(MeshData& data, QVector<int>& indices, int index) {
|
|||
vertex.texCoord = data.texCoords.at(texCoordIndex);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasMoreTexcoords = (data.attributes.size() > 1);
|
||||
if (hasMoreTexcoords) {
|
||||
if (data.attributes[1].texCoordIndices.empty()) {
|
||||
if (index < data.attributes[1].texCoords.size()) {
|
||||
vertex.texCoord1 = data.attributes[1].texCoords.at(index);
|
||||
}
|
||||
} else if (index < data.attributes[1].texCoordIndices.size()) {
|
||||
int texCoordIndex = data.attributes[1].texCoordIndices.at(index);
|
||||
if (texCoordIndex >= 0 && texCoordIndex < data.attributes[1].texCoords.size()) {
|
||||
vertex.texCoord1 = data.attributes[1].texCoords.at(texCoordIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<Vertex, int>::const_iterator it = data.indices.find(vertex);
|
||||
if (it == data.indices.constEnd()) {
|
||||
|
@ -799,7 +868,7 @@ void appendIndex(MeshData& data, QVector<int>& indices, int index) {
|
|||
data.extracted.mesh.vertices.append(position);
|
||||
data.extracted.mesh.normals.append(normal);
|
||||
data.extracted.mesh.texCoords.append(vertex.texCoord);
|
||||
|
||||
if (hasMoreTexcoords) { data.extracted.mesh.texCoords1.append(vertex.texCoord1); }
|
||||
} else {
|
||||
indices.append(*it);
|
||||
data.extracted.mesh.normals[*it] += normal;
|
||||
|
@ -838,13 +907,61 @@ ExtractedMesh extractMesh(const FBXNode& object) {
|
|||
// hack to work around wacky Makehuman exports
|
||||
data.normalsByVertex = true;
|
||||
}
|
||||
} else if (child.name == "LayerElementUV" && child.properties.at(0).toInt() == 0) {
|
||||
foreach (const FBXNode& subdata, child.children) {
|
||||
if (subdata.name == "UV") {
|
||||
data.texCoords = createVec2Vector(getDoubleVector(subdata));
|
||||
} else if (child.name == "LayerElementUV") {
|
||||
if (child.properties.at(0).toInt() == 0) {
|
||||
AttributeData attrib;
|
||||
attrib.index = child.properties.at(0).toInt();
|
||||
int unknown = 0;
|
||||
foreach (const FBXNode& subdata, child.children) {
|
||||
if (subdata.name == "UV") {
|
||||
data.texCoords = createVec2Vector(getDoubleVector(subdata));
|
||||
attrib.texCoords = createVec2Vector(getDoubleVector(subdata));
|
||||
} else if (subdata.name == "UVIndex") {
|
||||
data.texCoordIndices = getIntVector(subdata);
|
||||
attrib.texCoordIndices = getIntVector(subdata);
|
||||
} else if (subdata.name == "Name") {
|
||||
attrib.name = subdata.properties.at(0).toString().toStdString();
|
||||
} else {
|
||||
std::string subname = subdata.name.data();
|
||||
if (subdata.name == "Version") {
|
||||
} else if (subdata.name == "MappingInformationType") {
|
||||
} else if (subdata.name == "ReferenceInformationType") {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
}
|
||||
data.extracted.texcoordSetMap.insert(QString(attrib.name.c_str()), data.attributes.size());
|
||||
data.attributes.push_back(attrib);
|
||||
} else {
|
||||
AttributeData attrib;
|
||||
attrib.index = child.properties.at(0).toInt();
|
||||
int unknown = 0;
|
||||
foreach (const FBXNode& subdata, child.children) {
|
||||
if (subdata.name == "UV") {
|
||||
attrib.texCoords = createVec2Vector(getDoubleVector(subdata));
|
||||
} else if (subdata.name == "UVIndex") {
|
||||
attrib.texCoordIndices = getIntVector(subdata);
|
||||
} else if (subdata.name == "Name") {
|
||||
attrib.name = subdata.properties.at(0).toString().toStdString();
|
||||
} else {
|
||||
std::string subname = subdata.name.data();
|
||||
if (subdata.name == "Version") {
|
||||
} else if (subdata.name == "MappingInformationType") {
|
||||
} else if (subdata.name == "ReferenceInformationType") {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (subdata.name == "UVIndex") {
|
||||
data.texCoordIndices = getIntVector(subdata);
|
||||
QHash<QString, int>::iterator it = data.extracted.texcoordSetMap.find(QString(attrib.name.c_str()));
|
||||
if (it == data.extracted.texcoordSetMap.end()) {
|
||||
data.extracted.texcoordSetMap.insert(QString(attrib.name.c_str()), data.attributes.size());
|
||||
data.attributes.push_back(attrib);
|
||||
} else {
|
||||
// WTF same names for different UVs?
|
||||
unknown = data.attributes.size();
|
||||
}
|
||||
}
|
||||
} else if (child.name == "LayerElementMaterial") {
|
||||
|
@ -1014,11 +1131,27 @@ public:
|
|||
FBXTexture getTexture(const QString& textureID,
|
||||
const QHash<QString, QString>& textureNames,
|
||||
const QHash<QString, QByteArray>& textureFilenames,
|
||||
const QHash<QByteArray, QByteArray>& textureContent) {
|
||||
const QHash<QByteArray, QByteArray>& textureContent,
|
||||
const QHash<QString, TextureParam>& textureParams) {
|
||||
FBXTexture texture;
|
||||
texture.filename = textureFilenames.value(textureID);
|
||||
texture.name = textureNames.value(textureID);
|
||||
texture.content = textureContent.value(texture.filename);
|
||||
texture.transform.setIdentity();
|
||||
texture.texcoordSet = 0;
|
||||
QHash<QString, TextureParam>::const_iterator it = textureParams.constFind(textureID);
|
||||
if (it != textureParams.end()) {
|
||||
const TextureParam& p = (*it);
|
||||
texture.transform.setTranslation(p.translation);
|
||||
texture.transform.setRotation(glm::quat(glm::radians(p.rotation)));
|
||||
texture.transform.setScale(p.scaling);
|
||||
if (p.UVSet != "map1" || (p.UVSet != "UVSet0")) {
|
||||
texture.texcoordSet = 1;
|
||||
}
|
||||
|
||||
texture.texcoordSetName = p.UVSet;
|
||||
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
@ -1034,6 +1167,23 @@ bool checkMaterialsHaveTextures(const QHash<QString, Material>& materials,
|
|||
return false;
|
||||
}
|
||||
|
||||
int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const QHash<QString, int>& texcoordChannels) {
|
||||
if (texUVSetName.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
QHash<QString, int>::const_iterator tcUnit = texcoordChannels.find(QString(texUVSetName.c_str()));
|
||||
if (tcUnit != texcoordChannels.end()) {
|
||||
int channel = (*tcUnit);
|
||||
if (channel >= 2) {
|
||||
channel = 0;
|
||||
}
|
||||
return channel;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
|
@ -1048,6 +1198,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
QHash<QString, AnimationCurve> animationCurves;
|
||||
QHash<QString, QString> textureNames;
|
||||
QHash<QString, QByteArray> textureFilenames;
|
||||
QHash<QString, TextureParam> textureParams;
|
||||
QHash<QByteArray, QByteArray> textureContent;
|
||||
QHash<QString, Material> materials;
|
||||
QHash<QString, QString> typeFlags;
|
||||
|
@ -1109,7 +1260,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
}
|
||||
}
|
||||
QMultiHash<QString, WeightedIndex> blendshapeChannelIndices;
|
||||
|
||||
int unknown = 0;
|
||||
FBXGeometry geometry;
|
||||
float unitScaleFactor = 1.0f;
|
||||
foreach (const FBXNode& child, node.children) {
|
||||
|
@ -1312,7 +1463,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
models.insert(getID(object.properties), model);
|
||||
|
||||
} else if (object.name == "Texture") {
|
||||
TextureParam tex;
|
||||
bool texparam = false;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
std::string subname = subobject.name.data();
|
||||
if (subobject.name == "RelativeFilename") {
|
||||
// trim off any path information
|
||||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
|
@ -1323,8 +1477,60 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
QString name = QString(subobject.properties.at(0).toByteArray());
|
||||
name = name.left(name.indexOf('['));
|
||||
textureNames.insert(getID(object.properties), name);
|
||||
} else if (subobject.name == "Texture_Alpha_Source") {
|
||||
tex.assign<uint8_t>(tex.alphaSource, subobject.properties.at(0).value<int>());
|
||||
} else if (subobject.name == "ModelUVTranslation") {
|
||||
tex.assign(tex.UVTranslation, glm::vec2(subobject.properties.at(0).value<double>(),
|
||||
subobject.properties.at(1).value<double>()));
|
||||
} else if (subobject.name == "ModelUVScaling") {
|
||||
tex.assign(tex.UVScaling, glm::vec2(subobject.properties.at(0).value<double>(),
|
||||
subobject.properties.at(1).value<double>()));
|
||||
} else if (subobject.name == "Cropping") {
|
||||
tex.assign(tex.cropping, glm::vec4(subobject.properties.at(0).value<int>(),
|
||||
subobject.properties.at(1).value<int>(),
|
||||
subobject.properties.at(2).value<int>(),
|
||||
subobject.properties.at(3).value<int>()));
|
||||
} else if (subobject.name == "Properties70") {
|
||||
|
||||
QByteArray propertyName;
|
||||
int index;
|
||||
propertyName = "P";
|
||||
index = 4;
|
||||
foreach (const FBXNode& property, subobject.children) {
|
||||
if (property.name == propertyName) {
|
||||
QString v = property.properties.at(0).toString();
|
||||
std::string propName = v.toStdString();
|
||||
if (property.properties.at(0) == "UVSet") {
|
||||
tex.assign(tex.UVSet, property.properties.at(index).toString().toStdString());
|
||||
} else if (property.properties.at(0) == "CurrentTextureBlendMode") {
|
||||
tex.assign<uint8_t>(tex.currentTextureBlendMode, property.properties.at(index).value<int>());
|
||||
} else if (property.properties.at(0) == "UseMaterial") {
|
||||
tex.assign<bool>(tex.useMaterial, property.properties.at(index).value<int>());
|
||||
} else if (property.properties.at(0) == "Translation") {
|
||||
tex.assign(tex.translation, getVec3(property.properties, index));
|
||||
} else if (property.properties.at(0) == "Rotation") {
|
||||
tex.assign(tex.rotation, getVec3(property.properties, index));
|
||||
} else if (property.properties.at(0) == "Scaling") {
|
||||
tex.assign(tex.scaling, getVec3(property.properties, index));
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (subobject.name == "Type") {
|
||||
} else if (subobject.name == "Version") {
|
||||
} else if (subobject.name == "FileName") {
|
||||
} else if (subobject.name == "Media") {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tex.isDefault) {
|
||||
textureParams.insert(getID(object.properties), tex);
|
||||
}
|
||||
} else if (object.name == "Video") {
|
||||
QByteArray filename;
|
||||
QByteArray content;
|
||||
|
@ -1670,47 +1876,63 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
const QString& childID = children.at(i);
|
||||
if (materials.contains(childID)) {
|
||||
Material material = materials.value(childID);
|
||||
|
||||
bool detectDifferentUVs = false;
|
||||
FBXTexture diffuseTexture;
|
||||
QString diffuseTextureID = diffuseTextures.value(childID);
|
||||
if (!diffuseTextureID.isNull()) {
|
||||
diffuseTexture = getTexture(diffuseTextureID, textureNames, textureFilenames, textureContent);
|
||||
diffuseTexture = getTexture(diffuseTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
|
||||
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
|
||||
foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) {
|
||||
if (textureFilenames.contains(childTextureID)) {
|
||||
diffuseTexture = getTexture(diffuseTextureID, textureNames, textureFilenames, textureContent);
|
||||
diffuseTexture = getTexture(diffuseTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
}
|
||||
}
|
||||
diffuseTexture.texcoordSet = matchTextureUVSetToAttributeChannel(diffuseTexture.texcoordSetName, extracted.texcoordSetMap);
|
||||
|
||||
detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture normalTexture;
|
||||
QString bumpTextureID = bumpTextures.value(childID);
|
||||
if (!bumpTextureID.isNull()) {
|
||||
normalTexture = getTexture(bumpTextureID, textureNames, textureFilenames, textureContent);
|
||||
normalTexture = getTexture(bumpTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
generateTangents = true;
|
||||
|
||||
normalTexture.texcoordSet = matchTextureUVSetToAttributeChannel(normalTexture.texcoordSetName, extracted.texcoordSetMap);
|
||||
|
||||
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture specularTexture;
|
||||
QString specularTextureID = specularTextures.value(childID);
|
||||
if (!specularTextureID.isNull()) {
|
||||
specularTexture = getTexture(specularTextureID, textureNames, textureFilenames, textureContent);
|
||||
specularTexture = getTexture(specularTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
specularTexture.texcoordSet = matchTextureUVSetToAttributeChannel(specularTexture.texcoordSetName, extracted.texcoordSetMap);
|
||||
detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture emissiveTexture;
|
||||
QString emissiveTextureID = emissiveTextures.value(childID);
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent);
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
|
||||
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
|
||||
foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) {
|
||||
if (textureFilenames.contains(childTextureID)) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent);
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
}
|
||||
}
|
||||
|
||||
emissiveTexture.texcoordSet = matchTextureUVSetToAttributeChannel(emissiveTexture.texcoordSetName, extracted.texcoordSetMap);
|
||||
|
||||
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
if (detectDifferentUVs) {
|
||||
detectDifferentUVs = false;
|
||||
}
|
||||
|
||||
|
||||
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
||||
if (extracted.partMaterialTextures.at(j).first == materialIndex) {
|
||||
FBXMeshPart& part = extracted.mesh.parts[j];
|
||||
|
@ -1737,7 +1959,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
materialIndex++;
|
||||
|
||||
} else if (textureFilenames.contains(childID)) {
|
||||
FBXTexture texture = getTexture(childID, textureNames, textureFilenames, textureContent);
|
||||
FBXTexture texture = getTexture(childID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
||||
int partTexture = extracted.partMaterialTextures.at(j).second;
|
||||
if (partTexture == textureIndex && !(partTexture == 0 && materialsHaveTextures)) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <QVector>
|
||||
|
||||
#include <Extents.h>
|
||||
#include <Transform.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
@ -102,6 +103,10 @@ public:
|
|||
QString name;
|
||||
QByteArray filename;
|
||||
QByteArray content;
|
||||
|
||||
Transform transform;
|
||||
int texcoordSet;
|
||||
std::string texcoordSetName;
|
||||
};
|
||||
|
||||
/// A single part of a mesh (with the same material).
|
||||
|
@ -136,13 +141,14 @@ public:
|
|||
QVector<glm::vec3> tangents;
|
||||
QVector<glm::vec3> colors;
|
||||
QVector<glm::vec2> texCoords;
|
||||
QVector<glm::vec2> texCoords1;
|
||||
QVector<glm::vec4> clusterIndices;
|
||||
QVector<glm::vec4> clusterWeights;
|
||||
|
||||
QVector<FBXCluster> clusters;
|
||||
|
||||
Extents meshExtents;
|
||||
|
||||
|
||||
bool isEye;
|
||||
|
||||
QVector<FBXBlendshape> blendshapes;
|
||||
|
|
|
@ -136,7 +136,10 @@ protected:
|
|||
void invalidCache() const { _flags.set(FLAG_CACHE_INVALID, true); }
|
||||
|
||||
void flagTranslation() { _flags.set(FLAG_TRANSLATION, true); }
|
||||
void unflagTranslation() { _flags.set(FLAG_TRANSLATION, false); }
|
||||
|
||||
void flagRotation() { _flags.set(FLAG_ROTATION, true); }
|
||||
void unflagRotation() { _flags.set(FLAG_ROTATION, false); }
|
||||
|
||||
void flagScaling() { _flags.set(FLAG_SCALING, true); }
|
||||
void unflagScaling() { _flags.set(FLAG_SCALING, false); }
|
||||
|
@ -162,17 +165,23 @@ inline const Transform::Vec3& Transform::getTranslation() const {
|
|||
|
||||
inline void Transform::setTranslation(const Vec3& translation) {
|
||||
invalidCache();
|
||||
flagTranslation();
|
||||
if (translation == Vec3()) {
|
||||
unflagTranslation();
|
||||
} else {
|
||||
flagTranslation();
|
||||
}
|
||||
_translation = translation;
|
||||
}
|
||||
|
||||
inline void Transform::preTranslate(const Vec3& translation) {
|
||||
if (translation == Vec3() ) return;
|
||||
invalidCache();
|
||||
flagTranslation();
|
||||
_translation += translation;
|
||||
}
|
||||
|
||||
inline void Transform::postTranslate(const Vec3& translation) {
|
||||
if (translation == Vec3() ) return;
|
||||
invalidCache();
|
||||
flagTranslation();
|
||||
|
||||
|
@ -192,11 +201,16 @@ inline const Transform::Quat& Transform::getRotation() const {
|
|||
|
||||
inline void Transform::setRotation(const Quat& rotation) {
|
||||
invalidCache();
|
||||
flagRotation();
|
||||
if (rotation == Quat()) {
|
||||
unflagRotation();
|
||||
} else {
|
||||
flagRotation();
|
||||
}
|
||||
_rotation = rotation;
|
||||
}
|
||||
|
||||
inline void Transform::preRotate(const Quat& rotation) {
|
||||
if (rotation == Quat()) return;
|
||||
invalidCache();
|
||||
if (isRotating()) {
|
||||
_rotation = rotation * _rotation;
|
||||
|
@ -204,10 +218,12 @@ inline void Transform::preRotate(const Quat& rotation) {
|
|||
_rotation = rotation;
|
||||
}
|
||||
flagRotation();
|
||||
|
||||
_translation = glm::rotate(rotation, _translation);
|
||||
}
|
||||
|
||||
inline void Transform::postRotate(const Quat& rotation) {
|
||||
if (rotation == Quat()) return;
|
||||
invalidCache();
|
||||
|
||||
if (isNonUniform()) {
|
||||
|
|
Loading…
Reference in a new issue