// sets the resource directory to use when loading GUI resources
//-----------------------------------------------------------------------------
CPUTResult CPUTGuiController::SetResourceDirectory(const cString ResourceDirectory)
{
    // check to see if the specified directory is valid
    CPUTResult result = CPUT_SUCCESS;

    // resolve the directory to a full path
    cString FullPath;
    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();
    result = pServices->ResolveAbsolutePathAndFilename(ResourceDirectory, &FullPath);
    if(CPUTFAILED(result))
    {
        return result;
    }

    // check existence of directory
    result = pServices->DoesDirectoryExist(FullPath);
    if(CPUTFAILED(result))
    {
        return result;
    }

    // set the resource directory (absolute path)
    mResourceDirectory = FullPath;

    return result;
}
Exemplo n.º 2
0
// Set where CPUT will look for it's button images, fonts, etc
//-----------------------------------------------------------------------------
CPUTResult CPUT_DX11::SetCPUTResourceDirectory(const cString ResourceDirectory)
{
    // check to see if the specified directory is valid
    CPUTResult result = CPUT_SUCCESS;

    // resolve the directory to a full path
    cString fullPath;
    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();
    result = pServices->ResolveAbsolutePathAndFilename(ResourceDirectory, &fullPath);
    if(CPUTFAILED(result))
    {
        return result;
    }

    // check existence of directory
    result = pServices->DoesDirectoryExist(fullPath);
    if(CPUTFAILED(result))
    {
        return result;
    }

    // set the resource directory (absolute path)
    mResourceDirectory = fullPath;

    // tell the gui system where to look for it's resources
    // todo: do we want to force a flush/reload of all resources (i.e. change control graphics)
    result = CPUTGuiControllerDX11::GetController()->SetResourceDirectory(ResourceDirectory);

    return result;
}
Exemplo n.º 3
0
CPUTResult CPUTMeshDX11::ExtractVerticesandIndices()
{
	CPUTResult result = CPUT_SUCCESS;
	int vertexSizeInBytes;  
	
	result = GetByteSizeFromFormat((mpLayoutDescription + mNumberOfInputLayoutElements -1)->Format, vertexSizeInBytes);
	if(CPUTFAILED(result))
	{
		return result;
	}
	vertexSizeInBytes += (mpLayoutDescription + mNumberOfInputLayoutElements -1)->AlignedByteOffset;
	
	mpRawVertices = (Vertex*)_aligned_malloc(sizeof(__m128) * mVertexCount, 32);//new Vertex[m_VertexCount];
	char* vertexData = (char*)mpVertexData;
	for(unsigned int i = 0; i < mVertexCount; i++)
	{
		mpRawVertices[i].position.m128_f32[0] = *((float*)vertexData + 0);
		mpRawVertices[i].position.m128_f32[1] = *((float*)vertexData + 1);
		mpRawVertices[i].position.m128_f32[2] = *((float*)vertexData + 2);
		mpRawVertices[i].position.m128_f32[3] = 1.0f;

		vertexData = vertexData + vertexSizeInBytes;
	}

	mpRawIndices = new unsigned int[mIndexCount];
	char* indexData = (char*)mpIndexData;
	for(unsigned int i = 0; i < mIndexCount; i++, indexData += mIndexElementByteSize)
	{
		mpRawIndices[i] = *((unsigned int*)indexData);
	}
	return result;	
}
Exemplo n.º 4
0
//----------------------------------------------------------------
CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename)
{
    // Load the file
    cString             szCurrLine;
    CPUTConfigBlock    *pCurrBlock = NULL;
    FILE               *pFile = NULL;
    int                 nCurrBlock = 0;
    CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile);
    if(CPUTFAILED(result))
    {
        return result;
    }

	_locale_t locale = _get_current_locale();

	/* Determine file size */
	fseek(pFile, 0, SEEK_END);
	int nBytes = ftell(pFile); // for text files, this is an overestimate
	fseek(pFile, 0, SEEK_SET);

	/* Read the whole thing */
	char *pFileContents = new char[nBytes + 1];
	nBytes = (int)fread(pFileContents, 1, nBytes, pFile);
	fclose(pFile);

	pFileContents[nBytes] = 0; // add 0-terminator

	/* Count the number of blocks */
	const char *pCur = pFileContents;
	const char *pStart, *pEnd;

	while(ReadLine(&pStart, &pEnd, &pCur))
	{
		const char *pOpen = FindFirst(pStart, pEnd, '[');
		const char *pClose = FindLast(pOpen + 1, pEnd, ']');
		if (pOpen < pClose)
		{
			// This line is a valid block header
			mnBlockCount++;
		}
	}

    // For files that don't have any blocks, just add the entire file to one block
    if(mnBlockCount == 0)
    {
        mnBlockCount   = 1;
    }

	pCur = pFileContents;
    mpBlocks = new CPUTConfigBlock[mnBlockCount];
    pCurrBlock = mpBlocks;

	/* Find the first block first */
	while(ReadLine(&pStart, &pEnd, &pCur))
	{
		const char *pOpen = FindFirst(pStart, pEnd, '[');
		const char *pClose = FindLast(pOpen + 1, pEnd, ']');
		if (pOpen < pClose)
		{
			// This line is a valid block header
            pCurrBlock = mpBlocks + nCurrBlock++;
			AssignStr(pCurrBlock->mszName, pOpen + 1, pClose, locale);
            std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower);
		}
		else if (pStart < pEnd)
		{
			// It's a value
			if (pCurrBlock == NULL)
            {
				continue;
            }

			const char *pEquals = FindFirst(pStart, pEnd, '=');
			if (pEquals == pEnd)
			{
                // No value, just a key, save it anyway
				// Optimistically, we assume it's new
				cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;
				AssignStr(name, pStart, pEnd, locale);

                bool dup = false;
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(name))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
                    pCurrBlock->mnValueCount++;
                }
			}
			else
			{
				const char *pNameStart = pStart;
				const char *pNameEnd = pEquals;
				const char *pValStart = pEquals + 1;
				const char *pValEnd = pEnd;

				RemoveWhitespace(pNameStart, pNameEnd);
				RemoveWhitespace(pValStart, pValEnd);

				// Optimistically assume the name is new
				cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;
				AssignStr(name, pNameStart, pNameEnd, locale);
				std::transform(name.begin(), name.end(), name.begin(), ::tolower);

                bool dup = false;
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(name))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
                    AssignStr(pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue, pValStart, pValEnd, locale);
                    pCurrBlock->mnValueCount++;
                }
			}
		}
	}

	delete[] pFileContents;
    return CPUT_SUCCESS;
}
Exemplo n.º 5
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();
}
//-----------------------------------------------------------------------------
CPUTResult CPUTModel::LoadModelPayload(const cString &FileName)
{
    CPUTResult result = CPUT_SUCCESS;

    CPUTFileSystem::CPUTOSifstream file(FileName, std::ios::in | std::ios::binary);

    ASSERT( !file.fail(), _L("CPUTModel::LoadModelPayload() - Could not find binary model file: ") + FileName );

    // set up for mesh creation loop
    UINT meshIndex = 0;
    while(file.good() && !file.eof())
    {
        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two
        CPUTRawMeshData vertexFormatDesc;
        vertexFormatDesc.Read(file);
        if(file.eof())
        {
            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?
            break;
        }
        ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count"));

        // create the mesh.
        CPUTMesh *pMesh = mpMesh[meshIndex];

        // always a triangle list (at this point)
        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);

        // get number of data blocks in the vertex element (pos,norm,uv,etc)
        CPUTBufferElementInfo *pVertexElementInfo = new CPUTBufferElementInfo[vertexFormatDesc.mFormatDescriptorCount];

        // running count of each type of  element
        int positionStreamCount=0;
        int normalStreamCount=0;
        int texCoordStreamCount=0;
        int tangentStreamCount=0;
        int binormalStreamCount=0;
        int colorStreamCount=0;
		int blendWeightStreamCount = 0;
		int blendIndexStreamCount = 0;

        int runningOffset = 0;
        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)
        {
            // lookup the CPUT data type equivalent
            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT(vertexFormatDesc.mpElements[ii].mVertexElementType);
            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error.  This model file has an unknown data type in it's model data."));
            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)
            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];
            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)
            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;
            // store the number of elements (i.e. 3xF32, 3 elements)
            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here
            pVertexElementInfo[ii].mOffset = runningOffset;
            runningOffset = runningOffset + pVertexElementInfo[ii].mElementSizeInBytes;

            // extract the name of stream
            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];

            //TODO: Calculate Opengl semantic index elsewhere
            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)
            {
			//FIXME - this isn't right, and needs to change for DX and OpenGL
			//Probably just need to move semantic bind point into OpenGL, or something.
            //Currently, TEXCOORD is the only semantic with multiples in common use. Adding
            //semantic index works provided addtional attributes (e.g. vertex color) are not
            //present
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_POSITON:
                pVertexElementInfo[ii].mpSemanticName = "POSITION";
                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::POSITION;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_NORMAL:
                pVertexElementInfo[ii].mpSemanticName = "NORMAL";
                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::NORMAL;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TEXTURECOORD:
                pVertexElementInfo[ii].mpSemanticName = "TEXCOORD";
				pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;
                pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TEXCOORD + pVertexElementInfo[ii].mSemanticIndex;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TANGENT:
                pVertexElementInfo[ii].mpSemanticName = "TANGENT";
                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TANGENT;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_BINORMAL:
                pVertexElementInfo[ii].mpSemanticName = "BINORMAL";
                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::BINORMAL;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_VERTEXCOLOR:
                pVertexElementInfo[ii].mpSemanticName = "COLOR";
                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::COLOR;
                break;
            default:
                cString errorString = _L("Invalid vertex semantic in: '")+FileName+_L("'\n");
                TRACE(errorString.c_str());
                ASSERT(0, errorString);
            }
        }

        // Index buffer
        CPUTBufferElementInfo indexDataInfo;
        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? CPUT_U32 : CPUT_U16;
        indexDataInfo.mElementComponentCount = 1;
        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? sizeof(uint32_t) : sizeof(uint16_t);
        indexDataInfo.mOffset                = 0;
        indexDataInfo.mSemanticIndex         = 0;
        indexDataInfo.mpSemanticName         = NULL;

        if( vertexFormatDesc.mVertexCount && vertexFormatDesc.mIndexCount )
        {
            result = pMesh->CreateNativeResources(
                this,
                meshIndex,
                vertexFormatDesc.mFormatDescriptorCount,
                pVertexElementInfo,
                vertexFormatDesc.mVertexCount,
                (void*)vertexFormatDesc.mpVertices,
                &indexDataInfo,
                vertexFormatDesc.mIndexCount,
                vertexFormatDesc.mpIndices
            );
            if(CPUTFAILED(result))
            {
                return result;
            }
        }
        delete [] pVertexElementInfo;
        pVertexElementInfo = NULL;
        ++meshIndex;
    }
    ASSERT( file.eof(), _L("") );

    // close file
    file.close();
    
    return result;
}
//----------------------------------------------------------------
CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename)
{
    // Load the file
    cString             szCurrLine;
    CPUTConfigBlock    *pCurrBlock = NULL;
    FILE               *pFile = NULL;
    int                 nCurrBlock = 0;
    CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile);
    if(CPUTFAILED(result))
    {
        return result;
    }

    /* count the number of blocks */
    while(1)
    {
        /* Find the block */
        // Read lines until a '[' is found
        CPUTResult readResult = ReadLine(szCurrLine, pFile);
        if(readResult != CPUT_SUCCESS)
            break;

        size_t nOpenBracketIndex    = szCurrLine.find_first_of(_L('['));
        size_t nCloseBracketIndex   = szCurrLine.find_last_of(_L(']'));
        if(nOpenBracketIndex != cString::npos && nCloseBracketIndex != cString::npos)
        {   // This line is a valid block header
            mnBlockCount++;
        }
    };
    /* Mtl files don't have headers, so we have
    to do some magic to support them */
    if(mnBlockCount == 0)
    {
        mnBlockCount   = 1;
    }

    fseek(pFile, 0, SEEK_SET);
    mpBlocks = new CPUTConfigBlock[mnBlockCount];
    pCurrBlock = mpBlocks;

    /* Find the first block first */
    while(1)
    {
        /* Find the block */
        // Read lines until a '[' is found
        CPUTResult readResult = ReadLine(szCurrLine, pFile);
        if(readResult != CPUT_SUCCESS && szCurrLine == _L(""))
        {
            fclose(pFile);
            return CPUT_SUCCESS;
        }

        size_t nOpenBracketIndex    = szCurrLine.find_first_of(_L('['));
        size_t nCloseBracketIndex   = szCurrLine.find_last_of(_L(']'));
        if(nOpenBracketIndex != cString::npos && nCloseBracketIndex != cString::npos)
        {   // This line is a valid block header
            pCurrBlock = mpBlocks + nCurrBlock++;
            szCurrLine.erase(nCloseBracketIndex,1);
            pCurrBlock->mszName = szCurrLine.c_str()+1;
            /*
            size_t nSpaceIndex = szCurrLine.find_first_of(_L(' '));
            cString szValue = szCurrLine.substr(nSpaceIndex+1); 
            cString szName = szCurrLine.erase(nSpaceIndex, 1024); 
            RemoveWhitespace(szValue);
            RemoveWhitespace(szName);
            pCurrBlock->mName.szName = szName;
            pCurrBlock->mName.szValue = szValue;
            */
            std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower);
        }
        else if(szCurrLine != _L(""))
        {   // It's a value
            if(pCurrBlock == NULL)
            {
                continue;
            }

            size_t  nEqualsIndex = szCurrLine.find_first_of(_L('='));
            if(nEqualsIndex == cString::npos)
            {
                bool dup = false;
                // No value, just a key, save it anyway
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(szCurrLine))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
                    pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName = szCurrLine;
                    pCurrBlock->mnValueCount++;
                }
            }
            else
            {
                cString szValue = szCurrLine.substr(nEqualsIndex+1);
                cString szName = szCurrLine.erase(nEqualsIndex, 1024);
                RemoveWhitespace(szValue);
                RemoveWhitespace(szName);
                std::transform(szName.begin(), szName.end(), szName.begin(), ::tolower);

                bool dup = false;
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(szName))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
                    pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue = szValue;
                    pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName = szName;
                    pCurrBlock->mnValueCount++;
                }
            }
        }
    };

    fclose(pFile);
    return CPUT_SUCCESS;
}
//-----------------------------------------------------------------------------
CPUTResult CPUTMaterialDX11::LoadMaterial(const cString &fileName, const CPUTModel *pModel, int meshIndex)
{
    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
    mConfigBlock = *file.GetBlock(0);

    // get necessary device and AssetLibrary pointers
    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    // TODO:  The following code is very repetitive.  Consider generalizing so we can call a function instead.
    // see if there are any pixel/vertex/geo shaders to load
    CPUTConfigEntry *pValue, *pEntryPointName, *pProfileName;
    pValue   = mConfigBlock.GetValueByName(_L("VertexShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("VertexShaderMain"));
        pProfileName    = mConfigBlock.GetValueByName(_L("VertexShaderProfile"));
        pAssetLibrary->GetVertexShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpVertexShader );
        ReadShaderSamplersAndTextures( mpVertexShader->GetBlob(), &mVertexShaderParameters );
    }

    // load and store the pixel shader if it was specified
    pValue  = mConfigBlock.GetValueByName(_L("PixelShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("PixelShaderMain"));
        pProfileName    = mConfigBlock.GetValueByName(_L("PixelShaderProfile"));
        pAssetLibrary->GetPixelShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpPixelShader);
        ReadShaderSamplersAndTextures( mpPixelShader->GetBlob(), &mPixelShaderParameters );
    }

    // load and store the compute shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("ComputeShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("ComputeShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("ComputeShaderProfile"));
        pAssetLibrary->GetComputeShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpComputeShader);
        ReadShaderSamplersAndTextures( mpComputeShader->GetBlob(), &mComputeShaderParameters );
    }

    // load and store the geometry shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("GeometryShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("GeometryShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("GeometryShaderProfile"));
        pAssetLibrary->GetGeometryShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpGeometryShader);
        ReadShaderSamplersAndTextures( mpGeometryShader->GetBlob(), &mGeometryShaderParameters );
    }

    // load and store the hull shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("HullShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("HullShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("HullShaderProfile"));
        pAssetLibrary->GetHullShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpHullShader);
        ReadShaderSamplersAndTextures( mpHullShader->GetBlob(), &mHullShaderParameters );
    }

    // load and store the domain shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("DomainShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("DomainShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("DomainShaderProfile"));
        pAssetLibrary->GetDomainShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpDomainShader);
        ReadShaderSamplersAndTextures( mpDomainShader->GetBlob(), &mDomainShaderParameters );
    }

    // load and store the render state file if it was specified
    pValue = mConfigBlock.GetValueByName(_L("RenderStateFile"));
    if( pValue->IsValid() )
    {
        mpRenderStateBlock = pAssetLibrary->GetRenderStateBlock(pValue->ValueAsString());
    }

    // For each of the shader stages, bind shaders and buffers
    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage
    {
        BindTextures(        **pCur, pModel, meshIndex );
        BindBuffers(         **pCur, pModel, meshIndex );
        BindUAVs(            **pCur, pModel, meshIndex );
        BindConstantBuffers( **pCur, pModel, meshIndex );
    }

    return result;
}
    // Register all shared resources
    //--------------------------------------------------------------------------------
    CPUTResult CPUTButton::RegisterStaticResources(GLuint m_shaderID, GLuint modelViewMatrixID)
    {
        CPUTResult result;

        if(m_Registered)
            return CPUT_SUCCESS;

        // store shader ID and needed matrix ID's
        m_shaderProgram = m_shaderID;
        m_ModelViewMatrixID = glGetUniformLocation(m_shaderProgram, "ModelViewMatrix");

        m_textureUniformLocation = glGetUniformLocation(m_shaderProgram, "diffuseTexture");


        glUseProgram(m_shaderProgram);

        // load all the idle+active button images
        const int numberOfImages = CPUT_NUM_IMAGES_IN_BUTTON;
        cString pImageFilenames[numberOfImages] = 
        {        
            _L(".//controls//button//button-lt.png"),
            _L(".//controls//button//button-lm.png"),
            _L(".//controls//button//button-lb.png"),

            _L(".//controls//button//button-mt.png"),
            _L(".//controls//button//button-mm.png"),
            _L(".//controls//button//button-mb.png"),

            _L(".//controls//button//button-rt.png"),
            _L(".//controls//button//button-rm.png"),
            _L(".//controls//button//button-rb.png"),
        };

        // load each of the 9 quadrants of a button
        CPUTOSServices* pServices = CPUTOSServices::GetOSServices();

        // load each of the 9 quadrants of a button
        CPUTTextureLoader* pTextureLoader = CPUTTextureLoader::GetTextureLoader();
        for(int i=0; i<numberOfImages; i++)
        {
            result = pTextureLoader->LoadAndRegisterTexture(pImageFilenames[i], m_pButtonIdleTextureList[i], (GLuint&)m_pButtonIdleImageSizeList[i].width, (GLuint&)m_pButtonIdleImageSizeList[i].height, true, CPUT_PATH_SEARCH_RESOURCE_DIRECTORY);
            if(CPUTFAILED(result))
            {
                return result;
            }

            // calculate the 'border' sizes
            if(i<3)
            {
                if(m_SmallestLeftSizeIdle < m_pButtonIdleImageSizeList[i].width)
                {
                    m_SmallestLeftSizeIdle = m_pButtonIdleImageSizeList[i].width;
                }
            }

            if(i>5)
            {
                if(m_SmallestRightSizeIdle < m_pButtonIdleImageSizeList[i].width)
                {
                    m_SmallestRightSizeIdle = m_pButtonIdleImageSizeList[i].width;
                }
            }

            if( (0==i) || (3==i) || (6==i) )
            {
                if(m_SmallestTopSizeIdle < m_pButtonIdleImageSizeList[i].height)
                {
                    m_SmallestTopSizeIdle = m_pButtonIdleImageSizeList[i].height;
                }
            }
            if( (2==i) || (5==i) || (8==i) )
            {
                if(m_SmallestBottomSizeIdle < m_pButtonIdleImageSizeList[i].height)
                {
                    m_SmallestBottomSizeIdle = m_pButtonIdleImageSizeList[i].height;
                }
            }
        }


        // Load the 'pressed' button state images
        cString pPressedImageFilenames[numberOfImages] = 
        {
            _L(".//controls//button//button-pressed-lt.png"),
            _L(".//controls//button//button-pressed-lm.png"),
            _L(".//controls//button//button-pressed-lb.png"),

            _L(".//controls//button//button-pressed-mt.png"),
            _L(".//controls//button//button-pressed-mm.png"),
            _L(".//controls//button//button-pressed-mb.png"),

            _L(".//controls//button//button-pressed-rt.png"),
            _L(".//controls//button//button-pressed-rm.png"),
            _L(".//controls//button//button-pressed-rb.png"),
        };

        // load each of the 9 quadrants of button
        for(int i=0; i<numberOfImages; i++)
        {
            result = pTextureLoader->LoadAndRegisterTexture(pPressedImageFilenames[i], m_pButtonPressedTextureList[i], (GLuint&)m_pButtonPressedImageSizeList[i].width, (GLuint&)m_pButtonPressedImageSizeList[i].height, true, CPUT_PATH_SEARCH_RESOURCE_DIRECTORY);
            if(CPUTFAILED(result))
            {
                return result;
            }

            // calculate the 'border' sizes
            if(i<3)
            {
                if(m_SmallestLeftSizePressed < m_pButtonPressedImageSizeList[i].width)
                {
                    m_SmallestLeftSizePressed = m_pButtonPressedImageSizeList[i].width;
                }
            }

            if(i>5)
            {
                if(m_SmallestRightSizePressed < m_pButtonPressedImageSizeList[i].width)
                {
                    m_SmallestRightSizePressed = m_pButtonPressedImageSizeList[i].width;
                }
            }

            if( (0==i) || (3==i) || (6==i) )
            {
                if(m_SmallestTopSizePressed < m_pButtonPressedImageSizeList[i].height)
                {
                    m_SmallestTopSizePressed = m_pButtonPressedImageSizeList[i].height;
                }
            }
            if( (2==i) || (5==i) || (8==i) )
            {
                if(m_SmallestBottomSizePressed < m_pButtonPressedImageSizeList[i].height)
                {
                    m_SmallestBottomSizePressed = m_pButtonPressedImageSizeList[i].height;
                }
            }
        }

        m_Registered = true;

        return CPUT_SUCCESS;
    }
