/// <summary> /// Attaches the object to a specific <see cref="RenderContext"/> object. /// </summary> /// <param name="rc">The <see cref="RenderContext"/> object to be used.</param> public void AttachToContext(RenderContext rc) { _rc = rc; _clearColor = rc.ClearColor; var imgData = _rc.CreateImage(_screenWidth, _screenHeight, "black"); _contentLTex = _rc.CreateTexture(imgData); _contentRTex = _rc.CreateTexture(imgData); // initialize shader and image switch (_activeMode) { case Stereo3DMode.Oculus: _guiLImage = new GUIImage(null, 0, 0, _screenWidth/2, _screenHeight); _guiLImage.AttachToContext(rc); _guiLImage.Refresh(); _guiRImage = new GUIImage(null, _screenWidth/2, 0, _screenWidth/2, _screenHeight); _guiRImage.AttachToContext(rc); _guiRImage.Refresh(); _shaderProgram = _rc.CreateShader(OculusVs, OculusPs); _shaderTexture = _shaderProgram.GetShaderParam("vTexture"); _lensCenterParam = _shaderProgram.GetShaderParam("LensCenter"); _screenCenterParam = _shaderProgram.GetShaderParam("ScreenCenter"); _scaleParam = _shaderProgram.GetShaderParam("Scale"); _scaleInParam = _shaderProgram.GetShaderParam("ScaleIn"); _hdmWarpParam = _shaderProgram.GetShaderParam("HmdWarpParam"); break; case Stereo3DMode.Anaglyph: _shaderProgram = _rc.CreateShader(AnaglyphVs, AnaglyphPs); _shaderTexture = _shaderProgram.GetShaderParam("vTexture"); _guiLImage = new GUIImage(null, 0, 0, _screenWidth, _screenHeight); _guiLImage.AttachToContext(rc); _guiLImage.Refresh(); break; } }
/// <summary> /// Attaches this instance to a RenderContext. /// </summary> /// <param name="rc">The Render Context to attach to.</param> /// <remarks>A ShaderEffect must be attached to a context before you can render geometry with it. The main /// task performed in this method is compiling the provided shader source code and uploading the shaders to /// the gpu under the provided RenderContext.</remarks> public void AttachToContext(RenderContext rc) { if (rc == null) throw new ArgumentNullException("rc", "must pass a valid render context."); _rc = rc; int i=0, nPasses = _vertexShaderSrc.Length; try // to compile all the shaders { for (i = 0; i < nPasses; i++) { _compiledShaders[i] = _rc.CreateShader(_vertexShaderSrc[i], _pixelShaderSrc[i]); } } catch (Exception ex) { throw new Exception("Error while compiling shader for pass " + i, ex); } // Enumerate all shader parameters of all passes and enlist them in lookup tables _parameters = new Dictionary<string, EffectParam>(); _paramsPerPass = new List<List<EffectParam>>(); for (i = 0; i < nPasses; i++) { IEnumerable<ShaderParamInfo> paramList = _rc.GetShaderParamList(_compiledShaders[i]); _paramsPerPass.Add(new List<EffectParam>()); foreach (var paramNew in paramList) { Object initValue; if (_paramDecl.TryGetValue(paramNew.Name, out initValue)) { // IsAssignableFrom the boxed initValue object will cause JSIL to give an answer based on the value of the contents // If the type originally was float but contains an integral value (e.g. 3), JSIL.GetType() will return Integer... // Thus for primitve types (float, int, ) we hack a check ourselves. For other types (float2, ..) IsAssignableFrom works well. // ReSharper disable UseMethodIsInstanceOfType // ReSharper disable OperatorIsCanBeUsed var initValType = initValue.GetType(); if ( !( ( (paramNew.Type == typeof (int) || paramNew.Type == typeof (float)) && (initValType == typeof (int) || initValType == typeof (float) || initValType == typeof (double)) ) || (paramNew.Type.IsAssignableFrom(initValType)) ) ) { throw new Exception("Error preparing effect pass " + i + ". Shader parameter " + paramNew.Type.ToString() + " " + paramNew.Name + " was defined as " + initValType.ToString() + " " + paramNew.Name + " during initialization (different types)."); } // ReSharper restore OperatorIsCanBeUsed // ReSharper restore UseMethodIsInstanceOfType // Parameter was declared by user and type is correct in shader - carry on. EffectParam paramExisting; if (_parameters.TryGetValue(paramNew.Name, out paramExisting)) { // The parameter is already there from a previous pass. if (paramExisting.Info.Size != paramNew.Size || paramExisting.Info.Type != paramNew.Type) { // This should never happen due to the previous error check. Check it anyway... throw new Exception("Error preparing effect pass " + i + ". Shader parameter " + paramNew.Name + " already defined with a different type in effect pass " + paramExisting.ShaderInxs[0]); } // List the current pass to use this shader parameter paramExisting.ShaderInxs.Add(i); } else { paramExisting = new EffectParam() { Info = paramNew, ShaderInxs = new List<int>(new int[] {i}), Value = initValue }; _parameters.Add(paramNew.Name, paramExisting); } _paramsPerPass[i].Add(paramExisting); } } } }