From 8ca95fbeab949717d3c4824b78229547c0c7f2f3 Mon Sep 17 00:00:00 2001 From: Ronja Enseleit Date: Sun, 2 Jul 2023 18:50:35 +0200 Subject: [PATCH] rendering rects on iOS --- app/src/main/KDE.xcodeproj/project.pbxproj | 10 + .../UserInterfaceState.xcuserstate | Bin 113048 -> 114053 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 111 ++++++ app/src/main/cpp/Renderer.cpp | 3 +- app/src/main/cpp/Renderer.h | 2 + app/src/main/cpp/Texture.cpp | 60 +-- app/src/main/cpp/Texture.h | 6 + app/src/main/m/GameViewController.mm | 6 +- app/src/main/m/IOSAssetManager.h | 17 + app/src/main/m/IOSAssetManager.mm | 35 ++ app/src/main/m/MetalGfxInterface.h | 10 + app/src/main/m/MetalGfxInterface.mm | 17 + app/src/main/m/MetalViewDelegate.h | 2 + app/src/main/m/MetalViewDelegate.mm | 361 +++++++++--------- app/src/main/m/ShaderTypes.h | 16 +- app/src/main/m/Shaders.metal | 56 ++- 16 files changed, 481 insertions(+), 231 deletions(-) create mode 100644 app/src/main/m/IOSAssetManager.h create mode 100644 app/src/main/m/IOSAssetManager.mm diff --git a/app/src/main/KDE.xcodeproj/project.pbxproj b/app/src/main/KDE.xcodeproj/project.pbxproj index 3ec4e07..3764ea9 100644 --- a/app/src/main/KDE.xcodeproj/project.pbxproj +++ b/app/src/main/KDE.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + FB239F6B2A51983C0084874D /* IOSAssetManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = FB239F6A2A51983C0084874D /* IOSAssetManager.mm */; }; + FB239F6F2A519BE00084874D /* assets in Resources */ = {isa = PBXBuildFile; fileRef = FB239F6E2A519BE00084874D /* assets */; }; FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A74F2A50790A00F960DA /* AppDelegate.m */; }; FBA9A7532A50790A00F960DA /* MetalViewDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */; }; FBA9A7562A50790A00F960DA /* GameViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7552A50790A00F960DA /* GameViewController.mm */; }; @@ -27,6 +29,9 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + FB239F692A5197830084874D /* IOSAssetManager.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = IOSAssetManager.h; sourceTree = ""; }; + FB239F6A2A51983C0084874D /* IOSAssetManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = IOSAssetManager.mm; sourceTree = ""; }; + FB239F6E2A519BE00084874D /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; FBA9A7342A5078B800F960DA /* AssetManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AssetManager.h; path = cpp/AssetManager.h; sourceTree = ""; }; FBA9A7352A5078B800F960DA /* Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Font.cpp; path = cpp/Font.cpp; sourceTree = ""; }; FBA9A7372A5078B800F960DA /* Hash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Hash.h; path = cpp/Hash.h; sourceTree = ""; }; @@ -127,6 +132,8 @@ FBA9A7622A50790A00F960DA /* main.m */, FBA9A76C2A5096C500F960DA /* MetalGfxInterface.h */, FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */, + FB239F692A5197830084874D /* IOSAssetManager.h */, + FB239F6A2A51983C0084874D /* IOSAssetManager.mm */, ); path = m; sourceTree = ""; @@ -152,6 +159,7 @@ FBC6DF7A2A50782C00CA10E7 = { isa = PBXGroup; children = ( + FB239F6E2A519BE00084874D /* assets */, FBA9A7462A5078DC00F960DA /* m */, FBA9A7332A50789900F960DA /* cpp */, FBA9A74C2A50790A00F960DA /* Products */, @@ -217,6 +225,7 @@ buildActionMask = 2147483647; files = ( FBA9A7612A50790A00F960DA /* LaunchScreen.storyboard in Resources */, + FB239F6F2A519BE00084874D /* assets in Resources */, FBA9A75E2A50790A00F960DA /* Assets.xcassets in Resources */, FBA9A75C2A50790A00F960DA /* Main.storyboard in Resources */, ); @@ -235,6 +244,7 @@ FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */, FBA9A7762A50A58000F960DA /* Renderer.cpp in Sources */, FBA9A7682A50795000F960DA /* StringRepository.cpp in Sources */, + FB239F6B2A51983C0084874D /* IOSAssetManager.mm in Sources */, FBA9A7702A5098E800F960DA /* MetalGfxInterface.mm in Sources */, FBA9A7532A50790A00F960DA /* MetalViewDelegate.mm in Sources */, FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */, diff --git a/app/src/main/KDE.xcodeproj/project.xcworkspace/xcuserdata/ronjaenseleit.xcuserdatad/UserInterfaceState.xcuserstate b/app/src/main/KDE.xcodeproj/project.xcworkspace/xcuserdata/ronjaenseleit.xcuserdatad/UserInterfaceState.xcuserstate index 20b0ba40aa05c9bd7853aae63a141e01b0136471..75faa96e8c50b0706528a433a221a801bea87175 100644 GIT binary patch literal 114053 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∾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 K|Gz_Si~2ux6fHRb literal 113048 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%0AOG#Mex=atM)P0paUhHdJx67cq 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 K|Gz_z6#jqO>p18D diff --git a/app/src/main/KDE.xcodeproj/xcuserdata/ronjaenseleit.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/app/src/main/KDE.xcodeproj/xcuserdata/ronjaenseleit.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 4c1bb89..e264d4e 100644 --- a/app/src/main/KDE.xcodeproj/xcuserdata/ronjaenseleit.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/app/src/main/KDE.xcodeproj/xcuserdata/ronjaenseleit.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -20,5 +20,116 @@ landmarkType = "0"> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/cpp/Renderer.cpp b/app/src/main/cpp/Renderer.cpp index d1bc815..77ed149 100644 --- a/app/src/main/cpp/Renderer.cpp +++ b/app/src/main/cpp/Renderer.cpp @@ -171,6 +171,7 @@ void Renderer::addFontRect(float x, void Renderer::renderFrame(float width, float height) { + // This is done automatically under iOS and does not require a call. #if defined(_WIN32) || defined(__ANDROID__) openGLGfxRenderFrame((OpenGLGfx*)m_gfx, width, height); #endif @@ -179,7 +180,7 @@ void Renderer::renderFrame(float width, float height) void Renderer::getTextureSize(KDEStringHandle texture, unsigned int* w, unsigned int* h) { #ifdef __APPLE__ - + // TODO #else openGLGfxGetTextureSize((OpenGLGfx*)m_gfx, texture, w, h); #endif diff --git a/app/src/main/cpp/Renderer.h b/app/src/main/cpp/Renderer.h index a45ef14..23bc9f1 100644 --- a/app/src/main/cpp/Renderer.h +++ b/app/src/main/cpp/Renderer.h @@ -175,6 +175,8 @@ public: KDEStringHandle texture, unsigned int* w, unsigned int* h); + + void* getGfx() { return m_gfx; } private: Renderer(void* gfx); diff --git a/app/src/main/cpp/Texture.cpp b/app/src/main/cpp/Texture.cpp index 970e5c1..0db40a6 100644 --- a/app/src/main/cpp/Texture.cpp +++ b/app/src/main/cpp/Texture.cpp @@ -1,5 +1,10 @@ #include "Texture.h" #include "Profiling.h" +#include "Renderer.h" + +#ifdef __APPLE__ +#include "../m/MetalGfxInterface.h" +#endif #if defined(__ANDROID__) || defined(_WIN32) Texture::Texture() : m_texture(0) {} @@ -69,6 +74,35 @@ void Texture::bind() const glBindTexture(GL_TEXTURE_2D, m_texture); } +#else + +Texture::Texture() : m_texture(nullptr) {} + +Texture::Texture(unsigned int width, unsigned int height, const void* data) + : width_px(width), height_px(height) +{ + m_texture = metalGfxCreateTexture(Renderer::ptr->getGfx(), data, width, height, MetalGfxTextureFormat_RGBA); +} + +Texture::Texture(unsigned int width, unsigned int height, const void* data, int dummy) + : width_px(width), height_px(height) +{ + m_texture = metalGfxCreateTexture(Renderer::ptr->getGfx(), data, width, height, MetalGfxTextureFormat_Red); +} + +void Texture::destroy() +{ + metalGfxDestroyTexture(m_texture); + m_texture = nullptr; +} + +void Texture::bind() const +{ + /* This is a no-op under metal? */ +} + +#endif + void Texture::getTextureSize(unsigned int* w, unsigned int* h) { ZoneScoped; @@ -79,29 +113,3 @@ void Texture::getTextureSize(unsigned int* w, unsigned int* h) *h = height_px; } } - -#else - -Texture::Texture() {} - -Texture::Texture(unsigned int width, unsigned int height, const void* data) -{ -} - -Texture::Texture(unsigned int width, unsigned int height, const void* data, int dummy) -{ -} - -void Texture::destroy() -{ -} - -void Texture::bind() const -{ -} - -void Texture::getTextureSize(unsigned int* w, unsigned int* h) -{ -} - -#endif diff --git a/app/src/main/cpp/Texture.h b/app/src/main/cpp/Texture.h index 5b74cf8..7ed370f 100644 --- a/app/src/main/cpp/Texture.h +++ b/app/src/main/cpp/Texture.h @@ -37,9 +37,15 @@ public: unsigned int* w, unsigned int* h); +#ifdef __APPLE__ + void* getObj() { return m_texture; } +#endif + private: #if defined(_WIN32) || defined(__ANDROID__) GLuint m_texture; +#elif defined(__APPLE__) + void* m_texture; #endif int width_px; diff --git a/app/src/main/m/GameViewController.mm b/app/src/main/m/GameViewController.mm index 9656c42..d8469d9 100644 --- a/app/src/main/m/GameViewController.mm +++ b/app/src/main/m/GameViewController.mm @@ -9,6 +9,7 @@ #import "MetalViewDelegate.h" #include "../cpp/Renderer.h" +#include "IOSAssetManager.h" @implementation GameViewController { @@ -33,10 +34,9 @@ return; } + IOSAssetManager::create(); + _renderer = [[MetalViewDelegate alloc] initWithMetalKitView:_view]; - - [_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size]; - _view.delegate = _renderer; Renderer::create((__bridge void*)_renderer); diff --git a/app/src/main/m/IOSAssetManager.h b/app/src/main/m/IOSAssetManager.h new file mode 100644 index 0000000..7d88fd3 --- /dev/null +++ b/app/src/main/m/IOSAssetManager.h @@ -0,0 +1,17 @@ +#ifndef KRIMI_DINNER_ENGINE_IOSAssetManager_h +#define KRIMI_DINNER_ENGINE_IOSAssetManager_h + +#include "../cpp/AssetManager.h" + +class IOSAssetManager : public AssetManager +{ +public: + static void create(); + + bool loadFile(const char* path, FileBuffer* p_file_buffer) override; + + void releaseFileBuffer(FileBuffer& fb) override; + +}; + +#endif diff --git a/app/src/main/m/IOSAssetManager.mm b/app/src/main/m/IOSAssetManager.mm new file mode 100644 index 0000000..22c22ed --- /dev/null +++ b/app/src/main/m/IOSAssetManager.mm @@ -0,0 +1,35 @@ +#include "IOSAssetManager.h" + +#import +#include +#include + +void IOSAssetManager::create() +{ + ptr = new IOSAssetManager; +} + +bool IOSAssetManager::loadFile(const char* path, FileBuffer* p_file_buf) +{ + NSString* search_path = [NSString stringWithUTF8String:path]; + NSString* full_path = [[NSBundle mainBundle] pathForResource:search_path ofType:@"" inDirectory:@"assets"]; + NSData* content = [[NSFileManager defaultManager] contentsAtPath: full_path]; + + NSUInteger length = [content length]; + + void *buf = malloc((size_t)length); + if (!buf) + return false; + [content getBytes: buf length: length]; + p_file_buf->data = buf; + p_file_buf->size = (size_t)length; + p_file_buf->internal = NULL; + + return true; +} + +void IOSAssetManager::releaseFileBuffer(FileBuffer& fb) +{ + free((void*)fb.data); + memset(&fb, 0, sizeof(fb)); +} diff --git a/app/src/main/m/MetalGfxInterface.h b/app/src/main/m/MetalGfxInterface.h index 1a1b4d1..c331431 100644 --- a/app/src/main/m/MetalGfxInterface.h +++ b/app/src/main/m/MetalGfxInterface.h @@ -8,4 +8,14 @@ void metalGfxPushRect(void* metalGfxObj, KDERect rect, KDEStringHandle texture); void metalGfxPushFontRect(void* metalGfxObj, KDERect rect, float char_height, KDEStringHandle font, KDEStringHandle key); +typedef enum MetalGfxTextureFormat +{ + MetalGfxTextureFormat_RGBA, + MetalGfxTextureFormat_Red, +} MetalGfxTextureFormat; + +void* metalGfxCreateTexture(void* metalGfxObj, const void* pixels, unsigned int width, unsigned int height, MetalGfxTextureFormat format); + +void metalGfxDestroyTexture(void* textureObj); + #endif diff --git a/app/src/main/m/MetalGfxInterface.mm b/app/src/main/m/MetalGfxInterface.mm index e5a220a..81c0cac 100644 --- a/app/src/main/m/MetalGfxInterface.mm +++ b/app/src/main/m/MetalGfxInterface.mm @@ -1,5 +1,8 @@ #import #import "MetalViewDelegate.h" +#import + +#import "MetalGfxInterface.h" void metalGfxPushRect(void* metalGfxObj, KDERect rect, KDEStringHandle texture) { @@ -10,3 +13,17 @@ void metalGfxPushFontRect(void* metalGfxObj, KDERect rect, float char_height, KD { [(__bridge id)metalGfxObj pushRect:rect withFont:font withCharHeight:char_height withKey:key]; } + +void* metalGfxCreateTexture(void* metalGfxObj, const void* pixels, unsigned int width, unsigned int height, MetalGfxTextureFormat format) +{ + MTLPixelFormat pxFormat = (format == MetalGfxTextureFormat_RGBA) + ? MTLPixelFormatRGBA8Uint + : MTLPixelFormatR8Uint; + return (__bridge_retained void*)[(__bridge id)metalGfxObj createTexture:pixels width:width height:height format:pxFormat]; +} + +void metalGfxDestroyTexture(void* textureObj) +{ + id texture = (__bridge_transfer id)textureObj; + // Texture should be dropped here +} diff --git a/app/src/main/m/MetalViewDelegate.h b/app/src/main/m/MetalViewDelegate.h index 7b5fc96..2883cfb 100644 --- a/app/src/main/m/MetalViewDelegate.h +++ b/app/src/main/m/MetalViewDelegate.h @@ -20,5 +20,7 @@ -(void)pushRect:(KDERect)rect withFont:(KDEStringHandle)font withCharHeight:(float)char_height withKey:(KDEStringHandle)key; +-(nonnull id)createTexture:(nonnull const void*)data width:(unsigned int)width height:(unsigned int)height format:(MTLPixelFormat)format; + @end diff --git a/app/src/main/m/MetalViewDelegate.mm b/app/src/main/m/MetalViewDelegate.mm index 886a894..54eb417 100644 --- a/app/src/main/m/MetalViewDelegate.mm +++ b/app/src/main/m/MetalViewDelegate.mm @@ -1,12 +1,7 @@ -// -// Renderer.m -// KDE -// -// Created by Ronja Enseleit on 01.07.23. -// - #import #import +#include +#include #import "MetalViewDelegate.h" @@ -14,6 +9,7 @@ #import "ShaderTypes.h" #include "../cpp/Renderer.h" +#include "IOSAssetManager.h" static const NSUInteger MaxBuffersInFlight = 3; @@ -22,20 +18,25 @@ static const NSUInteger MaxBuffersInFlight = 3; dispatch_semaphore_t _inFlightSemaphore; id _device; id _commandQueue; - + id _dynamicUniformBuffer[MaxBuffersInFlight]; id _pipelineState; id _depthState; - id _colorMap; + id _dummyTexture; MTLVertexDescriptor *_mtlVertexDescriptor; - - uint8_t _uniformBufferIndex; - - matrix_float4x4 _projectionMatrix; - - float _rotation; - - MTKMesh *_mesh; + + vector_float2 _resolution; + + uint8_t _bufferIndex; + + id _vertexBuffers[MaxBuffersInFlight]; + // In number of rects + size_t _vertexBufferCapacities[MaxBuffersInFlight]; + + std::vector _drawRects; + std::vector> _drawTextures; + + std::map _textures; } -(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view; @@ -46,7 +47,6 @@ static const NSUInteger MaxBuffersInFlight = 3; _device = view.device; _inFlightSemaphore = dispatch_semaphore_create(MaxBuffersInFlight); [self _loadMetalWithView:view]; - [self _loadAssets]; } return self; @@ -55,35 +55,47 @@ static const NSUInteger MaxBuffersInFlight = 3; - (void)_loadMetalWithView:(nonnull MTKView *)view; { /// Load Metal state objects and initialize renderer dependent view properties - + view.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8; view.colorPixelFormat = MTLPixelFormatBGRA8Unorm_sRGB; view.sampleCount = 1; - + + _resolution = vector2((float)[view drawableSize].width, (float)[view drawableSize].height); + _mtlVertexDescriptor = [[MTLVertexDescriptor alloc] init]; - - _mtlVertexDescriptor.attributes[VertexAttributePosition].format = MTLVertexFormatFloat3; - _mtlVertexDescriptor.attributes[VertexAttributePosition].offset = 0; - _mtlVertexDescriptor.attributes[VertexAttributePosition].bufferIndex = BufferIndexMeshPositions; - - _mtlVertexDescriptor.attributes[VertexAttributeTexcoord].format = MTLVertexFormatFloat2; - _mtlVertexDescriptor.attributes[VertexAttributeTexcoord].offset = 0; - _mtlVertexDescriptor.attributes[VertexAttributeTexcoord].bufferIndex = BufferIndexMeshGenerics; - - _mtlVertexDescriptor.layouts[BufferIndexMeshPositions].stride = 12; - _mtlVertexDescriptor.layouts[BufferIndexMeshPositions].stepRate = 1; - _mtlVertexDescriptor.layouts[BufferIndexMeshPositions].stepFunction = MTLVertexStepFunctionPerVertex; - - _mtlVertexDescriptor.layouts[BufferIndexMeshGenerics].stride = 8; - _mtlVertexDescriptor.layouts[BufferIndexMeshGenerics].stepRate = 1; - _mtlVertexDescriptor.layouts[BufferIndexMeshGenerics].stepFunction = MTLVertexStepFunctionPerVertex; - + + _mtlVertexDescriptor.attributes[VertexAttributeDstP0].format = MTLVertexFormatFloat2; + _mtlVertexDescriptor.attributes[VertexAttributeDstP0].offset = 0; + _mtlVertexDescriptor.attributes[VertexAttributeDstP0].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.attributes[VertexAttributeDstP1].format = MTLVertexFormatFloat2; + _mtlVertexDescriptor.attributes[VertexAttributeDstP1].offset = offsetof(KDERect, dst_p1_x); + _mtlVertexDescriptor.attributes[VertexAttributeDstP1].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.attributes[VertexAttributeSrcP0].format = MTLVertexFormatFloat2; + _mtlVertexDescriptor.attributes[VertexAttributeSrcP0].offset = offsetof(KDERect, src_p0_x); + _mtlVertexDescriptor.attributes[VertexAttributeSrcP0].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.attributes[VertexAttributeSrcP1].format = MTLVertexFormatFloat2; + _mtlVertexDescriptor.attributes[VertexAttributeSrcP1].offset = offsetof(KDERect, src_p1_x); + _mtlVertexDescriptor.attributes[VertexAttributeSrcP1].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.attributes[VertexAttributeColor].format = MTLVertexFormatFloat4; + _mtlVertexDescriptor.attributes[VertexAttributeColor].offset = offsetof(KDERect, r); + _mtlVertexDescriptor.attributes[VertexAttributeColor].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.attributes[VertexAttributeExpandR].format = MTLVertexFormatInt; + _mtlVertexDescriptor.attributes[VertexAttributeExpandR].offset = offsetof(KDERect, expand_r); + _mtlVertexDescriptor.attributes[VertexAttributeExpandR].bufferIndex = BufferIndexRects; + + _mtlVertexDescriptor.layouts[BufferIndexRects].stride = sizeof(KDERect); + _mtlVertexDescriptor.layouts[BufferIndexRects].stepRate = 1; + _mtlVertexDescriptor.layouts[BufferIndexRects].stepFunction = MTLVertexStepFunctionPerInstance; + id defaultLibrary = [_device newDefaultLibrary]; - id vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; - id fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"]; - + MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineStateDescriptor.label = @"MyPipeline"; pipelineStateDescriptor.rasterSampleCount = view.sampleCount; @@ -93,83 +105,39 @@ static const NSUInteger MaxBuffersInFlight = 3; pipelineStateDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; pipelineStateDescriptor.depthAttachmentPixelFormat = view.depthStencilPixelFormat; pipelineStateDescriptor.stencilAttachmentPixelFormat = view.depthStencilPixelFormat; - + NSError *error = NULL; _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error]; if (!_pipelineState) { NSLog(@"Failed to created pipeline state, error %@", error); } - + MTLDepthStencilDescriptor *depthStateDesc = [[MTLDepthStencilDescriptor alloc] init]; depthStateDesc.depthCompareFunction = MTLCompareFunctionLess; - depthStateDesc.depthWriteEnabled = YES; + depthStateDesc.depthWriteEnabled = NO; _depthState = [_device newDepthStencilStateWithDescriptor:depthStateDesc]; - + for(NSUInteger i = 0; i < MaxBuffersInFlight; i++) { _dynamicUniformBuffer[i] = [_device newBufferWithLength:sizeof(Uniforms) options:MTLResourceStorageModeShared]; - + _dynamicUniformBuffer[i].label = @"UniformBuffer"; + + _vertexBufferCapacities[i] = 256; + _vertexBuffers[i] = [_device newBufferWithLength:sizeof(Rect) * _vertexBufferCapacities[i] + options:MTLResourceStorageModeShared]; } - + _commandQueue = [_device newCommandQueue]; + + // Create the dummy texture (1x1 px white) + uint8_t bytes[4] = { 255, 255, 255, 255 }; + _dummyTexture = [self createTexture:bytes width:1 height:1 format:MTLPixelFormatRGBA8Uint]; } -- (void)_loadAssets -{ - /// Load assets into metal objects - - NSError *error; - - MTKMeshBufferAllocator *metalAllocator = [[MTKMeshBufferAllocator alloc] - initWithDevice: _device]; - - MDLMesh *mdlMesh = [MDLMesh newBoxWithDimensions:(vector_float3){4, 4, 4} - segments:(vector_uint3){2, 2, 2} - geometryType:MDLGeometryTypeTriangles - inwardNormals:NO - allocator:metalAllocator]; - - MDLVertexDescriptor *mdlVertexDescriptor = - MTKModelIOVertexDescriptorFromMetal(_mtlVertexDescriptor); - - mdlVertexDescriptor.attributes[VertexAttributePosition].name = MDLVertexAttributePosition; - mdlVertexDescriptor.attributes[VertexAttributeTexcoord].name = MDLVertexAttributeTextureCoordinate; - - mdlMesh.vertexDescriptor = mdlVertexDescriptor; - - _mesh = [[MTKMesh alloc] initWithMesh:mdlMesh - device:_device - error:&error]; - - if(!_mesh || error) - { - NSLog(@"Error creating MetalKit mesh %@", error.localizedDescription); - } - - MTKTextureLoader* textureLoader = [[MTKTextureLoader alloc] initWithDevice:_device]; - - NSDictionary *textureLoaderOptions = - @{ - MTKTextureLoaderOptionTextureUsage : @(MTLTextureUsageShaderRead), - MTKTextureLoaderOptionTextureStorageMode : @(MTLStorageModePrivate) - }; - - _colorMap = [textureLoader newTextureWithName:@"ColorMap" - scaleFactor:1.0 - bundle:nil - options:textureLoaderOptions - error:&error]; - - if(!_colorMap || error) - { - NSLog(@"Error creating texture %@", error.localizedDescription); - } -} - -- (void)_updateGameState +- (NSUInteger)_updateGameState { // Demo code static float x = 1.f; @@ -188,21 +156,27 @@ static const NSUInteger MaxBuffersInFlight = 3; } #endif - Renderer::ptr->addRect(100, 100, 500, 500, 0.3f, 0.3f, 0.3f, 1.f); + Renderer::ptr->addRect(100, 100, 500, 500, 1.f, 1.f, 1.f, 1.f, StringRepository::global->internString("smiley_PNG42.png")); //Renderer::ptr->addRect(m_smiley_pos.x, m_smiley_pos.y, 500, 500, 0.f, x * x, 1.f - x * x, 1.f, m_smiley); + // Upload rects + if (_drawRects.size() > _vertexBufferCapacities[_bufferIndex]) { + size_t newCap = ((_drawRects.size() + 63) / 64) * 64; + _vertexBuffers[_bufferIndex] = [_device newBufferWithLength:sizeof(KDERect) * newCap + options:MTLResourceStorageModeShared]; + _vertexBufferCapacities[_bufferIndex] = newCap; + } + memcpy(_vertexBuffers[_bufferIndex].contents, + _drawRects.data(), + _drawRects.size() * sizeof(KDERect)); + NSUInteger rectCount = (NSUInteger)_drawRects.size(); + _drawRects.clear(); + /// Update any game state before encoding renderint commands to our drawable - Uniforms * uniforms = (Uniforms*)_dynamicUniformBuffer[_uniformBufferIndex].contents; - - uniforms->projectionMatrix = _projectionMatrix; - - vector_float3 rotationAxis = {1, 1, 0}; - matrix_float4x4 modelMatrix = matrix4x4_rotation(_rotation, rotationAxis); - matrix_float4x4 viewMatrix = matrix4x4_translation(0.0, 0.0, -8.0); - - uniforms->modelViewMatrix = matrix_multiply(viewMatrix, modelMatrix); - - _rotation += .01; + Uniforms * uniforms = (Uniforms*)_dynamicUniformBuffer[_bufferIndex].contents; + uniforms->resolution = _resolution; + + return rectCount; } - (void)drawInMTKView:(nonnull MTKView *)view @@ -211,7 +185,7 @@ static const NSUInteger MaxBuffersInFlight = 3; dispatch_semaphore_wait(_inFlightSemaphore, DISPATCH_TIME_FOREVER); - _uniformBufferIndex = (_uniformBufferIndex + 1) % MaxBuffersInFlight; + _bufferIndex = (_bufferIndex + 1) % MaxBuffersInFlight; id commandBuffer = [_commandQueue commandBuffer]; commandBuffer.label = @"MyCommand"; @@ -222,8 +196,8 @@ static const NSUInteger MaxBuffersInFlight = 3; dispatch_semaphore_signal(block_sema); }]; - [self _updateGameState]; - + NSUInteger rectCount = [self _updateGameState]; + /// Delay getting the currentRenderPassDescriptor until absolutely needed. This avoids /// holding onto the drawable and blocking the display pipeline any longer than necessary MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor; @@ -231,55 +205,72 @@ static const NSUInteger MaxBuffersInFlight = 3; if(renderPassDescriptor != nil) { /// Final pass rendering code here - id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; renderEncoder.label = @"MyRenderEncoder"; - [renderEncoder pushDebugGroup:@"DrawBox"]; + [renderEncoder pushDebugGroup:@"DrawRects"]; [renderEncoder setFrontFacingWinding:MTLWindingCounterClockwise]; - [renderEncoder setCullMode:MTLCullModeBack]; + [renderEncoder setCullMode:MTLCullModeNone]; [renderEncoder setRenderPipelineState:_pipelineState]; [renderEncoder setDepthStencilState:_depthState]; - [renderEncoder setVertexBuffer:_dynamicUniformBuffer[_uniformBufferIndex] + [renderEncoder setVertexBuffer:_dynamicUniformBuffer[_bufferIndex] offset:0 atIndex:BufferIndexUniforms]; - [renderEncoder setFragmentBuffer:_dynamicUniformBuffer[_uniformBufferIndex] + [renderEncoder setFragmentBuffer:_dynamicUniformBuffer[_bufferIndex] offset:0 atIndex:BufferIndexUniforms]; - for (NSUInteger bufferIndex = 0; bufferIndex < _mesh.vertexBuffers.count; bufferIndex++) - { - MTKMeshBuffer *vertexBuffer = _mesh.vertexBuffers[bufferIndex]; - if((NSNull*)vertexBuffer != [NSNull null]) - { - [renderEncoder setVertexBuffer:vertexBuffer.buffer - offset:vertexBuffer.offset - atIndex:bufferIndex]; + [renderEncoder setVertexBuffer:_vertexBuffers[_bufferIndex] + offset:0 + atIndex:BufferIndexRects]; + + size_t start = 0; + id currentTexture = _drawTextures[0]; + while (start < rectCount) { + for (size_t i = start; i < rectCount; ++i) { + id texture = _drawTextures[i]; + if (texture != currentTexture) { + size_t count = i - start; + [renderEncoder setFragmentTexture:currentTexture + atIndex:TextureIndexColor]; + + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:6 + instanceCount:count + baseInstance:start]; + start = i; + currentTexture = texture; + break; + } + else if (i == rectCount - 1) { + // just draw it + const size_t count = rectCount - start; + [renderEncoder setFragmentTexture:currentTexture + atIndex:TextureIndexColor]; + + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:6 + instanceCount:count + baseInstance:start]; + start = rectCount; + break; + } } } - - [renderEncoder setFragmentTexture:_colorMap - atIndex:TextureIndexColor]; - - for(MTKSubmesh *submesh in _mesh.submeshes) - { - [renderEncoder drawIndexedPrimitives:submesh.primitiveType - indexCount:submesh.indexCount - indexType:submesh.indexType - indexBuffer:submesh.indexBuffer.buffer - indexBufferOffset:submesh.indexBuffer.offset]; - } - + [renderEncoder popDebugGroup]; [renderEncoder endEncoding]; [commandBuffer presentDrawable:view.currentDrawable]; } + _drawTextures.clear(); [commandBuffer commit]; } @@ -287,62 +278,66 @@ static const NSUInteger MaxBuffersInFlight = 3; - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size { /// Respond to drawable size or orientation changes here - - float aspect = size.width / (float)size.height; - _projectionMatrix = matrix_perspective_right_hand(65.0f * (M_PI / 180.0f), aspect, 0.1f, 100.0f); + _resolution.x = (float)size.width; + _resolution.y = (float)size.height; } - (void)pushRect:(KDERect)rect withTexture:(KDEStringHandle)texture { - // TODO + Texture tex; + if (texture != 0) { + if (_textures.find(texture) == _textures.end()) { + if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) { + NSLog(@"Failed to load a texture"); + return; + } + _textures.insert(std::make_pair(texture, tex)); + } + else { + tex = _textures[texture]; + } + _drawTextures.push_back((__bridge id)tex.getObj()); + } + else { + _drawTextures.push_back(_dummyTexture); + } + _drawRects.push_back(rect); } - (void)pushRect:(KDERect)rect withFont:(KDEStringHandle)font withCharHeight:(float)char_height withKey:(KDEStringHandle)key { - // TODO + Texture tex; + if (key != 0) { + if (_textures.find(key) == _textures.end()) { + if (!AssetManager::ptr->loadFontBitmap(StringRepository::global->getString(font), char_height, &tex)) { + NSLog(@"Failed to load font"); + return; + } + _textures.insert(std::make_pair(key, tex)); + } + else { + tex = _textures[key]; + } + _drawTextures.push_back((__bridge id)tex.getObj()); + } + else { + _drawTextures.push_back(_dummyTexture); + } + _drawRects.push_back(rect); } -#pragma mark Matrix Math Utilities -matrix_float4x4 matrix4x4_translation(float tx, float ty, float tz) +-(id)createTexture:(nonnull const void*)data width:(unsigned int)width height:(unsigned int)height format:(MTLPixelFormat)format; { - return (matrix_float4x4) {{ - { 1, 0, 0, 0 }, - { 0, 1, 0, 0 }, - { 0, 0, 1, 0 }, - { tx, ty, tz, 1 } - }}; -} - -static matrix_float4x4 matrix4x4_rotation(float radians, vector_float3 axis) -{ - axis = vector_normalize(axis); - float ct = cosf(radians); - float st = sinf(radians); - float ci = 1 - ct; - float x = axis.x, y = axis.y, z = axis.z; - - return (matrix_float4x4) {{ - { ct + x * x * ci, y * x * ci + z * st, z * x * ci - y * st, 0}, - { x * y * ci - z * st, ct + y * y * ci, z * y * ci + x * st, 0}, - { x * z * ci + y * st, y * z * ci - x * st, ct + z * z * ci, 0}, - { 0, 0, 0, 1} - }}; -} - -matrix_float4x4 matrix_perspective_right_hand(float fovyRadians, float aspect, float nearZ, float farZ) -{ - float ys = 1 / tanf(fovyRadians * 0.5); - float xs = ys / aspect; - float zs = farZ / (nearZ - farZ); - - return (matrix_float4x4) {{ - { xs, 0, 0, 0 }, - { 0, ys, 0, 0 }, - { 0, 0, zs, -1 }, - { 0, 0, nearZ * zs, 0 } - }}; + MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format width:(NSUInteger)width height:(NSUInteger)height mipmapped:NO]; + + MTLRegion region = { {0, 0, 0}, {width, height, 1}}; + + id texture = [_device newTextureWithDescriptor: desc]; + NSUInteger bytesPerRow = 4 * width; + [texture replaceRegion:region mipmapLevel:0 withBytes:data bytesPerRow:bytesPerRow]; + return texture; } @end diff --git a/app/src/main/m/ShaderTypes.h b/app/src/main/m/ShaderTypes.h index ddd9121..c60491c 100644 --- a/app/src/main/m/ShaderTypes.h +++ b/app/src/main/m/ShaderTypes.h @@ -23,15 +23,18 @@ typedef NSInteger EnumBackingType; typedef NS_ENUM(EnumBackingType, BufferIndex) { - BufferIndexMeshPositions = 0, - BufferIndexMeshGenerics = 1, - BufferIndexUniforms = 2 + BufferIndexRects = 0, + BufferIndexUniforms = 1 }; typedef NS_ENUM(EnumBackingType, VertexAttribute) { - VertexAttributePosition = 0, - VertexAttributeTexcoord = 1, + VertexAttributeDstP0 = 0, + VertexAttributeDstP1 = 1, + VertexAttributeSrcP0 = 2, + VertexAttributeSrcP1 = 3, + VertexAttributeColor = 4, + VertexAttributeExpandR = 5 }; typedef NS_ENUM(EnumBackingType, TextureIndex) @@ -41,8 +44,7 @@ typedef NS_ENUM(EnumBackingType, TextureIndex) typedef struct { - matrix_float4x4 projectionMatrix; - matrix_float4x4 modelViewMatrix; + vector_float2 resolution; } Uniforms; #endif /* ShaderTypes_h */ diff --git a/app/src/main/m/Shaders.metal b/app/src/main/m/Shaders.metal index 1fb5a73..68ace7f 100644 --- a/app/src/main/m/Shaders.metal +++ b/app/src/main/m/Shaders.metal @@ -17,37 +17,71 @@ using namespace metal; typedef struct { - float3 position [[attribute(VertexAttributePosition)]]; - float2 texCoord [[attribute(VertexAttributeTexcoord)]]; + float2 dstP0 [[attribute(VertexAttributeDstP0)]]; + float2 dstP1 [[attribute(VertexAttributeDstP1)]]; + float2 srcP0 [[attribute(VertexAttributeSrcP0)]]; + float2 srcP1 [[attribute(VertexAttributeSrcP1)]]; + float4 color [[attribute(VertexAttributeColor)]]; + int expandR [[attribute(VertexAttributeExpandR)]]; } Vertex; typedef struct { float4 position [[position]]; + float4 color; float2 texCoord; + int expandR; } ColorInOut; +constant float2 vertices[6] = { + {-1.0, -1.0}, + {+1.0, -1.0}, + {-1.0, +1.0}, + {+1.0, -1.0}, + {+1.0, +1.0}, + {-1.0, +1.0} +}; + vertex ColorInOut vertexShader(Vertex in [[stage_in]], - constant Uniforms & uniforms [[ buffer(BufferIndexUniforms) ]]) + constant Uniforms & uniforms [[ buffer(BufferIndexUniforms) ]], + uint vertex_id [[vertex_id]]) { ColorInOut out; - - float4 position = float4(in.position, 1.0); - out.position = uniforms.projectionMatrix * uniforms.modelViewMatrix * position; - out.texCoord = in.texCoord; - + + float2 v = vertices[vertex_id]; + + float2 dstHalfSize = (in.dstP1 - in.dstP0) / 2.0; + float2 dstCenter = (in.dstP0 + in.dstP1) / 2.0; + float2 dstPos = v * dstHalfSize + dstCenter; + //dstPos.y = uniforms.resolution.y - dstPos.y; + out.position = float4(2.0 * (dstPos.x / uniforms.resolution.x) - 1.0, + 2.0 * (dstPos.y / uniforms.resolution.y) - 1.0, + 0.0, + 1.0); + out.color = in.color; + out.position.y *= -1.0; + + float2 srcHalfSize = (in.srcP1 - in.srcP0) / 2.0; + float2 srcCenter = (in.srcP0 + in.srcP1) / 2.0; + float2 srcPos = v * srcHalfSize + srcCenter; + out.texCoord = srcPos; + out.expandR = in.expandR; + return out; } fragment float4 fragmentShader(ColorInOut in [[stage_in]], constant Uniforms & uniforms [[ buffer(BufferIndexUniforms) ]], - texture2d colorMap [[ texture(TextureIndexColor) ]]) + texture2d colorMap [[ texture(TextureIndexColor) ]]) { constexpr sampler colorSampler(mip_filter::linear, mag_filter::linear, min_filter::linear); - half4 colorSample = colorMap.sample(colorSampler, in.texCoord.xy); + float4 colorSample = float4(colorMap.sample(colorSampler, in.texCoord.xy)) / 255.0 * in.color; - return float4(colorSample); + if (in.expandR == 1) + colorSample = colorSample.rrrr; + + return colorSample; }