public MetalKitEssentialsSubmesh(MTKSubmesh mtkSubmesh, MDLSubmesh mdlSubmesh, IMTLDevice device)
        {
            materialUniforms = device.CreateBuffer((nuint)Marshal.SizeOf <MaterialUniforms> (), MTLResourceOptions.CpuCacheModeDefault);
            var uniforms = Marshal.PtrToStructure <MaterialUniforms> (materialUniforms.Contents);

            submesh = mtkSubmesh;

            for (nuint i = 0; i < mdlSubmesh.Material.Count; i++)
            {
                MDLMaterialProperty property = ObjectAtIndexedSubscript(mdlSubmesh.Material, i);

                if (property == null)
                {
                    continue;
                }

                if (property.Name == "baseColorMap")
                {
                    if (property.Type != MDLMaterialPropertyType.String)
                    {
                        continue;
                    }

                    var textureURL    = new NSUrl(string.Format("file://{0}", property.StringValue));
                    var textureLoader = new MTKTextureLoader(device);

                    NSError error;
                    diffuseTexture = textureLoader.FromUrl(textureURL, null, out error);

                    if (diffuseTexture == null)
                    {
                        throw new Exception(string.Format("Diffuse texture load: {0}", error.LocalizedDescription));
                    }
                }
                else if (property.Name == "BlinnSpecularColor")
                {
                    if (property.Type == MDLMaterialPropertyType.Float4)
                    {
                        uniforms.specularColor = property.Float4Value;
                    }
                    else if (property.Type == MDLMaterialPropertyType.Float3)
                    {
                        uniforms.specularColor = new Vector4(property.Float3Value);
                    }
                }
                else if (property.Name == "emission")
                {
                    if (property.Type == MDLMaterialPropertyType.Float4)
                    {
                        uniforms.emissiveColor = property.Float4Value;
                    }
                    else if (property.Type == MDLMaterialPropertyType.Float3)
                    {
                        uniforms.emissiveColor = new Vector4(property.Float3Value);
                    }
                }
            }

            Marshal.StructureToPtr(uniforms, materialUniforms.Contents, true);
        }
예제 #2
0
        public static void Update(this IMTLResourceStateCommandEncoder This, IMTLTexture texture, MTLSparseTextureMappingMode mode, MTLRegion[] regions, nuint[] mipLevels, nuint[] slices)
        {
            if (texture == null)
            {
                throw new ArgumentNullException(nameof(texture));
            }
            if (regions == null)
            {
                throw new ArgumentNullException(nameof(regions));
            }
            if (mipLevels == null)
            {
                throw new ArgumentNullException(nameof(mipLevels));
            }
            if (slices == null)
            {
                throw new ArgumentNullException(nameof(slices));
            }

            var regionsHandle   = GCHandle.Alloc(regions, GCHandleType.Pinned);
            var mipLevelsHandle = GCHandle.Alloc(mipLevels, GCHandleType.Pinned);
            var slicesHandle    = GCHandle.Alloc(slices, GCHandleType.Pinned);

            try {
                var regionsPtr   = regionsHandle.AddrOfPinnedObject();
                var mipLevelsPtr = mipLevelsHandle.AddrOfPinnedObject();
                var slicesPtr    = slicesHandle.AddrOfPinnedObject();
                This.Update(texture, mode, regionsPtr, mipLevelsPtr, slicesPtr, (nuint)regions.Length);
            } finally {
                regionsHandle.Free();
                mipLevelsHandle.Free();
                slicesHandle.Free();
            }
        }
예제 #3
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
            {
                renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor();
            }

            renderPassDescriptor.ColorAttachments [0].Texture     = texture;
            renderPassDescriptor.ColorAttachments [0].LoadAction  = MTLLoadAction.Clear;
            renderPassDescriptor.ColorAttachments [0].ClearColor  = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f);
            renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store;

            if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height))
            {
                //  If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
                //  Then allocate one of the proper size
                MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
                if (ObjCRuntime.Runtime.Arch == ObjCRuntime.Arch.SIMULATOR)
                {
                    desc.StorageMode = MTLStorageMode.Private;
                }
                depthTex       = device.CreateTexture(desc);
                depthTex.Label = "Depth";

                renderPassDescriptor.DepthAttachment.Texture     = depthTex;
                renderPassDescriptor.DepthAttachment.LoadAction  = MTLLoadAction.Clear;
                renderPassDescriptor.DepthAttachment.ClearDepth  = 1.0f;
                renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare;
            }
        }
