Skip to content

Instantly share code, notes, and snippets.

@attilaz
Created June 11, 2015 14:35
Show Gist options
  • Save attilaz/434e2e8c08f482f71b10 to your computer and use it in GitHub Desktop.
Save attilaz/434e2e8c08f482f71b10 to your computer and use it in GitHub Desktop.
using metal wrapper
// Interface Orientation
UIInterfaceOrientation mnOrientation;
// Renderer globals
mtl::Device m_Device;
mtl::CommandQueue m_CommandQueue;
mtl::Library m_ShaderLibrary;
mtl::DepthStencilState m_DepthState;
// textured Quad
AAPLTexture *mpInTexture;
mtl::RenderPipelineState m_PipelineState;
// Quad representation
AAPLQuad *mpQuad;
// App control
dispatch_semaphore_t m_InflightSemaphore;
// Dimensions
CGSize m_Size;
// Viewing matrix is derived from an eye point, a reference point
// indicating the center of the scene, and an up vector.
simd::float4x4 m_LookAt;
// Translate the object in (x,y,z) space.
simd::float4x4 m_Translate;
// Quad transform buffers
simd::float4x4 m_Transform;
mtl::Buffer m_TransformBuffer;
// this value will cycle from 0 to kInFlightCommandBuffers whenever a display completes ensuring renderer clients
// can synchronize between kInFlightCommandBuffers count buffers, and thus avoiding a constant buffer from being overwritten between draws
NSUInteger m_ConstantDataBufferIndex;
void configure(AAPLView *view)
{
// find a usable Device
m_Device = mtl::Device(view.device);
view.depthPixelFormat = MTLPixelFormatDepth32Float;
view.stencilPixelFormat = MTLPixelFormatInvalid;
view.sampleCount = 1;
// create a new command queue
m_CommandQueue = m_Device.newCommandQueue();
if(!m_CommandQueue) {
assert(0);
}
m_ShaderLibrary = m_Device.newDefaultLibrary();
if(!m_ShaderLibrary) {
assert(0);
}
// preparePipelineState
// get the fragment function from the library
mtl::Function fragmentProgram = m_ShaderLibrary.newFunctionWithName("texturedQuadFragment");
if(!fragmentProgram)
assert(0);
// get the vertex function from the library
mtl::Function vertexProgram = m_ShaderLibrary.newFunctionWithName("texturedQuadVertex");
if(!vertexProgram)
assert(0);
NSLog(@">> ERROR: Couldn't load vertex function from default library");
// create a pipeline state for the quad
mtl::RenderPipelineDescriptor pQuadPipelineStateDescriptor = mtl::newRenderPipelineDescriptor();
if(!pQuadPipelineStateDescriptor)
{
assert(0);
} // if
pQuadPipelineStateDescriptor.depthAttachmentPixelFormat = view.depthPixelFormat;
pQuadPipelineStateDescriptor.stencilAttachmentPixelFormat = view.stencilPixelFormat;
pQuadPipelineStateDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
pQuadPipelineStateDescriptor.sampleCount = view.sampleCount;
pQuadPipelineStateDescriptor.vertexFunction = vertexProgram;
pQuadPipelineStateDescriptor.fragmentFunction = fragmentProgram;
NSError *pError = nil;
m_PipelineState = m_Device.newRenderPipelineStateWithDescriptor(pQuadPipelineStateDescriptor, &pError);
if(!m_PipelineState)
{
assert(0);
} // if
mtl::DepthStencilDescriptor pDepthStateDesc = mtl::newDepthStencilDescriptor();
if(!pDepthStateDesc)
assert(0);
pDepthStateDesc.depthCompareFunction = MTLCompareFunctionAlways;
pDepthStateDesc.depthWriteEnabled = YES;
m_DepthState = m_Device.newDepthStencilStateWithDescriptor(pDepthStateDesc);
if(!m_DepthState)
assert(0);
//prepareTransformBuffer
// allocate regions of memory for the constant buffer
m_TransformBuffer = m_Device.newBufferWithLength(kSzBufferLimitsPerFrame,0);
if(!m_TransformBuffer)
assert(0);
m_TransformBuffer.label("TransformBuffer");
// Default orientation is unknown
mnOrientation = UIInterfaceOrientationUnknown;
}
void render(AAPLView *view)
{
dispatch_semaphore_wait(m_InflightSemaphore, DISPATCH_TIME_FOREVER);
mtl::CommandBuffer commandBuffer = m_CommandQueue.commandBuffer();
// create a render command encoder so we can render into something
mtl::RenderPassDescriptor renderPassDescriptor = view.renderPassDescriptor;
if (renderPassDescriptor)
{
// Get a render encoder
mtl::RenderCommandEncoder renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
// Encode into a renderer
// set context state with the render encoder
renderEncoder.pushDebugGroup("encode quad");
renderEncoder.setFrontFacingWinding(MTLWindingCounterClockwise);
renderEncoder.setDepthStencilState(m_DepthState);
renderEncoder.setRenderPipelineState(m_PipelineState);
renderEncoder.setVertexBuffer(m_TransformBuffer,0,2);
renderEncoder.setFragmentTexture(mpInTexture.texture, 0);
// Encode quad vertex and texture coordinate buffers
[mpQuad encode:renderEncoder];
// tell the render context we want to draw our primitives
renderEncoder.drawPrimitives(MTLPrimitiveTypeTriangle, 0,6,1);
renderEncoder.endEncoding();
renderEncoder.popDebugGroup();
// Present and commit the command buffer
commandBuffer.presentDrawable(view.currentDrawable);
}
//Dispatch the command buffer
__block dispatch_semaphore_t dispatchSemaphore = m_InflightSemaphore;
[commandBuffer addCompletedHandler:^(id <MTLCommandBuffer> cmdb){
dispatch_semaphore_signal(dispatchSemaphore);
}];
commandBuffer.commit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment