refactor iOS

added mfb_set_resize_callback to iOS
minor fixes on iOS & MacOS X
This commit is contained in:
Carlos Aragones 2020-05-17 18:31:00 +02:00
parent 6a96ceb1f5
commit 2be0d5a7e0
9 changed files with 158 additions and 79 deletions

View File

@ -44,6 +44,8 @@ set(SrcMacOSX
set(SrcIOS
src/ios/WindowData_IOS.h
src/ios/iOSMiniFB.m
src/ios/iOSView.h
src/ios/iOSView.m
src/ios/iOSViewController.h
src/ios/iOSViewController.m
src/ios/iOSViewDelegate.h

View File

@ -223,6 +223,7 @@ bool mfb_set_viewport(struct mfb_window *window, unsigned offset_
void mfb_set_mouse_button_callback(struct mfb_window *window, mfb_mouse_button_func callback);
void mfb_set_mouse_move_callback(struct mfb_window *window, mfb_mouse_move_func callback);
void mfb_set_resize_callback(struct mfb_window *window, mfb_resize_func callback);
unsigned mfb_get_window_width(struct mfb_window *window);
unsigned mfb_get_window_height(struct mfb_window *window);

View File

@ -9,6 +9,5 @@ typedef struct Vertex {
} Vertex;
typedef struct {
id<MTLCommandQueue> command_queue;
id<MTLRenderPipelineState> pipeline_state;
Vertex vertices[4];
} SWindowData_IOS;

View File

@ -13,14 +13,26 @@ create_window_data(unsigned width, unsigned height) {
SWindowData *window_data;
window_data = malloc(sizeof(SWindowData));
if(window_data == 0x0) {
NSLog(@"Cannot allocate window data");
return 0x0;
}
memset(window_data, 0, sizeof(SWindowData));
SWindowData_IOS *window_data_ios = malloc(sizeof(SWindowData_IOS));
if(window_data_ios == 0x0) {
free(window_data);
NSLog(@"Cannot allocate ios window data");
return 0x0;
}
memset((void *) window_data_ios, 0, sizeof(SWindowData_IOS));
window_data->specific = window_data_ios;
window_data->window_width = [UIScreen mainScreen].bounds.size.width;
window_data->window_height = [UIScreen mainScreen].bounds.size.height;
float scale = [UIScreen mainScreen].scale;
window_data->specific = window_data_ios;
window_data->window_width = [UIScreen mainScreen].bounds.size.width * scale;
window_data->window_height = [UIScreen mainScreen].bounds.size.height * scale;
window_data->dst_width = width;
window_data->dst_height = height;
@ -29,8 +41,10 @@ create_window_data(unsigned width, unsigned height) {
window_data->buffer_height = height;
window_data->buffer_stride = width * 4;
window_data->draw_buffer = malloc(width * height * 4);
window_data->draw_buffer = malloc(width * height * 4);
if (!window_data->draw_buffer) {
free(window_data);
free(window_data_ios);
NSLog(@"Unable to create draw buffer");
return 0x0;
}
@ -47,6 +61,10 @@ mfb_open(const char *title, unsigned width, unsigned height) {
//-------------------------------------
struct mfb_window *
mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) {
UIWindow *window;
NSArray *windows;
size_t numWindows;
kUnused(title);
kUnused(flags);
@ -54,10 +72,15 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
if (window_data == 0x0) {
return 0x0;
}
UIWindow *window;
NSArray *windows;
size_t numWindows;
SWindowData_IOS *window_data_ios = (SWindowData_IOS *) window_data->specific;
static Vertex s_vertices[4] = {
{-1.0, -1.0, 0, 1},
{-1.0, 1.0, 0, 1},
{ 1.0, -1.0, 0, 1},
{ 1.0, 1.0, 0, 1},
};
memcpy(window_data_ios->vertices, s_vertices, sizeof(s_vertices));
windows = [[UIApplication sharedApplication] windows];
numWindows = [windows count];
@ -130,6 +153,7 @@ mfb_update(struct mfb_window *window, void *buffer) {
//-------------------------------------
mfb_update_state
mfb_update_events(struct mfb_window *window) {
kUnused(window);
return STATE_OK;
}
@ -138,12 +162,11 @@ extern double g_time_for_frame;
bool
mfb_wait_sync(struct mfb_window *window) {
kUnused(window);
return true;
}
//-------------------------------------
extern Vertex g_vertices[4];
bool
mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) {
SWindowData *window_data = (SWindowData *) window;
@ -165,17 +188,19 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y
float y1 = ((float) offset_y / window_data->window_height) * 2.0f - 1.0f;
float y2 = (((float) offset_y + height) / window_data->window_height) * 2.0f - 1.0f;
g_vertices[0].x = x1;
g_vertices[0].y = y1;
SWindowData_IOS *window_data_ios = (SWindowData_IOS *) window_data->specific;
g_vertices[1].x = x1;
g_vertices[1].y = y2;
window_data_ios->vertices[0].x = x1;
window_data_ios->vertices[0].y = y1;
g_vertices[2].x = x2;
g_vertices[2].y = y1;
window_data_ios->vertices[1].x = x1;
window_data_ios->vertices[1].y = y2;
g_vertices[3].x = x2;
g_vertices[3].y = y2;
window_data_ios->vertices[2].x = x2;
window_data_ios->vertices[2].y = y1;
window_data_ios->vertices[3].x = x2;
window_data_ios->vertices[3].y = y2;
return true;
}

View File

@ -8,13 +8,15 @@
#import <MetalKit/MetalKit.h>
#include "WindowData.h"
#include "WindowData_IOS.h"
// Our platform independent renderer class.
// Implements the MTKViewDelegate protocol which allows it to accept per-frame
// update and drawable resize callbacks.
@interface iOSViewDelegate : NSObject <MTKViewDelegate>
{
@public SWindowData *window_data;
@public SWindowData *window_data;
@public SWindowData_IOS *window_data_ios;
}
-(nonnull instancetype) initWithMetalKitView:(nonnull MTKView *) view windowData:(nonnull SWindowData *) windowData;

View File

@ -13,6 +13,7 @@
#include "WindowData_IOS.h"
#include <MiniFB.h>
#include <MiniFB_ios.h>
#include <MiniFB_internal.h>
//-------------------------------------
#define kShader(inc, src) @inc#src
@ -23,14 +24,6 @@ enum { MaxBuffersInFlight = 3 }; // Number of textures in flight (tripple buf
id<MTLDevice> g_metal_device = nil;
id<MTLLibrary> g_library = nil;
//--
Vertex g_vertices[4] = {
{-1.0, -1.0, 0, 1},
{-1.0, 1.0, 0, 1},
{ 1.0, -1.0, 0, 1},
{ 1.0, 1.0, 0, 1},
};
//--
NSString *g_shader_src = kShader(
"#include <metal_stdlib>\n",
@ -87,14 +80,15 @@ NSString *g_shader_src = kShader(
-(nonnull instancetype) initWithMetalKitView:(nonnull MTKView *) view windowData:(nonnull SWindowData *) windowData {
self = [super init];
if (self) {
self->window_data = windowData;
g_metal_device = view.device;
self->window_data = windowData;
self->window_data_ios = (SWindowData_IOS *) windowData->specific;
view.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
view.sampleCount = 1;
view.sampleCount = 1;
m_semaphore = dispatch_semaphore_create(MaxBuffersInFlight);
g_metal_device = view.device;
m_semaphore = dispatch_semaphore_create(MaxBuffersInFlight);
m_command_queue = [g_metal_device newCommandQueue];
[self _createShaders];
@ -157,8 +151,7 @@ NSString *g_shader_src = kShader(
}
//-------------------------------------
- (void) drawInMTKView:(nonnull MTKView *) view
{
- (void) drawInMTKView:(nonnull MTKView *) view {
// Per frame updates here
dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER);
@ -189,7 +182,7 @@ NSString *g_shader_src = kShader(
// Set render command encoder state
[renderEncoder setRenderPipelineState:m_pipeline_state];
[renderEncoder setVertexBytes:g_vertices length:sizeof(g_vertices) atIndex:0];
[renderEncoder setVertexBytes:window_data_ios->vertices length:sizeof(window_data_ios->vertices) atIndex:0];
//[renderEncoder setFragmentTexture:m_texture_buffers[m_current_buffer] atIndex:0];
[renderEncoder setFragmentTexture:m_texture_buffer atIndex:0];
@ -211,6 +204,10 @@ NSString *g_shader_src = kShader(
//-------------------------------------
- (void) mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
// Respond to drawable size or orientation changes here
window_data->window_width = size.width;
window_data->window_height = size.height;
kCall(resize_func, size.width, size.height);
}
@end

View File

@ -120,18 +120,24 @@ mfb_open(const char *title, unsigned width, unsigned height) {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct mfb_window *
mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
init_keycodes();
SWindowData *
create_window_data(unsigned width, unsigned height) {
SWindowData *window_data = malloc(sizeof(SWindowData));
if(window_data == 0x0) {
NSLog(@"Cannot allocate window data");
return 0x0;
}
memset(window_data, 0, sizeof(SWindowData));
SWindowData_OSX *window_data_osx = malloc(sizeof(SWindowData_OSX));
if(window_data_osx == 0x0) {
free(window_data);
NSLog(@"Cannot allocate osx window data");
return 0x0;
}
memset(window_data_osx, 0, sizeof(SWindowData_OSX));
window_data->specific = window_data_osx;
window_data->specific = window_data_osx;
window_data->window_width = width;
window_data->window_height = height;
@ -143,21 +149,34 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
window_data->buffer_height = height;
window_data->buffer_stride = width * 4;
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
#if defined(USE_METAL_API)
g_metal_device = MTLCreateSystemDefaultDevice();
if (!g_metal_device) {
NSLog(@"Metal is not supported on this device");
return 0x0;
}
if (!create_shaders((SWindowData_OSX *) window_data->specific)) {
window_data->draw_buffer = malloc(width * height * 4);
if (!window_data->draw_buffer) {
free(window_data_osx);
free(window_data);
NSLog(@"Unable to create draw buffer");
return 0x0;
}
#endif
return window_data;
}
struct mfb_window *
mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
SWindowData *window_data = create_window_data(width, height);
if (window_data == 0x0) {
return 0x0;
}
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
init_keycodes();
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
NSWindowStyleMask styles = NSWindowStyleMaskClosable | NSWindowStyleMaskTitled;
if (flags & WF_BORDERLESS)
@ -169,14 +188,27 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
NSRect rectangle = NSMakeRect(0, 0, width, height);
NSRect frameRect = [NSWindow frameRectForContentRect:rectangle styleMask:styles];
window_data_osx->window = [[OSXWindow alloc] initWithContentRect:frameRect styleMask:styles backing:NSBackingStoreBuffered defer:NO windowData:window_data];
if (!window_data_osx->window)
if (!window_data_osx->window) {
NSLog(@"Cannot create window");
if(window_data->draw_buffer != 0x0) {
free(window_data->draw_buffer);
window_data->draw_buffer = 0x0;
}
free(window_data_osx);
free(window_data);
return 0x0;
}
#if defined(USE_METAL_API)
window_data->draw_buffer = malloc(width * height * 4);
if (!window_data->draw_buffer)
g_metal_device = MTLCreateSystemDefaultDevice();
if (!g_metal_device) {
NSLog(@"Metal is not supported on this device");
return 0x0;
}
if (!create_shaders((SWindowData_OSX *) window_data->specific)) {
return 0x0;
}
static Vertex s_vertices[4] = {
{-1.0, -1.0, 0, 1},
@ -263,6 +295,12 @@ destroy_window_data(SWindowData *window_data) {
memset(window_data_osx, 0, sizeof(SWindowData_OSX));
free(window_data_osx);
}
if(window_data->draw_buffer != 0x0) {
free(window_data->draw_buffer);
window_data->draw_buffer = 0x0;
}
memset(window_data, 0, sizeof(SWindowData));
free(window_data);

View File

@ -6,17 +6,8 @@
#if defined(USE_METAL_API)
#import <MetalKit/MetalKit.h>
extern id<MTLDevice> g_metal_device;
extern id<MTLLibrary> g_library;
@implementation WindowViewController
- (void) mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
(void)view;
(void)size;
// resize
}
- (void) drawInMTKView:(nonnull MTKView *)view {
OSXWindow *window = (OSXWindow *) view.window;
SWindowData *window_data = window->window_data;
@ -84,6 +75,13 @@ extern id<MTLLibrary> g_library;
// Finalize rendering here & push the command buffer to the GPU
[commandBuffer commit];
}
- (void) mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
(void)view;
(void)size;
// resize
}
@end
#endif

View File

@ -17,6 +17,7 @@ struct mfb_window *g_window = 0x0;
uint32_t *g_buffer = 0x0;
uint32_t g_width = 0;
uint32_t g_height = 0;
float g_scale = 1;
//-------------------------------------
@interface AppDelegate ()
@ -37,6 +38,14 @@ mouse_move(struct mfb_window *window, int x, int y) {
NSLog(@"Touch moved %d, %d", x, y);
}
void
resize(struct mfb_window *window, int width, int height) {
kUnused(window);
g_width = width;
g_height = height;
NSLog(@"Resize %d, %d", width, height);
}
//-------------------------------------
@implementation AppDelegate
@ -44,18 +53,24 @@ mouse_move(struct mfb_window *window, int x, int y) {
- (void) OnUpdateFrame {
static int seed = 0xbeef;
int noise, carry;
int dis = 0;
if(g_buffer != 0x0) {
for (uint32_t i = 0; i < g_width * g_height; ++i) {
noise = seed;
noise >>= 3;
noise ^= seed;
carry = noise & 1;
noise >>= 1;
seed >>= 1;
seed |= (carry << 30);
noise &= 0xFF;
g_buffer[i] = MFB_RGB(noise, noise, noise);
uint32_t i = 0;
for (uint32_t y = 0; y < g_height; ++y) {
for (uint32_t x = 0; x < g_width; ++x) {
noise = seed;
noise >>= 3;
noise ^= seed;
carry = noise & 1;
noise >>= 1;
seed >>= 1;
seed |= (carry << 30);
noise &= 0xFF >> dis;
g_buffer[i++] = MFB_RGB(noise, noise, noise);
}
if((y & 0x07) == 0x07)
dis ^= 0x01;
}
}
@ -75,13 +90,15 @@ mouse_move(struct mfb_window *window, int x, int y) {
kUnused(launchOptions);
if(g_window == 0x0) {
g_width = [UIScreen mainScreen].bounds.size.width;
g_height = [UIScreen mainScreen].bounds.size.height;
g_scale = [UIScreen mainScreen].scale;
g_width = [UIScreen mainScreen].bounds.size.width * g_scale;
g_height = [UIScreen mainScreen].bounds.size.height * g_scale;
g_window = mfb_open("noise", g_width, g_height);
if(g_window != 0x0) {
g_buffer = malloc(g_width * g_height * 4);
mfb_set_mouse_move_callback(g_window, mouse_move);
mfb_set_mouse_button_callback(g_window, mouse_btn);
mfb_set_resize_callback(g_window, resize);
}
}