// Load and register all the resources needed by the GUI system
//-----------------------------------------------------------------------------
CPUTResult CPUTGuiControllerDX11::RegisterGUIResources(ID3D11DeviceContext *pImmediateContext, cString VertexShaderFilename, cString PixelShaderFilename, cString RenderStateFile, cString DefaultFontFilename, cString ControlAtlasTexture)
{
    if(NULL==pImmediateContext)
    {
        return CPUT_ERROR_INVALID_PARAMETER;
    }
    CPUTResult result;
    HRESULT hr;
    ID3D11Device *pD3dDevice = NULL;
    CPUTOSServices *pServices = NULL;
    CPUTAssetLibraryDX11 *pAssetLibrary = NULL;
    cString ErrorMessage;

    // Get the services/resource pointers we need
    pServices = CPUTOSServices::GetOSServices();
    pImmediateContext->GetDevice(&pD3dDevice);
    pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();

    // Get the resource directory
    cString ResourceDirectory;
    CPUTGuiControllerDX11::GetController()->GetResourceDirectory(ResourceDirectory);

    // 1. Load the renderstate configuration for the GUI system
    mpGUIRenderStateBlock = (CPUTRenderStateBlockDX11*) pAssetLibrary->GetRenderStateBlock(ResourceDirectory+RenderStateFile); 
    ASSERT(mpGUIRenderStateBlock, _L("Error loading the render state file (.rs) needed for the CPUT GUI system"));
    

    // 2. Store the shader path from AssetLibrary, change it to OUR resource directory
    cString OriginalAssetLibraryDirectory = pAssetLibrary->GetShaderDirectory();
    pAssetLibrary->SetShaderDirectoryName(ResourceDirectory);
    

    // 3. load the shaders for gui drawing
    // Load the GUI Vertex Shader
    cString FullPath, FinalPath;
    FullPath = mResourceDirectory + VertexShaderFilename;
    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);
    result = pAssetLibrary->GetVertexShader(FinalPath, pD3dDevice, _L("VS"), _L("vs_4_0"), &mpGUIVertexShader, true);
    CPUTSetDebugName( mpGUIVertexShader->GetNativeVertexShader(), _L("GUIVertexShader"));
    if(CPUTFAILED(result))
    {
        ASSERT(CPUTSUCCESS(result), _L("Error loading the vertex shader needed for the CPUT GUI system."));
    }
    ID3DBlob *pVertexShaderBlob = mpGUIVertexShader->GetBlob();

    // Load the GUI Pixel Shader
    FullPath = mResourceDirectory + PixelShaderFilename;
    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);
    result = pAssetLibrary->GetPixelShader(FinalPath, pD3dDevice, _L("PS"), _L("ps_4_0"), &mpGUIPixelShader, true);
    CPUTSetDebugName( mpGUIPixelShader->GetNativePixelShader(), _L("GUIPixelShader"));
    if(CPUTFAILED(result))
    {
        ASSERT(CPUTSUCCESS(result), _L("Error loading the pixel shader needed for the CPUT GUI system."));
    }

    // Restore the previous shader directory
    pAssetLibrary->SetShaderDirectoryName(OriginalAssetLibraryDirectory);
    

    // 4. Create the vertex layout description for all the GUI controls we'll draw
    // set vertex shader as active so we can configure it
    ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader();
    pImmediateContext->VSSetShader( pVertexShader, NULL, 0 );

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },		
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
    hr = pD3dDevice->CreateInputLayout( layout, numElements, pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), &mpVertexLayout );
    ASSERT( SUCCEEDED(hr), _L("Error creating CPUT GUI system input layout" ));
    CPUTSetDebugName( mpVertexLayout, _L("CPUT GUI InputLayout object"));
    

    // 5. create the vertex shader constant buffer pointers
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(GUIConstantBufferVS);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;
    hr = pD3dDevice->CreateBuffer( &bd, NULL, &mpConstantBufferVS );
    ASSERT( SUCCEEDED(hr), _L("Error creating constant buffer VS" ));
    CPUTSetDebugName( mpConstantBufferVS, _L("GUI ConstantBuffer"));
      
    // Set the texture directory for loading the control texture atlas
    pAssetLibrary->SetTextureDirectoryName(ResourceDirectory);

    // load the control atlas
    mpControlTextureAtlas = (CPUTTextureDX11*) pAssetLibrary->GetTexture(ControlAtlasTexture); 
    if(NULL==mpControlTextureAtlas)
    {
        return CPUT_TEXTURE_LOAD_ERROR;
    }
    mpControlTextureAtlasView = mpControlTextureAtlas->GetShaderResourceView();
    mpControlTextureAtlasView->AddRef();

    // restore the asset library's texture directory    
    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);
    

    // 6. Load the font atlas
    // store the existing asset library font directory
    OriginalAssetLibraryDirectory = pAssetLibrary->GetFontDirectory(); 

    // set font directory to the resource directory
    pAssetLibrary->SetFontDirectoryName(ResourceDirectory);
    mpFont = (CPUTFontDX11*) pAssetLibrary->GetFont(DefaultFontFilename); 
    if(NULL==mpFont)
    {
        return CPUT_TEXTURE_LOAD_ERROR;
    }
    mpTextTextureAtlas = mpFont->GetAtlasTexture();
    mpTextTextureAtlas->AddRef();
    mpTextTextureAtlasView = mpFont->GetAtlasTextureResourceView();
    mpTextTextureAtlasView->AddRef();    

    // restore the asset library's font directory    
    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);
    
    
    // 7. Set up the DirectX uber-buffers that the controls draw into
    int maxSize = max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE);
    maxSize = max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE);    
    maxSize *= sizeof( CPUTGUIVertex );
    char *pZeroedBuffer= new char[maxSize];
    memset(pZeroedBuffer, 0, maxSize);

    // set up buffer description
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE; //mUberBufferIndex;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    // initialization data (all 0's for now)
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = mpMirrorBuffer;

    // mpUberBuffer
    SAFE_RELEASE(mpUberBuffer);
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpUberBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpUberBuffer, _L("CPUT GUI: Control's main vertex buffer"));


    // mpTextUberBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpTextUberBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpTextUberBuffer, _L("CPUT GUI: control text vertex buffer"));


    // mpFocusedControlBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFocusedControlBuffer, _L("CPUT GUI: focused control images vertex buffer"));

    
    // mpFocusedControlTextBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; //mFocusedControlTextBufferIndex;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlTextBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFocusedControlTextBuffer, _L("CPUT GUI: focused control text vertex buffer"));

    // mpFPSDirectXBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFPSDirectXBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFPSDirectXBuffer, _L("CPUT GUI: FPS display text"));
    
    // no longer need the device - release it.
    SAFE_RELEASE(pD3dDevice);
    SAFE_DELETE_ARRAY(pZeroedBuffer);    


    // 8. Register all GUI sub-resources
    // Walk all the controls/fonts and have them register all their required static resources
    // Returning errors if you couldn't find your resources
    result = CPUTText::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTButton::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTCheckbox::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTSlider::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTDropdown::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }

    // create the FPS CPUTText object for drawing FPS
    mpFPSCounter = new CPUTText(_L("FPS:"), ID_CPUT_GUI_FPS_COUNTER, mpFont);
    mpFPSCounter->SetAutoArranged(false);
    mpFPSCounter->SetPosition(0,0);

    // start the timer
    mpFPSTimer->StartTimer();

    // done
    return CPUT_SUCCESS;
}
// Load and register all the resources needed by the GUI system
//-----------------------------------------------------------------------------
CPUTResult CPUTGuiControllerOGL::RegisterGUIResources()
{
    CPUTResult result = CPUT_SUCCESS;

	cString name = _L("$cbGUIValues");
    mpConstantBufferVS = new CPUTBufferOGL(name);
    GLuint id = mpConstantBufferVS->GetBufferID();
    GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, mpConstantBufferVS->GetBufferID()));
    GL_CHECK(glBufferData(GL_UNIFORM_BUFFER, sizeof(GUIConstantBufferVS), NULL, GL_DYNAMIC_DRAW)); // NULL to just init buffer size
    GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0));
    DEBUG_PRINT(_L("bind gui constant buffers: %d\n"), id);