예제 #4
0
        private void PlatformConstruct(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            PixelFormat pixelFormat,
            int width,
            int height,
            TextureMipMapData[] mipMapData)
        {
            var textureDescriptor = MTLTextureDescriptor.CreateTexture2DDescriptor(
                pixelFormat.ToMTLPixelFormat(),
                (nuint)width,
                (nuint)height,
                true); // Ignored, because we'll set the mip level count explicitly below.

            textureDescriptor.Usage = MTLTextureUsage.ShaderRead;

            textureDescriptor.MipmapLevelCount = (nuint)mipMapData.Length;

            _originalPixelFormat = pixelFormat;

            DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(textureDescriptor));

            for (var i = 0; i < mipMapData.Length; i++)
            {
                SetData(
                    i,
                    mipMapData[i].Data,
                    mipMapData[i].BytesPerRow);
            }
        }
예제 #5
0
 public Texture(string name, string extension)
 {
     path         = NSBundle.MainBundle.PathForResource(name, extension);
     Width        = 0;
     Height       = 0;
     MetalTexture = null;
     flip         = true;
 }
		void LoadAssets ()
		{
			var textureLoader = new MTKTextureLoader (metalView.Device);
			NSUrl url = NSBundle.MainBundle.GetUrlForResource ("AnimalImage", "png");

			NSError error;
			sourceTexture = textureLoader.FromUrl (url, null, out error);
		}
예제 #7
0
		public Texture (string name, string extension)
		{
			path = NSBundle.MainBundle.PathForResource (name, extension);
			Width = 0;
			Height = 0;
			MetalTexture = null;
			flip = true;
		}
예제 #8
0
        bool NeedUpdate(IMTLTexture texture, IMTLTexture textureToCompare)
        {
            bool doUpdate = false;

            doUpdate = (textureToCompare.Width != texture.Width) || (textureToCompare.Height != texture.Height) || (textureToCompare.SampleCount != SampleCount);

            return(doUpdate);
        }
        void LoadAssets()
        {
            var   textureLoader = new MTKTextureLoader(metalView.Device);
            NSUrl url           = NSBundle.MainBundle.GetUrlForResource("AnimalImage", "png");

            NSError error;

            sourceTexture = textureLoader.TextureWithContentsOfUrl(url, null, out error);
        }
예제 #10
0
        private void PlatformConstruct(
            GraphicsDevice graphicsDevice,
            PixelFormat pixelFormat,
            int arraySize,
            int width,
            int height,
            TextureBindFlags bindFlags,
            int mipMapCount,
            TextureMipMapData[] mipMapData)
        {
            var descriptor = new MTLTextureDescriptor
            {
                ArrayLength = (nuint) arraySize,
                CpuCacheMode = MTLCpuCacheMode.DefaultCache,
                Depth = 1,
                Height = (nuint) height,
                MipmapLevelCount = (nuint) mipMapCount,
                PixelFormat = pixelFormat.ToMTLPixelFormat(),
                ResourceOptions = MTLResourceOptions.StorageModeManaged,
                SampleCount = 1,
                StorageMode = MTLStorageMode.Managed,
                TextureType = arraySize > 1 ? MTLTextureType.k2DArray : MTLTextureType.k2D,
                Width = (nuint) width,
                Usage = bindFlags.ToMTLTextureUsage()
            };

            DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(descriptor));

            if (mipMapData != null)
            {
                for (var i = 0; i < mipMapData.Length; i++)
                {
                    var mipWidth = CalculateMipMapSize(i, width);
                    var mipHeight = CalculateMipMapSize(i, height);

                    var region = MTLRegion.Create2D(0, 0, mipWidth, mipHeight);

                    var dataHandle = GCHandle.Alloc(mipMapData[i].Data, GCHandleType.Pinned);
                    try
                    {
                        DeviceTexture.ReplaceRegion(
                            region,
                            (nuint) i,
                            dataHandle.AddrOfPinnedObject(),
                            (nuint) mipMapData[i].BytesPerRow);
                    }
                    finally
                    {
                        dataHandle.Free();
                    }
                }
            }
        }
 private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, float clearValue)
 {
     DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(new MTLTextureDescriptor
     {
         ArrayLength      = 1,
         CpuCacheMode     = MTLCpuCacheMode.DefaultCache,
         Depth            = 1,
         Height           = (nuint)height,
         MipmapLevelCount = 1,
         PixelFormat      = MTLPixelFormat.Depth32Float,
         ResourceOptions  = MTLResourceOptions.StorageModePrivate,
         SampleCount      = 1,
         StorageMode      = MTLStorageMode.Private,
         TextureType      = MTLTextureType.k2D,
         Usage            = MTLTextureUsage.RenderTarget,
         Width            = (nuint)width
     }));
 }
