Beispiel #1
0
void CalculateSpotMatrix(Matrix4& dest, Light* light, const Vector3& translation)
{
    Node* lightNode = light->GetNode();
    Matrix3x4 posAdjust(translation, Quaternion::IDENTITY, 1.0f);
    Matrix3x4 spotView = Matrix3x4(lightNode->GetWorldPosition(), lightNode->GetWorldRotation(), 1.0f).Inverse();
    Matrix4 spotProj(Matrix4::ZERO);
    Matrix4 texAdjust(Matrix4::IDENTITY);
    
    // Make the projected light slightly smaller than the shadow map to prevent light spill
    float h = 1.005f / tanf(light->GetFov() * M_DEGTORAD * 0.5f);
    float w = h / light->GetAspectRatio();
    spotProj.m00_ = w;
    spotProj.m11_ = h;
    spotProj.m22_ = 1.0f / Max(light->GetRange(), M_EPSILON);
    spotProj.m32_ = 1.0f;
    
    #ifdef URHO3D_OPENGL
    texAdjust.SetTranslation(Vector3(0.5f, 0.5f, 0.5f));
    texAdjust.SetScale(Vector3(0.5f, -0.5f, 0.5f));
    #else
    texAdjust.SetTranslation(Vector3(0.5f, 0.5f, 0.0f));
    texAdjust.SetScale(Vector3(0.5f, -0.5f, 1.0f));
    #endif
    
    dest = texAdjust * spotProj * spotView * posAdjust;
}
Beispiel #2
0
    void DiSprite::UpdateGeometry(DiRenderTarget* rt)
    {
        if (mQuads.empty())
        {
            mPrimitiveCount = 0;
            return;
        }

        if (!rt)
            return;

        ReleaseSourceData();

        auto vb = Driver->CreateVertexBuffer();
        if (!vb)
            return;

        mSourceData.push_back(vb);

        mVerticesNum = 6 * mQuads.size();
        mPrimitiveCount = 2 * mQuads.size();
        uint32 vertSize = (3 + 2) * sizeof(float) + sizeof(ARGB);

        mSourceData[0]->Create(mVerticesNum*vertSize);
        uint8* lockedData = DI_NEW uint8[mVerticesNum*vertSize];

        uint32 w = (uint32)(rt->GetWidth() * rt->GetViewport().mWidth);
        uint32 h = (uint32)(rt->GetHeight() * rt->GetViewport().mHeight);

        DiVec2 invScreenSize;
        invScreenSize = DiVec2(1.0f / (float)w, 1.0f / (float)h);
    
        DiVec2 posAdjust(1, -1);

        float* dest = (float*)lockedData;
        if (!mMaterial || mMaterial->HasTexture())
        {
            for (auto it = mQuads.begin(); it != mQuads.end(); ++it)
            {
                DiQuadElement quad = *it;

                DiVec2 topLeft, bottomRight, topLeftUv, bottomRightUv;

                quad.top *= -1;
                quad.bottom *= -1;

                if (!quad.absCoord)
                {
                    quad.left *= (float)w;
                    quad.right *= (float)w;
                    quad.top *= (float)h;
                    quad.bottom *= (float)h;
                }

                topLeft = (DiVec2((float)quad.left, (float)quad.top)/*+DiVec2(0.5f,0.5f)*/) * invScreenSize*2;
                bottomRight = (DiVec2((float)quad.right, (float)quad.bottom)/*+DiVec2(0.5f,0.5f)*/) * invScreenSize*2;

                topLeft -= posAdjust;
                bottomRight -= posAdjust;

                topLeftUv = DiVec2((float)quad.leftUv, (float)quad.topUv);
                bottomRightUv = DiVec2((float)quad.rightUv, (float)quad.bottomUv);

                *dest++ = topLeft.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topLeftColor; dest++;
                *dest++ = topLeftUv.x; *dest++ = topLeftUv.y;

                *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomLeftColor; dest++;
                *dest++ = topLeftUv.x; *dest++ = bottomRightUv.y;

                *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topRightColor; dest++;
                *dest++ = bottomRightUv.x; *dest++ = topLeftUv.y;

                *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topRightColor; dest++;
                *dest++ = bottomRightUv.x; *dest++ = topLeftUv.y;

                *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomLeftColor; dest++;
                *dest++ = topLeftUv.x; *dest++ = bottomRightUv.y;

                *dest++ = bottomRight.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomRightColor; dest++;
                *dest++ = bottomRightUv.x; *dest++ = bottomRightUv.y;
            }
        }
        else
        {
            for (auto it = mQuads.begin(); it != mQuads.end(); ++it)
            {
                DiQuadElement quad = *it;
                  quad.top *= -1;
                  quad.bottom *= -1;

                if (!quad.absCoord)
                {
                    quad.left *= (float)w;
                    quad.right *= (float)w;
                    quad.top *= (float)h;
                    quad.bottom *= (float)h;
                }

                DiVec2 topLeft, bottomRight, topLeftUV, bottomRightUV;
                topLeft = (DiVec2((float)quad.left, (float)quad.top)) * invScreenSize*2;
                bottomRight = (DiVec2((float)quad.right, (float)quad.bottom)) * invScreenSize*2;

                topLeft -= posAdjust;
                bottomRight -= posAdjust;

                *dest++ = topLeft.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topLeftColor; dest++;
                dest += 2;

                *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomLeftColor; dest++;
                dest += 2;

                *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topRightColor; dest++;
                dest += 2;

                *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.topRightColor; dest++;
                dest += 2;

                *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomLeftColor; dest++;
                dest += 2;

                *dest++ = bottomRight.x; *dest++ = bottomRight.y; *dest++ = 0.0f;
                *((ARGB*)dest) = quad.bottomRightColor; dest++;
                dest += 2;
            }
        }

        mSourceData[0]->WriteData(0, mVerticesNum*vertSize, lockedData);
        DI_DELETE[] lockedData;
        mSourceData[0]->SetStride(vertSize);
    }