//    GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, mpConstantBufferVS->GetBufferID(), mpConstantBufferVS->GetBufferID()));
    DEBUG_PRINT(_L("completed bind gui constant buffers\n"));
    CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer(_L(""), name, _L(""), mpConstantBufferVS);

    CPUTAssetLibraryOGL *pAssetLibrary = NULL;
    pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibraryOGL::GetAssetLibrary();

    // Get the resource directory
    cString mediaDirectory;
    mediaDirectory = pAssetLibrary->GetMediaDirectoryName();

    mpTextMaterial = pAssetLibrary->GetMaterial(_L("guimaterial_text"));
    mpControlMaterial = pAssetLibrary->GetMaterial(_L("guimaterial_control"));

    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)},
    };

    unsigned int maxSize = std::max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE);
    maxSize = std::max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE);    
    maxSize *= sizeof( CPUTGUIVertex );

    mpUberBuffer = new CPUTMeshOGL();
    mpUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpMirrorBuffer, NULL, 0, NULL);

    mpTextUberBuffer = new CPUTMeshOGL();
    mpTextUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, NULL, NULL, 0, NULL);

    mpFocusedControlBuffer = new CPUTMeshOGL();
	mpFocusedControlBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpFocusedControlMirrorBuffer, NULL, 0, NULL);

    mpFocusedControlTextBuffer = new CPUTMeshOGL();
	mpFocusedControlTextBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpFocusedControlTextMirrorBuffer, NULL, 0, NULL);

    // Walk all the controls/fonts and have them register all their required static resources
    // Returning errors if you couldn't find your resources
    result = CPUTText::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTButton::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTCheckbox::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTSlider::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTDropdown::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    DEBUG_PRINT(_L("Exit RegisterGUIResources()\n"));
    return CPUT_SUCCESS;
}
Exemplo n.º 12
0
// Create a window context
//-----------------------------------------------------------------------------
CPUTResult CPUT_OGL::CPUTCreateWindowAndContext(const cString WindowTitle, CPUTWindowCreationParams windowParams)
{
    CPUTResult result = CPUT_SUCCESS;

    HEAPCHECK;

    // We shouldn't destroy old window if it already exist, 
    // Framework user should do this by himself to be aware
    // of what he is doing.
    if( mpWindow )
    {
        return CPUT_ERROR_WINDOW_ALREADY_EXISTS;
    }

    result = MakeWindow(WindowTitle, windowParams);
    if(CPUTFAILED(result))
    {
        return result;
    }


    HEAPCHECK;

    // create the GL context
    result = CreateOGLContext(windowParams.deviceParams);
    if(CPUTFAILED(result))
    {
        return result;
    }


    HEAPCHECK;

    result = CreateContext();

    CPUTRenderStateBlock *pBlock = new CPUTRenderStateBlockOGL();
    CPUTRenderStateBlock::SetDefaultRenderStateBlock( pBlock );

    cString name = _L("$cbPerFrameValues");
    mpPerFrameConstantBuffer = new CPUTBufferOGL(name);
    GLuint id = mpPerFrameConstantBuffer->GetBufferID();
#ifndef CPUT_FOR_OGLES2
    GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, mpPerFrameConstantBuffer->GetBufferID()));
    GL_CHECK(glBufferData(GL_UNIFORM_BUFFER, sizeof(CPUTFrameConstantBuffer), NULL, GL_DYNAMIC_DRAW)); // NULL to just init buffer size
    DEBUG_PRINT(_L("bind per frame buffer buffer %d\n"), id);