예제 #12
0
        bool PrepareCompute()
        {
            NSError error;

            // Create a compute kernel function
            IMTLFunction function = shaderLibrary.CreateFunction("grayscale");

            if (function == null)
            {
                Console.WriteLine("ERROR: Failed creating a new function!");
                return(false);
            }

            // Create a compute kernel
            kernel = device.CreateComputePipelineState(function, out error);
            if (kernel == null)
            {
                Console.WriteLine("ERROR: Failed creating a compute kernel: %@", error.Description);
                return(false);
            }

            MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false);

            if (texDesc == null)
            {
                Console.WriteLine("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!");
                return(false);
            }

            outTexture = device.CreateTexture(texDesc);
            if (outTexture == null)
            {
                Console.WriteLine("ERROR: Failed creating an output 2d texture!");
                return(false);
            }

            // Set the compute kernel's workgroup size and count
            workgroupSize = new MTLSize(1, 1, 1);
            localCount    = new MTLSize((nint)size.Width, (nint)size.Height, 1);
            return(true);
        }
예제 #13
0
        public AmtImageView(MgImageViewCreateInfo pCreateInfo)
        {
            if (pCreateInfo == null)
            {
                throw new ArgumentNullException(nameof(pCreateInfo));
            }


            if (pCreateInfo.Image == null)
            {
                throw new ArgumentNullException(nameof(pCreateInfo.Image));
            }

            var bImage = (AmtImage)pCreateInfo.Image;

            mImageView = bImage.OriginalTexture.CreateTextureView(
                AmtFormatExtensions.GetPixelFormat(pCreateInfo.Format),
                TranslateTextureType(pCreateInfo.ViewType),
                GenerateLevelRange(pCreateInfo.SubresourceRange),
                GenerateSliceRange(pCreateInfo.SubresourceRange));
        }
예제 #14
0
        void Draw(IMTLTexture texture)
        {
            GCHandle pinnedTransform = GCHandle.Alloc(vertexFactory.Vertices.ToArray(), GCHandleType.Pinned);
            IntPtr   ptr             = pinnedTransform.AddrOfPinnedObject();

            pinnedTransform.Free();

            var rstate        = renderPipelineState;
            var commandBuffer = commandQueue.CommandBuffer();
            var currentRenderPassDescriptor = mtkView.CurrentRenderPassDescriptor;
            var encoder = commandBuffer.CreateRenderCommandEncoder(currentRenderPassDescriptor);

            encoder.PushDebugGroup("RenderFrame");
            encoder.SetRenderPipelineState(rstate);
            encoder.SetVertexBytes(ptr, (nuint)vertexFactory.Size(), index: 0);
            encoder.SetFragmentTexture(texture, index: 0);
            encoder.DrawPrimitives(MTLPrimitiveType.TriangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1);
            encoder.PopDebugGroup();
            encoder.EndEncoding();
            commandBuffer.Commit();
        }
        public MetalKitEssentialsSubmesh(MTKSubmesh mtkSubmesh, MDLSubmesh mdlSubmesh, IMTLDevice device)
        {
            materialUniforms = device.CreateBuffer ((nuint)Marshal.SizeOf <MaterialUniforms> (), MTLResourceOptions.CpuCacheModeDefault);
            var uniforms = Marshal.PtrToStructure <MaterialUniforms> (materialUniforms.Contents);
            submesh = mtkSubmesh;

            for (nuint i = 0; i < mdlSubmesh.Material.Count; i++) {
                MDLMaterialProperty property = ObjectAtIndexedSubscript (mdlSubmesh.Material, i);

                if (property == null)
                    continue;

                if (property.Name == "baseColorMap") {

                    if (property.Type != MDLMaterialPropertyType.String)
                        continue;

                    var textureURL = new NSUrl (string.Format ("file://{0}", property.StringValue));
                    var textureLoader = new MTKTextureLoader (device);

                    NSError error;
                    diffuseTexture = textureLoader.FromUrl (textureURL, null, out error);

                    if (diffuseTexture == null)
                        throw new Exception (string.Format ("Diffuse texture load: {0}", error.LocalizedDescription));
                } else if (property.Name == "BlinnSpecularColor") {
                    if (property.Type == MDLMaterialPropertyType.Float4)
                        uniforms.specularColor = property.Float4Value;
                    else if (property.Type == MDLMaterialPropertyType.Float3)
                        uniforms.specularColor = new Vector4 (property.Float3Value);
                } else if (property.Name == "emission") {
                    if(property.Type == MDLMaterialPropertyType.Float4)
                        uniforms.emissiveColor = property.Float4Value;
                    else if (property.Type == MDLMaterialPropertyType.Float3)
                        uniforms.emissiveColor = new Vector4 (property.Float3Value);
                }
            }

            Marshal.StructureToPtr (uniforms, materialUniforms.Contents, true);
        }
