/// <summary> /// This event will be fired immediately after the Direct3D device has been /// created, which will happen during application initialization and windowed/full screen /// toggles. This is the best location to create Pool.Managed resources since these /// resources need to be reloaded whenever the device is destroyed. Resources created /// here should be released in the Disposing event. /// </summary> private void OnCreateDevice(object sender, DeviceEventArgs e) { // Initialize the font drawingFont = ResourceCache.GetGlobalInstance().CreateFont(e.Device, 15, 0, FontWeight.Bold, 1, false, CharacterSet.Default, Precision.Default, FontQuality.Default, PitchAndFamily.FamilyDoNotCare | PitchAndFamily.DefaultPitch , "Arial"); // Create the vertex shader and declaration VertexElement[] elements = new VertexElement[] { new VertexElement(0, 0, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.Position, 0), VertexElement.VertexDeclarationEnd }; vertexDecl = new VertexDeclaration(e.Device, elements); // Find the shader file string path = Utility.FindMediaFile("HLSLwithoutEffects.Fx"); // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the // shader debugger. Debugging vertex shaders requires either REF or software vertex // processing, and debugging pixel shaders requires REF. The // ShaderFlags.Force*SoftwareNoOptimizations flag improves the debug experience in the // shader debugger. It enables source level debugging, prevents instruction // reordering, prevents dead code elimination, and forces the compiler to compile // against the next higher available software target, which ensures that the // unoptimized shaders do not exceed the shader model limitations. Setting these // flags will cause slower rendering since the shaders will be unoptimized and // forced into software. See the DirectX documentation for more information about // using the shader debugger. ShaderFlags shaderFlags = ShaderFlags.None; #if (DEBUG_VS) shaderFlags |= ShaderFlags.ForceVertexShaderSoftwareNoOptimizations; #endif #if (DEBUG_PS) shaderFlags |= ShaderFlags.ForcePixelShaderSoftwareNoOptimizations; #endif string errors; using (GraphicsStream code = ShaderLoader.CompileShaderFromFile(path, "Ripple", null, null, "vs_1_1", shaderFlags, out errors, out constantTable)) { // We will store these constants in an effect handle here for performance reasons. // You could simply use the string value (i.e., "worldViewProj") in the SetValue call // and it would work just as well, but that actually requires an allocation to be made // and can actually slow your performance down. It's much more efficient to simply // cache these handles for use later worldViewHandle = constantTable.GetConstant(null, "worldViewProj"); timeHandle = constantTable.GetConstant(null, "appTime"); // Create the shader shader = new VertexShader(e.Device, code); } // Setup the camera's view parameters camera.SetViewQuat(new Quaternion(-0.275f, 0.3f, 0.0f, 0.7f)); }
public void Run(OpsContext context, OpsStatement statement) { ShadeArgs args = statement.Arguments as ShadeArgs; ConstantTable constantTable = SetupDevice(context, args); EffectHandle hTarget = constantTable.GetConstant(null, "Target"); ArrayList containers = statement.GetContent(context); OpsConsole.WriteLine("Shading textures with \"{0}\"", args.File); foreach (OpsTexture container in containers) { if (hTarget != null) { context.Device.SetTexture( constantTable.GetSamplerIndex(hTarget), container.Texture); } if (container.Texture is Texture) { Texture oldTexture = container.Texture as Texture; Texture newTexture = OpsTextureHelper.CloneTexture(oldTexture, Usage.None, Pool.Managed); for (int mip = 0; mip < oldTexture.LevelCount; mip++) { SurfaceDescription sd = oldTexture.GetLevelDescription(mip); CheckFormatValid(sd.Format); Surface rt = context.Device.CreateRenderTarget(sd.Width, sd.Height, sd.Format, MultiSampleType.None, 0, true); context.Device.SetRenderTarget(0, rt); ShadeVertex[] vb = new ShadeVertex[] { ShadeVertex.ForTexture(-1.0f, -1.0f, sd.Width, sd.Height), ShadeVertex.ForTexture(1.0f, -1.0f, sd.Width, sd.Height), ShadeVertex.ForTexture(-1.0f, 1.0f, sd.Width, sd.Height), ShadeVertex.ForTexture(1.0f, 1.0f, sd.Width, sd.Height), }; context.Device.BeginScene(); context.Device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vb); context.Device.EndScene(); context.Device.SetRenderTarget(0, context.Device.GetBackBuffer(0, 0, BackBufferType.Mono)); SurfaceLoader.FromSurface(newTexture.GetSurfaceLevel(mip), rt, Filter.None | (container.SRGB?Filter.SrgbOut:0), 0); } oldTexture.Dispose(); container.Texture = newTexture; } else if (container.Texture is VolumeTexture) { VolumeTexture oldTexture = container.Texture as VolumeTexture; VolumeTexture newTexture = OpsTextureHelper.CloneVolume(oldTexture, Usage.None, Pool.Managed); for (int mip = 0; mip < oldTexture.LevelCount; mip++) { VolumeDescription vd = oldTexture.GetLevelDescription(mip); CheckFormatValid(vd.Format); Surface sliceRT = context.Device.CreateRenderTarget(vd.Width, vd.Height, vd.Format, MultiSampleType.None, 0, true); for (int slice = 0; slice < vd.Depth; slice++) { context.Device.SetRenderTarget(0, sliceRT); ShadeVertex[] vb = new ShadeVertex[] { ShadeVertex.ForVolume(-1.0f, -1.0f, slice, vd.Width, vd.Height, vd.Depth), ShadeVertex.ForVolume(1.0f, -1.0f, slice, vd.Width, vd.Height, vd.Depth), ShadeVertex.ForVolume(-1.0f, 1.0f, slice, vd.Width, vd.Height, vd.Depth), ShadeVertex.ForVolume(1.0f, 1.0f, slice, vd.Width, vd.Height, vd.Depth), }; context.Device.BeginScene(); context.Device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vb); context.Device.EndScene(); context.Device.SetRenderTarget(0, context.Device.GetBackBuffer(0, 0, BackBufferType.Mono)); OpsTextureHelper.LoadVolumeSliceFromSurface(newTexture, mip, slice, Filter.None | (container.SRGB?Filter.SrgbOut:0), sliceRT); } sliceRT.Dispose(); } oldTexture.Dispose(); container.Texture = newTexture; } else if (container.Texture is CubeTexture) { CubeTexture oldTexture = container.Texture as CubeTexture; CubeTexture newTexture = OpsTextureHelper.CloneCube(oldTexture, Usage.None, Pool.Managed); for (int mip = 0; mip < oldTexture.LevelCount; mip++) { SurfaceDescription sd = oldTexture.GetLevelDescription(mip); CheckFormatValid(sd.Format); Surface rt = context.Device.CreateRenderTarget(sd.Width, sd.Height, sd.Format, MultiSampleType.None, 0, true); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.PositiveX, mip, sd.Width, container.SRGB); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.PositiveY, mip, sd.Width, container.SRGB); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.PositiveZ, mip, sd.Width, container.SRGB); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.NegativeX, mip, sd.Width, container.SRGB); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.NegativeY, mip, sd.Width, container.SRGB); RenderCubeMapFace(context, newTexture, rt, CubeMapFace.NegativeZ, mip, sd.Width, container.SRGB); } oldTexture.Dispose(); container.Texture = newTexture; } } }
protected void ProcessParamElement( ConstantTable constantTable, EffectHandle parent, string prefix, int index ) { var constant = constantTable.GetConstant( parent, index ); // Since D3D HLSL doesn't deal with naming of array and struct parameters // automatically, we have to do it by hand var desc = constantTable.GetConstantDescription( constant ); var paramName = desc.Name; // trim the odd '$' which appears at the start of the names in HLSL if ( paramName.StartsWith( "$" ) ) { paramName = paramName.Remove( 0, 1 ); } // Also trim the '[0]' suffix if it exists, we will add our own indexing later if (paramName.EndsWith("[0]")) { paramName.Remove( paramName.Length - 3 ); } if (desc.Class == ParameterClass.Struct) { // work out a new prefix for the nextest members if its an array, we need the index prefix = prefix + paramName + "."; // Cascade into struct for (var i = 0; i < desc.StructMembers; ++i) { ProcessParamElement(constantTable, constant, prefix, i); } } else { // process params if ( desc.Type == ParameterType.Float || desc.Type == ParameterType.Int || desc.Type == ParameterType.Bool ) { var paramIndex = desc.RegisterIndex; var name = prefix + paramName; var def = new GpuProgramParameters.GpuConstantDefinition(); def.LogicalIndex = paramIndex; // populate type, array size & element size PopulateDef( desc, def ); if ( def.IsFloat ) { def.PhysicalIndex = floatLogicalToPhysical.BufferSize; lock ( floatLogicalToPhysical.Mutex ) { floatLogicalToPhysical.Map.Add( paramIndex, new GpuProgramParameters.GpuLogicalIndexUse( def.PhysicalIndex, def.ArraySize*def.ElementSize, GpuProgramParameters.GpuParamVariability.Global ) ); floatLogicalToPhysical.BufferSize += def.ArraySize*def.ElementSize; } } else { def.PhysicalIndex = intLogicalToPhysical.BufferSize; lock ( intLogicalToPhysical.Mutex ) { intLogicalToPhysical.Map.Add( paramIndex, new GpuProgramParameters.GpuLogicalIndexUse( def.PhysicalIndex, def.ArraySize*def.ElementSize, GpuProgramParameters.GpuParamVariability.Global ) ); intLogicalToPhysical.BufferSize += def.ArraySize*def.ElementSize; } } if ( !parametersMap.ContainsKey( paramName ) ) { parametersMap.Add( paramName, def ); /* parametersMapSizeAsBuffer += sizeof ( int ); parametersMapSizeAsBuffer += paramName.Length; parametersMapSizeAsBuffer += Marshal.SizeOf( def ); */ } } } }