//FIXME: constant buffer binding
    GL_CHECK(ES3_COMPAT(glBindBufferBase(GL_UNIFORM_BUFFER, id, id)));
    DEBUG_PRINT(_L("completed - bind buffer %d\n"), id);
    GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0));
#else
#warning "Need to do something with uniform buffers here"
#endif
    CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer(_L(""), name, _L(""), mpPerFrameConstantBuffer);
    
    name = _L("$cbPerModelValues");
    mpPerModelConstantBuffer = new CPUTBufferOGL(name, GL_UNIFORM_BUFFER, GL_DYNAMIC_DRAW, sizeof(CPUTModelConstantBuffer), NULL);
    
    id = mpPerModelConstantBuffer->GetBufferID();
#ifndef CPUT_FOR_OGLES2
    DEBUG_PRINT(_L("Bind per model values %d"), id);
    GL_CHECK(ES3_COMPAT(glBindBufferBase(GL_UNIFORM_BUFFER, id, id)));
    DEBUG_PRINT(_L("Completed bind per model values"));
    GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0));
#else
#warning "Need to do something with uniform buffers here"
#endif
    CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer(_L(""), name, _L(""), mpPerModelConstantBuffer);

    name = _L("$cbGUIConstants");
    CPUTBuffer* pBuffer = new CPUTBufferOGL(name, GL_UNIFORM_BUFFER, GL_DYNAMIC_DRAW, sizeof(GUIConstants), NULL);
    
    CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer(_L(""), name, _L(""), pBuffer);
    SAFE_RELEASE(pBuffer);
	// 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("cbGUIValues"), _L("$cbGUIValues") );
    HEAPCHECK;

    // Trigger a post-create user callback event
    Create();
    HEAPCHECK;

    //
    // Start the timer after everything is initialized and assets have been loaded
    //
    mpTimer->StartTimer();

    int x,y,width,height;
    mpWindow->GetClientDimensions(&x, &y, &width, &height);

    ResizeWindow(width,height);

    return result;
}
Exemplo n.º 13
0
    // Register the buffer with OpenGL
    //-----------------------------------------------------------------------------
    CPUTResult CPUTMesh::Register(void** ppLayout)
    {
        CPUTResult result;
        result = UnRegister();
        if(CPUTFAILED(result))
            return result;

        int NumberOfVertexStreamsInThisMesh = GetVertexStreamCount();
        int NumberOfTotalStreamsInThisMesh=NumberOfVertexStreamsInThisMesh;

        // if indexed, we need one additional vbo
        if(IsIndexedMesh())
            NumberOfTotalStreamsInThisMesh++;

        // allocate the variables we'll need for this operation
        //m_ppDXBufferObjects = new ID3D11Buffer*[NumberOfVertexStreamsInThisMesh];
        //D3D11_INPUT_ELEMENT_DESC* layout = new D3D11_INPUT_ELEMENT_DESC[ NumberOfVertexStreamsInThisMesh ];
        //m_pStreamStrides = new UINT[NumberOfVertexStreamsInThisMesh];
        //m_pStreamOffsets = new UINT[NumberOfVertexStreamsInThisMesh];

        // generate 1 VAO (vertex array object) to hold all these streams
        glGenVertexArrays(1, &m_VertexArrayObjectID);

        // Bind VAO so you can 
        glBindVertexArray(m_VertexArrayObjectID);

        // generate 'stream' slots
        m_pVertexBufferObjectIDs = new GLuint[NumberOfTotalStreamsInThisMesh];   

        glGenBuffers(NumberOfTotalStreamsInThisMesh, m_pVertexBufferObjectIDs);


        for(int j=0; j<NumberOfVertexStreamsInThisMesh; j++)
        {
            // register each stream of each mesh, storing it's DX object pointer
            CPUTMeshStream* stream = GetVertexStream(j);

            if(CPUT_STREAM_ELEMENT_LAYOUT_UNIFORM == stream->GetStreamElementLayoutType())
            {
                // non-indexed
                CPUTMeshStreamUniform* uniformStream = (CPUTMeshStreamUniform*) stream;

                // deterimine the number of components per generic vertex attribute. Must be 1, 2, 3, or 4.  


                // bind this stream's data
                GLenum glDataType;
                void* pData = NULL;
                glDataType = ConvertCPUTFormatToGL(uniformStream->GetDataFormatElementType());
                glBindBuffer(GL_ARRAY_BUFFER, m_pVertexBufferObjectIDs[j]);
                uniformStream->Lock(&pData);
                glBufferData(GL_ARRAY_BUFFER, uniformStream->GetDataElementBlockSize() * uniformStream->GetNumberVerticies(), pData, GL_STATIC_DRAW);
                uniformStream->Unlock();
                glVertexAttribPointer((GLuint)j, uniformStream->GetNumberDataFormatElements(), glDataType, GL_FALSE, 0, 0); 
                glEnableVertexAttribArray(j); // slot number

                // Store the number of verticies
                // TODO: BUG - what if there diff number of elements/stream?
                m_NumberOfVerticies = uniformStream->GetNumberVerticies();

            } 
            else if(CPUT_STREAM_ELEMENT_LAYOUT_FLEXIBLE == stream->GetStreamElementLayoutType())
            {
                // TODO: fill this out with flexible streams
            }
            else
            {
                // TODO: ERROR
            }
        }

        // register any index stream (if there is one)
        if(IsIndexedMesh())
        {
            CPUTMeshStream* stream = GetIndexStream();

            if(CPUT_STREAM_ELEMENT_LAYOUT_UNIFORM == stream->GetStreamElementLayoutType())
            {
                void* pData = NULL;
                CPUTMeshStreamUniform* uniformStream = (CPUTMeshStreamUniform*) stream;

                // bind index stream and fill data
                // last m_pVertexBufferObjectID[] is always the Index buffer (if there is one)
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pVertexBufferObjectIDs[NumberOfTotalStreamsInThisMesh-1]);
                uniformStream->Lock(&pData);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, uniformStream->GetDataElementBlockSize() * uniformStream->GetNumberVerticies(), pData, GL_STATIC_DRAW);
                uniformStream->Unlock();
                // this is an indexed mesh, so draw as such
                m_MeshDrawingType = CPUT_STREAM_TYPE_INDEX;
                m_NumberOfVerticies = uniformStream->GetNumberVerticies();
            }
        }

        // unbind what we were doing
        // todo: would be better to restore the user's state instead of just blast over it with 0
        glBindVertexArray(0);

        return CPUT_SUCCESS;
    }
