Merge pull request #3955 from ey6es/master

Fix for normal and specular maps on skinned models.
This commit is contained in:
Philip Rosedale 2014-12-11 15:23:59 -08:00
commit b160d5b571
2 changed files with 35 additions and 102 deletions

View file

@ -134,38 +134,21 @@ void Model::setOffset(const glm::vec3& offset) {
_snappedToRegistrationPoint = false; _snappedToRegistrationPoint = false;
} }
void Model::initProgram(ProgramObject& program, Model::Locations& locations, int specularTextureUnit) { void Model::initProgram(ProgramObject& program, Model::Locations& locations, bool link) {
if (link) {
program.bindAttributeLocation("tangent", gpu::Stream::TANGENT);
program.bindAttributeLocation("texcoord1", gpu::Stream::TEXCOORD1);
program.link();
}
program.bind(); program.bind();
#ifdef Q_OS_MAC
// HACK: Assign explicitely the attribute channel to avoid a bug on Yosemite
glBindAttribLocation(program.programId(), 4, "tangent");
glLinkProgram(program.programId());
#endif
glBindAttribLocation(program.programId(), gpu::Stream::TANGENT, "tangent");
glBindAttribLocation(program.programId(), gpu::Stream::TEXCOORD1, "texcoord1");
glLinkProgram(program.programId());
locations.tangent = program.attributeLocation("tangent"); locations.tangent = program.attributeLocation("tangent");
locations.alphaThreshold = program.uniformLocation("alphaThreshold"); locations.alphaThreshold = program.uniformLocation("alphaThreshold");
locations.texcoordMatrices = program.uniformLocation("texcoordMatrices"); locations.texcoordMatrices = program.uniformLocation("texcoordMatrices");
locations.emissiveParams = program.uniformLocation("emissiveParams"); locations.emissiveParams = program.uniformLocation("emissiveParams");
program.setUniformValue("diffuseMap", 0); program.setUniformValue("diffuseMap", 0);
program.setUniformValue("normalMap", 1); program.setUniformValue("normalMap", 1);
int loc = program.uniformLocation("specularMap"); int loc = program.uniformLocation("specularMap");
@ -184,50 +167,22 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, int
locations.emissiveTextureUnit = -1; locations.emissiveTextureUnit = -1;
} }
if (!program.isLinked()) {
program.release(); program.release();
} }
program.release(); void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) {
program.bindAttributeLocation("tangent", gpu::Stream::TANGENT);
program.bindAttributeLocation("texcoord1", gpu::Stream::TEXCOORD1);
program.bindAttributeLocation("clusterIndices", gpu::Stream::SKIN_CLUSTER_INDEX);
program.bindAttributeLocation("clusterWeights", gpu::Stream::SKIN_CLUSTER_WEIGHT);
program.link();
} initProgram(program, locations, false);
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations, int specularTextureUnit) {
initProgram(program, locations, specularTextureUnit);
#ifdef Q_OS_MAC
// HACK: Assign explicitely the attribute channel to avoid a bug on Yosemite
glBindAttribLocation(program.programId(), 5, "clusterIndices");
glBindAttribLocation(program.programId(), 6, "clusterWeights");
glLinkProgram(program.programId());
#endif
// HACK: Assign explicitely the attribute channel to avoid a bug on Yosemite
glBindAttribLocation(program.programId(), gpu::Stream::SKIN_CLUSTER_INDEX, "clusterIndices");
glBindAttribLocation(program.programId(), gpu::Stream::SKIN_CLUSTER_WEIGHT, "clusterWeights");
glLinkProgram(program.programId());
program.bind(); program.bind();
locations.clusterMatrices = program.uniformLocation("clusterMatrices"); locations.clusterMatrices = program.uniformLocation("clusterMatrices");
locations.clusterIndices = program.attributeLocation("clusterIndices"); locations.clusterIndices = program.attributeLocation("clusterIndices");
locations.clusterWeights = program.attributeLocation("clusterWeights"); locations.clusterWeights = program.attributeLocation("clusterWeights");
program.release(); program.release();
@ -269,7 +224,6 @@ void Model::init() {
if (!_program.isLinked()) { if (!_program.isLinked()) {
_program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert"); _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert");
_program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag"); _program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag");
_program.link();
initProgram(_program, _locations); initProgram(_program, _locations);
@ -277,7 +231,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/model_normal_map.vert"); Application::resourcesPath() + "shaders/model_normal_map.vert");
_normalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _normalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_normal_map.frag"); Application::resourcesPath() + "shaders/model_normal_map.frag");
_normalMapProgram.link();
initProgram(_normalMapProgram, _normalMapLocations); initProgram(_normalMapProgram, _normalMapLocations);
@ -285,7 +238,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/model.vert"); Application::resourcesPath() + "shaders/model.vert");
_specularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _specularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_specular_map.frag"); Application::resourcesPath() + "shaders/model_specular_map.frag");
_specularMapProgram.link();
initProgram(_specularMapProgram, _specularMapLocations); initProgram(_specularMapProgram, _specularMapLocations);
@ -293,22 +245,19 @@ void Model::init() {
Application::resourcesPath() + "shaders/model_normal_map.vert"); Application::resourcesPath() + "shaders/model_normal_map.vert");
_normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_normal_specular_map.frag"); Application::resourcesPath() + "shaders/model_normal_specular_map.frag");
_normalSpecularMapProgram.link();
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations, 2); initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
_translucentProgram.addShaderFromSourceFile(QGLShader::Vertex, _translucentProgram.addShaderFromSourceFile(QGLShader::Vertex,
Application::resourcesPath() + "shaders/model.vert"); Application::resourcesPath() + "shaders/model.vert");
_translucentProgram.addShaderFromSourceFile(QGLShader::Fragment, _translucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_translucent.frag"); Application::resourcesPath() + "shaders/model_translucent.frag");
_translucentProgram.link();
initProgram(_translucentProgram, _translucentLocations); initProgram(_translucentProgram, _translucentLocations);
// Lightmap // Lightmap
_lightmapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_lightmap.vert"); _lightmapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_lightmap.vert");
_lightmapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_lightmap.frag"); _lightmapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_lightmap.frag");
_lightmapProgram.link();
initProgram(_lightmapProgram, _lightmapLocations); initProgram(_lightmapProgram, _lightmapLocations);
@ -316,7 +265,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert"); Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
_lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_lightmap_normal_map.frag"); Application::resourcesPath() + "shaders/model_lightmap_normal_map.frag");
_lightmapNormalMapProgram.link();
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations); initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
@ -324,7 +272,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/model_lightmap.vert"); Application::resourcesPath() + "shaders/model_lightmap.vert");
_lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_lightmap_specular_map.frag"); Application::resourcesPath() + "shaders/model_lightmap_specular_map.frag");
_lightmapSpecularMapProgram.link();
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations); initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
@ -332,20 +279,17 @@ void Model::init() {
Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert"); Application::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
_lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_lightmap_normal_specular_map.frag"); Application::resourcesPath() + "shaders/model_lightmap_normal_specular_map.frag");
_lightmapNormalSpecularMapProgram.link();
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations, 2); initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
// end lightmap // end lightmap
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert"); _shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
_shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, _shadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_shadow.frag"); Application::resourcesPath() + "shaders/model_shadow.frag");
_shadowProgram.link();
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert"); _skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert");
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag"); _skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag");
_skinProgram.link();
initSkinProgram(_skinProgram, _skinLocations); initSkinProgram(_skinProgram, _skinLocations);
@ -353,7 +297,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_normal_map.frag"); Application::resourcesPath() + "shaders/model_normal_map.frag");
_skinNormalMapProgram.link();
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations); initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
@ -361,7 +304,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/skin_model.vert"); Application::resourcesPath() + "shaders/skin_model.vert");
_skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_specular_map.frag"); Application::resourcesPath() + "shaders/model_specular_map.frag");
_skinSpecularMapProgram.link();
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations); initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
@ -369,15 +311,13 @@ void Model::init() {
Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
_skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, _skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_normal_specular_map.frag"); Application::resourcesPath() + "shaders/model_normal_specular_map.frag");
_skinNormalSpecularMapProgram.link();
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations, 2); initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations);
_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,
Application::resourcesPath() + "shaders/model_shadow.frag"); Application::resourcesPath() + "shaders/model_shadow.frag");
_skinShadowProgram.link();
initSkinProgram(_skinShadowProgram, _skinShadowLocations); initSkinProgram(_skinShadowProgram, _skinShadowLocations);
@ -385,7 +325,6 @@ void Model::init() {
Application::resourcesPath() + "shaders/skin_model.vert"); Application::resourcesPath() + "shaders/skin_model.vert");
_skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment, _skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
Application::resourcesPath() + "shaders/model_translucent.frag"); Application::resourcesPath() + "shaders/model_translucent.frag");
_skinTranslucentProgram.link();
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations); initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
} }
@ -600,8 +539,6 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face)) { if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face)) {
float bestDistance = std::numeric_limits<float>::max(); float bestDistance = std::numeric_limits<float>::max();
float bestTriangleDistance = std::numeric_limits<float>::max();
bool someTriangleHit = false;
float distanceToSubMesh; float distanceToSubMesh;
BoxFace subMeshFace; BoxFace subMeshFace;
@ -615,7 +552,6 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) { if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) {
if (distanceToSubMesh < bestDistance) { if (distanceToSubMesh < bestDistance) {
if (pickAgainstTriangles) { if (pickAgainstTriangles) {
someTriangleHit = false;
if (!_calculatedMeshTrianglesValid) { if (!_calculatedMeshTrianglesValid) {
recalculateMeshBoxes(pickAgainstTriangles); recalculateMeshBoxes(pickAgainstTriangles);
} }
@ -628,9 +564,6 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
float thisTriangleDistance; float thisTriangleDistance;
if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) { if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) {
if (thisTriangleDistance < bestDistance) { if (thisTriangleDistance < bestDistance) {
bestTriangleDistance = thisTriangleDistance;
someTriangleHit = true;
bestDistance = thisTriangleDistance; bestDistance = thisTriangleDistance;
intersectedSomething = true; intersectedSomething = true;
face = subMeshFace; face = subMeshFace;

View file

@ -347,7 +347,7 @@ private:
static Locations _lightmapSpecularMapLocations; static Locations _lightmapSpecularMapLocations;
static Locations _lightmapNormalSpecularMapLocations; static Locations _lightmapNormalSpecularMapLocations;
static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1); static void initProgram(ProgramObject& program, Locations& locations, bool link = true);
class SkinLocations : public Locations { class SkinLocations : public Locations {
public: public:
@ -363,7 +363,7 @@ private:
static SkinLocations _skinShadowLocations; static SkinLocations _skinShadowLocations;
static SkinLocations _skinTranslucentLocations; static SkinLocations _skinTranslucentLocations;
static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1); static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes
bool _calculatedMeshBoxesValid; bool _calculatedMeshBoxesValid;