const RightDrawer::WaterPlaneShaderProgramAndParameters& RightDrawer::getWaterPlaneProgram(WaterPlaneShaderProgramIndex params) { boolean bNew; auto it = waterPlaneShaderPrograms.insert(bNew, params); if(!bNew) return *it->val; it->val = new WaterPlaneShaderProgramAndParameters(); boolean bNewPS; auto psIt = waterPlanePixelShaders.insert(bNewPS, params.ps); PixelShader* ps; if(bNewPS){ ps = new PixelShader(*this); String code = getWaterPlanePixelShaderCode(params.ps); ps->init(code); psIt->val = ps; } else ps = psIt->val; boolean bNewVS; auto vsIt = meshVertexShaders.insert(bNewVS, params.vs); VertexShader* vs; if(bNewVS){ vs = new VertexShader(*this); String code = getMeshVertexShaderCode(params.vs); vs->init(code); vsIt->val = vs; } else vs = vsIt->val; ShaderProgram* prog = new ShaderProgram(*this); Array<String> args = getVertexShaderAttributesCode((EVertexFormat)params.vs.format); Array<ConstString> arr; foreach(it, args) arr.push(it->toConst()); prog->init(*vs, *ps, arr.constRange()); it->val->init(prog); return *it->val; }