Exemplo n.º 14
0
    // Force resize of the button to given dimensions
    //--------------------------------------------------------------------------------
    CPUTResult CPUTButton::Resize(int width, int height)
    {
        CPUTResult result = CPUT_SUCCESS;

        int safeWidth, safeHeight;    

        switch(m_ControlState)
        {
        case CPUT_CONTROL_ACTIVE:
            safeWidth = m_ButtonDimensions.x + m_SmallestLeftSizeIdle + m_SmallestRightSizeIdle + 1; 
            safeHeight = m_ButtonDimensions.y + m_SmallestTopSizeIdle + m_SmallestBottomSizeIdle + 1;
            break;

        case CPUT_CONTROL_INACTIVE:
            assert(false); // todo: error! unknown state - using idle dimensions as a default
            safeWidth = m_ButtonDimensions.x + m_SmallestLeftSizeIdle + m_SmallestRightSizeIdle + 1; 
            safeHeight = m_ButtonDimensions.y + m_SmallestTopSizeIdle + m_SmallestBottomSizeIdle + 1;
            break;

        case CPUT_CONTROL_PRESSED:
            safeWidth = m_ButtonDimensions.x + m_SmallestLeftSizePressed + m_SmallestRightSizePressed + 1; 
            safeHeight = m_ButtonDimensions.y + m_SmallestTopSizePressed + m_SmallestBottomSizePressed + 1;
            break;

        default:
            assert(false); // todo: error! unknown state - using idle dimensions as a default
            safeWidth = m_ButtonDimensions.x + m_SmallestLeftSizeIdle + m_SmallestRightSizeIdle + 1; 
            safeHeight = m_ButtonDimensions.y + m_SmallestTopSizeIdle + m_SmallestBottomSizeIdle + 1;
        }

        // if the user's dimensions are smaller than the smallest 'safe' dimensions of the button,
        // use the safe ones instead.
        if(safeWidth > width)
            width = safeWidth;
        if(safeHeight > height)
            height = safeHeight;

        // add some padding for nicety
        width += CPUT_BUTTON_TEXT_BORDER_PADDING_X;
        height += CPUT_BUTTON_TEXT_BORDER_PADDING_Y;


        if( (m_ButtonDimensions.width != width) || (m_ButtonDimensions.height != height) )
        {
            // store the new dimensions
            m_ButtonDimensions.width = width;
            m_ButtonDimensions.height = height;

            // calculate the pieces we'll need to rebuild
            int middleWidth = width - m_SmallestLeftSizeIdle - m_SmallestRightSizeIdle;
            int middleHeight = height - m_SmallestTopSizeIdle - m_SmallestBottomSizeIdle;

            // create a new quads with the correct size
            // Idle button quads
            //glDeleteBuffers(2, m_pIdleVertexBufferObjectIDs[1*2]);
            //glDeleteVertexArrays(1, &m_pIdleVertexArrayObjectIDs[1]);
            result = RegisterQuad(m_pButtonIdleSizeList[1].width, middleHeight, m_pIdleVertexArrayObjectIDs[1], &m_pIdleVertexBufferObjectIDs[1*2]);
            m_pButtonIdleSizeList[1].height = middleHeight;
            if(CPUTFAILED(result))
                return result;

            result = RegisterQuad(middleWidth, m_pButtonIdleSizeList[3].height, m_pIdleVertexArrayObjectIDs[3], &m_pIdleVertexBufferObjectIDs[3*2]);
            m_pButtonIdleSizeList[3].width = middleWidth;
            if(CPUTFAILED(result))
                return result;
            result = RegisterQuad(middleWidth, middleHeight, m_pIdleVertexArrayObjectIDs[4], &m_pIdleVertexBufferObjectIDs[4*2]);
            m_pButtonIdleSizeList[4].width = middleWidth;
            m_pButtonIdleSizeList[4].height = middleHeight;
            if(CPUTFAILED(result))
                return result;
            result = RegisterQuad(middleWidth, m_pButtonIdleSizeList[5].height, m_pIdleVertexArrayObjectIDs[5], &m_pIdleVertexBufferObjectIDs[5*2]);
            m_pButtonIdleSizeList[5].width = middleWidth;
            if(CPUTFAILED(result))
                return result;

            result = RegisterQuad(m_pButtonIdleSizeList[7].width, middleHeight, m_pIdleVertexArrayObjectIDs[7], &m_pIdleVertexBufferObjectIDs[7*2]);
            m_pButtonIdleSizeList[7].height = middleHeight;
            if(CPUTFAILED(result))
                return result;


            // Pressed button quads        
            result = RegisterQuad(m_pButtonPressedSizeList[1].width, middleHeight, m_pPressedVertexArrayObjectIDs[1], &m_pPressedVertexBufferObjectIDs[1*2]);
            m_pButtonPressedSizeList[1].height = middleHeight;
            if(CPUTFAILED(result))
                return result;

            result = RegisterQuad(middleWidth, m_pButtonPressedSizeList[3].height, m_pPressedVertexArrayObjectIDs[3], &m_pPressedVertexBufferObjectIDs[3*2]);
            m_pButtonPressedSizeList[3].width = middleWidth;
            if(CPUTFAILED(result))
                return result;
            result = RegisterQuad(middleWidth, middleHeight, m_pPressedVertexArrayObjectIDs[4], &m_pPressedVertexBufferObjectIDs[4*2]);
            m_pButtonPressedSizeList[4].width = middleWidth;
            m_pButtonPressedSizeList[4].height = middleHeight;
            if(CPUTFAILED(result))
                return result;
            result = RegisterQuad(middleWidth, m_pButtonPressedSizeList[5].height, m_pPressedVertexArrayObjectIDs[5], &m_pPressedVertexBufferObjectIDs[5*2]);
            m_pButtonPressedSizeList[5].width = middleWidth;
            if(CPUTFAILED(result))
                return result;

            result = RegisterQuad(m_pButtonPressedSizeList[7].width, middleHeight, m_pPressedVertexArrayObjectIDs[7], &m_pPressedVertexBufferObjectIDs[7*2]);
            m_pButtonPressedSizeList[7].height = middleHeight;
            if(CPUTFAILED(result))
                return result;
        }


        return result;
    }
