private InstanceModelResources CreateInstanceResources() { var instanceResources = new InstanceModelResources(); instanceResources.TransformationBuffer = GraphicsProvider.ResourceFactory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); instanceResources.NodeBuffers = new DeviceBuffer[_loadedResources.GeosetCount]; instanceResources.Pipelines = new Pipeline[_loadedResources.GeosetCount][]; instanceResources.ResourceSets = new ResourceSet[_loadedResources.GeosetCount][]; for (var geoset = 0; geoset < _loadedResources.GeosetCount; geoset++) { instanceResources.NodeBuffers[geoset] = GraphicsProvider.ResourceFactory.CreateBuffer(new BufferDescription( NodeAnimInfo.BlittableSize, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); var material = _loadedResources.Materials[_loadedResources.MaterialIds[geoset]]; var layers = material.Layers; var hasFSFlag = material.RenderMode.HasFlag(MaterialRenderMode.FullResolution); instanceResources.Pipelines[geoset] = new Pipeline[layers.Length]; instanceResources.ResourceSets[geoset] = new ResourceSet[layers.Length]; for (var layer = 0; layer < layers.Length; layer++) { var cachedPipeline = GraphicsProvider.ResourceFactory.GetPipeline(new SimplePipelineDescription { FilterMode = FilterMode.Blend, FaceType = FaceType.Triangles, OutputDescription = GraphicsProvider.GraphicsDevice.SwapchainFramebuffer.OutputDescription, }); instanceResources.Pipelines[geoset][layer] = cachedPipeline.Pipeline; instanceResources.ResourceSets[geoset][layer] = GraphicsProvider.ResourceFactory.CreateResourceSet(new ResourceSetDescription( cachedPipeline.ResourceLayout, hasFSFlag ? GraphicsProvider.FullScreenProjectionBuffer : GraphicsProvider.ProjectionBuffer, hasFSFlag ? GraphicsProvider.FullScreenViewBuffer : GraphicsProvider.ViewBuffer, hasFSFlag ? GraphicsProvider.FullScreenWorldBuffer : GraphicsProvider.WorldBuffer, instanceResources.TransformationBuffer, instanceResources.NodeBuffers[geoset], _sharedResources.Textures[layers[layer].TextureId], GraphicsProvider.GraphicsDevice.Aniso4xSampler)); } } return(instanceResources); }
private void CreateResources(LoadedModelResources?modelResources, string?modelPath) { var isModelCached = _cachedResources.TryGetValue(modelPath ?? string.Empty, out var cachedResources); if (isModelCached) { _loadedResources = cachedResources.LoadedResources; _sharedResources = cachedResources.SharedResources; } else { if (modelResources is null) { using (var modelStream = GraphicsProvider.Path2ModelStream(modelPath)) { if (modelStream is null) { throw new FileNotFoundException(modelPath); } _loadedResources = ModelLoader.LoadModel(modelStream); } } else { _loadedResources = modelResources; } _sharedResources = CreateSharedResources(_loadedResources); if (!string.IsNullOrEmpty(modelPath)) { _cachedResources.Add(modelPath, new CachedModelResources { LoadedResources = _loadedResources, SharedResources = _sharedResources, }); } } _instanceResources = CreateInstanceResources(); }
private InstanceModelResources CreateInstanceResources() { var instanceResources = new InstanceModelResources(); instanceResources.TransformationBuffer = GraphicsProvider.ResourceFactory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); instanceResources.NodeBuffers = new DeviceBuffer[_loadedResources.GeosetCount]; instanceResources.Pipelines = new Pipeline[_loadedResources.GeosetCount][]; instanceResources.ResourceSets = new ResourceSet[_loadedResources.GeosetCount][]; for (var geoset = 0; geoset < _loadedResources.GeosetCount; geoset++) { instanceResources.NodeBuffers[geoset] = GraphicsProvider.ResourceFactory.CreateBuffer(new BufferDescription( NodeAnimInfo.BlittableSize, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); var material = _loadedResources.Materials[_loadedResources.MaterialIds[geoset]]; DeviceBuffer projection, view, world; var modelType = material.RenderMode.HasFlag(MaterialRenderMode.FullResolution) ? ModelType.FullResolution : _modelType; switch (modelType) { case ModelType.Default: case ModelType.Sky: projection = GraphicsProvider.ProjectionBuffer; view = GraphicsProvider.ViewBuffer; world = GraphicsProvider.WorldBuffer; break; case ModelType.FullResolution: projection = GraphicsProvider.FullResolutionProjectionBuffer; view = GraphicsProvider.FullResolutionViewBuffer; world = GraphicsProvider.FullResolutionWorldBuffer; break; case ModelType.UI: projection = GraphicsProvider.UIProjectionBuffer; view = GraphicsProvider.UIViewBuffer; world = GraphicsProvider.UIWorldBuffer; break; default: throw new InvalidEnumArgumentException(nameof(modelType), (int)modelType, typeof(ModelType)); } var layers = material.Layers; instanceResources.Pipelines[geoset] = new Pipeline[layers.Length]; instanceResources.ResourceSets[geoset] = new ResourceSet[layers.Length]; for (var layer = 0; layer < layers.Length; layer++) { var cachedPipeline = GraphicsProvider.ResourceFactory.GetPipeline(new SimplePipelineDescription { FilterMode = layers[layer].FilterMode, FaceType = FaceType.Triangles, LayerShading = layers[layer].ShadingFlags, OutputDescription = GraphicsProvider.GraphicsDevice.SwapchainFramebuffer.OutputDescription, }); instanceResources.Pipelines[geoset][layer] = cachedPipeline.Pipeline; instanceResources.ResourceSets[geoset][layer] = GraphicsProvider.ResourceFactory.CreateResourceSet(new ResourceSetDescription( cachedPipeline.ResourceLayout, projection, view, world, instanceResources.TransformationBuffer, instanceResources.NodeBuffers[geoset], _sharedResources.Textures[layers[layer].TextureId], GraphicsProvider.GraphicsDevice.Aniso4xSampler)); } } return(instanceResources); }
private void CreateResources(LoadedModelResources?modelResources, string?modelPath) { var isModelCached = _cachedResources.TryGetValue(modelPath ?? string.Empty, out var cachedResources); if (isModelCached) { _loadedResources = cachedResources.LoadedResources; _sharedResources = cachedResources.SharedResources; _batch = _modelBatches[cachedResources]; } else { if (modelResources is null) { using (var modelStream = GraphicsProvider.Path2ModelStream(modelPath !)) { if (modelStream is null) { throw new FileNotFoundException(modelPath); } try { _loadedResources = ModelLoader.LoadModel(modelStream); } catch (Exception e) { throw new InvalidDataException($"Unable to load model: {modelPath}", e); } } } else { _loadedResources = modelResources; } _sharedResources = CreateSharedResources(_loadedResources); cachedResources = new CachedModelResources { LoadedResources = _loadedResources, SharedResources = _sharedResources, }; _batch = new ModelBatch { Models = new HashSet <ModelInstance>(), }; _modelBatches.Add(cachedResources, _batch); if (!string.IsNullOrEmpty(modelPath)) { _cachedResources.Add(modelPath, cachedResources); } } _instanceResources = CreateInstanceResources(); _batch.Models.Add(this); }