// Load and register all the resources needed by the GUI system
//-----------------------------------------------------------------------------
CPUTResult CPUTGuiControllerDX11::Initialize(const std::string& material, const std::string& font)
{
    ID3D11DeviceContext* pImmediateContext = CPUT_DX11::GetContext();
    ID3D11Device *pDevice = CPUT_DX11::GetDevice();
    CPUTAssetLibrary* pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
    HRESULT hr = S_OK;
    std::string ErrorMessage;

    CPUTResult result = CPUT_SUCCESS;
    {
        std::string name = "$cbGUIValues";
        CPUTBufferDesc desc;
        desc.cpuAccess = BUFFER_CPU_WRITE;
        desc.memory = BUFFER_DYNAMIC;
        desc.target = BUFFER_UNIFORM;
        desc.pData = NULL;
        desc.sizeBytes = sizeof(GUIConstantBufferVS);
        mpConstantBufferVS = CPUTBuffer::Create(name, &desc);
        pAssetLibrary->AddConstantBuffer(name, "", "", mpConstantBufferVS);
    }

    mpMaterial = pAssetLibrary->GetMaterial(material);
    mpFont = pAssetLibrary->GetFont(font);
    
    CPUTBufferElementInfo pGUIVertex[3] = {
        { "POSITION", 0, 0, CPUT_F32, 3, 3*sizeof(float), 0 },            
        { "TEXCOORD", 0, 1, CPUT_F32, 2, 2*sizeof(float), 3*sizeof(float)},
        { "COLOR",    0, 2, CPUT_F32, 4, 4*sizeof(float), 5*sizeof(float)},
    };
    
    mpUberBuffer = CPUTMeshDX11::Create();
    mpUberBuffer->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);
    mpUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, mBufferSize, mpMirrorBuffer, NULL, 0, NULL);
    return CPUT_SUCCESS;
}
Пример #2
0
/**
 * This is the main entry point of a native application that is using
 * android_native_app_glue.  It runs in its own thread, with its own
 * event loop for receiving input events and doing other things.
 */
