コード例 #1
0
/// @todo fixme: Should use the visual plane heights of subsectors.
static bool middleMaterialCoversOpening(LineSide const &side)
{
    if (!side.hasSector()) return false;  // Never.

    if (!side.hasSections()) return false;
    //if (!side.middle().hasMaterial()) return false;

    MaterialAnimator *matAnimator = side.middle().materialAnimator();
    /* material().as<ClientMaterial>()
            .getAnimator(Rend_MapSurfaceMaterialSpec());*/

    if (!matAnimator) return false;

    // Ensure we have up to date info about the material.
    matAnimator->prepare();

    // Might the material cover the opening?
    if (matAnimator->isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)
    {
        // Stretched middles always cover the opening.
        if (side.isFlagged(SDF_MIDDLE_STRETCH))
            return true;

        Sector const &frontSec = side.sector();
        Sector const *backSec  = side.back().sectorPtr();

        // Determine the opening between the visual sector planes at this edge.
        coord_t openBottom;
        if (backSec && backSec->floor().heightSmoothed() > frontSec.floor().heightSmoothed())
        {
            openBottom = backSec->floor().heightSmoothed();
        }
        else
        {
            openBottom = frontSec.floor().heightSmoothed();
        }

        coord_t openTop;
        if (backSec && backSec->ceiling().heightSmoothed() < frontSec.ceiling().heightSmoothed())
        {
            openTop = backSec->ceiling().heightSmoothed();
        }
        else
        {
            openTop = frontSec.ceiling().heightSmoothed();
        }

        if (matAnimator->dimensions().y >= openTop - openBottom)
        {
            // Possibly; check the placement.
            if(side.leftHEdge()) // possibility of degenerate BSP leaf
            {
                WallEdge edge(WallSpec::fromMapSide(side, LineSide::Middle),
                              *side.leftHEdge(), Line::From);
                return (edge.isValid() && edge.top().z() > edge.bottom().z()
                        && edge.top().z() >= openTop && edge.bottom().z() <= openBottom);
            }
        }
    }

    return false;
}
コード例 #2
0
    void updateDecorations(Surface &suf, MaterialAnimator &matAnimator,
        Vector2f const &materialOrigin, Vector3d const &topLeft,
        Vector3d const &bottomRight, Sector *containingSector = nullptr)
    {
        Vector3d delta = bottomRight - topLeft;
        if(de::fequal(delta.length(), 0)) return;

        Material &material = matAnimator.material();
        int const axis = suf.normal().maxAxis();

        Vector2d sufDimensions;
        if(axis == 0 || axis == 1)
        {
            sufDimensions.x = std::sqrt(de::squared(delta.x) + de::squared(delta.y));
            sufDimensions.y = delta.z;
        }
        else
        {
            sufDimensions.x = std::sqrt(de::squared(delta.x));
            sufDimensions.y = delta.y;
        }

        if(sufDimensions.x < 0) sufDimensions.x = -sufDimensions.x;
        if(sufDimensions.y < 0) sufDimensions.y = -sufDimensions.y;

        // Generate a number of decorations.
        int decorIndex = 0;

        material.forAllDecorations([&suf, &matAnimator, &materialOrigin
                                   , &topLeft, &bottomRight, &containingSector
                                   , &delta, &axis, &sufDimensions, &decorIndex]
                                   (MaterialDecoration &decor)
        {
            Vector2i const &matDimensions               = matAnimator.material().dimensions();
            MaterialAnimator::Decoration const &decorSS = matAnimator.decoration(decorIndex);

            // Skip values must be at least one.
            Vector2i skip = Vector2i(decor.patternSkip().x + 1, decor.patternSkip().y + 1)
                                .max(Vector2i(1, 1));

            Vector2f repeat = matDimensions * skip;
            if(repeat == Vector2f(0, 0))
                return LoopAbort;

            Vector3d origin = topLeft + suf.normal() * decorSS.elevation();

            float s = de::wrap(decorSS.origin().x - matDimensions.x * decor.patternOffset().x + materialOrigin.x,
                               0.f, repeat.x);

            // Plot decorations.
            for(; s < sufDimensions.x; s += repeat.x)
            {
                // Determine the topmost point for this row.
                float t = de::wrap(decorSS.origin().y - matDimensions.y * decor.patternOffset().y + materialOrigin.y,
                                   0.f, repeat.y);

                for(; t < sufDimensions.y; t += repeat.y)
                {
                    float const offS = s / sufDimensions.x;
                    float const offT = t / sufDimensions.y;
                    Vector3d patternOffset(offS, axis == VZ? offT : offS, axis == VZ? offS : offT);

                    Vector3d decorOrigin     = origin + delta * patternOffset;
                    ConvexSubspace *subspace = suf.map().bspLeafAt(decorOrigin).subspacePtr();

                    if(!subspace) continue;
                    if(!subspace->contains(decorOrigin)) continue;

                    if(containingSector)
                    {
                        // The point must be in the correct sector.
                        if(containingSector != &subspace->sector())
                            continue;
                    }

                    suf.addDecoration(new LightDecoration(decorSS, decorOrigin));
                }
            }

            decorIndex += 1;
            return LoopContinue;
        });
    }
