#include "BsScriptShader.h" #include "BsScriptResourceManager.h" #include "BsScriptMeta.h" #include "BsMonoField.h" #include "BsMonoClass.h" #include "BsMonoArray.h" #include "BsMonoManager.h" namespace BansheeEngine { /** * @brief Shader parameter types that can be handled using managed code. */ enum class ShaderParameterType // Note: This must match C# ShaderParameterType enum { Float, Vector2, Vector3, Vector4, Color, Matrix3, Matrix4, Texture2D, Texture3D, TextureCube, Sampler }; ScriptShader::ScriptShader(MonoObject* instance, const HShader& shader) :TScriptResource(instance, shader) { } void ScriptShader::initRuntimeData() { metaData.scriptClass->addInternalCall("Internal_GetShaderParameters", &ScriptShader::internal_GetShaderParameters); } void ScriptShader::internal_GetShaderParameters(ScriptShader* nativeInstance, MonoArray** outNames, MonoArray** outTypes, MonoArray** outVisibility) { HShader shader = nativeInstance->getHandle(); if (!shader.isLoaded()) return; const Map& dataParams = shader->getDataParams(); const Map& textureParams = shader->getTextureParams(); const Map& samplerParams = shader->getSamplerParams(); struct ParamInfo { String name; ShaderParameterType type; bool internal; }; Vector paramInfos; // TODO - Ignoring int, bool, struct and non-square matrices // TODO - Ignoring buffers and load/store textures for (auto& param : dataParams) { ShaderParameterType type; bool isValidType = false; bool isInternal = !param.second.rendererSemantic.empty(); switch (param.second.type) { case GPDT_FLOAT1: type = ShaderParameterType::Float; isValidType = true; break; case GPDT_FLOAT2: type = ShaderParameterType::Vector2; isValidType = true; break; case GPDT_FLOAT3: type = ShaderParameterType::Vector3; isValidType = true; break; case GPDT_FLOAT4: type = ShaderParameterType::Vector4; isValidType = true; break; case GPDT_MATRIX_3X3: type = ShaderParameterType::Matrix3; isValidType = true; break; case GPDT_MATRIX_4X4: type = ShaderParameterType::Matrix4; isValidType = true; break; case GPDT_COLOR: type = ShaderParameterType::Color; isValidType = true; break; } if (isValidType) paramInfos.push_back({ param.first, type, isInternal }); } for (auto& param : textureParams) { ShaderParameterType type; bool isValidType = false; bool isInternal = !param.second.rendererSemantic.empty(); switch (param.second.type) { case GPOT_TEXTURE2D: case GPOT_TEXTURE2DMS: type = ShaderParameterType::Texture2D; isValidType = true; break; case GPOT_TEXTURE3D: type = ShaderParameterType::Texture3D; isValidType = true; break; case GPOT_TEXTURECUBE: type = ShaderParameterType::TextureCube; isValidType = true; break; } if (isValidType) paramInfos.push_back({ param.first, type, isInternal }); } for (auto& param : samplerParams) { ShaderParameterType type = ShaderParameterType::Sampler; bool isInternal = !param.second.rendererSemantic.empty(); paramInfos.push_back({ param.first, type, isInternal }); } UINT32 totalNumParams = (UINT32)paramInfos.size(); ScriptArray names = ScriptArray::create(totalNumParams); ScriptArray types = ScriptArray::create(totalNumParams); ScriptArray visibility = ScriptArray::create(totalNumParams); UINT32 idx = 0; for (auto& param : paramInfos) { names.set(idx, param.name); types.set(idx, param.type); visibility.set(idx, param.internal); idx++; } *outNames = names.getInternal(); *outTypes = types.getInternal(); *outVisibility = visibility.getInternal(); } MonoObject* ScriptShader::createInstance() { return metaData.scriptClass->createInstance(); } }