void android_main(struct android_app* state)
{
    // Make sure glue isn't stripped.
    app_dummy();

    LOGI("\n\n********************************");
    LOGI("      STARTING SAMPLE");
    LOGI("********************************\n\n");

    // create an instance of my sample
    MySample *pSample = new MySample();
    if (!pSample)
    {
        LOGI("Failed to allocate MySample");
        return;
    }

     // Assign the sample back into the app state
    state->userData = pSample;
    state->onAppCmd = cput_handle_cmd;
    state->onInputEvent = CPUT_OGL::cput_handle_input;


    // We make the assumption we are running from the executable's dir in
    // the CPUT SampleStart directory or it won't be able to use the relative paths to find the default
    // resources    
    cString ResourceDirectory;

    CPUTFileSystem::GetExecutableDirectory(&ResourceDirectory);

    // Different executable and assets locations on different OS'es.
    // Consistency should be maintained in all OS'es and API's.
    ResourceDirectory.append(GUI_LOCATION);

	// Initialize the system and give it the base CPUT resource directory (location of GUI images/etc)
    // For now, we assume it's a relative directory from the executable directory.  Might make that resource
    // directory location an env variable/hardcoded later
    CPUTWindowAndroid::SetAppState(state);
	pSample->CPUTInitialize(ResourceDirectory);

    CPUTFileSystem::GetExecutableDirectory(&ResourceDirectory);

    // Different executable and assets locations on different OS'es.
    // Consistency should be maintained in all OS'es and API's.
    ResourceDirectory.append(SYSTEM_LOCATION);
    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
    pAssetLibrary->SetSystemDirectoryName(ResourceDirectory);

    // start the main message loop
    pSample->CPUTMessageLoop();

    // cleanup resources
    SAFE_DELETE(pSample);
    pSample = NULL;

    state->userData = NULL;
}
//-----------------------------------------
void CPUTPostProcess::CreatePostProcess(
    CPUTRenderTargetColor *pSourceRenderTarget
){
    mpRTSourceRenderTarget    = pSourceRenderTarget;

    GLuint sourceFormat  = mpRTSourceRenderTarget->GetColorFormat();
    UINT sourceWidth          = mpRTSourceRenderTarget->GetWidth();
    UINT sourceHeight         = mpRTSourceRenderTarget->GetHeight();

    mpRTDownSample4x4         = new CPUTRenderTargetColor();
    mpRTDownSample4x4PingPong = new CPUTRenderTargetColor();
    mpRT64x64                 = new CPUTRenderTargetColor();
    mpRT4x4                   = new CPUTRenderTargetColor();
    mpRT1x1                   = new CPUTRenderTargetColor();

    mpRTDownSample4x4->CreateRenderTarget(         _L("PostProcessDownsample4x4"),         sourceWidth/4, sourceHeight/4,          sourceFormat );
    mpRTDownSample4x4PingPong->CreateRenderTarget( _L("PostProcessDownsample4x4PingPong"), sourceWidth/4, sourceHeight/4,          sourceFormat );
    mpRT64x64->CreateRenderTarget(                 _L("PostProcessRT64x64"),                          64,             64, DXGI_FORMAT_R32_FLOAT ); 
    mpRT4x4->CreateRenderTarget(                   _L("PostProcessRT4x4"),                             8,              8, DXGI_FORMAT_R32_FLOAT ); 
    mpRT1x1->CreateRenderTarget(                   _L("PostProcessRT1x1"),                             1,              1, DXGI_FORMAT_R32_FLOAT );

    CPUTAssetLibrary *pLibrary = CPUTAssetLibrary::GetAssetLibrary();
    mpMaterialDownSampleBackBuffer4x4 = pLibrary->GetMaterial(_L("PostProcess/DownSampleBackBuffer4x4"));
    mpMaterialDownSample4x4           = pLibrary->GetMaterial(_L("PostProcess/DownSample4x4"));
    mpMaterialDownSample4x4Alpha      = pLibrary->GetMaterial(_L("PostProcess/DownSample4x4Alpha"));
    mpMaterialDownSampleLogLum        = pLibrary->GetMaterial(_L("PostProcess/DownSampleLogLum"));
    mpMaterialBlurHorizontal          = pLibrary->GetMaterial(_L("PostProcess/BlurHorizontal"));
    mpMaterialBlurVertical            = pLibrary->GetMaterial(_L("PostProcess/BlurVertical"));
    mpMaterialComposite               = pLibrary->GetMaterial(_L("PostProcess/Composite"));
    mpMaterialSpriteNoAlpha           = pLibrary->GetMaterial(_L("PostProcess/Sprite"));

    mpFullScreenSprite = new CPUTSprite();
    mpFullScreenSprite->CreateSprite( -1.0f, -1.0f, 2.0f, 2.0f, _L("Sprite") );
}
Пример #4
0
void Menu_FaceMapping::LoadFace(const std::string &filename)
{
	mObjFilename = filename;
	mFaceModel.LoadObjFilename(filename);

	CPUTTexture *texture;
	mFaceCPUTModel = mFaceModel.LoadCPUTModel(&texture);

	CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
	pAssetLibrary->SetRootRelativeMediaDirectory("MyAssets");
	std::string matName = pAssetLibrary->GetMaterialDirectoryName();
	CPUTFileSystem::CombinePath(matName, "displace_map_render.mtl", &matName);

	CPUTMaterial *material = CPUTMaterial::Create(matName);
	material->OverridePSTexture(0, texture);
	mFaceCPUTModel->SetMaterial(0, &material, 1);
}
// Handle resize events
//-----------------------------------------------------------------------------
void MySample::ResizeWindow(UINT width, UINT height)
{
    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

    // Before we can resize the swap chain, we must release any references to it.
    // We could have a "AssetLibrary::ReleaseSwapChainResources(), or similar.  But,
    // Generic "release all" works, is simpler to implement/maintain, and is not performance critical.
    pAssetLibrary->ReleaseTexturesAndBuffers();

    // Resize the CPUT-provided render target
    CPUT_DX11::ResizeWindow( width, height );

    // Resize any application-specific render targets here
    if( mpCamera ) mpCamera->SetAspectRatio(((float)width)/((float)height));

    pAssetLibrary->RebindTexturesAndBuffers();
}
Пример #6
0
//-----------------------------------------------------------------------------
CPUTAssetSet *CPUTAssetSet::Create( const std::string &name, const std::string &absolutePathAndFilename, int numSystemMaterials, std::string *pSystemMaterialNames )
{
    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

    // Create the root node.
    CPUTNullNode *pRootNode = CPUTNullNode::Create();
    pRootNode->SetName("_CPUTAssetSetRootNode_");

    // Create the asset set, set its root, and load it
    CPUTAssetSet   *pNewAssetSet = new CPUTAssetSet();
	pNewAssetSet->IsEnabled = true;
    pNewAssetSet->SetRoot( pRootNode );
    pAssetLibrary->AddNullNode( name, "", "_Root", pRootNode );

    CPUTResult result = pNewAssetSet->LoadAssetSet(absolutePathAndFilename, numSystemMaterials, pSystemMaterialNames);
    if( CPUTSUCCESS(result) )
    {
        pAssetLibrary->AddAssetSet(name, "", "", pNewAssetSet);
        return pNewAssetSet;
    }
    ASSERT( CPUTSUCCESS(result), "Error loading AssetSet\n'"+absolutePathAndFilename+"'");
    pNewAssetSet->Release();
    return NULL;
}
Пример #7
0
void SampleUtil_Init()
{
	std::string dir;
	CPUTFileSystem::GetExecutableDirectory(&dir);
	CPUTFileSystem::StripDirectoriesFromPath(&dir, 4);
	CPUTFileSystem::CombinePath(dir, "Media\\MyAssets", &gUtilGlob.myAssetsDirectory);
	CPUTFileSystem::CombinePath(dir, "userdata", &gUtilGlob.userDataDirectory);

	CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
	for (int i = 0; i < CODE_TEXTURE_COUNT; i++)
	{
		char textureName[64];
		snprintf(textureName, sizeof(textureName), "$CODETEXTURE%d", i);
		std::string textureNameString = std::string(textureName);
		gUtilGlob.codeTextures[i] = (CPUTTextureDX11*)CPUTTextureDX11::Create(textureNameString, NULL, NULL);
		pAssetLibrary->AddTexture(textureName, "", "", gUtilGlob.codeTextures[i]);
	}
	gUtilGlob.codeMaterial = pAssetLibrary->GetMaterial("MyAssets/codesprite");

	pAssetLibrary->SetMediaDirectoryName(GetMyAssetsDirectory() + "\\");
	gUtilGlob.meshPreviewMaterial = pAssetLibrary->GetMaterial("meshpreview");


	// Load cube and sphere
	pAssetLibrary->SetRootRelativeMediaDirectory("");

	std::string filename;
	CPUTFileSystem::GetMediaDirectory(&filename);
	CPUTFileSystem::CombinePath(filename, "common.scene", &filename);
	gUtilGlob.boxScene = CPUTScene::Create();
	gUtilGlob.boxScene->LoadScene(filename.c_str());
	gUtilGlob.boxModel = pAssetLibrary->FindModel("pCube1", true);

 
	pAssetLibrary->SetMediaDirectoryName(GetMyAssetsDirectory() + "\\");
	CPUTMaterial *quadSpriteMat = pAssetLibrary->GetMaterial("debugQuad");
	gUtilGlob.QuadSprite = CPUTSprite::Create(0.0f, 0.0f, 1.0f, 1.0f, quadSpriteMat);
	SAFE_RELEASE(quadSpriteMat);

}
Пример #8
0
void MySample::CreateResources()
{
    CPUT_DX11::CreateResources();
    int width, height;
    mpWindow->GetClientDimensions(&width, &height);

    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

    std::string executableDirectory;
    std::string mediaDirectory;

    CPUTFileSystem::GetExecutableDirectory(&executableDirectory);
    CPUTFileSystem::ResolveAbsolutePathAndFilename(executableDirectory + "../../../../Media/", &mediaDirectory);
    
	pAssetLibrary->SetMediaDirectoryName(mediaDirectory + "gui_assets/");
    pAssetLibrary->SetSystemDirectoryName(mediaDirectory + "System/");
    pAssetLibrary->SetFontDirectoryName(mediaDirectory + "gui_assets/Font/");

    CPUTGuiController *pGUI = CPUTGetGuiController();
    pGUI->Initialize("guimaterial_dds_16", "arial_16.fnt");

    pGUI->SetCallback(this);

    pAssetLibrary->SetMediaDirectoryName(mediaDirectory);

    mpShadowRenderTarget = CPUTRenderTargetDepth::Create();
    mpShadowRenderTarget->CreateRenderTarget(std::string("$shadow_depth"), SHADOW_WIDTH_HEIGHT, SHADOW_WIDTH_HEIGHT, DXGI_FORMAT_D32_FLOAT);

    CPUTMaterial* pDebugMaterial = pAssetLibrary->GetMaterial("%sprite");
    mpDebugSprite = CPUTSprite::Create(-1.0f, -1.0f, 0.5f, 0.5f, pDebugMaterial);
    SAFE_RELEASE(pDebugMaterial);

    mpCameraController = CPUTCameraControllerFPS::Create();
    mpShadowCamera = CPUTCamera::Create(CPUT_ORTHOGRAPHIC);
     
    pGUI->Resize(width, height);
	
}
Пример #9
0
void MySample::Create()
{
	CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
    cString ExecutableDirectory;
    CPUTFileSystem::GetExecutableDirectory(&ExecutableDirectory);
    ExecutableDirectory.append(_L(ASSET_LOCATION));
    pAssetLibrary->SetMediaDirectoryName(ExecutableDirectory);

#ifdef ENABLE_GUI
    CPUTGuiControllerOGL *pGUI = (CPUTGuiControllerOGL*)CPUTGetGuiController();
    std::string mediaDirectory = ws2s(pAssetLibrary->GetMediaDirectoryName());
    std::string fontDirectory("Font/");
    CPUTFont *pFont = CPUTFont::CreateFont(SYSTEM_LOCATION + fontDirectory, "arial_64.fnt");

    pGUI->SetFont(pFont);

    //
    // Create some controls
    //   
	CPUTDropdown *pDropdownMethod;
	
	pGUI->CreateText(_L("Test Font"), ID_IGNORE_CONTROL_ID, ID_MAIN_PANEL, &pTextMethod);
	pTextMethod->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
	CreateInstancingControlButtons();
#endif

	CPUTFileSystem::GetExecutableDirectory(&ExecutableDirectory);
    ExecutableDirectory.append(_L(ASSET_LOCATION));
    pAssetLibrary->SetMediaDirectoryName(ExecutableDirectory);


    int width, height;
    mpWindow->GetClientDimensions(&width, &height);
    DEBUG_PRINT(_L("Resize Window"));

    ResizeWindow(width, height);

    mpScene = new CPUTScene();
    DEBUG_PRINT(_L("Load Scene"));

    // Load the scene
    if (CPUTFAILED(mpScene->LoadScene(SCENE_FILE)))
    {
        LOGI("Failed to Load Scene, try loading asset set individually");
        CPUTAssetSet *pAssetSet = NULL;
        pAssetSet = pAssetLibrary->GetAssetSet( ASSET_SET_FILE );
        mpScene->AddAssetSet(pAssetSet);
        pAssetSet->Release();
    }
    LOGI("Loaded the scene");

    // Get the camera. Get the first camera encountered in the scene or
    // if there are none, create a new one.
    unsigned int numAssets = mpScene->GetNumAssetSets();
    for (unsigned int i = 0; i < numAssets; ++i) {
        CPUTAssetSet *pAssetSet = mpScene->GetAssetSet(i);
        if (pAssetSet->GetCameraCount() > 0) {
            mpCamera = pAssetSet->GetFirstCamera();
            break;
        }
    }

    // Create the camera
    if (mpCamera == NULL)
    {
        mpCamera = new CPUTCamera();
        pAssetLibrary->AddCamera( _L(""), _L("SampleStart Camera"), _L(""), mpCamera );
		
		mpCamera->SetPosition( 0.0f, cameraY, 100.0f );

        // Set the projection matrix for all of the cameras to match our window.
        // TODO: this should really be a viewport matrix.  Otherwise, all cameras will have the same FOV and aspect ratio, etc instead of just viewport dimensions.
        mpCamera->SetAspectRatio(((float)width)/((float)height));
    }

    mpCamera->SetFov(DegToRad(90.0)); // TODO: Fix converter's FOV bug (Maya generates cameras for which fbx reports garbage for fov)
    mpCamera->SetFarPlaneDistance(100000.0f);
    mpCamera->Update();

    mpCameraController = new CPUTCameraControllerFPS();
    mpCameraController->SetCamera(mpCamera);
    mpCameraController->SetLookSpeed(0.004f);
    mpCameraController->SetMoveSpeed(150.0f);

	// retrieve function pointer
    glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) ( eglGetProcAddress( "glDrawElementsInstanced" ) );


    if( glDrawElementsInstancedEXT == NULL )
    {
        LOGE( "Failed to load extension pointer" );
    }
	
	currentRowCount = NUM_ROWS / 1.5;
	currentColCount = NUM_COLUMNS;
	
	LOGI("Getting handles for materials");

	// get handles to switch instancing / non instancing
	pAssetLibrary->PrintAssetLibrary();

	supportMaterial = pAssetLibrary->GetMaterialByName("instanceV2/Material/concreteMultiMaterial.mtl");
	techMaterial = pAssetLibrary->GetMaterialByName("instanceV2/Material/techALowMultiMataterial.mtl");

	isInstanced = true;
	
	CPUTModel *pModel = pAssetLibrary->GetModelByName( _L( ".instangeGrptechALow" ) );
	pModel->SetDrawModelCallBack((DrawModelCallBackFunc)drawCallback);
	pModel = pAssetLibrary->GetModelByName( _L( ".instangeGrpconcrete" ) );
	pModel->SetDrawModelCallBack((DrawModelCallBackFunc)drawCallback);

	UINT supportCount = supportMaterial->GetMaterialEffectCount();
	UINT techCount = techMaterial->GetMaterialEffectCount();

	glFrontFace(GL_CW);
    UpdateMatrixBuffers();
}
Пример #10
0
//-----------------------------------------------
HRESULT CPUTRenderTargetColor::CreateRenderTarget(
    std::string     textureName,
    UINT        width,
    UINT        height,
    DXGI_FORMAT colorFormat,
    UINT        multiSampleCount,
    bool        createUAV,
    bool        recreate
)
{
    HRESULT result;

    mName             = textureName;
    mWidth            = width;
    mHeight           = height;
    mColorFormat      = colorFormat;
    mMultiSampleCount = multiSampleCount;

    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

    // Create the color texture
    int createFlags = createUAV 
        ? D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS
        : D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;

    mColorDesc = CD3D11_TEXTURE2D_DESC(
        colorFormat,
        width,
        height,
        1, // Array Size
        1, // MIP Levels
        createFlags,
        D3D11_USAGE_DEFAULT,
        0,
        mMultiSampleCount, 0
    );

    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();

    // If MSAA enabled, then create MSAA texture
    if( mMultiSampleCount>1 )
    {
        result = pD3dDevice->CreateTexture2D( &mColorDesc, NULL, &mpColorTextureDXMSAA );
        ASSERT( SUCCEEDED(result), "Failed creating MSAA render target texture" );

        D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D11_SRV_DIMENSION_TEXTURE2DMS, 0 };
        srDesc.Texture2D.MipLevels = 1;
        result = pD3dDevice->CreateShaderResourceView( mpColorTextureDXMSAA, &srDesc, &mpColorSRVMSAA );
        ASSERT( SUCCEEDED(result), "Failed creating MSAA render target shader resource view" );
        CPUTSetDebugName( mpColorSRVMSAA, textureName + " ColorMSAA" );

        if( !recreate )
        {
            std::string msaaName = mName + "_MSAA";
            mpColorTextureMSAA = CPUTTextureDX11::Create( msaaName );

            // If the name starts with a '$', then its an internal texture (has no filesystem path).
            // Otherwise, its a file, so prepend filesystem path
            CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();
            std::string finalName;
            if( mName.at(0) == '$' )
            {
                finalName = msaaName;
            }else
            {
                CPUTFileSystem::ResolveAbsolutePathAndFilename( (pAssetLibrary->GetTextureDirectoryName() + msaaName), &finalName);
            }
            pAssetLibrary->AddTexture( finalName, "", "", mpColorTextureMSAA );
        }
        ((CPUTTextureDX11*)mpColorTextureMSAA)->SetTextureAndShaderResourceView( mpColorTextureDXMSAA, mpColorSRVMSAA );
    }
    
    // Create non-MSAA texture.  If we're MSAA, then we'll resolve into this.  If not, then we'll render directly to this one.
    mColorDesc.SampleDesc.Count = 1;
    result = pD3dDevice->CreateTexture2D( &mColorDesc, NULL, &mpColorTextureDX );
    ASSERT( SUCCEEDED(result), "Failed creating render target texture" );

    // Create the shader-resource view from the non-MSAA texture
    D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D11_SRV_DIMENSION_TEXTURE2D, 0 };
    srDesc.Texture2D.MipLevels = 1;
    result = pD3dDevice->CreateShaderResourceView( mpColorTextureDX, &srDesc, &mpColorSRV );
    ASSERT( SUCCEEDED(result), "Failed creating render target shader resource view" );
    CPUTSetDebugName( mpColorSRV, textureName + " Color" );

    mHasUav = createUAV; // Remember, so we know to recreate it (or not) on RecreateRenderTarget()
    if( createUAV )
    {
        // D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D_SRV_DIMENSION_BUFFER, 0 };
        D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
        memset( &uavDesc, 0, sizeof(uavDesc) );
        uavDesc.Format = colorFormat;
        uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
        uavDesc.Texture2D.MipSlice = 0;
        result = pD3dDevice->CreateUnorderedAccessView( mpColorTextureDX, &uavDesc, &mpColorUAV );
        ASSERT( SUCCEEDED(result), "Failed creating render target buffer shader resource view" );
        CPUTSetDebugName( mpColorUAV, textureName + " Color Buffer" );
    }
    if( !recreate )
    {
        mpColorTexture = CPUTTextureDX11::Create(mName);
        pAssetLibrary->AddTexture( mName, "", "", mpColorTexture );

        mpColorBuffer = CPUTBuffer::Create(mName, NULL);
        ((CPUTBufferDX11*)mpColorBuffer)->SetUnorderedAccessView(mpColorUAV);
        //SeCPUTBufferDX11::CreateWithUAV(mName, NULL, mpColorUAV); // We don't have an ID3D11Buffer, but we want to track this UAV as if the texture was a buffer.
        pAssetLibrary->AddBuffer( mName, "", "", mpColorBuffer );
    }
    ((CPUTTextureDX11*)mpColorTexture)->SetTextureAndShaderResourceView( mpColorTextureDX, mpColorSRV);

    // Choose our render target.  If MSAA, then use the MSAA texture, and use resolve to fill the non-MSAA texture.
    ID3D11Texture2D *pColorTexture = (mMultiSampleCount>1) ? mpColorTextureDXMSAA : mpColorTextureDX;
    result = pD3dDevice->CreateRenderTargetView( pColorTexture, NULL, &mpColorRenderTargetView );
    ASSERT( SUCCEEDED(result), "Failed creating render target view" );
    CPUTSetDebugName( mpColorRenderTargetView, mName );

    return S_OK;
}
Пример #11
0
//-----------------------------------------------
HRESULT CPUTRenderTargetDepth::CreateRenderTarget(
    std::string     textureName,
    UINT        width,
    UINT        height,
    DXGI_FORMAT depthFormat,
    UINT        multiSampleCount,
    bool        recreate
)
{
    HRESULT result;

    mName             = textureName;
    mWidth            = width;
    mHeight           = height;
    mDepthFormat      = depthFormat;
    mMultiSampleCount = multiSampleCount;


    // NOTE: The following doesn't work for DX10.0 devices.
    // They don't support binding an MSAA depth texture as 

    // If we have a DX 10.1 or no MSAA, then create a shader resource view, and add a CPUTTexture to the AssetLibrary
    D3D_FEATURE_LEVEL featureLevel = gpSample->GetFeatureLevel();
    bool supportsResourceView = ( featureLevel >= D3D_FEATURE_LEVEL_10_1) || (mMultiSampleCount==1);

    D3D11_TEXTURE2D_DESC depthDesc = {
        width,
        height,
        1, // MIP Levels
        1, // Array Size
        DXGI_FORMAT(depthFormat - 1), //  DXGI_FORMAT_R32_TYPELESS
        mMultiSampleCount, 0,
        D3D11_USAGE_DEFAULT,
        D3D11_BIND_DEPTH_STENCIL | (supportsResourceView ? D3D11_BIND_SHADER_RESOURCE : 0),
        0, // CPU Access flags
        0 // Misc flags
    };

    // Create either a Texture2D, or Texture2DMS, depending on multisample count.
    D3D11_DSV_DIMENSION dsvDimension = (mMultiSampleCount>1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;

    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();
    result = pD3dDevice->CreateTexture2D( &depthDesc, NULL, &mpDepthTextureDX );
    ASSERT( SUCCEEDED(result), "Failed creating depth texture.\nAre you using MSAA with a DX10.0 GPU?\nOnly DX10.1 and above can create a shader resource view for an MSAA depth texture." );

    D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = { depthFormat, dsvDimension, 0 };
    result = pD3dDevice->CreateDepthStencilView( mpDepthTextureDX, &dsvd, &mpDepthStencilView );
    ASSERT( SUCCEEDED(result), "Failed creating depth stencil view" );
    CPUTSetDebugName( mpDepthStencilView, mName );

    if( supportsResourceView )
    {
        D3D11_SRV_DIMENSION srvDimension = (mMultiSampleCount>1) ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
        // Create the shader-resource view
        D3D11_SHADER_RESOURCE_VIEW_DESC depthRsDesc =
        {
            DXGI_FORMAT(depthFormat + 1),
            srvDimension,
            0
        };
        // TODO: Support optionally creating MIP chain.  Then, support MIP generation (e.g., GenerateMIPS()).
        depthRsDesc.Texture2D.MipLevels = 1;

        result = pD3dDevice->CreateShaderResourceView( mpDepthTextureDX, &depthRsDesc, &mpDepthResourceView );
        ASSERT( SUCCEEDED(result), "Failed creating render target shader resource view" );
        CPUTSetDebugName( mpDepthResourceView, textureName + " Depth" );

        if( !recreate )
        {
            CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

            mpDepthTexture = CPUTTextureDX11::Create(mName);
            pAssetLibrary->AddTexture( mName, "", "", mpDepthTexture );
        }
        ((CPUTTextureDX11*)mpDepthTexture)->SetTextureAndShaderResourceView(mpDepthTextureDX, mpDepthResourceView);
    }
    return S_OK;
}
Пример #12
0
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetSet::LoadAssetSet(std::string name, int numSystemMaterials, std::string *pSystemMaterialNames)
{
    CPUTResult result = CPUT_SUCCESS;

    // if not found, load the set file
    CPUTConfigFile ConfigFile;
    result = ConfigFile.LoadFile(name);
    if( !CPUTSUCCESS(result) )
    {
        return result;
    }
    // ASSERT( CPUTSUCCESS(result), "Failed loading set file '" + name + "'." );

    mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node
    mppAssetList = new CPUTRenderNode*[mAssetCount];
    mppAssetList[0] = mpRootNode;
    mpRootNode->AddRef();

    CPUTAssetLibrary *pAssetLibrary = (CPUTAssetLibrary*)CPUTAssetLibrary::GetAssetLibrary();

	CPUTAnimation *pDefaultAnimation = NULL;
    for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it)
    {
        CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii);
		ASSERT(pBlock != NULL, "Cannot find block");

        if( !pBlock )
        {
            return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND;
        }

        std::string nodeType = pBlock->GetValueByName("type")->ValueAsString();
        CPUTRenderNode *pParentNode = NULL;

        // TODO: use Get*() instead of Load*() ?

        std::string name = pBlock->GetValueByName("name")->ValueAsString();

        int parentIndex;
        CPUTRenderNode *pNode = NULL;
        if(0==nodeType.compare("null"))
        {
            pNode  = pNode = CPUTNullNode::Create();
            result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1];
            std::string &parentPrefix = pParentNode->GetPrefix();
            std::string prefix = parentPrefix;
            prefix.append(".");
            prefix.append(name);
            pNode->SetPrefix(prefix);
      //      pNode->SetPrefix( parentPrefix + "." + name );
            pAssetLibrary->AddNullNode("", parentPrefix + name, "", (CPUTNullNode*)pNode);
            // Add this null's name to our prefix
            // Append this null's name to our parent's prefix
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
        }
        else if(0==nodeType.compare("model"))
        {
            CPUTConfigEntry *pValue = pBlock->GetValueByName( "instance" );
            CPUTModel *pModel = CPUTModel::Create();
            if( pValue == &CPUTConfigEntry::sNullConfigValue )
            {
                // Not found.  So, not an instance.
                pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames);
            }
            else
            {
                int instance = pValue->ValueAsInt();

                // If the current node is an instance of itself then it has no "master" model
                if(ii == instance)
                {
                    // TODO: create instance model object
                    pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames);
                }
                else
                {
                    pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1], numSystemMaterials, pSystemMaterialNames);
                }
            }
            pParentNode = mppAssetList[parentIndex+1];
            pModel->SetParent( pParentNode );
            pParentNode->AddChild( pModel );
            std::string &parentPrefix = pParentNode->GetPrefix();
            pModel->SetPrefix( parentPrefix );
            pAssetLibrary->AddModel(name, parentPrefix, "", pModel);

            pModel->UpdateBoundsWorldSpace();