예제 #16
0
        public override void Resize()
        {
#if __IOS__
            UIView view   = (UIView)ObjCRuntime.Runtime.GetNSObject(_window);
            nfloat scale  = UIScreen.MainScreen.Scale;
            nfloat width  = view.Bounds.Size.Width * scale;
            nfloat height = view.Bounds.Size.Height * scale;
            _layer.Frame = view.Layer.Frame;
#else
            NSView view   = (NSView)ObjCRuntime.Runtime.GetNSObject(_window);
            nfloat width  = view.Bounds.Size.Width;
            nfloat height = view.Bounds.Size.Height;
#endif
            _layer.DrawableSize = new CGSize(width, height);

            MTLTextureDescriptor descriptor = new MTLTextureDescriptor();
            if (_samples > 1)
            {
                descriptor.TextureType = MTLTextureType.k2DMultisample;
                descriptor.PixelFormat = _layer.PixelFormat;
                descriptor.Width       = (uint)width;
                descriptor.Height      = (uint)height;
                descriptor.SampleCount = _samples;
                IMTLTexture colorAA = _dev.CreateTexture(descriptor);
                _descriptor.ColorAttachments[0].Texture = colorAA;
            }

            descriptor.TextureType = _samples > 1 ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
            descriptor.PixelFormat = MTLPixelFormat.Stencil8;
            descriptor.Width       = (uint)width;
            descriptor.Height      = (uint)height;
            descriptor.SampleCount = _samples;

            IMTLTexture stencil = _dev.CreateTexture(descriptor);
            _descriptor.StencilAttachment.Texture = stencil;
        }
예제 #17
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            mtkView          = (MTKView)View;
            mtkView.Delegate = this;
            mtkView.Device   = device;

            mtkView.SampleCount              = 1;
            mtkView.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            mtkView.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            mtkView.PreferredFramesPerSecond = 60;
            mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("cube_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment");

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();

            vertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[0].BufferIndex = 0;
            vertexDescriptor.Attributes[0].Offset      = 0;
            vertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[1].BufferIndex = 0;
            vertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);
            vertexDescriptor.Attributes[2].Format      = MTLVertexFormat.Float2;
            vertexDescriptor.Attributes[2].BufferIndex = 0;
            vertexDescriptor.Attributes[2].Offset      = 8 * sizeof(float);

            vertexDescriptor.Layouts[0].Stride = 10 * sizeof(float);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0);

            this.clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            this.view = CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY);
            var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);

            proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100);

            constantBuffer = device.CreateBuffer(64, MTLResourceOptions.CpuCacheModeDefault);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat,
            };

            MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0];

            renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat;

            NSError error;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStateDesc = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthState = device.CreateDepthStencilState(depthStateDesc);

            // Texture
            NSImage          image            = NSImage.ImageNamed("crate.png");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.texture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.Repeat,
                TAddressMode = MTLSamplerAddressMode.Repeat,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);
        }