Exemplo n.º 15
0
//-----------------------------------------------------------------------------
CPUTResult CPUTModel::LoadModelPayload(const cString &File)
{
    CPUTResult result = CPUT_SUCCESS;

    std::ifstream file(File.c_str(), std::ios::in | std::ios::binary);
    ASSERT( !file.fail(), _L("CPUTModelDX11::LoadModelPayload() - Could not find binary model file: ") + File );

    // set up for mesh creation loop
    UINT meshIndex = 0;
    while(file.good() && !file.eof())
    {
        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two
        CPUTRawMeshData vertexFormatDesc;
        vertexFormatDesc.Read(file);
        if(file.eof())
        {
            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?
            break;
        }
        ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count"));

        // create the mesh.
        CPUTMesh *pMesh = mpMesh[meshIndex];

        // always a triangle list (at this point)
        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);

        // get number of data blocks in the vertex element (pos,norm,uv,etc)
        // YUCK! TODO: Use fixed-size array of elements
        CPUTBufferInfo *pVertexElementInfo = new CPUTBufferInfo[vertexFormatDesc.mFormatDescriptorCount];
        // pMesh->SetBounds(vertexFormatDesc.mBboxCenter, vertexFormatDesc.mBboxHalf);

        // running count of each type of  element
        int positionStreamCount=0;
        int normalStreamCount=0;
        int texCoordStreamCount=0;
        int tangentStreamCount=0;
        int binormalStreamCount=0;
        int colorStreamCount=0;

        int RunningOffset = 0;
        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)
        {
            // lookup the CPUT data type equivalent
            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[vertexFormatDesc.mpElements[ii].mVertexElementType];
            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error.  This model file has an unknown data type in it's model data."));
            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)
            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];
            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)
            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;
            // store the number of elements (i.e. 3xF32, 3 elements)
            pVertexElementInfo[ii].mElementCount = vertexFormatDesc.mVertexCount;
            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here
            pVertexElementInfo[ii].mOffset = RunningOffset;
            RunningOffset = RunningOffset + pVertexElementInfo[ii].mElementSizeInBytes;

            // extract the name of stream
            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];

            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)
            {
            case CPUT_VERTEX_ELEMENT_POSITON:
                pVertexElementInfo[ii].mpSemanticName = "POSITION";
                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_NORMAL:
                pVertexElementInfo[ii].mpSemanticName = "NORMAL";
                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TEXTURECOORD:
                pVertexElementInfo[ii].mpSemanticName = "TEXCOORD";
                pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TANGENT:
                pVertexElementInfo[ii].mpSemanticName = "TANGENT";
                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_BINORMAL:
                pVertexElementInfo[ii].mpSemanticName = "BINORMAL";
                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_VERTEXCOLOR:
                pVertexElementInfo[ii].mpSemanticName = "COLOR";
                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;
                break;
            default:
                cString errorString = _L("Invalid vertex semantic in: '")+File+_L("'\n");
                TRACE(errorString.c_str());
                ASSERT(0, errorString);
            }
        }

        // Index buffer
        CPUTBufferInfo indexDataInfo;
        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == tUINT32) ? CPUT_U32 : CPUT_U16;
        indexDataInfo.mElementComponentCount = 1;
        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == tUINT32) ? sizeof(UINT32) : sizeof(UINT16);
        indexDataInfo.mElementCount          = vertexFormatDesc.mIndexCount;
        indexDataInfo.mOffset                = 0;
        indexDataInfo.mSemanticIndex         = 0;
        indexDataInfo.mpSemanticName         = NULL;

        if( pVertexElementInfo->mElementCount && indexDataInfo.mElementCount )
        {
            result = pMesh->CreateNativeResources(
                this,
                meshIndex,
                vertexFormatDesc.mFormatDescriptorCount,
                pVertexElementInfo,
                (void*)vertexFormatDesc.mpVertices,
                &indexDataInfo,
                &vertexFormatDesc.mpIndices[0]
            );
            if(CPUTFAILED(result))
            {
                return result;
            }

            // CC added
            result = pMesh->ExtractVerticesandIndices();
            if(CPUTFAILED(result))
            {
                return result;  
            }
            // CC added ends
        }
        delete [] pVertexElementInfo;
        pVertexElementInfo = NULL;
        ++meshIndex;
    }
    ASSERT( file.eof(), _L("") );

    // close file
    file.close();

    return result;
}
Exemplo n.º 16
0
// incoming resize event to be handled and translated
//-----------------------------------------------------------------------------
void CPUT_DX11::ResizeWindow(UINT width, UINT height)
{
    HRESULT hr;
    CPUTResult result;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();

    // TODO: Making the back and depth buffers into CPUTRenderTargets should simplify this (CPUTRenderTarget* manages RTV, SRV, UAV, etc.)
    if( mpBackBuffer )         ((CPUTBufferDX11*)mpBackBuffer)->ReleaseBuffer();
    if( mpDepthBuffer )        ((CPUTBufferDX11*)mpDepthBuffer)->ReleaseBuffer();
    if( mpBackBufferTexture )  ((CPUTTextureDX11*)mpBackBufferTexture)->ReleaseTexture();
    if( mpDepthBufferTexture ) ((CPUTTextureDX11*)mpDepthBufferTexture)->ReleaseTexture();

    // Make sure we don't have any buffers bound.
    mpContext->ClearState();
    Present();
    mpContext->Flush();

    SAFE_RELEASE(mpBackBufferRTV);
    SAFE_RELEASE(mpBackBufferSRV);
    SAFE_RELEASE(mpBackBufferUAV);
    SAFE_RELEASE(mpDepthStencilSRV);

    CPUT::ResizeWindow( width, height );

    // Call the sample's clean up code if present.
    ReleaseSwapChain();

    // handle the internals of a resize
    int windowWidth, windowHeight;
    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();
    pServices->GetClientDimensions( &windowWidth, &windowHeight);

    // resize the swap chain
    hr = mpSwapChain->ResizeBuffers(mSwapChainBufferCount, windowWidth, windowHeight, mSwapChainFormat, 0);
    ASSERT( SUCCEEDED(hr), _L("Error resizing swap chain") );

    // re-create the render-target view
    ID3D11Texture2D *pSwapChainBuffer = NULL;
    hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*) (&pSwapChainBuffer));
    ASSERT(SUCCEEDED(hr), _L(""));
    hr = mpD3dDevice->CreateRenderTargetView( pSwapChainBuffer, NULL, &mpBackBufferRTV);
    ASSERT(SUCCEEDED(hr), _L(""));
    hr = mpD3dDevice->CreateShaderResourceView( pSwapChainBuffer, NULL, &mpBackBufferSRV);
    ASSERT(SUCCEEDED(hr), _L(""));
