⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgconverter.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        else if (TryVersion(CG_PROFILE_PS_2_X, acFilename, acEntry, aacArgs))
        {
            m_pkShader->AddProgram (Shader::DIRECTX, 
                cgGetProgramString(m_kProgram, CG_COMPILED_PROGRAM),
                Shader::PS_2_X );
            DbgPrintf( "\t***Warning: PS 2.X profiles may not work with "\
                "every graphics card.\n" );
            DbgPrintf( "\tDX-PS 2.X profile created\n");
        }
        else
        {
            DbgPrintf( "\t***Warning!!! Program will not work under DX.\n" );
        }

        cgDestroyProgram( m_kProgram );
    }

    DbgPrintf( "\n");
}
//----------------------------------------------------------------------------
CgConverter::~CgConverter ()
{
    if ( cgIsContext(m_kContext) )
    {
        cgDestroyContext(m_kContext);
    }

    if ( cgIsProgram(m_kProgram) )
    {
        cgDestroyProgram(m_kProgram);
    }

    if ( m_pkShader )
        delete m_pkShader;

    if ( m_pkConsts )
        delete m_pkConsts;
}
//----------------------------------------------------------------------------
void CgConverter::CreateShaderConstants ()
{
    if ( m_pkConsts )
        delete m_pkConsts;
    
    m_pkConsts = new ShaderConstants();
    RecurseProgramParameters(cgGetFirstParameter(m_kProgram, CG_PROGRAM));

    DbgPrintf( "Total User/State Constants: %i\n", 
        m_pkConsts->GetNumConstants() );
}
//----------------------------------------------------------------------------
void CgConverter::RecurseProgramParameters(CGparameter kParam)
{
    if (kParam == 0)
        return;

    int i, arraySize;

    do
    {
        switch(cgGetParameterType(kParam))
        {
            case CG_STRUCT:
                RecurseProgramParameters(cgGetFirstStructParameter(kParam));
                break;
            case CG_ARRAY:
                arraySize = cgGetArraySize(kParam, 0);
                for (i = 0; i < arraySize; ++i)
                {
                    RecurseProgramParameters(cgGetArrayParameter(kParam, i));
                }
                break;
            default:
                // handle the single parameter

                // sanity check
                if (!cgIsParameter(kParam))
                {
                    FatalError("Not a parameter.");
                }
                // make sure it is actually used in the program
                if ( cgIsParameterReferenced(kParam) )
                {
                    AddParam( kParam );
                }
                break;
        }
    } while((kParam = cgGetNextParameter(kParam))!= 0);
}