예제 #18
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            mtkView          = (MTKView)View;
            mtkView.Delegate = this;
            mtkView.Device   = device;

            mtkView.SampleCount              = 1;
            mtkView.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            mtkView.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            mtkView.PreferredFramesPerSecond = 60;
            mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction triangleVertexProgram = defaultLibrary.CreateFunction("triangle_vertex");
            IMTLFunction cubeVertexProgram     = defaultLibrary.CreateFunction("cube_vertex");

            // Load the fragment program into the library
            IMTLFunction triangleFragmentProgram = defaultLibrary.CreateFunction("triangle_fragment");
            IMTLFunction cubeFragmentProgram     = defaultLibrary.CreateFunction("cube_fragment");

            // Triangle vertex descriptor
            MTLVertexDescriptor triangleVertexDescriptor = new MTLVertexDescriptor();

            triangleVertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            triangleVertexDescriptor.Attributes[0].BufferIndex = 0;
            triangleVertexDescriptor.Attributes[0].Offset      = 0;
            triangleVertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float4;
            triangleVertexDescriptor.Attributes[1].BufferIndex = 0;
            triangleVertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);

            triangleVertexDescriptor.Layouts[0].Stride       = 8 * sizeof(float);
            triangleVertexDescriptor.Layouts[0].StepRate     = 1;
            triangleVertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            // Cube vertex descriptor
            MTLVertexDescriptor cubeVertexDescriptor = new MTLVertexDescriptor();

            cubeVertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            cubeVertexDescriptor.Attributes[0].BufferIndex = 0;
            cubeVertexDescriptor.Attributes[0].Offset      = 0;
            cubeVertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float2;
            cubeVertexDescriptor.Attributes[1].BufferIndex = 0;
            cubeVertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);

            cubeVertexDescriptor.Layouts[0].Stride       = 6 * sizeof(float);
            cubeVertexDescriptor.Layouts[0].StepRate     = 1;
            cubeVertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            // Create buffers
            triangleVertexBuffer = device.CreateBuffer(triangleVertexData, MTLResourceOptions.CpuCacheModeDefault);
            cubeVertexBuffer     = device.CreateBuffer(cubeVertexData, MTLResourceOptions.CpuCacheModeDefault);

            this.clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            this.view = CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY);
            var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);

            this.proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100);
            this.cubeParameters.WorldViewProjection = Matrix4.Identity;
            cubeConstantBuffer = device.CreateBuffer((uint)Marshal.SizeOf(this.cubeParameters), MTLResourceOptions.CpuCacheModeDefault);

            // Create Pipeline Descriptor
            var trianglePipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = triangleVertexProgram,
                FragmentFunction             = triangleFragmentProgram,
                VertexDescriptor             = triangleVertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat,
            };

            var cubePipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = cubeVertexProgram,
                FragmentFunction             = cubeFragmentProgram,
                VertexDescriptor             = cubeVertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat,
            };

            MTLRenderPipelineColorAttachmentDescriptor triangleRenderBufferAttachment = trianglePipelineStateDescriptor.ColorAttachments[0];

            triangleRenderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat;

            MTLRenderPipelineColorAttachmentDescriptor cubeRenderBufferAttachment = cubePipelineStateDescriptor.ColorAttachments[0];

            cubeRenderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat;

            NSError error;

            trianglePipelineState = device.CreateRenderPipelineState(trianglePipelineStateDescriptor, out error);
            if (trianglePipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            cubePipelineState = device.CreateRenderPipelineState(cubePipelineStateDescriptor, out error);
            if (cubePipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStencilDescriptor = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthStencilState = device.CreateDepthStencilState(depthStencilDescriptor);

            // Texture
            NSImage          image            = NSImage.ImageNamed("crate.png");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.cubeTexture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.Repeat,
                TAddressMode = MTLSamplerAddressMode.Repeat,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);

            // Create FrameBuffer texture
            IMTLTexture          drawableTexture   = mtkView.CurrentDrawable.Texture;
            MTLTextureDescriptor textureDescriptor = new MTLTextureDescriptor()
            {
                Width            = drawableTexture.Width,
                Height           = drawableTexture.Height,
                PixelFormat      = drawableTexture.PixelFormat,
                TextureType      = drawableTexture.TextureType,
                MipmapLevelCount = drawableTexture.MipmapLevelCount,
                ArrayLength      = drawableTexture.ArrayLength,
                SampleCount      = drawableTexture.SampleCount,
                Depth            = drawableTexture.Depth,
                CpuCacheMode     = drawableTexture.CpuCacheMode,
                Usage            = MTLTextureUsage.RenderTarget,
                StorageMode      = MTLStorageMode.Managed,
            };

            this.colorFrameBufferTexture = device.CreateTexture(textureDescriptor);
        }
예제 #19
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
                renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor ();

            renderPassDescriptor.ColorAttachments [0].Texture = texture;
            renderPassDescriptor.ColorAttachments [0].LoadAction = MTLLoadAction.Clear;
            renderPassDescriptor.ColorAttachments [0].ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f);
            renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store;

            if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height)) {
                //  If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
                //  Then allocate one of the proper size
                MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
                depthTex = device.CreateTexture (desc);
                depthTex.Label = "Depth";

                renderPassDescriptor.DepthAttachment.Texture = depthTex;
                renderPassDescriptor.DepthAttachment.LoadAction = MTLLoadAction.Clear;
                renderPassDescriptor.DepthAttachment.ClearDepth = 1.0f;
                renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare;
            }
        }
예제 #20
0
 public AmtImageView(IMTLTexture texture)
 {
     mImageView = texture;
 }