コード例 #3
0
void Rend_DrawMaskedWall(drawmaskedwallparams_t const &parms)
{
    DENG_ASSERT_IN_MAIN_THREAD();
    DENG_ASSERT_GL_CONTEXT_ACTIVE();

    TextureVariant *tex = nullptr;
    if(::renderTextures)
    {
        MaterialAnimator *matAnimator = parms.animator;
        DENG2_ASSERT(matAnimator);

        // Ensure we have up to date info about the material.
        matAnimator->prepare();

        tex = matAnimator->texUnit(MaterialAnimator::TU_LAYER0).texture;
    }

    // Do we have a dynamic light to blend with?
    // This only happens when multitexturing is enabled.
    bool withDyn = false;
    dint normal = 0, dyn = 1;
    if(parms.modTex && ::numTexUnits > 1)
    {
        if(IS_MUL)
        {
            normal = 1;
            dyn    = 0;
        }
        else
        {
            normal = 0;
            dyn    = 1;
        }

        GL_SelectTexUnits(2);
        GL_ModulateTexture(IS_MUL ? 4 : 5);

        // The dynamic light.
        glActiveTexture(IS_MUL ? GL_TEXTURE0 : GL_TEXTURE1);
        /// @todo modTex may be the name of a "managed" texture.
        GL_BindTextureUnmanaged(renderTextures ? parms.modTex : 0,
                                gl::ClampToEdge, gl::ClampToEdge);

        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, parms.modColor);

        // The actual texture.
        glActiveTexture(IS_MUL ? GL_TEXTURE1 : GL_TEXTURE0);
        GL_BindTexture(tex);

        withDyn = true;
    }
    else
    {
        GL_ModulateTexture(1);
        glEnable(GL_TEXTURE_2D);
        GL_BindTexture(tex);
        normal = 0;
    }

    GL_BlendMode(parms.blendMode);

    GLenum normalTarget = normal? GL_TEXTURE1 : GL_TEXTURE0;
    GLenum dynTarget    =    dyn? GL_TEXTURE1 : GL_TEXTURE0;

    // Draw one quad. This is obviously not a very efficient way to render
    // lots of masked walls, but since 3D models and sprites must be
    // rendered interleaved with masked walls, there's not much that can be
    // done about this.
    if(withDyn)
    {
        glBegin(GL_QUADS);
            glColor4fv(parms.vertices[0].color);
            glMultiTexCoord2f(normalTarget, parms.texCoord[0][0], parms.texCoord[1][1]);

            glMultiTexCoord2f(dynTarget, parms.modTexCoord[0][0], parms.modTexCoord[1][1]);

            glVertex3f(parms.vertices[0].pos[0],
                       parms.vertices[0].pos[2],
                       parms.vertices[0].pos[1]);

            glColor4fv(parms.vertices[1].color);
            glMultiTexCoord2f(normalTarget, parms.texCoord[0][0], parms.texCoord[0][1]);

            glMultiTexCoord2f(dynTarget, parms.modTexCoord[0][0], parms.modTexCoord[0][1]);

            glVertex3f(parms.vertices[1].pos[0],
                       parms.vertices[1].pos[2],
                       parms.vertices[1].pos[1]);

            glColor4fv(parms.vertices[3].color);
            glMultiTexCoord2f(normalTarget, parms.texCoord[1][0], parms.texCoord[0][1]);

            glMultiTexCoord2f(dynTarget, parms.modTexCoord[1][0], parms.modTexCoord[0][1]);

            glVertex3f(parms.vertices[3].pos[0],
                       parms.vertices[3].pos[2],
                       parms.vertices[3].pos[1]);

            glColor4fv(parms.vertices[2].color);
            glMultiTexCoord2f(normalTarget, parms.texCoord[1][0], parms.texCoord[1][1]);

            glMultiTexCoord2f(dynTarget, parms.modTexCoord[1][0], parms.modTexCoord[1][1]);

            glVertex3f(parms.vertices[2].pos[0],
                       parms.vertices[2].pos[2],
                       parms.vertices[2].pos[1]);
        glEnd();

        // Restore normal GL state.
        GL_SelectTexUnits(1);
        GL_ModulateTexture(1);
    }
    else
    {
        glBegin(GL_QUADS);
            glColor4fv(parms.vertices[0].color);
            glTexCoord2f(parms.texCoord[0][0], parms.texCoord[1][1]);

            glVertex3f(parms.vertices[0].pos[0],
                       parms.vertices[0].pos[2],
                       parms.vertices[0].pos[1]);

            glColor4fv(parms.vertices[1].color);
            glTexCoord2f(parms.texCoord[0][0], parms.texCoord[0][1]);

            glVertex3f(parms.vertices[1].pos[0],
                       parms.vertices[1].pos[2],
                       parms.vertices[1].pos[1]);

            glColor4fv(parms.vertices[3].color);
            glTexCoord2f(parms.texCoord[1][0], parms.texCoord[0][1]);

            glVertex3f(parms.vertices[3].pos[0],
                       parms.vertices[3].pos[2],
                       parms.vertices[3].pos[1]);

            glColor4fv(parms.vertices[2].color);
            glTexCoord2f(parms.texCoord[1][0], parms.texCoord[1][1]);

            glVertex3f(parms.vertices[2].pos[0],
                       parms.vertices[2].pos[2],
                       parms.vertices[2].pos[1]);
        glEnd();
    }

    glDisable(GL_TEXTURE_2D);
    GL_BlendMode(BM_NORMAL);
}
コード例 #4
0
 void materialAnimatorDecorationStageChanged(MaterialAnimator &animator)
 {
     markSurfacesForRedecoration(animator.material());
 }