예제 #1
0
plDynamicTextMap    *plLayerConverter::ICreateDynTextMap( const plString &layerName, uint32_t width, uint32_t height,
                                                        bool includeAlphaChannel, plMaxNode *node )
{
    hsGuardBegin( "plPlasmaMAXLayer::ICreateDynTextMap" );

    plKey               key;
    plDynamicTextMap    *map = nil;

    
    // Need a unique key name for every layer that uses one. We could also key
    // off of width and height, but layerName should be more than plenty
    plString texName = plFormat("{}_dynText", layerName);

    // Does it already exist?
    key = node->FindPageKey( plDynamicTextMap::Index(), texName );
    if( key != nil )
    {
        map = plDynamicTextMap::ConvertNoRef( key->GetObjectPtr() );
        if( map != nil )
            return map;
    }

    // Create
    map = new plDynamicTextMap();
    map->SetNoCreate( width, height, includeAlphaChannel );

    /// Add a key for it
    key = hsgResMgr::ResMgr()->NewKey( texName, map, node->GetLocation() );

    // All done!
    return map;

    hsGuardEnd;
}
예제 #2
0
hsVertexShader& hsVertexShader::Instance()
{
    hsGuardBegin("hsVertexShader::Instance");
    static hsVertexShader instance;
    return instance;
    hsGuardEnd; 
}
예제 #3
0
plLayerInterface* plLayerConverter::IConvertAngleAttenLayer(plPlasmaMAXLayer *layer, 
                                                                plMaxNode *maxNode, uint32_t blendFlags, 
                                                                bool preserveUVOffset, bool upperLayer)
{
    hsGuardBegin( "plPlasmaMAXLayer::IConvertAngleAttenLayer" );
    if( !upperLayer )
    {
        fErrorMsg->Set(true, maxNode->GetName(), "Angle Attenuation layers can only be used as a top layer").Show();
        fErrorMsg->Set();
        return nil;
    }
    plAngleAttenLayer* aaLay = (plAngleAttenLayer*)layer;
    Box3 fade = aaLay->GetFade();
    float tr0 = cosf(DegToRad(180.f - fade.Min().x));
    float op0 = cosf(DegToRad(180.f - fade.Min().y));
    float tr1 = cosf(DegToRad(180.f - fade.Max().x));
    float op1 = cosf(DegToRad(180.f - fade.Max().y));

    int loClamp = aaLay->GetLoClamp();
    int hiClamp = aaLay->GetHiClamp();

    int uvwSrc = aaLay->Reflect() ? plLayerInterface::kUVWReflect : plLayerInterface::kUVWNormal;

    plLayer* lut = ICreateAttenuationLayer(plString::FromUtf8(layer->GetName()), maxNode, uvwSrc, tr0, op0, tr1, op1, loClamp, hiClamp);

    return lut;

    hsGuardEnd;
}
예제 #4
0
void hsVertexShader::Close()
{
    hsGuardBegin("hsVertexShader::DeInitLights");

    fLightMapGen = nil;

    hsGuardEnd;
}
예제 #5
0
//
// Create Bitmap
//
plMipmap *plBitmapCreator::ICreateBitmap(plBitmapData *bd)
{
    hsGuardBegin("hsConverterUtils::CreateBitmap");

    // Load the bitmap
    BitmapInfo bi;
    bi.SetName(bd->fileName.AsString().c_str());

#if 0 // This isn't really an issue since the textures are packed -Colin
    const int kMaxFileNameLength = 30;
    if (strlen(bi.Filename()) > kMaxFileNameLength)
    {
        // Allow to continue, But make it painful
        char errStr[256];
        sprintf(errStr, "File name longer than %d, won't burn to CD (%s)", kMaxFileNameLength, bi.Filename());//bitmapTex->GetName());
        MessageBox(GetActiveWindow(), errStr, bd->fileName, MB_OK|MB_ICONEXCLAMATION);  
    }
#endif

    bool notMipped = (bd->texFlags & plMipmap::kForceOneMipLevel) != 0;
    float sigma = bd->sig;
    
    // Load the bitmap
    Bitmap *bm = TheManager->Load(&bi);
    if (!bm)
    {
        // FIXME
        /*
        if (fErrorMsg->Set(!(fWarned & kWarnedNoMoreBitmapLoadErr), 
            "Error loading bitmap", pathName).CheckAskOrCancel())
        {
            fWarned |= kWarnedNoMoreBitmapLoadErr;
        }
        */
        return nil;
    }
    BitmapStorage *storage = bm->Storage();
    BitmapInfo *bInfo = &storage->bi;

    ICheckOutBitmap(bInfo, bm, bd->fileName);

    //
    // Create a plMipmap 
    //
    plMipmap *hBitmap = new plMipmap;
    if( (bm->Width() ^ (bm->Width() & -bm->Width()))
        ||(bm->Height() ^ (bm->Height() & -bm->Height())) )
    {
        IResampBitmap(bm, *hBitmap);
    }
    else if( ((bm->Width() >> 3) > bm->Height())||((bm->Height() >> 3) > bm->Width()) )
    {
        IResampBitmap(bm, *hBitmap);
    }
    else
    {
예제 #6
0
plLayerConverter    &plLayerConverter::Instance( void )
{
    hsGuardBegin( "plLayerConverter::Instance" );

    static plLayerConverter     instance;

    return instance;

    hsGuardEnd;
}
예제 #7
0
hsVertexShader::hsVertexShader() :
    fConverterUtils(hsConverterUtils::Instance()),
    fInterface(nil),
    fLightMapGen(nil),
    fShaded(0)
{
    hsGuardBegin("hsVertexShader::hsVertexShader");
    fLocalToWorld.Reset();
    hsGuardEnd;
}
예제 #8
0
plLayerInterface    *plLayerConverter::ConvertTexmap( Texmap *texmap,
                                                        plMaxNode *maxNode,
                                                        uint32_t blendFlags, bool preserveUVOffset,
                                                        bool upperLayer )
{
    hsGuardBegin( "plLayerConverter::ConvertTexmap" );
    
    fDbgNodeName = maxNode->GetName();

    // We only convert plPlasmaMAXLayers
    plPlasmaMAXLayer    *layer = plPlasmaMAXLayer::GetPlasmaMAXLayer( texmap );
    if( layer == nil )
    {
        fErrorMsg->Set( true, "Plasma Layer Error", "Cannot convert layer '%s'--unrecognized MAX layer type", texmap->GetName() );
        fErrorMsg->Show();
        fErrorMsg->Set();
        return nil;
    }

    // KLUDGE - Some things don't set the name for their layers (ie projected
    // runtime lights).  So that we don't end up with an empty keyname, set the
    // name to the nodes name if there isn't one. -Colin
    const char* layerName = layer->GetName();
    if (!layerName || layerName[0] == '\0')
        layer->SetName(maxNode->GetName());

    // Switch on the class ID
    plLayerInterface    *plasmaLayer = nil;

    if( layer->ClassID() == LAYER_TEX_CLASS_ID )
        plasmaLayer = IConvertLayerTex( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );

    else if( layer->ClassID() == STATIC_ENV_LAYER_CLASS_ID )
        plasmaLayer = IConvertStaticEnvLayer( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );

    else if( layer->ClassID() == DYNAMIC_ENV_LAYER_CLASS_ID )
        plasmaLayer = IConvertDynamicEnvLayer( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );

    else if( layer->ClassID() == DYN_TEXT_LAYER_CLASS_ID )
        plasmaLayer = IConvertDynamicTextLayer( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );

    else if( layer->ClassID() == ANGLE_ATTEN_LAYER_CLASS_ID )
        plasmaLayer = IConvertAngleAttenLayer( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );

    else if( layer->ClassID() == MAX_CAMERA_LAYER_CLASS_ID )
        plasmaLayer = IConvertCameraLayer( layer, maxNode, blendFlags, preserveUVOffset, upperLayer );


    IRegisterConversion( layer, plasmaLayer );

    return plasmaLayer;

    hsGuardEnd;
}
예제 #9
0
void hsVertexShader::Open()
{
    hsGuardBegin("hsVertexShader::InitLights");

    fLocalToWorld.Reset();

    fInterface = ::GetCOREInterface();

    fLightMapGen = &plLightMapGen::Instance();

    hsGuardEnd;
}
예제 #10
0
plLayer     *plLayerConverter::ICreateLayer( const plString &name, bool upperLayer, plLocation &loc )
{
    hsGuardBegin( "plPlasmaMAXLayer::ICreateLayer" );

    plLayer *layer = new plLayer;
    layer->InitToDefault();

    hsgResMgr::ResMgr()->NewKey( name, layer, loc );

    return layer;

    hsGuardEnd;
}
예제 #11
0
void hsVertexShader::IShadeVertices( plGeometrySpan *span, hsBitVector *dirtyVector, INode* node, bool translucent )
{
    hsGuardBegin( "hsVertexShader::IShadeVertices" );

    plMaxNode* maxNode = (plMaxNode*)node;
    if( maxNode->CanConvert() && (nil != maxNode->GetLightMapComponent()) )
        return;

    int     index;

    hsPoint3        position;
    hsVector3       normal;
    hsColorRGBA     color, illum;
    plTmpVertex3    *vertices;


    /// Allocate temp vertex array
    vertices = new plTmpVertex3[ span->fNumVerts ];
    for( index = 0; index < span->fNumVerts; index++ )
    {
        span->ExtractVertex( index, &position, &normal, &color, &illum );
        span->ExtractInitColor( index, &color, &illum );

        /// fShadeColorTable is the shaded portion. fIllumColorTable is the illuminated portion;
        /// for more and less confusing details, see above.
        fShadeColorTable[ index ].Set( color.r, color.g, color.b, color.a );
        fIllumColorTable[ index ].Set( illum.r, illum.g, illum.b, 1 );

        position = fLocalToWorld * position;
        normal = fNormalToWorld * normal;

        vertices[ index ].fLocalPos = position;
        vertices[ index ].fNormal = normal;
        vertices[ index ].fNormal.Normalize();
    }

    const char* dbgNodeName = node->GetName();

    TimeValue t = fInterface->GetTime();
    Box3 bbox;
    node->EvalWorldState(t).obj->GetDeformBBox(t, bbox, &node->GetObjectTM(t));
    plMaxLightContext ctx(bbox, t);

    for( index = 0; index < span->fNumVerts; index++ )
        INativeShadeVtx(fIllumColorTable[index], ctx, vertices[ index ], translucent);

    // Delete temp arrays
    delete [] vertices;

    hsGuardEnd;
}
예제 #12
0
plLayerInterface    *plLayerConverter::IConvertDynamicTextLayer( plPlasmaMAXLayer *layer, 
                                                                plMaxNode *maxNode, uint32_t blendFlags, 
                                                                bool preserveUVOffset, bool upperLayer )
{
    hsGuardBegin( "plLayerConverter::IConvertDynamicTextLayer" );

    plDynamicTextLayer  *maxLayer;
    IParamBlock2        *bitmapPB;
    plLocation          loc;

    maxLayer = (plDynamicTextLayer *)layer;
    loc = maxNode->GetLocation();
    bitmapPB = maxLayer->GetParamBlockByID( plDynamicTextLayer::kBlkBitmap );
    
    if( !bitmapPB )
    {
        fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show();
        fErrorMsg->Set();
        return nil;
    }

    // Get a new layer to play with
    plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( maxLayer->GetName() ), upperLayer, loc );


    /// UV Gen
    IProcessUVGen( maxLayer, plasmaLayer, nil, preserveUVOffset );

    // Create the "texture"
    plDynamicTextMap *texture = ICreateDynTextMap( plasmaLayer->GetKeyName(), 
                                                    bitmapPB->GetInt( plDynamicTextLayer::kBmpExportWidth ), 
                                                    bitmapPB->GetInt( plDynamicTextLayer::kBmpExportHeight ),
                                                    bitmapPB->GetInt( plDynamicTextLayer::kBmpIncludeAlphaChannel ),
                                                    maxNode );

    // Set the initial bitmap if necessary
    uint32_t *initBuffer = IGetInitBitmapBuffer( maxLayer );
    if( initBuffer != nil )
    {
        texture->SetInitBuffer( initBuffer );
        delete [] initBuffer;
    }

    // Add the texture in
    hsgResMgr::ResMgr()->AddViaNotify( texture->GetKey(), new plLayRefMsg( plasmaLayer->GetKey(), plRefMsg::kOnCreate, 0, plLayRefMsg::kTexture ), plRefFlags::kActiveRef );

    // All done!
    return (plLayerInterface *)plasmaLayer;

    hsGuardEnd;
}
예제 #13
0
bool hsVertexShader::IsTranslucent( hsGMaterial *material )
{
    hsGuardBegin("hsVertexShader::IsTranslucent");

    if( material )
    {
        plLayerInterface* layer = material->GetLayer(0);
        if( layer && ( layer->GetShadeFlags() & hsGMatState::kShadeSoftShadow ) )
        {
            return true;
        }
    }

    return false;
    hsGuardEnd; 
}
예제 #14
0
void    plLayerConverter::IProcessUVGen( plPlasmaMAXLayer *srcLayer, plLayer *destLayer, 
                                        plBitmapData *bitmapData, bool preserveUVOffset )
{
    hsGuardBegin( "plPlasmaMAXLayer::IProcessUVGen" );

    StdUVGen *uvGen = (StdUVGen *)srcLayer->GetTheUVGen();

    int tiling = uvGen->GetTextureTiling();

    // If set this indicates the texture map is tiled in U
    if (!(tiling & U_WRAP))
    {
        destLayer->SetClampFlags( destLayer->GetClampFlags() | hsGMatState::kClampTextureU );
        if( bitmapData != nil )
            bitmapData->clampFlags |= plBitmapData::kClampU;
    }

    // If set this indicates the texture map is tiled in V
    if (!(tiling & V_WRAP))
    {
        destLayer->SetClampFlags( destLayer->GetClampFlags() | hsGMatState::kClampTextureV );
        if( bitmapData != nil )
            bitmapData->clampFlags |= plBitmapData::kClampV;
    }

    // UVW Src
    int32_t uvwSrc = srcLayer->GetMapChannel() - 1;

    if( fErrorMsg->Set( !( fWarned & kWarnedTooManyUVs ) &&
                        ( ( uvwSrc < 0 ) || ( uvwSrc >= plGeometrySpan::kMaxNumUVChannels ) ),
                        destLayer->GetKeyName().c_str(), "Only %d UVW channels (1-%d) currently supported",
        plGeometrySpan::kMaxNumUVChannels, plGeometrySpan::kMaxNumUVChannels).CheckAskOrCancel() )
        fWarned |= kWarnedTooManyUVs;
    fErrorMsg->Set( false );

    destLayer->SetUVWSrc( uvwSrc );

    // Get the actual texture transform
    hsMatrix44 hsTopX;
    if (uvGen && (hsControlConverter::Instance().StdUVGenToHsMatrix44(&hsTopX, uvGen, preserveUVOffset == true)))
        destLayer->SetTransform( hsTopX );

    // All done!
    hsGuardEnd;
}
예제 #15
0
plLayerInterface    *plLayerConverter::IConvertCameraLayer(plPlasmaMAXLayer *layer, 
                                                           plMaxNode *maxNode, uint32_t blendFlags, 
                                                           bool preserveUVOffset, bool upperLayer)
{
    hsGuardBegin( "plLayerConverter::IConvertCameraLayer" );

    IParamBlock2        *pb;
    plLocation          loc;

    loc = maxNode->GetLocation();
    pb = layer->GetParamBlockByID(plMAXCameraLayer::kBlkMain);

    if (!pb)
    {
        fErrorMsg->Set(!pb, "Plasma Layer Error", "Paramblock for Plasma Camera Layer not found" ).Show();
        fErrorMsg->Set();
        return nil;
    }

    plLayer *plasmaLayer = ICreateLayer (plString::FromUtf8(layer->GetName()), upperLayer, loc);

    plMaxNode *rootNode = (plMaxNode*)pb->GetINode(ParamID(plMAXCameraLayer::kRootNode));
    plDynamicCamMap *map = plEnvMapComponent::GetCamMap(rootNode ? rootNode : maxNode);
    if (map)
    {
        int32_t texFlags = 0;
        if (!pb->GetInt(ParamID(plMAXCameraLayer::kExplicitCam)))
        {
            plasmaLayer->SetUVWSrc(plLayerInterface::kUVWPosition);
            plasmaLayer->SetMiscFlags(hsGMatState::kMiscCam2Screen | hsGMatState::kMiscPerspProjection);
            hsgResMgr::ResMgr()->AddViaNotify(rootNode->GetSceneObject()->GetKey(), new plGenRefMsg(map->GetKey(), plRefMsg::kOnCreate, -1, plDynamicCamMap::kRefRootNode), plRefFlags::kActiveRef);
            hsgResMgr::ResMgr()->AddViaNotify(plasmaLayer->GetKey(), new plGenRefMsg(map->GetKey(), plRefMsg::kOnCreate, -1, plDynamicCamMap::kRefMatLayer), plRefFlags::kActiveRef);
            if (!pb->GetInt(ParamID(plMAXCameraLayer::kForce)))
            {
                plBitmap *disableTexture = hsMaterialConverter::Instance().GetStaticColorTexture(pb->GetColor(ParamID(plMAXCameraLayer::kDisableColor)), loc);
                hsgResMgr::ResMgr()->AddViaNotify(disableTexture->GetKey(), new plGenRefMsg(map->GetKey(), plRefMsg::kOnCreate, -1, plDynamicCamMap::kRefDisableTexture), plRefFlags::kActiveRef);
            }
        }
        else
        {
            plMaxNode *camNode = (plMaxNode*)pb->GetINode(ParamID(plMAXCameraLayer::kCamera));
            if (camNode)
            {
                const plCameraModifier1 *mod = plCameraModifier1::ConvertNoRef(camNode->GetSceneObject()->GetModifierByType(plCameraModifier1::Index()));
                if (mod)
                    hsgResMgr::ResMgr()->AddViaNotify(mod->GetKey(), new plGenRefMsg(map->GetKey(), plRefMsg::kOnCreate, -1, plDynamicCamMap::kRefCamera), plRefFlags::kActiveRef);
            }

            plasmaLayer->SetUVWSrc(pb->GetInt(ParamID(plMAXCameraLayer::kUVSource)));
        }

        hsTArray<plMaxNode*> nodeList;
        hsMaterialConverter::GetNodesByMaterial(maxNode->GetMtl(), nodeList);
        int i;
        for (i = 0; i < nodeList.GetCount(); i++)
        {
            hsgResMgr::ResMgr()->AddViaNotify(nodeList[i]->GetSceneObject()->GetKey(), new plGenRefMsg(map->GetKey(), plRefMsg::kOnCreate, -1, plDynamicCamMap::kRefTargetNode), plRefFlags::kActiveRef);
        }
        hsgResMgr::ResMgr()->AddViaNotify(map->GetKey(), new plLayRefMsg(plasmaLayer->GetKey(), plRefMsg::kOnCreate, -1, plLayRefMsg::kTexture), plRefFlags::kActiveRef);

    }

    return plasmaLayer;

    hsGuardEnd;
}
예제 #16
0
plLayerInterface    *plLayerConverter::IConvertDynamicEnvLayer( plPlasmaMAXLayer *layer, 
                                                                plMaxNode *maxNode, uint32_t blendFlags, 
                                                                bool preserveUVOffset, bool upperLayer )
{
    hsGuardBegin( "plLayerConverter::IConvertDynamicEnvLayer" );

    IParamBlock2        *bitmapPB;
    plLocation          loc;

    loc = maxNode->GetLocation();
    bitmapPB = layer->GetParamBlockByID( plDynamicEnvLayer::kBlkBitmap );
    
    if( !bitmapPB )
    {
        fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show();
        fErrorMsg->Set();
        return nil;
    }

    // Get a new layer to play with
    plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( layer->GetName() ), upperLayer, loc );

    // Get the anchor node
    plMaxNode   *anchor = (plMaxNode *)bitmapPB->GetINode( plDynamicEnvLayer::kBmpAnchorNode );
    if( anchor == nil )
        // Default to self as the anchor--just make sure we make unique versions of this material!
        anchor = maxNode;
    
    if( !anchor->CanConvert() || !( anchor->GetForceLocal() || anchor->GetDrawable() ) )
    {
        fErrorMsg->Set( true, "Plasma Layer Error", "The dynamic envMap material %s has an invalid anchor specified. Please specify a valid Plasma scene object as an anchor.", plasmaLayer->GetKeyName().c_str() ).Show();
        fErrorMsg->Set();
        return (plLayerInterface *)plasmaLayer;
    }

    // Create texture and add it to list if unique
    int32_t texFlags = 0;

    /// Since we're a cubic environMap, we don't care about the UV transform nor the uvwSrc
    plasmaLayer->SetUVWSrc( 0 );
    plasmaLayer->SetUVWSrc( plasmaLayer->GetUVWSrc() | plLayerInterface::kUVWReflect );

    // Create the texture.  If it works, assign it to the layer
    plString texName;
    if( anchor == maxNode )
    {
        // Self-anchoring material, make sure the name is unique via the nodeName
        texName = plFormat("{}_cubicRT@{}", plasmaLayer->GetKeyName(), maxNode->GetName());
    }
    else
        texName = plFormat("{}_cubicRT", plasmaLayer->GetKeyName());

    plBitmap *texture = (plBitmap *)IMakeCubicRenderTarget( texName, maxNode, anchor );
    if( texture )
        hsgResMgr::ResMgr()->AddViaNotify( texture->GetKey(), new plLayRefMsg( plasmaLayer->GetKey(), plRefMsg::kOnCreate, 0, plLayRefMsg::kTexture ), plRefFlags::kActiveRef );

    // Tag this layer as reflective cubic environmentmapping
    if( bitmapPB->GetInt(plDynamicEnvLayer::kBmpRefract) )
        plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseRefractionXform );
    else
        plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseReflectionXform );

    return (plLayerInterface *)plasmaLayer;

    hsGuardEnd;
}
예제 #17
0
plLayerInterface    *plLayerConverter::IConvertStaticEnvLayer( plPlasmaMAXLayer *layer, 
                                                                plMaxNode *maxNode, uint32_t blendFlags, 
                                                                bool preserveUVOffset, bool upperLayer )
{
    hsGuardBegin( "plLayerConverter::IConvertStaticEnvLayer" );

    IParamBlock2        *bitmapPB;
    plLocation          loc;

    loc = maxNode->GetLocation();
    bitmapPB = layer->GetParamBlockByID( plStaticEnvLayer::kBlkBitmap );
    
    if( !bitmapPB )
    {
        fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show();
        fErrorMsg->Set();
        return nil;
    }

    // Get a new layer to play with
    plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( layer->GetName() ), upperLayer, loc );

    // Get the texture info
    PBBitmap *pbbm = bitmapPB->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap + 0 );
    BitmapInfo *bi = nil;
    if( pbbm )
        bi = &pbbm->bi;

    // If the texture had bad info, assert and return the empty layer
    if (!bi || !bi->Name() || !strcmp(bi->Name(), ""))
    {
        // Or don't assert since it can get annoying when you are using someone
        // elses file and don't have all the textures.
        return (plLayerInterface *)plasmaLayer;
    }

    // Setup the texture creation parameters
    plBitmapData bd;
    bd.fileName = bi->Name();

    // Create texture and add it to list if unique
    int32_t texFlags = 0;

    // Texture Alpha/Color
    if( bitmapPB->GetInt( plStaticEnvLayer::kBmpInvertColor ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendInvertColor );
    if( bitmapPB->GetInt( plStaticEnvLayer::kBmpDiscardColor ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexColor );
    if( bitmapPB->GetInt( kBmpDiscardAlpha ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexAlpha );
    if( bitmapPB->GetInt( plStaticEnvLayer::kBmpInvertAlpha ) )
        bd.invertAlpha = true;

    // Texture quality
    if( bitmapPB->GetInt( plStaticEnvLayer::kBmpNonCompressed ) )
        texFlags |= plBitmap::kForceNonCompressed;

    switch( bitmapPB->GetInt( plStaticEnvLayer::kBmpScaling ) )
    {
        case plStaticEnvLayer::kScalingHalf: texFlags |= plBitmap::kHalfSize;  break;
        case plStaticEnvLayer::kScalingNone: texFlags |= plBitmap::kNoMaxSize; break;
    }

    bd.texFlags = texFlags;
    bd.isStaticCubicEnvMap = true;
    for( int i = 0; i < 6; i++ )
    {
        PBBitmap *face = bitmapPB->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap + i );
        if( !face )
            return (plLayerInterface *)plasmaLayer;
        bd.faceNames[ i ] = face->bi.Name();
    }

    // Get detail parameters
    if( bitmapPB->GetInt( plStaticEnvLayer::kBmpUseDetail ) )
    {                                           // TODO: be smarter
        if( blendFlags & hsGMatState::kBlendAdd )
            bd.createFlags = plMipmap::kCreateDetailAdd;
        else if( blendFlags & hsGMatState::kBlendMult )
            bd.createFlags = plMipmap::kCreateDetailMult;
        else
            bd.createFlags = plMipmap::kCreateDetailAlpha;

        bd.detailDropoffStart = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStartSize ) ) / 100.f;
        bd.detailDropoffStop = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStopSize ) ) / 100.f;
        bd.detailMax = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStartOpac ) ) / 100.f;
        bd.detailMin = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStopOpac ) ) / 100.f;
    }

    /// Since we're a cubic environMap, we don't care about the UV transform nor the uvwSrc
    plasmaLayer->SetUVWSrc( 0 );
    plasmaLayer->SetUVWSrc( plasmaLayer->GetUVWSrc() | plLayerInterface::kUVWReflect );

    // Create the texture.  If it works, assign it to the layer
    if( ( plasmaLayer = IAssignTexture( &bd, maxNode, plasmaLayer, upperLayer ) ) == nil )
        return nil;

    // Tag this layer as reflective cubic environmentmapping
    if( bitmapPB->GetInt(plStaticEnvLayer::kBmpRefract) )
        plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseRefractionXform );
    else
        plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseReflectionXform );

    return (plLayerInterface *)plasmaLayer;

    hsGuardEnd;
}
예제 #18
0
void hsVertexShader::IShadeSpan( plGeometrySpan *span, INode* node )
{
    hsColorRGBA         preDiffuse, rtDiffuse, matAmbient;
    hsBitVector         dirtyVector;
    int                 i;
    bool                translucent, shadeIt, addingIt;
    plLayerInterface    *layer = nil;


    hsGuardBegin("hsVertexShader::ShadeSpan");
    
    const char* dbgNodeName = node->GetName(); 

    if( span->fNumVerts == 0 )
        return;

    fShadeColorTable = new hsColorRGBA[ span->fNumVerts ];  
    fIllumColorTable = new hsColorRGBA[ span->fNumVerts ];  
    
    translucent = IsTranslucent( span->fMaterial );

    /// Get material layer #0
    addingIt = false;
    shadeIt = !( span->fProps & plGeometrySpan::kPropNoPreShade );

    if( span->fMaterial->GetNumLayers() != 0 )
    {
        layer = span->fMaterial->GetLayer( 0 );
        if( layer->GetShadeFlags() & hsGMatState::kShadeNoShade )
            shadeIt = false;
        if( layer->GetBlendFlags() & hsGMatState::kBlendAdd )
            addingIt = true;
    }
    float opacity = 1.f;
    for( i = 0; i < span->fMaterial->GetNumLayers(); i++ )
    {
        plLayerInterface* lay = span->fMaterial->GetLayer(i);
        if( (lay->GetBlendFlags() & hsGMatState::kBlendAlpha)
            &&
            (
                !i  
                ||
                (lay->GetMiscFlags() & hsGMatState::kMiscRestartPassHere)
            )
          )
        {
            opacity = span->fMaterial->GetLayer(i)->GetOpacity();
        }
    }

    /// Generate color table
    if( shadeIt )
        IShadeVertices( span, &dirtyVector, node, translucent );
    else
    {
        for( i = 0; i < span->fNumVerts; i++ )  
        {
            /// This is good for the old way, but not sure about the new way. Test once new way is in again -mcn
//          fShadeColorTable[ i ].Set( 1, 1, 1, 1 );
//          fIllumColorTable[ i ].Set( 0, 0, 0, 1 );
            hsPoint3    position;
            hsVector3   normal;
            hsColorRGBA color, illum;

            span->ExtractVertex( i, &position, &normal, &color, &illum );
            span->ExtractInitColor( i, &color, &illum );
            fShadeColorTable[ i ].Set( color.r, color.g, color.b, color.a );
            fIllumColorTable[ i ].Set( illum.r, illum.g, illum.b, 1 );
        }
    }

    /// Get mat colors to modulate by
    if( layer == nil )
    {
        preDiffuse.Set( 1, 1, 1, 1 );
        rtDiffuse.Set( 1, 1, 1, 1 );
        matAmbient.Set( 0, 0, 0, 0 );
    }
    else
    {
        if( layer->GetShadeFlags() & hsGMatState::kShadeWhite )
        {
            preDiffuse.Set( 1, 1, 1, 1 );
            rtDiffuse.Set( 1, 1, 1, 1 );
            matAmbient.Set( 0, 0, 0, 0 );
        }
        else
        {
            preDiffuse = layer->GetPreshadeColor();     // This is for vertex-based lighting, which basically ignores preshading
            rtDiffuse = layer->GetRuntimeColor();       // This is for vertex-based lighting, which basically ignores preshading
            matAmbient = layer->GetAmbientColor();
            matAmbient.a = 0;
        }
        preDiffuse.a = opacity;
        rtDiffuse.a = opacity;
    }
#if 0

    /// Multiply by the material color, and scale by opacity if we're additive blending
    /// Apply colors now, multiplying by the material color as we go
    for( i = 0; i < span->fNumVerts; i++ )
    {
        fShadeColorTable[ i ] *= matDiffuse;
        fShadeColorTable[ i ] += matAmbient;
        fIllumColorTable[ i ] *= matDiffuse;
        fIllumColorTable[ i ] += matAmbient;
    }

    if( addingIt )
    {
        for( i = 0; i < span->fNumVerts; i++ )
        {
            float opacity = fShadeColorTable[ i ].a;
            fShadeColorTable[ i ] *= opacity;
            fIllumColorTable[ i ] *= opacity;
        }
    }
#else
    /// Combine shade and illum together into the diffuse color
    if( ( span->fProps & plGeometrySpan::kLiteMask ) != plGeometrySpan::kLiteMaterial )
    {
        /// The two vertex lighting formulas take in a vetex color pre-processed, i.e. in 
        /// the form of: vtxColor = ( maxVtxColor * materialDiffuse + maxIllumColor )
        span->fProps |= plGeometrySpan::kDiffuseFoldedIn;
        if( !shadeIt )
        {
            for( i = 0; i < span->fNumVerts; i++ )
            {
                fIllumColorTable[ i ].a = 0;
                fShadeColorTable[ i ] = (fShadeColorTable[ i ] * rtDiffuse) + fIllumColorTable[ i ];
                fIllumColorTable[ i ].Set( 0, 0, 0, 0 );
            }
        }
        else
        {
            for( i = 0; i < span->fNumVerts; i++ )
            {
                fIllumColorTable[ i ].a = 1.f;
                // Following needs to be changed to allow user input vertex colors to modulate
                // the runtime light values.
//              fShadeColorTable[ i ] = fIllumColorTable[ i ] * rtDiffuse;
                fShadeColorTable[ i ] = fShadeColorTable[ i ] * fIllumColorTable[ i ] * rtDiffuse;
                fIllumColorTable[ i ].Set( 0, 0, 0, 0 );
            }
        }
    }
    else
    {
        if( !shadeIt )
        {
            // Not shaded, so runtime lit, so we want BLACK vertex colors
            for( i = 0; i < span->fNumVerts; i++ )
            {
                fShadeColorTable[ i ].Set( 0, 0, 0, 0 );
                fIllumColorTable[ i ].Set( 0, 0, 0, 0 );
            }
        }
        else
        {
            for( i = 0; i < span->fNumVerts; i++ )
            {
                fShadeColorTable[ i ] *= fIllumColorTable[ i ];
                fIllumColorTable[ i ].Set( 0, 0, 0, 0 );
            }
        }
    }
#endif

    /// Loop and stuff
    for( i = 0; i < span->fNumVerts; i++ )
        span->StuffVertex( i, fShadeColorTable + i, fIllumColorTable + i );

    delete [] fShadeColorTable;       
    delete [] fIllumColorTable;       

    hsGuardEnd;
}
예제 #19
0
plLayerInterface    *plLayerConverter::IConvertLayerTex( plPlasmaMAXLayer *layer, 
                                                                plMaxNode *maxNode, uint32_t blendFlags, 
                                                                bool preserveUVOffset, bool upperLayer )
{
    hsGuardBegin( "plLayerConverter::IConvertLayerTex" );

    IParamBlock2        *bitmapPB;
    plLocation          loc;


    loc = maxNode->GetLocation();
    bitmapPB = layer->GetParamBlockByID( plLayerTex::kBlkBitmap );
    
    if( !bitmapPB )
    {
        fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show();
        fErrorMsg->Set();
        return nil;
    }

    // Get a new layer to play with
    plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( layer->GetName() ), upperLayer, loc );

    // We're using a texture, try and get its info
    PBBitmap    *pbbm = nil;
    BitmapInfo  *bi = nil;

    if( bitmapPB->GetInt( kBmpUseBitmap ) )
    {
        if( bitmapPB )
            pbbm = bitmapPB->GetBitmap( kBmpBitmap );
        if( pbbm )
            bi = &pbbm->bi;
    }

    // If the texture had bad info, assert and return the empty layer
    if( !bi || !bi->Name() || !strcmp(bi->Name(), "") )
    {
        if( upperLayer )
        {
            if( fErrorMsg->Set( !( fWarned & kWarnedNoUpperTexture ), "Plasma Export Error", sWarnNoUpperTexture, maxNode->GetName() ).CheckAskOrCancel() )
                fWarned |= kWarnedNoUpperTexture; 
            fErrorMsg->Set( false );

            delete plasmaLayer;
            return nil;
        }
        else
        {
            return (plLayerInterface *)plasmaLayer;
        }
    }

    // Setup the texture creation parameters
    plBitmapData bd;
    bd.fileName = bi->Name();

    // Create texture and add it to list if unique
    int32_t texFlags = 0;//hsGTexture::kMipMap;

    // Texture Alpha/Color
    if( bitmapPB->GetInt( kBmpInvertColor ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendInvertColor );
    if( bitmapPB->GetInt( kBmpDiscardColor ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexColor );
    if( bitmapPB->GetInt( kBmpDiscardAlpha ) )
        plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexAlpha );
    if( bitmapPB->GetInt( kBmpInvertAlpha ) )
        bd.invertAlpha = true;

    // Texture quality
    if( bitmapPB->GetInt( kBmpNonCompressed ) )
        texFlags |= plBitmap::kForceNonCompressed;

    if( bitmapPB->GetInt( kBmpNoDiscard ) )
        texFlags |= plBitmap::kDontThrowAwayImage;

    switch( bitmapPB->GetInt( kBmpScaling ) )
    {
        case kScalingHalf: texFlags |= plBitmap::kHalfSize;  break;
        case kScalingNone: texFlags |= plBitmap::kNoMaxSize; break;
    }

    // Mip map filtering.
    if( bitmapPB->GetInt( kBmpNoFilter ) )
        texFlags |= plBitmap::kForceOneMipLevel;
    if( bitmapPB->GetInt( kBmpMipBias ) )
    {
        plasmaLayer->SetZFlags( plasmaLayer->GetZFlags() | hsGMatState::kZLODBias );
        plasmaLayer->SetLODBias( bitmapPB->GetFloat( kBmpMipBiasAmt, fConverterUtils.GetTime( fInterface ) ) );
    }
    float sig = bitmapPB->GetFloat( kBmpMipBlur );

    bd.texFlags = texFlags;
    bd.sig = sig;

    // Get detail parameters
    if( bitmapPB->GetInt( kBmpUseDetail ) )
    {                                           // TODO: be smarter
        if( blendFlags & hsGMatState::kBlendAdd )
            bd.createFlags |= plMipmap::kCreateDetailAdd;
        else if( blendFlags & hsGMatState::kBlendMult )
            bd.createFlags |= plMipmap::kCreateDetailMult;
        else
            bd.createFlags |= plMipmap::kCreateDetailAlpha;
        bd.detailDropoffStart = float(bitmapPB->GetInt(kBmpDetailStartSize)) / 100.f;
        bd.detailDropoffStop = float(bitmapPB->GetInt(kBmpDetailStopSize)) / 100.f;
        bd.detailMax = float(bitmapPB->GetInt(kBmpDetailStartOpac)) / 100.f;
        bd.detailMin = float(bitmapPB->GetInt(kBmpDetailStopOpac)) / 100.f;
    }

    // Get max export dimension (since the function we eventually call
    // expects the max of the two dimensions, we figure that out here and
    // pass it on)
    bd.maxDimension = bitmapPB->GetInt( kBmpExportWidth );
    int expHt = bitmapPB->GetInt( kBmpExportHeight );
    if( bd.maxDimension < expHt )
        bd.maxDimension = expHt;
    int clipID = 0, w;
    for( clipID = 0, w = bi->Width(); w > bd.maxDimension; w >>= 1, clipID++ );

    // Do the UV gen (before we do texture, since it could modify the bitmapData struct)
    IProcessUVGen( layer, plasmaLayer, &bd, preserveUVOffset );

    // Create the texture.  If it works, assign it to the layer
    if( ( plasmaLayer = IAssignTexture( &bd, maxNode, plasmaLayer, upperLayer, clipID ) ) == nil )
        return nil;

    // All done!
    return (plLayerInterface *)plasmaLayer;

    hsGuardEnd;
}
예제 #20
0
hsVertexShader::~hsVertexShader()
{
    hsGuardBegin("hsVertexShader::~hsVertexShader");
    hsGuardEnd;
}