예제 #21
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            mtkView          = (MTKView)View;
            mtkView.Delegate = this;
            mtkView.Device   = device;

            mtkView.SampleCount              = 1;
            mtkView.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            mtkView.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            mtkView.PreferredFramesPerSecond = 60;
            mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("mesh_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("mesh_fragment");

            // Generate meshes
            MTKMeshBufferAllocator mtkBufferAllocator = new MTKMeshBufferAllocator(device);
            NSUrl     url       = NSBundle.MainBundle.GetUrlForResource("Fighter", "obj");
            MDLAsset  mdlAsset  = new MDLAsset(url, new MDLVertexDescriptor(), mtkBufferAllocator);
            MDLObject mdlObject = mdlAsset.GetObject(0);
            MDLMesh   mdlMesh   = mdlObject as MDLMesh;

            NSError error;

            objMesh = new MTKMesh(mdlMesh, device, out error);

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = MTLVertexDescriptor.FromModelIO(objMesh.VertexDescriptor);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            this.clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            this.view = CreateLookAt(new Vector3(0, 1, 2), new Vector3(0, 0, 0), Vector3.UnitY);
            var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);

            this.proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100);

            this.constantBuffer = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat
            };

            pipelineStateDescriptor.ColorAttachments[0].PixelFormat = mtkView.ColorPixelFormat;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStateDesc = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthState = device.CreateDepthStencilState(depthStateDesc);

            NSImage          image            = NSImage.ImageNamed("Fighter_Diffuse.jpg");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.texture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.ClampToEdge,
                TAddressMode = MTLSamplerAddressMode.ClampToEdge,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);
        }
예제 #22
0
        public bool Finalize(IMTLDevice device)
        {
            if (MetalTexture != null)
            {
                return(true);
            }

            UIImage image = UIImage.FromFile(path);

            if (image == null)
            {
                return(false);
            }

            using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB()) {
                if (colorSpace == null)
                {
                    return(false);
                }

                Width  = image.CGImage.Width;
                Height = image.CGImage.Height;

                nuint width    = (nuint)Width;
                nuint height   = (nuint)Height;
                nuint rowBytes = width * 4;

                var context = new CGBitmapContext(IntPtr.Zero,
                                                  (int)width,
                                                  (int)height,
                                                  8,
                                                  (int)rowBytes,
                                                  colorSpace,
                                                  CGImageAlphaInfo.PremultipliedLast);

                if (context == null)
                {
                    return(false);
                }

                var bounds = new CGRect(0f, 0f, width, height);
                context.ClearRect(bounds);

                // Vertical Reflect
                if (flip)
                {
                    context.TranslateCTM(width, height);
                    context.ScaleCTM(-1f, -1f);
                }

                context.DrawImage(bounds, image.CGImage);
                MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, width, height, false);

                if (texDesc == null)
                {
                    return(false);
                }

                MetalTexture = device.CreateTexture(texDesc);

                if (MetalTexture == null)
                {
                    context.Dispose();
                    return(false);
                }

                IntPtr pixels = context.Data;

                if (pixels != IntPtr.Zero)
                {
                    var region = new MTLRegion();
                    region.Origin.X    = 0;
                    region.Origin.Y    = 0;
                    region.Size.Width  = (nint)width;
                    region.Size.Height = (nint)height;

                    MetalTexture.ReplaceRegion(region, 0, pixels, rowBytes);
                }

                context.Dispose();
            }

            return(true);
        }
예제 #23
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            view          = (MTKView)View;
            view.Delegate = this;
            view.Device   = device;

            view.SampleCount              = 1;
            view.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            view.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            view.PreferredFramesPerSecond = 60;
            view.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("quad_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("quad_fragment");

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();

            vertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[0].BufferIndex = 0;
            vertexDescriptor.Attributes[0].Offset      = 0;
            vertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float2;
            vertexDescriptor.Attributes[1].BufferIndex = 0;
            vertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);

            vertexDescriptor.Layouts[0].Stride = 6 * sizeof(float);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            this.vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0);

            this.mipmapping     = 0;
            this.constantBuffer = device.CreateBuffer(sizeof(float), MTLResourceOptions.CpuCacheModeDefault);
            SetConstantBuffer(this.mipmapping, constantBuffer);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = view.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = view.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = view.DepthStencilPixelFormat
            };

            pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat;

            NSError error;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStateDesc = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthState = device.CreateDepthStencilState(depthStateDesc);

            // Texture KTX
            NSUrl            url = NSBundle.MainBundle.GetUrlForResource("crate", "ktx");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error);

            Console.WriteLine("Failed to created pipeline state, error {0}", error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                MipFilter    = MTLSamplerMipFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.ClampToEdge,
                TAddressMode = MTLSamplerAddressMode.ClampToEdge,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);

            this.clock = new System.Diagnostics.Stopwatch();
            this.clock.Start();
            this.time = 0;
        }
예제 #24
0
 internal RenderTarget(GraphicsDevice graphicsDevice, IMTLTexture deviceTexture)
     : base(graphicsDevice)
 {
     DeviceTexture = deviceTexture;
 }
예제 #25
0
 private void PlatformConstruct(GraphicsDevice graphicsDevice, Texture texture)
 {
     DeviceTexture = texture.DeviceTexture;
 }
예제 #26
0
 public void SetTexture(IMTLTexture texture)
 {
     mTexture = texture;
 }
