Ejemplo n.º 1
0
//=============================================================================
// Return the number of pixels colliding between the two sprites.
// Pre: The device supports a stencil buffer and pOcclusionQuery points to
// a valid occlusionQuery object.
// Post: Returns the number of pixels of overlap
//=============================================================================
DWORD Graphics::pixelCollision(const SpriteData &sprite1, const SpriteData &sprite2)
{
    if(!stencilSupport)     // if no stencil buffer support
        return 0;

    beginScene();

    // Set up stencil buffer using current entity
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    device3d->SetRenderState(D3DRS_STENCILFUNC,     D3DCMP_ALWAYS);
    device3d->SetRenderState(D3DRS_STENCILREF,      0x1);
    device3d->SetRenderState(D3DRS_STENCILMASK,     0xffffffff);
    device3d->SetRenderState(D3DRS_STENCILWRITEMASK,0xffffffff);
    device3d->SetRenderState(D3DRS_STENCILFAIL,     D3DSTENCILOP_KEEP);
    device3d->SetRenderState(D3DRS_STENCILPASS,     D3DSTENCILOP_REPLACE);

    // Write a 1 into the stencil buffer for each non-transparent pixel in ent
    spriteBegin();
    // Enable stencil buffer (must be after spriteBegin)
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    drawSprite(sprite2);            // write 1s to stencil buffer
    spriteEnd();

    // Change stencil buffer to only allow writes where the stencil value is 1
    // (where the ent sprite is colliding with the current sprite)
    device3d->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
    device3d->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
    
    // Begin occlusion query to count pixels that are drawn
    pOcclusionQuery->Issue(D3DISSUE_BEGIN);

    spriteBegin();
    // Enable stencil buffer (must be after spriteBegin)
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    drawSprite(sprite1);            // draw current entity 
    spriteEnd();
    // End occlusion query
    pOcclusionQuery->Issue(D3DISSUE_END);

    // Wait until the GPU is finished.
    while(S_FALSE == pOcclusionQuery->GetData( &numberOfPixelsColliding, 
                                  sizeof(DWORD), D3DGETDATA_FLUSH ))
    {}

    // Turn off stencil
    device3d->SetRenderState(D3DRS_STENCILENABLE, false);

    endScene();
    return numberOfPixelsColliding;
}
DWORD Graphics::pixelCollision(const SpriteData &sprite1, const SpriteData &sprite2)
{
    if(!stencilSupport)    
        return 0;

    beginScene();

 
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    device3d->SetRenderState(D3DRS_STENCILFUNC,     D3DCMP_ALWAYS);
    device3d->SetRenderState(D3DRS_STENCILREF,      0x1);
    device3d->SetRenderState(D3DRS_STENCILMASK,     0xffffffff);
    device3d->SetRenderState(D3DRS_STENCILWRITEMASK,0xffffffff);
    device3d->SetRenderState(D3DRS_STENCILFAIL,     D3DSTENCILOP_KEEP);
    device3d->SetRenderState(D3DRS_STENCILPASS,     D3DSTENCILOP_REPLACE);

    spriteBegin();
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    drawSprite(sprite2);           
    spriteEnd();

    device3d->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
    device3d->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
    
    pOcclusionQuery->Issue(D3DISSUE_BEGIN);

    spriteBegin();
    device3d->SetRenderState(D3DRS_STENCILENABLE,   true);
    drawSprite(sprite1);           
    spriteEnd();
    pOcclusionQuery->Issue(D3DISSUE_END);

    while(S_FALSE == pOcclusionQuery->GetData( &numberOfPixelsColliding, 
                                  sizeof(DWORD), D3DGETDATA_FLUSH ))
    {}
    device3d->SetRenderState(D3DRS_STENCILENABLE, false);

    endScene();
    return numberOfPixelsColliding;
}