#ifdef  SUPPORT_DRAWING_BOUNDING_BOXES
            // Create a mesh for rendering the bounding box
            // TODO: There is definitely a better way to do this.  But, want to see the bounding boxes!
            pModel->CreateBoundingBoxMesh();
#endif
            pNode = pModel;
        }
        else if(0==nodeType.compare("light"))
        {
            pNode = CPUTLight::Create();
            ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
            std::string &parentPrefix = pParentNode->GetPrefix();
            pNode->SetPrefix( parentPrefix );
            pAssetLibrary->AddLight(name, parentPrefix, "", (CPUTLight*)pNode);
        }
        else if(0==nodeType.compare("camera"))
        {
            pNode = CPUTCamera::Create(CPUT_PERSPECTIVE);
            ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
            std::string &parentPrefix = pParentNode->GetPrefix();
            pNode->SetPrefix( parentPrefix );
            pAssetLibrary->AddCamera(name, parentPrefix, "", (CPUTCamera*)pNode);
            if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();}
            ++mCameraCount;
        }
        else
        {
            ASSERT(0,"Unsupported node type '" + nodeType + "'.");
        }

        CPUTConfigEntry *pAnimValue = pBlock->GetValueByName( "Animation0" );
		//int autoPlayAnimationIndex = pBlock->GetValueByName( "DefaultAnimation" );
        for(int i = 1; pAnimValue != &CPUTConfigEntry::sNullConfigValue; ++i )
        {
			CPUTAnimation *pCurrentAnimation = pAssetLibrary->GetAnimation(pAnimValue->ValueAsString());
			
            //First Animation will be default for now
			if(pCurrentAnimation != NULL && i == 1 /*autoPlayAnimationIndex*/)
			{
				pDefaultAnimation = pCurrentAnimation ;
                pCurrentAnimation->AddRef();
			}

            std::stringstream animName;
            animName << "Animation" << i;
            pAnimValue = pBlock->GetValueByName(animName.str());
            pNode->mAnimationList.push_back(pCurrentAnimation);
        }

        // Add the node to our asset list (i.e., the linear list, not the hierarchical)
        mppAssetList[ii+1] = pNode;
        // Don't AddRef.Creating it set the refcount to 1.  We add it to the list, and then we're done with it.
        // Net effect is 0 (+1 to add to list, and -1 because we're done with it)
        // pNode->AddRef();
    }

    //Set the default animation to the current Asset Set
	if(pDefaultAnimation != NULL && mAssetCount > 1)
	{
        //Apply Animation to root of the setfile
		mppAssetList[1]->SetAnimation(pDefaultAnimation);
	}
	SAFE_RELEASE(pDefaultAnimation);
    return result;
}
Пример #13
0
void Menu_FaceMapping::Init()
{
	MenuBase::Init();

	SetDefaultTweaks(&mTweaks);

	CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

	mpFaceMapRTColor = CPUTRenderTargetColor::Create();
	mpFaceMapRTColor->CreateRenderTarget("$FaceColor", FACE_DISPLACEMENT_WIDTH_HEIGHT, FACE_DISPLACEMENT_WIDTH_HEIGHT, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);

	mpFaceMapRTDepth = CPUTRenderTargetColor::Create();
	mpFaceMapRTDepth->CreateRenderTarget("$FaceDisplacement", FACE_DISPLACEMENT_WIDTH_HEIGHT, FACE_DISPLACEMENT_WIDTH_HEIGHT, DXGI_FORMAT_R32_FLOAT);

	mpFaceMapDepthBuffer = CPUTRenderTargetDepth::Create();
	mpFaceMapDepthBuffer->CreateRenderTarget("$FaceDisplacementDepth", FACE_DISPLACEMENT_WIDTH_HEIGHT, FACE_DISPLACEMENT_WIDTH_HEIGHT, DXGI_FORMAT_D32_FLOAT);

	mDisplacementCamera = CPUTCamera::Create(CPUT_ORTHOGRAPHIC);
	mDisplacementCamera->SetPosition(0.0f, 0.0f, -10.0f);
	mDisplacementCamera->LookAt( 0.0f, 0.0f, 0.0f );
	
	mDisplacementCamera->SetFarPlaneDistance(20);
	mDisplacementCamera->SetNearPlaneDistance(1.0f);
	mDisplacementCamera->SetAspectRatio(1.0f);
	mDisplacementCamera->SetWidth(10);
	mDisplacementCamera->SetHeight(10);
	mDisplacementCamera->Update();
	
	pAssetLibrary->SetRootRelativeMediaDirectory("MyAssets");
	CPUTMaterial* mat = pAssetLibrary->GetMaterial("render_map_diffuse");
	mMapSprites[FaceMapTexture_Color] = CPUTSprite::Create(-1.0f, -1.0f, 0.5f, 0.5f, mat);
	SAFE_RELEASE(mat);
	mat = pAssetLibrary->GetMaterial("render_map_depth");
	mMapSprites[FaceMapTexture_Depth] = CPUTSprite::Create(-1.0f, -0.4f, 0.5f, 0.5f, mat);
	SAFE_RELEASE(mat);

	// load the head model
	std::string mediaFilename;
	CPUTFileSystem::GetMediaDirectory(&mediaFilename);
	pAssetLibrary->SetMediaDirectoryName(mediaFilename+"\\");
	CPUTFileSystem::CombinePath(mediaFilename, "basicHead_03.scene", &mediaFilename);
	mScene = CPUTScene::Create();
	mScene->LoadScene(mediaFilename);
	mHeadModel = pAssetLibrary->FindModel("head4", true);

	CPUTAssetSet *hairSetMale = pAssetLibrary->FindAssetByNameNoPath("hairMale_01.set", CPUTAssetLibrary::mpAssetSetList);
	CPUTAssetSet *hairSetMale_Black = pAssetLibrary->FindAssetByNameNoPath("hairMale_01_black.set", CPUTAssetLibrary::mpAssetSetList);
	CPUTAssetSet *hairSetFemale = pAssetLibrary->FindAssetByNameNoPath("hairGeekGirl.set", CPUTAssetLibrary::mpAssetSetList);
	CPUTAssetSet *hairSetFemale_Blonde = pAssetLibrary->FindAssetByNameNoPath("hairGeekGirl_blonde.set", CPUTAssetLibrary::mpAssetSetList);
	CPUTAssetSet *hairSetFemale_Black = pAssetLibrary->FindAssetByNameNoPath("hairGeekGirl_black.set", CPUTAssetLibrary::mpAssetSetList);
	CPUTAssetSet *hairSetCrazy = pAssetLibrary->FindAssetByNameNoPath("hair_01.set", CPUTAssetLibrary::mpAssetSetList);

	HairInfo info;
	info.name = "Hair Short";
	info.set = hairSetMale;
	mHairList.push_back(info);

	info.name = "Hair Short Black";
	info.set = hairSetMale_Black;
	mHairList.push_back(info);

	info.name = "Hair Long";
	info.set = hairSetFemale;
	mHairList.push_back(info);

	info.name = "Hair Long Blonde";
	info.set = hairSetFemale_Blonde;
	mHairList.push_back(info);

	info.name = "Hair Long Black";
	info.set = hairSetFemale_Black;
	mHairList.push_back(info);

	info.name = "Madness";
	info.set = hairSetCrazy;
	mHairList.push_back(info);


	GetCPUTLandmark( std::string( "LANDMARK_EYE_LEFT_CENTER" ), &mHeadLandmark_LeftEyeCenter);
	GetCPUTLandmark( std::string( "LANDMARK_EYE_RIGHT_CENTER" ), &mHeadLandmark_RightEyeCenter);
	GetCPUTLandmark(std::string("LANDMARK_NOSE_TIP"), &mHeadLandmark_NoseTip);

	mCameraController = new CPUTCameraModelViewer();
	mCameraController->SetTarget(float3(0, 0, 0));
	mCameraController->SetDistance( 20, 10, 40);
	mCameraController->SetViewAngles(0, 0);

	mMapProjectionCamera = CPUTCamera::Create(CPUT_ORTHOGRAPHIC);
	float y = 5.0f;
	mMapProjectionCamera->SetPosition(0.0f, y, -10.0f );
	mMapProjectionCamera->LookAt(0.0f, y, 0.0f);

	mMapProjectionCamera->SetFarPlaneDistance(100);
	mMapProjectionCamera->SetNearPlaneDistance(0.1f);
	mMapProjectionCamera->SetAspectRatio(1.0f);
	mMapProjectionCamera->SetWidth(15);
	mMapProjectionCamera->SetHeight(15);
	mMapProjectionCamera->Update();

    mSaveSculptedObj = false;
}
// Handle OnCreation events
//-----------------------------------------------------------------------------
void MySample::Create()
{    
    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();

    gLightDir.normalize();

    // TODO: read from cmd line, using these as defaults
    //pAssetLibrary->SetMediaDirectoryName(    _L("Media"));

    CPUTGuiControllerDX11 *pGUI = CPUTGetGuiController();

    // create some controls
	CPUTButton     *pButton = NULL;
    pGUI->CreateButton(_L("Fullscreen"), ID_FULLSCREEN_BUTTON, ID_MAIN_PANEL, &pButton);
	pGUI->CreateDropdown( L"Rasterizer Technique: SCALAR", ID_RASTERIZE_TYPE, ID_MAIN_PANEL, &mpTypeDropDown);
    mpTypeDropDown->AddSelectionItem( L"Rasterizer Technique: SSE" );
   	mpTypeDropDown->SetSelectedItem(mSOCType + 1);
   
	wchar_t string[CPUT_MAX_STRING_LENGTH];
    pGUI->CreateText(    _L("Occluders                                              \t"), ID_OCCLUDERS, ID_MAIN_PANEL, &mpOccludersText);
	
	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of Models: \t%d"), mNumOccluders);
	pGUI->CreateText(string, ID_NUM_OCCLUDERS, ID_MAIN_PANEL, &mpNumOccludersText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tDepth rasterized models: %d"), mNumOccludersR2DB);
	pGUI->CreateText(string, ID_NUM_OCCLUDERS_RASTERIZED_TO_DB, ID_MAIN_PANEL, &mpOccludersR2DBText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of tris: \t\t%f"), mNumOccluderTris);
	pGUI->CreateText(string, ID_NUM_OCCLUDER_TRIS, ID_MAIN_PANEL, &mpOccluderTrisText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tDepth rasterized tris: \t%f"), mNumOccluderRasterizedTris);
	pGUI->CreateText(string, ID_NUM_OCCLUDER_RASTERIZED_TRIS, ID_MAIN_PANEL, &mpOccluderRasterizedTrisText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tDepth raterizer time: \t%f"), mRasterizeTime);
	pGUI->CreateText(string, ID_RASTERIZE_TIME, ID_MAIN_PANEL, &mpRasterizeTimeText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("Occluder Size Threshold: %0.4f"), mOccluderSizeThreshold);
	pGUI->CreateSlider(string, ID_OCCLUDER_SIZE, ID_MAIN_PANEL, &mpOccluderSizeSlider);
	mpOccluderSizeSlider->SetScale(0, 5.0, 51);
	mpOccluderSizeSlider->SetValue(mOccluderSizeThreshold);
	mpOccluderSizeSlider->SetTickDrawing(false);
    
	pGUI->CreateText(_L("Occludees                                              \t"), ID_OCCLUDEES, ID_MAIN_PANEL, &mpOccludeesText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of Models: \t%d"), mNumOccludees);
	pGUI->CreateText(string, ID_NUM_OCCLUDEES, ID_MAIN_PANEL, &mpNumOccludeesText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tModels culled: \t%d"), mNumCulled);
	pGUI->CreateText(string, ID_NUM_CULLED, ID_MAIN_PANEL, &mpCulledText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tModels visible: \t%d"), mNumVisible);
	pGUI->CreateText(string, ID_NUM_VISIBLE, ID_MAIN_PANEL, &mpVisibleText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of tris: \t%d"), (int)mNumOccludeeTris);
	pGUI->CreateText(string, ID_NUM_OCCLUDEE_TRIS, ID_MAIN_PANEL, &mpOccludeeTrisText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tCulled Triangles: \t%d"), (int)mNumOccludeeCulledTris);
	pGUI->CreateText(string, ID_NUM_OCCLUDEE_CULLED_TRIS, ID_MAIN_PANEL, &mpCulledTrisText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tVisible Triangles: \t%d"), (int)mNumOccludeeVisibleTris);
	pGUI->CreateText(string, ID_NUM_OCCLUDEE_VISIBLE_TRIS, ID_MAIN_PANEL, &mpVisibleTrisText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tVisible Triangles: \t%0.2f ms"), mDepthTestTime);
	pGUI->CreateText(string, ID_DEPTHTEST_TIME, ID_MAIN_PANEL, &mpDepthTestTimeText);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("Occludee Size Threshold: %0.4f"), mOccludeeSizeThreshold);
	pGUI->CreateSlider(string, ID_OCCLUDEE_SIZE, ID_MAIN_PANEL, &mpOccludeeSizeSlider);
	mpOccludeeSizeSlider->SetScale(0, 0.1f, 41);
	mpOccludeeSizeSlider->SetValue(mOccludeeSizeThreshold);
	mpOccludeeSizeSlider->SetTickDrawing(false);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("Total Cull time: %0.2f"), mTotalCullTime);
	pGUI->CreateText(string, ID_TOTAL_CULL_TIME, ID_MAIN_PANEL, &mpTotalCullTimeText);

	pGUI->CreateCheckbox(_L("Depth Test Culling"),  ID_ENABLE_CULLING, ID_MAIN_PANEL, &mpCullingCheckBox);
	pGUI->CreateCheckbox(_L("Frustum Culling"),  ID_ENABLE_FCULLING, ID_MAIN_PANEL, &mpFCullingCheckBox);
	pGUI->CreateCheckbox(_L("View Depth Buffer"),  ID_DEPTH_BUFFER_VISIBLE, ID_MAIN_PANEL, &mpDBCheckBox);
	pGUI->CreateCheckbox(_L("View Bounding Box"),  ID_BOUNDING_BOX_VISIBLE, ID_MAIN_PANEL, &mpBBCheckBox);
	pGUI->CreateCheckbox(_L("Multi Tasking"), ID_ENABLE_TASKS, ID_MAIN_PANEL, &mpTasksCheckBox);
	pGUI->CreateCheckbox(_L("Vsync"), ID_VSYNC_ON_OFF, ID_MAIN_PANEL, &mpVsyncCheckBox);
	pGUI->CreateCheckbox(_L("Pipeline"), ID_PIPELINE, ID_MAIN_PANEL, &mpPipelineCheckBox);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("Number of draw calls: \t%d"), mNumDrawCalls);
	pGUI->CreateText(string, ID_NUM_DRAW_CALLS, ID_MAIN_PANEL, &mpDrawCallsText),
	
	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("Depth Test Tasks: \t\t%d"), mNumDepthTestTasks);
    pGUI->CreateSlider(string, ID_DEPTH_TEST_TASKS, ID_MAIN_PANEL, &mpDepthTestTaskSlider);
	mpDepthTestTaskSlider->SetScale(1, (float)NUM_DT_TASKS, 11);
	mpDepthTestTaskSlider->SetValue((float)mNumDepthTestTasks);
	mpDepthTestTaskSlider->SetTickDrawing(false);
	mpAABB->SetDepthTestTasks(mNumDepthTestTasks);

    //
    // Create Static text
    //
    pGUI->CreateText( _L("F1 for Help"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
    pGUI->CreateText( _L("[Escape] to quit application"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
    pGUI->CreateText( _L("A,S,D,F - move camera position"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
    pGUI->CreateText( _L("Q - camera position up"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
    pGUI->CreateText( _L("E - camera position down"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
    pGUI->CreateText( _L("mouse + right click - camera look location"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);
	pGUI->CreateText( _L("size thresholds : computed using screen space metris"), ID_IGNORE_CONTROL_ID, ID_SECONDARY_PANEL);

    pGUI->SetActivePanel(ID_MAIN_PANEL);
    pGUI->DrawFPS(true);

    // Add our programatic (and global) material parameters
    CPUTMaterial::mGlobalProperties.AddValue( _L("cbPerFrameValues"), _L("$cbPerFrameValues") );
    CPUTMaterial::mGlobalProperties.AddValue( _L("cbPerModelValues"), _L("$cbPerModelValues") );
    CPUTMaterial::mGlobalProperties.AddValue( _L("_Shadow"), _L("$shadow_depth") );

	// Creating a render target to view the CPU rasterized depth buffer
	mpCPUDepthBuf[0] = new char[SCREENW*SCREENH*4];
	mpCPUDepthBuf[1] = new char[SCREENW*SCREENH*4];
	mpGPUDepthBuf    = new char[SCREENW*SCREENH*4];

	CD3D11_TEXTURE2D_DESC cpuRenderTargetDescSSE
	(
		DXGI_FORMAT_R8G8B8A8_UNORM,
        SCREENW * 2, // TODO: round up to full tile sizes
        SCREENH / 2,
        1, // Array Size
        1, // MIP Levels
		D3D11_BIND_SHADER_RESOURCE,
        D3D11_USAGE_DEFAULT,
		0
    );
	HRESULT hr;
	hr = mpD3dDevice->CreateTexture2D(&cpuRenderTargetDescSSE, NULL, &mpCPURenderTargetSSE[0]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating render target."));

	hr = mpD3dDevice->CreateTexture2D(&cpuRenderTargetDescSSE, NULL, &mpCPURenderTargetSSE[1]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating render target."));

	hr = mpD3dDevice->CreateShaderResourceView(mpCPURenderTargetSSE[0], NULL, &mpCPUSRVSSE[0]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating shader resource view."));

	hr = mpD3dDevice->CreateShaderResourceView(mpCPURenderTargetSSE[1], NULL, &mpCPUSRVSSE[1]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating shader resource view."));

	// Corresponding texture object
	CPUTTextureDX11 *pDummyTex0 = new CPUTTextureDX11;
	pDummyTex0->SetTextureAndShaderResourceView(mpCPURenderTargetSSE[0], mpCPUSRVSSE[0]);
	pAssetLibrary->AddTexture( _L("$depthbuf_tex_SSE"), pDummyTex0 );
	SAFE_RELEASE(pDummyTex0);

	CPUTTextureDX11 *pDummyTex1 = new CPUTTextureDX11;
	pDummyTex1->SetTextureAndShaderResourceView(mpCPURenderTargetSSE[1], mpCPUSRVSSE[1]);
	pAssetLibrary->AddTexture( _L("$depthbuf_tex_SSE"), pDummyTex1 );
	SAFE_RELEASE(pDummyTex1);

	CD3D11_TEXTURE2D_DESC cpuRenderTargetDescScalar
	(
		DXGI_FORMAT_R8G8B8A8_UNORM,
        SCREENW, // TODO: round up to full tile sizes
        SCREENH,
        1, // Array Size
        1, // MIP Levels
		D3D11_BIND_SHADER_RESOURCE,
        D3D11_USAGE_DEFAULT,
		0
    );
	hr = mpD3dDevice->CreateTexture2D(&cpuRenderTargetDescScalar, NULL, &mpCPURenderTargetScalar[0]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating render target."));

	hr = mpD3dDevice->CreateTexture2D(&cpuRenderTargetDescScalar, NULL, &mpCPURenderTargetScalar[1]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating render target."));

	hr = mpD3dDevice->CreateShaderResourceView(mpCPURenderTargetScalar[0], NULL, &mpCPUSRVScalar[0]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating shader resource view."));

	hr = mpD3dDevice->CreateShaderResourceView(mpCPURenderTargetScalar[1], NULL, &mpCPUSRVScalar[1]);
	ASSERT(SUCCEEDED(hr), _L("Failed creating shader resource view."));

	// Corresponding texture object
	CPUTTextureDX11 *pDummyTex2 = new CPUTTextureDX11;
	pDummyTex2->SetTextureAndShaderResourceView(mpCPURenderTargetScalar[0], mpCPUSRVScalar[0]);
	pAssetLibrary->AddTexture( _L("$depthbuf_tex_Scalar"), pDummyTex2 );
	SAFE_RELEASE(pDummyTex2);

	CPUTTextureDX11 *pDummyTex3 = new CPUTTextureDX11;
	pDummyTex3->SetTextureAndShaderResourceView(mpCPURenderTargetScalar[1], mpCPUSRVScalar[1]);
	pAssetLibrary->AddTexture( _L("$depthbuf_tex_Scalar"), pDummyTex3 );
	SAFE_RELEASE(pDummyTex3);

	// Create default shaders
    CPUTPixelShaderDX11  *pPS       = CPUTPixelShaderDX11::CreatePixelShaderFromMemory(            _L("$DefaultShader"), CPUT_DX11::mpD3dDevice,          _L("PSMain"), _L("ps_4_0"), gpDefaultShaderSource );
    CPUTPixelShaderDX11  *pPSNoTex  = CPUTPixelShaderDX11::CreatePixelShaderFromMemory(   _L("$DefaultShaderNoTexture"), CPUT_DX11::mpD3dDevice, _L("PSMainNoTexture"), _L("ps_4_0"), gpDefaultShaderSource );
    CPUTVertexShaderDX11 *pVS       = CPUTVertexShaderDX11::CreateVertexShaderFromMemory(          _L("$DefaultShader"), CPUT_DX11::mpD3dDevice,          _L("VSMain"), _L("vs_4_0"), gpDefaultShaderSource );
    CPUTVertexShaderDX11 *pVSNoTex  = CPUTVertexShaderDX11::CreateVertexShaderFromMemory( _L("$DefaultShaderNoTexture"), CPUT_DX11::mpD3dDevice, _L("VSMainNoTexture"), _L("vs_4_0"), gpDefaultShaderSource );

    // We just want to create them, which adds them to the library.  We don't need them any more so release them, leaving refCount at 1 (only library owns a ref)
    SAFE_RELEASE(pPS);
    SAFE_RELEASE(pPSNoTex);
    SAFE_RELEASE(pVS);
    SAFE_RELEASE(pVSNoTex);

    // load shadow casting material+sprite object
    cString ExecutableDirectory;
    CPUTOSServices::GetOSServices()->GetExecutableDirectory(&ExecutableDirectory);
    pAssetLibrary->SetMediaDirectoryName(  ExecutableDirectory+_L("..\\..\\Media\\"));

    mpShadowRenderTarget = new CPUTRenderTargetDepth();
    mpShadowRenderTarget->CreateRenderTarget( cString(_L("$shadow_depth")), SHADOW_WIDTH_HEIGHT, SHADOW_WIDTH_HEIGHT, DXGI_FORMAT_D32_FLOAT );

    mpDebugSprite = new CPUTSprite();
    mpDebugSprite->CreateSprite( -1.0f, -1.0f, 0.5f, 0.5f, _L("Sprite") );

	int width, height;
    CPUTOSServices::GetOSServices()->GetClientDimensions(&width, &height);

	// Depth buffer visualization material
	mpShowDepthBufMtrlScalar = (CPUTMaterialDX11*)CPUTAssetLibraryDX11::GetAssetLibrary()->GetMaterial( _L("showDepthBufScalar"));
	mpShowDepthBufMtrlSSE = (CPUTMaterialDX11*)CPUTAssetLibraryDX11::GetAssetLibrary()->GetMaterial( _L("showDepthBufSSE"));
		
	if(mSOCType == SCALAR_TYPE)
	{
		mpCPURenderTarget[0] = mpCPURenderTargetScalar[0];
		mpCPURenderTarget[1] = mpCPURenderTargetScalar[1];
		mpCPUSRV[0]          = mpCPUSRVScalar[0];
		mpCPUSRV[1]          = mpCPUSRVScalar[1];
		mpShowDepthBufMtrl   = mpShowDepthBufMtrlScalar;
		rowPitch			 = SCREENW * 4;
	}
	else
	{
		mpCPURenderTarget[0] = mpCPURenderTargetSSE[0];
		mpCPURenderTarget[1] = mpCPURenderTargetSSE[1];
		mpCPUSRV[0]          = mpCPUSRVSSE[0];
		mpCPUSRV[1]          = mpCPUSRVSSE[1];
		mpShowDepthBufMtrl = mpShowDepthBufMtrlSSE;
		rowPitch			 = 2 * SCREENW * 4;
	}

    // Call ResizeWindow() because it creates some resources that our blur material needs (e.g., the back buffer)
    ResizeWindow(width, height);

    CPUTRenderStateBlockDX11 *pBlock = new CPUTRenderStateBlockDX11();
    CPUTRenderStateDX11 *pStates = pBlock->GetState();

    // Override default sampler desc for our default shadowing sampler
    pStates->SamplerDesc[1].Filter         = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
    pStates->SamplerDesc[1].AddressU       = D3D11_TEXTURE_ADDRESS_BORDER;
    pStates->SamplerDesc[1].AddressV       = D3D11_TEXTURE_ADDRESS_BORDER;
    pStates->SamplerDesc[1].ComparisonFunc = D3D11_COMPARISON_GREATER;
    pBlock->CreateNativeResources();
    CPUTAssetLibrary::GetAssetLibrary()->AddRenderStateBlock( _L("$DefaultRenderStates"), pBlock );
    pBlock->Release(); // We're done with it.  The library owns it now.

    //
    // Load .set files to load the castle scene
	//
    pAssetLibrary->SetMediaDirectoryName(_L("..\\..\\Media\\Castle\\"));

#ifdef DEBUG
    mpAssetSetDBR[0] = pAssetLibrary->GetAssetSet(_L("castleLargeOccluders"));
	ASSERT(mpAssetSetDBR[0], _L("Failed loading castle."));

	mpAssetSetDBR[1] = pAssetLibrary->GetAssetSet(_L("groundDebug"));
	ASSERT(mpAssetSetDBR[1], _L("Failed loading ground."));

	mpAssetSetAABB[0] = pAssetLibrary->GetAssetSet(_L("marketStallsDebug"));
	ASSERT(mpAssetSetAABB, _L("Failed loading marketStalls"));

	mpAssetSetAABB[1] = pAssetLibrary->GetAssetSet(_L("castleSmallDecorationsDebug"));
	ASSERT(mpAssetSetAABB, _L("Failed loading castleSmallDecorations"));
#else
    mpAssetSetDBR[0] = pAssetLibrary->GetAssetSet(_L("castleLargeOccluders"));
	ASSERT(mpAssetSetDBR[0], _L("Failed loading castle."));

	mpAssetSetDBR[1] = pAssetLibrary->GetAssetSet(_L("ground"));
	ASSERT(mpAssetSetDBR[1], _L("Failed loading ground."));

	mpAssetSetAABB[0] = pAssetLibrary->GetAssetSet(_L("marketStalls"));
	ASSERT(mpAssetSetAABB, _L("Failed loading marketStalls"));

	mpAssetSetAABB[1] = pAssetLibrary->GetAssetSet(_L("castleSmallDecorations"));
	ASSERT(mpAssetSetAABB, _L("Failed loading castleSmallDecorations"));
#endif

	mpAssetSetSky = pAssetLibrary->GetAssetSet(_L("sky"));
	ASSERT(mpAssetSetSky, _L("Failed loading sky"));

	// For every occluder model in the sene create a place holder 
	// for the CPU transformed vertices of the model.   
	mpDBR->CreateTransformedModels(mpAssetSetDBR, OCCLUDER_SETS);
	// Get number of occluders in the scene
	mNumOccluders = mpDBR->GetNumOccluders();
	// Get number of occluder triangles in the scene 
	mNumOccluderTris = mpDBR->GetNumTriangles();


	// For every occludee model in the scene create a place holder
	// for the triangles that make up the model axis aligned bounding box
	mpAssetSetAABB[2] = mpAssetSetDBR[0];
	mpAssetSetAABB[3] = mpAssetSetDBR[1];

	mpAABB->CreateTransformedAABBoxes(mpAssetSetAABB, OCCLUDEE_SETS);
	// Get number of occludees in the scene
	mNumOccludees = mpAABB->GetNumOccludees();
	// Get number of occluddee triangles in the scene
	mNumOccludeeTris = mpAABB->GetNumTriangles();
	
	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of Models: \t%d"), mNumOccluders);
	mpNumOccludersText->SetText(string);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of tris: \t\t%d"), mNumOccluderTris);
	mpOccluderTrisText->SetText(string);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of Model: \t%d"), mNumOccludees);
	mpNumOccludeesText->SetText(string);

	swprintf_s(&string[0], CPUT_MAX_STRING_LENGTH, _L("\tNumber of tris: \t\t%d"), mNumOccludeeTris);
	mpOccludeeTrisText->SetText(string);

	CPUTCheckboxState state;
	if(mEnableCulling)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else 
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpCullingCheckBox->SetCheckboxState(state);

	if(mEnableFCulling)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else 
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpFCullingCheckBox->SetCheckboxState(state);
	mpDBR->SetEnableFCulling(mEnableFCulling);
	mpAABB->SetEnableFCulling(mEnableFCulling);

	if(mViewDepthBuffer)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else 
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpDBCheckBox->SetCheckboxState(state);

	if(mEnableTasks)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else 
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpTasksCheckBox->SetCheckboxState(state);

	if(mSyncInterval)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpVsyncCheckBox->SetCheckboxState(state);

	if(mPipeline)
	{
		state = CPUT_CHECKBOX_CHECKED;
	}
	else
	{
		state = CPUT_CHECKBOX_UNCHECKED;
	}
	mpPipelineCheckBox->SetCheckboxState(state);

	// Setting occluder size threshold in DepthBufferRasterizer
	mpDBR->SetOccluderSizeThreshold(mOccluderSizeThreshold);
	// Setting occludee size threshold in AABBoxRasterizer
	mpAABB->SetOccludeeSizeThreshold(mOccludeeSizeThreshold);
	
	//
	// If no cameras were created from the model sets then create a default simple camera
	// and add it to the camera array.
	//
    if( mpAssetSetDBR[0] && mpAssetSetDBR[0]->GetCameraCount() )
    {
        mpCamera = mpAssetSetDBR[0]->GetFirstCamera();
        mpCamera->AddRef(); 
    } else
    {
        mpCamera = new CPUTCamera();
        CPUTAssetLibraryDX11::GetAssetLibrary()->AddCamera( _L("SampleStart Camera"), mpCamera );

        mpCamera->SetPosition( 0.0f, 0.0f, 5.0f );
        // Set the projection matrix for all of the cameras to match our window.
        // TODO: this should really be a viewport matrix.  Otherwise, all cameras will have the same FOV and aspect ratio, etc instead of just viewport dimensions.
        mpCamera->SetAspectRatio(((float)width)/((float)height));
    }
    mpCamera->SetFov(XMConvertToRadians(60.0f)); // TODO: Fix converter's FOV bug (Maya generates cameras for which fbx reports garbage for fov)
    mpCamera->SetFarPlaneDistance(gFarClipDistance);
	mpCamera->SetPosition(27.0f, 2.0f, 47.0f);
	mpCamera->LookAt(41.0f, 8.0f, -50.0f);
    mpCamera->Update();

    // Set up the shadow camera (a camera that sees what the light sees)
    float3 lookAtPoint(0.0f, 0.0f, 0.0f);
    float3 half(1.0f, 1.0f, 1.0f);
    if( mpAssetSetDBR[0] )
    {
        mpAssetSetDBR[0]->GetBoundingBox( &lookAtPoint, &half );
    }
    float length = half.length();

    mpShadowCamera = new CPUTCamera();
    mpShadowCamera->SetFov(XMConvertToRadians(45));
    mpShadowCamera->SetAspectRatio(1.0f);
    float fov = mpShadowCamera->GetFov();
    float tanHalfFov = tanf(fov * 0.5f);
    float cameraDistance = length/tanHalfFov;
    float nearDistance = cameraDistance * 0.1f;
    mpShadowCamera->SetNearPlaneDistance(nearDistance);
    mpShadowCamera->SetFarPlaneDistance(2.0f * cameraDistance);
    CPUTAssetLibraryDX11::GetAssetLibrary()->AddCamera( _L("ShadowCamera"), mpShadowCamera );
    float3 shadowCameraPosition = lookAtPoint - gLightDir * cameraDistance;
    mpShadowCamera->SetPosition( shadowCameraPosition );
    mpShadowCamera->LookAt( lookAtPoint.x, lookAtPoint.y, lookAtPoint.z );
    mpShadowCamera->Update();

    mpCameraController = new CPUTCameraControllerFPS();
    mpCameraController->SetCamera(mpCamera);
    mpCameraController->SetLookSpeed(0.004f);
    mpCameraController->SetMoveSpeed(2.5f);

	gLightDir = float3(-40.48f, -142.493f, -3.348f);
	gLightDir = gLightDir.normalize();

	QueryPerformanceFrequency(&glFrequency); 
}
Пример #15
0
//-----------------------------------------------------------------------------
CPUTResult CPUTMaterial::LoadMaterial(
    const cString   &fileName,
    const CPUTModel *pModel,
    int        meshIndex,
    const char     **pShaderMacros,
    int        systemMaterialCount,
    cString   *pSystemMaterialNames,
    int        externalCount,
    cString   *pExternalName,
    float4    *pExternals,
    int       *pExternalOffset,
    int       *pExternalSize
    ){
        CPUTResult result = CPUT_SUCCESS;

        mMaterialName = fileName;
        mMaterialNameHash = CPUTComputeHash( mMaterialName );

        // Open/parse the file
        CPUTConfigFile file;
        result = file.LoadFile(fileName);
        if(CPUTFAILED(result))
        {
            return result;
        }

        // Make a local copy of all the parameters
        CPUTConfigBlock *pBlock = file.GetBlock(0);
        ASSERT( pBlock, _L("Error getting parameter block") );
        if( !pBlock )
        {
            return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND;
        }
        mConfigBlock = *pBlock;

        CPUTAssetLibrary *pAssetLibrary = (CPUTAssetLibrary*)CPUTAssetLibrary::GetAssetLibrary();


        mMaterialEffectCount = 0;
        if( mConfigBlock.GetValueByName( _L("MultiMaterial") )->ValueAsBool() )
        {
            // Count materials;
            for(;;)
            {
                CPUTConfigEntry *pValue = mConfigBlock.GetValueByName( _L("Material") + itoc(mMaterialEffectCount) );
                if( pValue->IsValid() )
                {
                    ++mMaterialEffectCount;
                } else
                {
                    break;
                }
            }
            ASSERT(mMaterialEffectCount != 0, _L("MultiMaterial specified, but no sub materials given.") );

            // Reserve space for "authored" materials plus system materials
            mpMaterialEffectNames = new cString[mMaterialEffectCount+systemMaterialCount];
            int ii;
            for( ii=0; ii<mMaterialEffectCount; ii++ )
            {
                CPUTConfigEntry *pValue = mConfigBlock.GetValueByName( _L("Material") + itoc(ii) );
                mpMaterialEffectNames[ii] = pAssetLibrary->GetMaterialEffectPath(pValue->ValueAsString(), false);
            }
        }
        else
        {
            mMaterialEffectCount = 1;
            mpMaterialEffectNames = new cString[mMaterialEffectCount+systemMaterialCount];
            mpMaterialEffectNames[0] = fileName;
        }


        CPUT_SHADER_MACRO *pFinalShaderMacros = (CPUT_SHADER_MACRO*)pShaderMacros;
        CPUT_SHADER_MACRO *pUserSpecifiedMacros = NULL;

        // The real material count includes the system material count
        mMaterialEffectCount += systemMaterialCount;
        for( int ii=0; ii<systemMaterialCount; ii++ )
        {
            // Read additional macros from .mtl file
            cString macroBlockName = _L("defines") + itoc(ii);
            CPUTConfigBlock *pMacrosBlock = file.GetBlockByName(macroBlockName);
            int numUserSpecifiedMacros = 0;
            if( pMacrosBlock )
            {
                ReadMacrosFromConfigBlock( pMacrosBlock, (CPUT_SHADER_MACRO*)pShaderMacros, &pUserSpecifiedMacros, &numUserSpecifiedMacros, &pFinalShaderMacros );
            } 

            // System materials "grow" from the end; the 1st system material is at the end of the list.
            mpMaterialEffectNames[mMaterialEffectCount-systemMaterialCount+ii] = pSystemMaterialNames[ii];

            for( int kk=0; kk<numUserSpecifiedMacros; kk++ )
            {
                // ReadMacrosFromConfigBlock allocates memory (ws2s does).  Delete it here.
                SAFE_DELETE(pUserSpecifiedMacros[kk].Name);
                SAFE_DELETE(pUserSpecifiedMacros[kk].Definition);
            }
            SAFE_DELETE_ARRAY( pFinalShaderMacros );
            SAFE_DELETE_ARRAY( pUserSpecifiedMacros );
        }
        mpMaterialEffects = new CPUTMaterialEffect*[mMaterialEffectCount+1];
        for( int ii=0; ii<mMaterialEffectCount; ii++ )
        {
            mpMaterialEffects[ii] = pAssetLibrary->GetMaterialEffect( mpMaterialEffectNames[ii], true, pModel, meshIndex,(const char**)pFinalShaderMacros );
        }
        mpMaterialEffects[mMaterialEffectCount] = NULL;

        return result; // This material is a multi-material, so we're done.
}