private void initCommon() { setOpaque(true); setBackgroundColor(null); metalLayer = (CAMetalLayer) getLayer(); device = MTLDevice.getSystemDefaultDevice(); metalLayer.setDevice(device); metalLayer.setPixelFormat(MTLPixelFormat.BGRA8Unorm); // this is the default but if we wanted to perform compute on the final // rendering layer we could set this to false metalLayer.setFramebufferOnly(true); }
public void setupRenderPassDescriptor(MTLTexture texture) { // create lazily if (renderPassDescriptor == null) { renderPassDescriptor = new MTLRenderPassDescriptor(); } // create a color attachment every frame since we have to recreate the // texture every frame MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.getColorAttachments().get(0); colorAttachment.setTexture(texture); // make sure to clear every frame for best performance colorAttachment.setLoadAction(MTLLoadAction.Clear); colorAttachment.setClearColor(new MTLClearColor(0.65, 0.65, 0.65, 1.0)); // if sample count is greater than 1, render into using MSAA, then // resolve into our color texture if (sampleCount > 1) { boolean doUpdate = msaaTex != null && ((msaaTex.getWidth() != texture.getWidth()) || (msaaTex.getHeight() != texture.getHeight()) || (msaaTex.getSampleCount() != sampleCount)); if (msaaTex == null || (msaaTex != null && doUpdate)) { MTLTextureDescriptor desc = MTLTextureDescriptor.create2DDescriptor( MTLPixelFormat.BGRA8Unorm, texture.getWidth(), texture.getHeight(), false); desc.setTextureType(MTLTextureType._2DMultisample); // sample count was specified to the view by the renderer. // this must match the sample count given to any pipeline state // using this render pass descriptor desc.setSampleCount(sampleCount); msaaTex = device.newTexture(desc); } // When multisampling, perform rendering to _msaaTex, then resolve // to 'texture' at the end of the scene colorAttachment.setTexture(msaaTex); colorAttachment.setResolveTexture(texture); // set store action to resolve in this case colorAttachment.setStoreAction(MTLStoreAction.MultisampleResolve); } else { // store only attachments that will be presented to the screen, as // in this case colorAttachment.setStoreAction(MTLStoreAction.Store); } // color0 // Now create the depth and stencil attachments if (depthPixelFormat != MTLPixelFormat.Invalid) { boolean doUpdate = depthTex != null && ((depthTex.getWidth() != texture.getWidth()) || (depthTex.getHeight() != texture.getHeight()) || (depthTex.getSampleCount() != sampleCount)); if (depthTex == null || doUpdate) { // 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.create2DDescriptor( depthPixelFormat, texture.getWidth(), texture.getHeight(), false); desc.setTextureType((sampleCount > 1) ? MTLTextureType._2DMultisample : MTLTextureType._2D); desc.setSampleCount(sampleCount); depthTex = device.newTexture(desc); MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.getDepthAttachment(); depthAttachment.setTexture(depthTex); depthAttachment.setLoadAction(MTLLoadAction.Clear); depthAttachment.setStoreAction(MTLStoreAction.DontCare); depthAttachment.setClearDepth(1.0); } } // depth if (stencilPixelFormat != MTLPixelFormat.Invalid) { boolean doUpdate = stencilTex != null && ((stencilTex.getWidth() != texture.getWidth()) || (stencilTex.getHeight() != texture.getHeight()) || (stencilTex.getSampleCount() != sampleCount)); if (stencilTex == null || doUpdate) { // If we need a stencil 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.create2DDescriptor( stencilPixelFormat, texture.getWidth(), texture.getHeight(), false); desc.setTextureType((sampleCount > 1) ? MTLTextureType._2DMultisample : MTLTextureType._2D); desc.setSampleCount(sampleCount); stencilTex = device.newTexture(desc); MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.getStencilAttachment(); stencilAttachment.setTexture(stencilTex); stencilAttachment.setLoadAction(MTLLoadAction.Clear); stencilAttachment.setStoreAction(MTLStoreAction.DontCare); stencilAttachment.setClearStencil(0); } } // stencil }