예제 #27
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
            {
                renderPassDescriptor = new MTLRenderPassDescriptor();
            }

            MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0];

            colorAttachment.Texture    = texture;
            colorAttachment.LoadAction = MTLLoadAction.Clear;
            colorAttachment.ClearColor = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f);

            if (SampleCount > 1)
            {
                if (msaaTex == null || NeedUpdate(texture, msaaTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false);
                    desc.TextureType = MTLTextureType.k2DMultisample;
                    desc.SampleCount = SampleCount;
                    msaaTex          = device.CreateTexture(desc);
                }

                colorAttachment.Texture        = msaaTex;
                colorAttachment.ResolveTexture = texture;

                // set store action to resolve in this case
                colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve;
            }
            else
            {
                colorAttachment.StoreAction = MTLStoreAction.Store;
            }

            if (DepthPixelFormat != MTLPixelFormat.Invalid)
            {
                if (depthTex == null || NeedUpdate(texture, depthTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(DepthPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
                    depthAttachment.Texture     = depthTex;
                    depthAttachment.LoadAction  = MTLLoadAction.Clear;
                    depthAttachment.StoreAction = MTLStoreAction.DontCare;
                    depthAttachment.ClearDepth  = 1.0;
                }
            }

            if (StencilPixelFormat != MTLPixelFormat.Invalid)
            {
                if (stencilTex == null || NeedUpdate(texture, stencilTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(StencilPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
                    stencilAttachment.Texture      = depthTex;
                    stencilAttachment.LoadAction   = MTLLoadAction.Clear;
                    stencilAttachment.StoreAction  = MTLStoreAction.DontCare;
                    stencilAttachment.ClearStencil = 1;
                }
            }
        }
예제 #28
0
		bool PrepareCompute ()
		{
			NSError error;

			// Create a compute kernel function
			IMTLFunction function = shaderLibrary.CreateFunction ("grayscale");
			if(function == null) {
				Console.WriteLine ("ERROR: Failed creating a new function!");
				return false;
			}

			// Create a compute kernel
			kernel = device.CreateComputePipelineState (function, out error);
			if(kernel == null) {
				Console.WriteLine ("ERROR: Failed creating a compute kernel: %@", error.Description);
				return false;
			}

			MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false);
			if(texDesc == null) {
				Console.WriteLine ("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!");
				return false;
			}

			outTexture = device.CreateTexture (texDesc);
			if(outTexture == null) {
				Console.WriteLine ("ERROR: Failed creating an output 2d texture!");
				return false;
			}

			// Set the compute kernel's workgroup size and count
			workgroupSize = new MTLSize (1, 1, 1);
			localCount = new MTLSize ((nint)size.Width, (nint)size.Height, 1);
			return true;
		}
예제 #29
0
 public AmtImage(IMTLTexture texture)
 {
     mOriginalTexture = texture;
 }
예제 #30
0
		void SetupRenderPassDescriptorForTexture (IMTLTexture texture)
		{
			if (renderPassDescriptor == null)
				renderPassDescriptor = new MTLRenderPassDescriptor ();

			MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0];
			colorAttachment.Texture = texture;
			colorAttachment.LoadAction = MTLLoadAction.Clear;
			colorAttachment.ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f);

			if (SampleCount > 1) {
				if (msaaTex == null || NeedUpdate (texture, msaaTex)) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false);
					desc.TextureType = MTLTextureType.k2DMultisample;
					desc.SampleCount = SampleCount;
					msaaTex = device.CreateTexture (desc);
				}

				colorAttachment.Texture = msaaTex;
				colorAttachment.ResolveTexture = texture;

				// set store action to resolve in this case
				colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve;
			} else {
				colorAttachment.StoreAction = MTLStoreAction.Store;
			}

			if (DepthPixelFormat != MTLPixelFormat.Invalid && (depthTex == null || NeedUpdate (texture, depthTex))) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (DepthPixelFormat, texture.Width, texture.Height, false);
					desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
					desc.SampleCount = SampleCount;
					depthTex = device.CreateTexture (desc);

					MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
					depthAttachment.Texture = depthTex;
					depthAttachment.LoadAction = MTLLoadAction.Clear;
					depthAttachment.StoreAction = MTLStoreAction.DontCare;
					depthAttachment.ClearDepth = 1.0;
			}

			if (StencilPixelFormat != MTLPixelFormat.Invalid && (stencilTex == null || NeedUpdate (texture, stencilTex))) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (StencilPixelFormat, texture.Width, texture.Height, false);
					desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
					desc.SampleCount = SampleCount;
					stencilTex = device.CreateTexture (desc);

					MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
					stencilAttachment.Texture = stencilTex;
					stencilAttachment.LoadAction = MTLLoadAction.Clear;
					stencilAttachment.StoreAction = MTLStoreAction.DontCare;
					stencilAttachment.ClearStencil = 0;
			}
		}