//----------------------------------------------------------------------------
void CgConverter::AddParam (CGparameter kParam)
{
    CGresource kResource;
    const char* acName = cgGetParameterName(kParam);

    int iTemp, iTemp2, iRegister, iSize, iTypeOption;
    StateConstantType iConstType = USER_DEFINED;

    // We don't need to handle out parameters (at this point)
    // DX and GL handle both of these automatically
    if ( cgGetParameterDirection(kParam) == CG_OUT )
    {
        DbgPrintf( "\tOutput (%s), ignored\n", acName );
        return;
    }

    switch (cgGetParameterVariability(kParam))
    {
        case CG_VARYING:
            // update the 
            DbgPrintf( "\tVarying (%s), ", acName );

            kResource = cgGetParameterBaseResource(kParam);

            if ( kResource == CG_TEXCOORD0 )
            {
                iTemp = cgGetParameterResourceIndex(kParam);

                iRegister = GetRegister(kParam);
                m_aiTexCoordRegHint[iTemp] = iRegister;
                DbgPrintf( "TEXCOORD%i (v%i)\n", iTemp, iRegister );
            }
            else if ( kResource == CG_POSITION0 )
            {
                iTemp = cgGetParameterResourceIndex(kParam);
                // only position 0 is accepted in WML
                if (iTemp)
                {
                    FatalError( "May only use Position0 or Position.");
                }

                iRegister = GetRegister(kParam);
                m_iVertexRegHint = iRegister;
                DbgPrintf( "POSITION (v%i)\n", iRegister );
            }
            else if ( kResource == CG_NORMAL0 )
            {
                iTemp = cgGetParameterResourceIndex(kParam);
                // only normal 0 is accepted in WML
                if (iTemp)
                {
                    FatalError( "May only use Normal0 or Normal.");
                }
                iRegister = GetRegister(kParam);
                m_iNormalRegHint = iRegister;
                DbgPrintf( "NORMAL (v%i)\n", iRegister );
            }
            else if ( kResource == CG_COLOR0 )
            {
                iTemp = cgGetParameterResourceIndex(kParam);
                // only color 0 is accepted in WML
                if (iTemp)
                {
                    FatalError( "May only use Color0 or Color.");
                }
                iRegister = GetRegister(kParam);
                m_iColorRegHint = iRegister;
                DbgPrintf( "COLOR (v%i)\n", iRegister );
            }
            else
            {
                DbgPrintf( "ignored\n" );
            }
 

            break;
        case CG_UNIFORM:
            DbgPrintf( "\tUniform (%s), ", acName );

            iRegister = cgGetParameterResourceIndex(kParam);

            iSize = GetSize( kParam );

            if (!iSize)
                return;

            if (!strncmp(acName, "Wml", 3))
            {
                MatchConstantName (acName, iConstType, iTypeOption);

                // you must pick the correct type (float4 or float4x4) for
                // state constants
                if ( StateConstant::Size(iConstType) != iSize )
                {
                    FatalError( "Wrong size for state constant." );
                }
                m_pkConsts->AddConstant( acName, iRegister, 
                    StateConstant::Size(iConstType), iConstType, 
                    iTypeOption);
                DbgPrintf( "state constant (c%i)\n", iRegister );
            }
            else
            {
                iConstType = USER_DEFINED;
                m_pkConsts->AddConstant( acName, iRegister, 
                    iSize, iConstType, 0);
                DbgPrintf( "user constant (c%i)\n", iRegister );

            }
 
            break;
        case CG_CONSTANT:
            DbgPrintf( "\tUniform (%s), ", acName );

            iRegister = cgGetParameterResourceIndex(kParam);
            iSize = GetSize( kParam );
            if (!iSize)
                return;

            iConstType = NUMERICAL_CONSTANT;
            m_pkConsts->AddConstant( acName, iRegister, 
                iSize, iConstType, 0, cgGetParameterValues(kParam,
                CG_CONSTANT, &iTemp2));

            DbgPrintf( "numerical constant (c%i) [", iRegister );
            for( iTemp = 0; iTemp < 4*iSize-1; iTemp++ )
            {
                DbgPrintf( "%.2f, ", (float)(cgGetParameterValues(kParam,
                    CG_CONSTANT, &iTemp2)[iTemp]) );
            }
            DbgPrintf( "%.2f", (float)(cgGetParameterValues(kParam,
                CG_CONSTANT, &iTemp2)[iTemp]) );

            DbgPrintf( "]\n");
            break;

        default:
            FatalError( "Unknown parameter type!\n" );
    }
}
//----------------------------------------------------------------------------
void CgConverter::MatchConstantName (const char* acName, 
    StateConstantType& riType, int& riTypeOption)
{
    int iTemp;

    for (int i = 0; i < StateConstant::NumTypes(); i++)
    {
        if ( !strncmp(acName, StateConstant::Name(i), 
            strlen(StateConstant::Name(i))) )
        {
            riType = (StateConstantType)i;
            switch( riType )
            {
                case RENDERER_MODVIEW:
                case RENDERER_PROJ:
                case RENDERER_MODVIEWPROJ:
                case RENDERER_MOD:
                    iTemp = (int)strlen(StateConstant::Name(i));
                    if ( strlen(acName) == iTemp )
                    {
                        riTypeOption = (int)SC_NORMAL;
                    }
                    else if (!strcmp(&acName[iTemp], "InvTrans"))
                    {
                        riTypeOption = (int)SC_INVERSETRANSPOSE;
                    }
                    else if (!strcmp(&acName[iTemp], "Inv"))
                    {
                        riTypeOption = (int)SC_INVERSE;
                    }
                    else if (!strcmp(&acName[iTemp], "Trans"))
                    {
                        riTypeOption = (int)SC_TRANSPOSE;
                    }
                    else
                    {
                        FatalError( "Invalid Suffix on Matrix type.\n" );
                    }
                    break;
                case LIGHT_POSITION:
                case LIGHT_DIRECTION:
                case LIGHT_AMBIENT:
                case LIGHT_DIFFUSE:
                case LIGHT_SPECULAR:
                case LIGHT_SPOTCUTOFF:
                case LIGHT_ATTENPARAMS:
                    if ( strlen(acName) == strlen(StateConstant::Name(i))+1 )
                    {
                        // lights have a single digit after them
                        // e.g. LIGHT_POSITION0 or LIGHT_AMBIENT7
                        riTypeOption = (int)acName[strlen(acName)-1]-(int)'0';
                        if ( ( riTypeOption < 0 ) || ( riTypeOption >=8 ) )
                        {
                            FatalError( "Illegal light num." );
                        }
                    }
                    else
                    {
                        FatalError( "Lights must have one digit"\
                            " in their name.\n" );
                     }
                    break;
                default:
                    if ( strlen(acName) == strlen(StateConstant::Name(i)) )
                    {
                        riTypeOption = 0;
                    }
                    else
                    {
                        FatalError( "Invalid trailing characters "\
                            "on constant." );
                    }
                    break;
            }

            // if found one, don't check anymore
            break;
        }
    }

    // if none found
    if ( i == StateConstant::NumTypes() )
    {
        // See list in StateConstant.{h, cpp} for valid constant names
        FatalError( "Invalid state constant name." );
    }
}
//----------------------------------------------------------------------------
int CgConverter::GetRegister (CGparameter kParam)
{
    return cgD3D9ResourceToDeclUsage(cgGetParameterResource(kParam));
}
//----------------------------------------------------------------------------
bool CgConverter::TryVersion (CGprofile kProfile, const char* acFilename,
    const char* acEntry, const char** aacArgs)
{
    if ( cgIsProgram(m_kProgram) )
        cgDestroyProgram(m_kProgram);

    m_kProgram = cgCreateProgramFromFile(m_kContext, CG_SOURCE, 
        acFilename, kProfile, acEntry, aacArgs );

    if (cgIsProgram(m_kProgram))
    {
        // Probably need to look for "// %i instructions" line
        return true;
    }
    else
        return false;
}
//----------------------------------------------------------------------------
void CgConverter::WriteObjectToFile (char* acFilename)
{
    m_pkShader->Write( acFilename );
}
//----------------------------------------------------------------------------
void CgConverter::DbgPrintf (char* acFormat, ...)
{
    if ( m_bQuiet )
        return;

    va_list kArgs;
    va_start(kArgs, acFormat);
    vprintf(acFormat,kArgs);
    va_end(kArgs);
}
//----------------------------------------------------------------------------
void CgConverter::FatalError (const char* acMessage)
{
    printf( "\n***ERROR: " );
    printf( acMessage );
    printf( "\n" );
    exit(-1);
}
//----------------------------------------------------------------------------
int CgConverter::GetSize (CGparameter kParam)
{
    CGtype kType = cgGetParameterType(kParam);
    switch( kType )
    {
        case CG_FLOAT:
        case CG_FLOAT2:
        case CG_FLOAT3:
        case CG_FLOAT4:
            return 1;
        case CG_FLOAT3x3:
            return 3;
        case CG_FLOAT4x4:
            return 4;
        case CG_SAMPLER1D:
        case CG_SAMPLER2D:
        case CG_SAMPLER3D:
        case CG_SAMPLERRECT:
        case CG_SAMPLERCUBE:
            // types not handled by the converter, should be ignored
            return 0;
            break;
        default:
            FatalError( "Type not handled by WML (sorry)!\n" );
            return 0;
            break;
    }
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -