예제 #1
0
파일: xformCommonAPI.cpp 프로젝트: JT-a/USD
static
bool
_IsMatrixIdentity(const GfMatrix4d& matrix)
{
    const GfMatrix4d IDENTITY(1.0);
    const double TOLERANCE = 1e-6;

    if (GfIsClose(matrix.GetRow(0), IDENTITY.GetRow(0), TOLERANCE)      &&
            GfIsClose(matrix.GetRow(1), IDENTITY.GetRow(1), TOLERANCE)  &&
            GfIsClose(matrix.GetRow(2), IDENTITY.GetRow(2), TOLERANCE)  &&
            GfIsClose(matrix.GetRow(3), IDENTITY.GetRow(3), TOLERANCE)) {
        return true;
    }

    return false;
}
예제 #2
0
void
GlfSimpleLightingContext::BindUniformBlocks(GlfBindingMapPtr const &bindingMap)
{
    if (not _lightingUniformBlock)
        _lightingUniformBlock = GlfUniformBlock::New();
    if (not _shadowUniformBlock)
        _shadowUniformBlock = GlfUniformBlock::New();
    if (not _materialUniformBlock)
        _materialUniformBlock = GlfUniformBlock::New();

    bool shadowExists = false;
    if ((not _lightingUniformBlockValid or
         not _shadowUniformBlockValid) and _lights.size() > 0) {
        int numLights = GetNumLightsUsed();

        // 16byte aligned
        struct LightSource {
            float position[4];
            float ambient[4];
            float diffuse[4];
            float specular[4];
            float spotDirection[4];
            float spotCutoff;
            float spotFalloff;
            float padding[2];
            float attenuation[4];
            bool hasShadow;
            int32_t shadowIndex;
            int32_t padding2[2];
        };

        struct Lighting {
            int32_t useLighting;
            int32_t useColorMaterialDiffuse;
            int32_t padding[2];
            LightSource lightSource[0];
        };

        // 16byte aligned
        struct ShadowMatrix {
            float viewToShadowMatrix[16];
            float basis0[4];
            float basis1[4];
            float basis2[4];
            float bias;
            float padding[3];
        };

        struct Shadow {
            ShadowMatrix shadow[0];
        };

        size_t lightingSize = sizeof(Lighting) + sizeof(LightSource) * numLights;
        size_t shadowSize = sizeof(ShadowMatrix) * numLights;
        Lighting *lightingData = (Lighting *)alloca(lightingSize);
        Shadow *shadowData = (Shadow *)alloca(shadowSize);

        memset(shadowData, 0, shadowSize);
        memset(lightingData, 0, lightingSize);

        GfMatrix4d viewToWorldMatrix = _worldToViewMatrix.GetInverse();

        lightingData->useLighting = _useLighting;
        lightingData->useColorMaterialDiffuse = _useColorMaterialDiffuse;

        for (int i = 0; _useLighting and i < numLights; ++i) {
            GlfSimpleLight const &light = _lights[i];

            setVec4(lightingData->lightSource[i].position,
                    light.GetPosition() * _worldToViewMatrix);
            setVec4(lightingData->lightSource[i].diffuse, light.GetDiffuse());
            setVec4(lightingData->lightSource[i].ambient, light.GetAmbient());
            setVec4(lightingData->lightSource[i].specular, light.GetSpecular());
            setVec3(lightingData->lightSource[i].spotDirection,
                    _worldToViewMatrix.TransformDir(light.GetSpotDirection()));
            setVec3(lightingData->lightSource[i].attenuation,
                    light.GetAttenuation());
            lightingData->lightSource[i].spotCutoff = light.GetSpotCutoff();
            lightingData->lightSource[i].spotFalloff = light.GetSpotFalloff();
            lightingData->lightSource[i].hasShadow = light.HasShadow();

            if (lightingData->lightSource[i].hasShadow) {
                int shadowIndex = light.GetShadowIndex();
                lightingData->lightSource[i].shadowIndex = shadowIndex;

                GfMatrix4d viewToShadowMatrix = viewToWorldMatrix *
                    _shadows->GetWorldToShadowMatrix(shadowIndex);

                double invBlur = 1.0/(std::max(0.0001F, light.GetShadowBlur()));
                GfMatrix4d mat = viewToShadowMatrix.GetInverse();
                GfVec4f xVec = GfVec4f(mat.GetRow(0) * invBlur);
                GfVec4f yVec = GfVec4f(mat.GetRow(1) * invBlur);
                GfVec4f zVec = GfVec4f(mat.GetRow(2));

                shadowData->shadow[shadowIndex].bias = light.GetShadowBias();
                setMatrix(shadowData->shadow[shadowIndex].viewToShadowMatrix,
                          viewToShadowMatrix);
                setVec4(shadowData->shadow[shadowIndex].basis0, xVec);
                setVec4(shadowData->shadow[shadowIndex].basis1, yVec);
                setVec4(shadowData->shadow[shadowIndex].basis2, zVec);

                shadowExists = true;
            }
        }

        _lightingUniformBlock->Update(lightingData, lightingSize);
        _lightingUniformBlockValid = true;

        if (shadowExists) {
            _shadowUniformBlock->Update(shadowData, shadowSize);
            _shadowUniformBlockValid = true;
        }
    }

    _lightingUniformBlock->Bind(bindingMap, _tokens->lightingUB);

    if (shadowExists) {
        _shadowUniformBlock->Bind(bindingMap, _tokens->shadowUB);
    }

    if (not _materialUniformBlockValid) {
        // has to be matched with the definition of simpleLightingShader.glslfx
        struct Material {
            float ambient[4];
            float diffuse[4];
            float specular[4];
            float emission[4];
            float sceneColor[4];  // XXX: should be separated?
            float shininess;
            float padding[3];
        } materialData;

        memset(&materialData, 0, sizeof(materialData));

        setVec4(materialData.ambient, _material.GetAmbient());
        setVec4(materialData.diffuse, _material.GetDiffuse());
        setVec4(materialData.specular, _material.GetSpecular());
        setVec4(materialData.emission, _material.GetEmission());
        materialData.shininess = _material.GetShininess();
        setVec4(materialData.sceneColor, _sceneAmbient);

        _materialUniformBlock->Update(&materialData, sizeof(materialData));
        _materialUniformBlockValid = true;
    }

    _materialUniformBlock->Bind(bindingMap, _tokens->materialUB);
}