예제 #31
0
		public bool Finalize (IMTLDevice device)
		{
			if (MetalTexture != null)
				return true;

			UIImage image = UIImage.FromFile (path);

			if (image == null)
				return false;

			using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ()) {

				if (colorSpace == null)
					return false;

				Width = image.CGImage.Width;
				Height = image.CGImage.Height;

				nuint width = (nuint)Width;
				nuint height = (nuint)Height;
				nuint rowBytes = width * 4;

				var context = new CGBitmapContext (IntPtr.Zero,
					              (int)width,
					              (int)height,
					              8,
					              (int)rowBytes,
					              colorSpace,
					              CGImageAlphaInfo.PremultipliedLast);

				if (context == null)
					return false;

				var bounds = new CGRect (0f, 0f, width, height);
				context.ClearRect (bounds);

				// Vertical Reflect
				if (flip) {
					context.TranslateCTM (width, height);
					context.ScaleCTM (-1f, -1f);
				}

				context.DrawImage (bounds, image.CGImage);
				MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, width, height, false);

				if (texDesc == null)
					return false;

				MetalTexture = device.CreateTexture (texDesc);

				if (MetalTexture == null) {
					context.Dispose ();
					return false;
				}

				IntPtr pixels = context.Data;

				if (pixels != IntPtr.Zero) {
					var region = new MTLRegion ();
					region.Origin.X = 0;
					region.Origin.Y = 0;
					region.Size.Width = (nint)width;
					region.Size.Height = (nint)height;

					MetalTexture.ReplaceRegion (region, 0, pixels, rowBytes);
				}

				context.Dispose ();
			}

			return true;
		}
예제 #32
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            mtkView          = (MTKView)View;
            mtkView.Delegate = this;
            mtkView.Device   = device;

            mtkView.SampleCount              = 1;
            mtkView.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            mtkView.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            mtkView.PreferredFramesPerSecond = 60;
            mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("cube_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment");

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();

            vertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[0].BufferIndex = 0;
            vertexDescriptor.Attributes[0].Offset      = 0;
            vertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float3;
            vertexDescriptor.Attributes[1].BufferIndex = 0;
            vertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);
            vertexDescriptor.Attributes[2].Format      = MTLVertexFormat.Float2;
            vertexDescriptor.Attributes[2].BufferIndex = 0;
            vertexDescriptor.Attributes[2].Offset      = 7 * sizeof(float);

            vertexDescriptor.Layouts[0].Stride = 9 * sizeof(float);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            // Primitive
            Torus(1.0f, 0.3f, 28, out List <PositionNormalTexture> vertexData, out List <ushort> indexData);

            vertexBuffer   = device.CreateBuffer(vertexData.ToArray(), MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0);
            indexDataArray = indexData.ToArray();
            indexBuffer    = device.CreateBuffer(indexDataArray, MTLResourceOptions.CpuCacheModeDefault);

            // Use clock
            this.clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            Vector3 cameraPosition = new Vector3(0, 0, 1.5f);

            this.view = CreateLookAt(cameraPosition, new Vector3(0, 0, 0), Vector3.UnitY);
            var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);

            proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100);


            // Constant Buffer
            this.param = new Parameters()
            {
                CameraPosition      = cameraPosition,
                WorldViewProjection = Matrix4.Identity,
                World = Matrix4.Identity,
                WorldInverseTranspose = Matrix4.Identity,
            };

            this.constantBuffer = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = mtkView.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = mtkView.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat,
            };

            MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0];

            renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat;

            NSError error;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStateDesc = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthState = device.CreateDepthStencilState(depthStateDesc);


            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            // Texture
            NSUrl url = NSBundle.MainBundle.GetUrlForResource("cubemap2", "ktx");

            this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error);

            Console.WriteLine("Failed to created pipeline state, error {0}", error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                MipFilter    = MTLSamplerMipFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.ClampToEdge,
                TAddressMode = MTLSamplerAddressMode.ClampToEdge,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);
        }
예제 #33
0
 internal RenderTarget(GraphicsDevice graphicsDevice, IMTLTexture texture)
     : base(graphicsDevice)
 {
     Texture = texture;
 }
예제 #34
0
		bool NeedUpdate (IMTLTexture texture, IMTLTexture textureToCompare)
		{
			bool doUpdate = false;
			doUpdate = (textureToCompare.Width != texture.Width) || (textureToCompare.Height != texture.Height) || (textureToCompare.SampleCount != SampleCount);

			return doUpdate;
		}