Created
June 11, 2015 14:35
-
-
Save attilaz/434e2e8c08f482f71b10 to your computer and use it in GitHub Desktop.
using metal wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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