rendering rects on iOS
This commit is contained in:
parent
fca5628279
commit
8ca95fbeab
|
@ -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 = "<group>"; };
|
||||
FB239F6A2A51983C0084874D /* IOSAssetManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = IOSAssetManager.mm; sourceTree = "<group>"; };
|
||||
FB239F6E2A519BE00084874D /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = "<group>"; };
|
||||
FBA9A7342A5078B800F960DA /* AssetManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AssetManager.h; path = cpp/AssetManager.h; sourceTree = "<group>"; };
|
||||
FBA9A7352A5078B800F960DA /* Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Font.cpp; path = cpp/Font.cpp; sourceTree = "<group>"; };
|
||||
FBA9A7372A5078B800F960DA /* Hash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Hash.h; path = cpp/Hash.h; sourceTree = "<group>"; };
|
||||
|
@ -127,6 +132,8 @@
|
|||
FBA9A7622A50790A00F960DA /* main.m */,
|
||||
FBA9A76C2A5096C500F960DA /* MetalGfxInterface.h */,
|
||||
FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */,
|
||||
FB239F692A5197830084874D /* IOSAssetManager.h */,
|
||||
FB239F6A2A51983C0084874D /* IOSAssetManager.mm */,
|
||||
);
|
||||
path = m;
|
||||
sourceTree = "<group>";
|
||||
|
@ -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 */,
|
||||
|
|
Binary file not shown.
|
@ -20,5 +20,116 @@
|
|||
landmarkType = "0">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "230CC0C2-A8D1-4213-8AE3-3C387755A129"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "55"
|
||||
endingLineNumber = "55"
|
||||
landmarkName = "-_loadMetalWithView:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "FB626E75-87DB-404F-90BE-27B364652473"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "63"
|
||||
endingLineNumber = "63"
|
||||
landmarkName = "-_loadMetalWithView:"
|
||||
landmarkType = "7">
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "FB626E75-87DB-404F-90BE-27B364652473 - 54c402e8093d4dff"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "-[MetalViewDelegate _loadMetalWithView:]"
|
||||
moduleName = "KDE"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/ronjaenseleit/Documents/KDE/app/src/main/m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "70"
|
||||
endingLineNumber = "70"
|
||||
offsetFromSymbolStart = "132">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "FB626E75-87DB-404F-90BE-27B364652473 - 54c402e8093d4dff"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "-[MetalViewDelegate _loadMetalWithView:]"
|
||||
moduleName = "KDE"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/ronjaenseleit/Documents/KDE/app/src/main/m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "70"
|
||||
endingLineNumber = "70"
|
||||
offsetFromSymbolStart = "116">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "FB626E75-87DB-404F-90BE-27B364652473 - 54c402e8093d4cd4"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "-[MetalViewDelegate _loadMetalWithView:]"
|
||||
moduleName = "KDE"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/ronjaenseleit/Documents/KDE/app/src/main/m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "63"
|
||||
endingLineNumber = "63"
|
||||
offsetFromSymbolStart = "116">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "ABBF5C68-10CF-4FF5-BB6F-D86C5D352BB2"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "cpp/AssetManager.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "20"
|
||||
endingLineNumber = "20"
|
||||
landmarkName = "AssetManager::loadTexture(path, p_texture)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "7C88C504-1B41-4373-879B-61403D971D39"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "m/MetalViewDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "281"
|
||||
endingLineNumber = "281"
|
||||
landmarkName = "-mtkView:drawableSizeWillChange:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -175,6 +175,8 @@ public:
|
|||
KDEStringHandle texture,
|
||||
unsigned int* w,
|
||||
unsigned int* h);
|
||||
|
||||
void* getGfx() { return m_gfx; }
|
||||
|
||||
private:
|
||||
Renderer(void* gfx);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
17
app/src/main/m/IOSAssetManager.h
Normal file
17
app/src/main/m/IOSAssetManager.h
Normal file
|
@ -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
|
35
app/src/main/m/IOSAssetManager.mm
Normal file
35
app/src/main/m/IOSAssetManager.mm
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include "IOSAssetManager.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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));
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "MetalViewDelegate.h"
|
||||
#import <MetalKit/MetalKit.h>
|
||||
|
||||
#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<MTLTexture> texture = (__bridge_transfer id)textureObj;
|
||||
// Texture should be dropped here
|
||||
}
|
||||
|
|
|
@ -20,5 +20,7 @@
|
|||
|
||||
-(void)pushRect:(KDERect)rect withFont:(KDEStringHandle)font withCharHeight:(float)char_height withKey:(KDEStringHandle)key;
|
||||
|
||||
-(nonnull id<MTLTexture>)createTexture:(nonnull const void*)data width:(unsigned int)width height:(unsigned int)height format:(MTLPixelFormat)format;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
//
|
||||
// Renderer.m
|
||||
// KDE
|
||||
//
|
||||
// Created by Ronja Enseleit on 01.07.23.
|
||||
//
|
||||
|
||||
#import <simd/simd.h>
|
||||
#import <ModelIO/ModelIO.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#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 <MTLDevice> _device;
|
||||
id <MTLCommandQueue> _commandQueue;
|
||||
|
||||
|
||||
id <MTLBuffer> _dynamicUniformBuffer[MaxBuffersInFlight];
|
||||
id <MTLRenderPipelineState> _pipelineState;
|
||||
id <MTLDepthStencilState> _depthState;
|
||||
id <MTLTexture> _colorMap;
|
||||
id <MTLTexture> _dummyTexture;
|
||||
MTLVertexDescriptor *_mtlVertexDescriptor;
|
||||
|
||||
uint8_t _uniformBufferIndex;
|
||||
|
||||
matrix_float4x4 _projectionMatrix;
|
||||
|
||||
float _rotation;
|
||||
|
||||
MTKMesh *_mesh;
|
||||
|
||||
vector_float2 _resolution;
|
||||
|
||||
uint8_t _bufferIndex;
|
||||
|
||||
id<MTLBuffer> _vertexBuffers[MaxBuffersInFlight];
|
||||
// In number of rects
|
||||
size_t _vertexBufferCapacities[MaxBuffersInFlight];
|
||||
|
||||
std::vector<KDERect> _drawRects;
|
||||
std::vector<id<MTLTexture>> _drawTextures;
|
||||
|
||||
std::map<KDEStringHandle, Texture> _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<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
|
||||
|
||||
id <MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
|
||||
|
||||
id <MTLFunction> 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 <MTLCommandBuffer> 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 <MTLRenderCommandEncoder> 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<MTLTexture> currentTexture = _drawTextures[0];
|
||||
while (start < rectCount) {
|
||||
for (size_t i = start; i < rectCount; ++i) {
|
||||
id<MTLTexture> 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<MTLTexture>)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<MTLTexture> texture = [_device newTextureWithDescriptor: desc];
|
||||
NSUInteger bytesPerRow = 4 * width;
|
||||
[texture replaceRegion:region mipmapLevel:0 withBytes:data bytesPerRow:bytesPerRow];
|
||||
return texture;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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<half> colorMap [[ texture(TextureIndexColor) ]])
|
||||
texture2d<uint> 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user