#ifdef CREATE_SWAP_CHAIN_UAV
    // Not every DXGI format supports UAV.  So, create UAV only if sample chooses to do so.
    hr = mpD3dDevice->CreateUnorderedAccessView( pSwapChainBuffer, NULL, &mpBackBufferUAV);
    ASSERT(SUCCEEDED(hr), _L(""));
#endif
    // Add the back buffer to the asset library.  Create CPUTBuffer and a CPUTTexture forms and add them.
    if( mpBackBuffer )
    {
        ((CPUTBufferDX11*)mpBackBuffer)->SetBufferAndViews( NULL, mpBackBufferSRV, mpBackBufferUAV );
    }
    else
    {
        cString backBufferName = _L("$BackBuffer"); 
        mpBackBuffer  = new CPUTBufferDX11( backBufferName,  NULL, mpBackBufferUAV );
        pAssetLibrary->AddBuffer( backBufferName, mpBackBuffer );
    }
    if( mpBackBufferTexture )
    {
        ((CPUTTextureDX11*)mpBackBufferTexture)->SetTextureAndShaderResourceView( NULL, mpBackBufferSRV );
    }
    else
    {
        cString backBufferName = _L("$BackBuffer"); 
        mpBackBufferTexture  = new CPUTTextureDX11( backBufferName, NULL, mpBackBufferSRV );
        pAssetLibrary->AddTexture( backBufferName, mpBackBufferTexture );
    }

    // release the old depth buffer objects
    // release the temporary swap chain buffer
    SAFE_RELEASE(pSwapChainBuffer);
    SAFE_RELEASE(mpDepthStencilBuffer);
    SAFE_RELEASE(mpDepthStencilState);
    SAFE_RELEASE(mpDepthStencilView);

    result = CreateAndBindDepthBuffer(windowWidth, windowHeight);
    if(CPUTFAILED(result))
    {
        // depth buffer creation error
        ASSERT(0,_L(""));
    }

    if( mpDepthBuffer )
    {
        ((CPUTBufferDX11*)mpDepthBuffer)->SetBufferAndViews( NULL, mpDepthStencilSRV, NULL );
    }
    else
    {
        cString depthBufferName = _L("$DepthBuffer"); 
        mpDepthBuffer  = new CPUTBufferDX11( depthBufferName, NULL, mpDepthStencilSRV );
        pAssetLibrary->AddBuffer( depthBufferName, mpDepthBuffer );
    }
    if( mpDepthBufferTexture )
    {
        ((CPUTTextureDX11*)mpDepthBufferTexture)->SetTextureAndShaderResourceView( NULL, mpDepthStencilSRV );
    }
    else
    {
        cString DepthBufferName = _L("$DepthBuffer"); 
        mpDepthBufferTexture  = new CPUTTextureDX11( DepthBufferName, NULL, mpDepthStencilSRV );
        pAssetLibrary->AddTexture( DepthBufferName, mpDepthBufferTexture );
    }

    // Release our extra reference to each view.
    // if(mpBackBufferSRV)   mpBackBufferSRV->Release();
    // if(mpBackBufferUAV)   mpBackBufferUAV->Release();
    // if(mpDepthStencilSRV) mpDepthStencilSRV->Release();;

    // set the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT) windowWidth;
    vp.Height = (FLOAT)windowHeight;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    mpContext->RSSetViewports( 1, &vp );

    // trigger the GUI manager to resize
    CPUTGuiControllerDX11::GetController()->Resize();
}
CPUTResult CPUTMaterialEffectOGL::LoadMaterialEffect(
    const cString   &fileName,
    const CPUTModel *pModel,
          int        meshIndex,
    const char     **pShaderMacros,
          int        externalCount,
          cString   *pExternalName,
          float4    *pExternals,
          int       *pExternalOffset,
          int       *pExternalSize
){
    CPUTResult result = CPUT_SUCCESS;
	CPUTConfigEntry *pValue;

    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;

    // get necessary device and AssetLibrary pointers
    //ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();
    CPUTAssetLibraryOGL *pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary();

   {
        CPUTConfigEntry *pEntryPointName, *pProfileName;
        int numFiles = 0;
        cString pBase = _L("VertexShaderFileOGL_");
        cString pName = pBase + to_cString(numFiles+1);
        std::vector<cString> filenames;
        while (mConfigBlock.GetValueByName(pName)->IsValid())
        {
            filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString());
            numFiles++;
            pName = pBase + to_cString(numFiles+1);
        }
        if(numFiles > 0)
        {
            pEntryPointName = mConfigBlock.GetValueByName(_L("VertexShaderMain"));
            pProfileName    = mConfigBlock.GetValueByName(_L("VertexShaderProfile"));
            pAssetLibrary->GetVertexShader(
                filenames,
                /*pD3dDevice,*/
                _L("VertexShaderMain"),
                pProfileName->ValueAsString(),
                &mpVertexShader,
                false,
                (CPUT_SHADER_MACRO*)pShaderMacros
            );
        }
    }

#ifdef CPUT_SUPPORT_TESSELLATION
    {
        int numFiles = 0;
        cString pBase = _L("ControlShaderFileOGL_");
        cString pName = pBase + to_cString(numFiles+1);
        std::vector<cString> filenames;
        while (mConfigBlock.GetValueByName(pName)->IsValid())
        {
            filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString());
            numFiles++;
            pName = pBase + to_cString(numFiles+1);
        }
        if(numFiles > 0) 
        {
			pAssetLibrary->GetHullShader(
                filenames,
                /* pD3dDevice,*/
                _L("ControlShaderMain"), 
                _L(""),
                &mpControlShader,
                false,
                (CPUT_SHADER_MACRO*)pShaderMacros
            );
        }
    }
    {
        int numFiles = 0;
        cString pBase = _L("EvaluationShaderFileOGL_");
        cString pName = pBase + to_cString(numFiles+1);
        std::vector<cString> filenames;
        while (mConfigBlock.GetValueByName(pName)->IsValid())
        {
            filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString());
            numFiles++;
            pName = pBase + to_cString(numFiles+1);
        }
        if(numFiles > 0) 
        {
			pAssetLibrary->GetDomainShader(
                filenames,
                /* pD3dDevice,*/
                _L("EvaluationShaderMain"), 
                _L(""),
                &mpEvaluationShader,
                false,
                (CPUT_SHADER_MACRO*)pShaderMacros
            );
        }
    }
