#pragma once #include "BsCorePrerequisites.h" #include "BsGpuParamDesc.h" #include "BsGpuParams.h" #include "BsRenderAPI.h" #include "BsGpuParamBlockBuffer.h" namespace BansheeEngine { /** * Macros used for manually constructing parameter block buffers used by GPU programs. */ #define BS_PARAM_BLOCK_BEGIN(Name) \ struct Name \ { \ Name() \ { \ Vector params = getEntries(); \ RenderAPICore& rapi = RenderAPICore::instance(); \ \ mBlockDesc = rapi.generateParamBlockDesc(#Name, params); \ \ SPtr paramsDesc = bs_shared_ptr_new(); \ paramsDesc->paramBlocks[#Name] = mBlockDesc; \ for (auto& param : params) \ paramsDesc->params[param.name] = param; \ \ mParams = GpuParamsCore::create(paramsDesc, rapi.getGpuProgramHasColumnMajorMatrices()); \ \ mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32)); \ mParams->setParamBlockBuffer(#Name, mBuffer); \ initEntries(); \ } \ \ const SPtr& getBuffer() const { return mBuffer; } \ const GpuParamBlockDesc& getDesc() const { return mBlockDesc; } \ \ private: \ struct META_FirstEntry {}; \ static void META_GetPrevEntries(Vector& params, META_FirstEntry id) { } \ void META_InitPrevEntry(const SPtr& params, META_FirstEntry id) { } \ \ typedef META_FirstEntry #define BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, NumElements) \ META_Entry_##Name; \ \ struct META_NextEntry_##Name {}; \ static void META_GetPrevEntries(Vector& params, META_NextEntry_##Name id) \ { \ META_GetPrevEntries(params, META_Entry_##Name##()); \ \ params.push_back(GpuParamDataDesc()); \ GpuParamDataDesc& newEntry = params.back(); \ newEntry.name = #Name; \ newEntry.type = (GpuParamDataType)TGpuDataParamInfo::TypeId; \ newEntry.arraySize = NumElements; \ } \ \ void META_InitPrevEntry(const SPtr& params, META_NextEntry_##Name id) \ { \ META_InitPrevEntry(params, META_Entry_##Name##()); \ params->getParam(#Name, Name); \ } \ \ public: \ TGpuDataParam Name; \ \ private: \ typedef META_NextEntry_##Name #define BS_PARAM_BLOCK_ENTRY(Type, Name) BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, 1) #define BS_PARAM_BLOCK_END \ META_LastEntry; \ \ static Vector getEntries() \ { \ Vector entries; \ META_GetPrevEntries(entries, META_LastEntry()); \ return entries; \ } \ \ void initEntries() \ { \ META_InitPrevEntry(mParams, META_LastEntry()); \ } \ \ SPtr mParams; \ SPtr mBuffer; \ GpuParamBlockDesc mBlockDesc; \ }; }