#endif
    {
        int numFiles = 0;
        cString pBase = _L("GeometryShaderFileOGL_");
        cString pName = pBase + to_cString(numFiles+1);
        std::vector<cString> filenames;
        while (mConfigBlock.GetValueByName(pName)->IsValid())
        {
            filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString());
            numFiles++;
            pName = pBase + to_cString(numFiles+1);
        }
        if(numFiles > 0) 
        {
			pAssetLibrary->GetGeometryShader(
                filenames,
                /* pD3dDevice,*/
                _L("GeometryShaderMain"), 
                _L(""),
                &mpGeometryShader,
                false,
                (CPUT_SHADER_MACRO*)pShaderMacros
            );
        }
    }

    // load and store the pixel shader if it was specified
    {
        int numFiles = 0;
        cString pBase = _L("FragmentShaderFileOGL_");
        cString pName = pBase + to_cString(numFiles+1);
        std::vector<cString> filenames;
        while (mConfigBlock.GetValueByName(pName)->IsValid())
        {
            filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString());
            numFiles++;
            pName = pBase + to_cString(numFiles+1);
        }
        if(numFiles > 0) 
        {
            pAssetLibrary->GetPixelShader(
                filenames,
                /* pD3dDevice,*/
                _L("FragmentShaderMain"), //mConfigBlock.GetValueByName(_L("FragmentShaderMain"))->ValueAsString(),
                mConfigBlock.GetValueByName(_L("FragmentShaderProfile"))->ValueAsString(),
                &mpFragmentShader,
                false,
                (CPUT_SHADER_MACRO*)pShaderMacros
            );
        }
    }

    // load and store the render state file if it was specified
    pValue = mConfigBlock.GetValueByName(_L("RenderStateFile"));
    if( pValue->IsValid() )
    {
        mpRenderStateBlock = pAssetLibrary->GetRenderStateBlock(pValue->ValueAsString());
    }


    int IsLinked;
    char *shaderProgramInfoLog;
    int maxLength;
    
     mShaderProgram = glCreateProgram();
 
    // Attach our shaders to our program
    // Attach our shaders to our program
    if (mpVertexShader) {
        GL_CHECK(glAttachShader(mShaderProgram, mpVertexShader->GetShaderID()));
    }
    if (mpFragmentShader) {
        GL_CHECK(glAttachShader(mShaderProgram, mpFragmentShader->GetShaderID()));
    }
    if (mpControlShader) {
        GL_CHECK(glAttachShader(mShaderProgram, mpControlShader->GetShaderID()));
    }
    if (mpEvaluationShader) {
        GL_CHECK(glAttachShader(mShaderProgram, mpEvaluationShader->GetShaderID()));
    }
	if (mpGeometryShader) {
		GL_CHECK(glAttachShader(mShaderProgram, mpGeometryShader->GetShaderID()));
	}
    /*
    GL_CHECK(glBindAttribLocation(mShaderProgram, 0, "in_Position"));
    GL_CHECK(glBindAttribLocation(mShaderProgram, 1, "inNormal"));
    GL_CHECK(glBindAttribLocation(mShaderProgram, 2, "inBinormal"));
    GL_CHECK(glBindAttribLocation(mShaderProgram, 3, "inTangent"));
    GL_CHECK(glBindAttribLocation(mShaderProgram, 4, "inTex"));
      */          
    
    // Link our program
    // At this stage, the vertex and fragment programs are inspected, optimized and a binary code is generated for the shader.
    // The binary code is uploaded to the GPU, if there is no error.
    GL_CHECK(glLinkProgram(mShaderProgram));
 
    // Again, we must check and make sure that it linked. If it fails, it would mean either there is a mismatch between the vertex
    // and fragment shaders. It might be that you have surpassed your GPU's abilities. Perhaps too many ALU operations or
    // too many texel fetch instructions or too many interpolators or dynamic loops.
 
    GL_CHECK(glGetProgramiv(mShaderProgram, GL_LINK_STATUS, (int *)&IsLinked));
    if(IsLinked == false)
    {
        // Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv.
        glGetProgramiv(mShaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
 
        // The maxLength includes the NULL character
        shaderProgramInfoLog = (char *)malloc(maxLength);
 
        // Notice that glGetProgramInfoLog, not glGetShaderInfoLog.
        glGetProgramInfoLog(mShaderProgram, maxLength, &maxLength, shaderProgramInfoLog);
        DEBUG_PRINT_ALWAYS((_L("Failed to link shader program:\n%s\n"), shaderProgramInfoLog));
        ASSERT(false, _L("glLinkProgram failed"));

        // Handle the error in an appropriate way such as displaying a message or writing to a log file.
        // In this simple program, we'll just leave
        //DEBUG_PRINT_ALWAYS(("Failed to link shader program:\n%s\n", shaderProgramInfoLog));
        free(shaderProgramInfoLog);
    }
    
    // Shader must be successfully linked before we can query uniform locations
    ReadShaderSamplersAndTextures( mShaderProgram, &mVertexShaderParameters );
    glUseProgram(0);
// For each of the shader stages, bind shaders and buffers
//    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage
    {
        BindTextures(        mVertexShaderParameters, pModel, meshIndex );
        //BindTextures(        **pCur, pModel, meshIndex );
        //BindBuffers(         **pCur, pModel, meshIndex );
        BindUAVs(            mVertexShaderParameters, pModel, meshIndex );
        BindConstantBuffers( mVertexShaderParameters, pModel, meshIndex );
    }
    
    return result;
}
Exemplo n.º 18
0
// Create a window context
//-----------------------------------------------------------------------------
CPUTResult CPUT_DX11::CPUTCreateWindowAndContext(const cString WindowTitle, CPUTWindowCreationParams windowParams)
{
    CPUTResult result = CPUT_SUCCESS;

    HEAPCHECK;

    // create the window
    result = MakeWindow(WindowTitle, windowParams.windowWidth, windowParams.windowHeight, windowParams.windowPositionX, windowParams.windowPositionY);
    if(CPUTFAILED(result))
    {
        return result;
    }

    HEAPCHECK;

    // create the DX context
    result = CreateDXContext(windowParams.deviceParams);
    if(CPUTFAILED(result))
    {
        return result;
    }

    CPUTModelDX11::CreateModelConstantBuffer();

    HEAPCHECK;
#define ENABLE_GUI
#ifdef ENABLE_GUI
    // initialize the gui controller 
    // Use the ResourceDirectory that was given during the Initialize() function
    // to locate the GUI+font resources
    CPUTGuiControllerDX11 *pGUIController = CPUTGuiControllerDX11::GetController();
    cString ResourceDirectory = GetCPUTResourceDirectory();
    result = pGUIController->Initialize(mpContext, ResourceDirectory);
    if(CPUTFAILED(result))
    {
        return result;
    }
    // register the callback object for GUI events as our sample
    CPUTGuiControllerDX11::GetController()->SetCallback(this);
#endif
    HEAPCHECK;
    DrawLoadingFrame();
    HEAPCHECK;
    
    // warn the user they are using the software rasterizer
    if((D3D_DRIVER_TYPE_REFERENCE == mdriverType) || (D3D_DRIVER_TYPE_WARP == mdriverType))
    {
        CPUTOSServices::GetOSServices()->OpenMessageBox(_L("Performance warning"), _L("Your graphics hardware does not support the DirectX features required by this sample. The sample is now running using the DirectX software rasterizer."));
    }


    // trigger a post-create user callback event
    HEAPCHECK;
    Create();
    HEAPCHECK;

    //
    // Start the timer after everything is initialized and assets have been loaded
    //
    mpTimer->StartTimer();

    // if someone triggers the shutdown routine in on-create, exit
    if(mbShutdown)
    {
        return result;
    }

    // does user want to start in fullscreen mode?
    if(true == windowParams.startFullscreen)
    {
        result = CPUTToggleFullScreenMode();
        if(CPUTFAILED(result))
        {
            return result;
        }
    }

    // fill first frame with clear values so render order later is ok
    const float srgbClearColor[] = { 0.0993f, 0.0993f, 0.0993f, 1.0f };
    mpContext->ClearRenderTargetView( mpBackBufferRTV, srgbClearColor );
    mpContext->ClearDepthStencilView(mpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0);

    // trigger a 'resize' event
    int x,y,width,height;
    CPUTOSServices::GetOSServices()->GetClientDimensions(&x, &y, &width, &height);
    ResizeWindow(width,height);

    return result;
}
Exemplo n.º 19
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.
}