mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 19:31:30 +11:00
merge macos-metal -> master
commit 2d8e0c1692120e9997bd8d376be8a7cc2536429d Author: Daniel Collin <daniel@collin.com> Date: Tue Oct 23 20:51:09 2018 +0200 Bump to 0.11 and added info about macOS Metal commit 0f77968317194f2f72b86da287c04484aeee762a Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 17:44:26 2018 +0200 Tripple buffer textures commit d268c10576c7e9063bd4605aed4a939d956eeb6b Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 16:59:20 2018 +0200 Some cleanup commit 5544773e62afec6f69d0c3b6309e60a543905fef Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 16:24:45 2018 +0200 Working but no proper sync yet commit 843a6625cfddac5a6e2d8e61170f796e763e4002 Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 15:26:45 2018 +0200 Working texture commit 1d4446f1f10c497dde07e0d20c92eb8bb6f836ec Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 14:45:52 2018 +0200 Removed vertex data We construct this in the shader instead commit 2e8027d73a1635e26e412dbda6494193fd04a060 Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 14:42:36 2018 +0200 Fullscreen triangle setup commit 5efd974704c11577944ffdeff9eb9dd4fa40bde0 Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 14:16:23 2018 +0200 Triangle on screen commit d9cf4eb7557f73adfbe1764f3da94a837a4ef8d3 Author: Daniel Collin <daniel@collin.com> Date: Sun Oct 21 12:17:04 2018 +0200 Some hacky metal with clear screen
This commit is contained in:
parent
335f505ef2
commit
79608b38a2
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
This project follows semantic versioning.
|
This project follows semantic versioning.
|
||||||
|
|
||||||
|
### v0.11 (2018-10-23)
|
||||||
|
|
||||||
|
- [changed] macOS now uses Metal for rendering the buffer.
|
||||||
|
|
||||||
### v0.10.7 (2018-08-10)
|
### v0.10.7 (2018-08-10)
|
||||||
|
|
||||||
Thanks to Lukas Kalbertodt for these changes!
|
Thanks to Lukas Kalbertodt for these changes!
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "minifb"
|
name = "minifb"
|
||||||
version = "0.10.7"
|
version = "0.11"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
authors = ["Daniel Collin <daniel@collin.com>"]
|
authors = ["Daniel Collin <daniel@collin.com>"]
|
||||||
description = "Cross-platform window setup with optional bitmap rendering"
|
description = "Cross-platform window setup with optional bitmap rendering"
|
||||||
|
|
|
@ -14,7 +14,7 @@ Usage
|
||||||
```toml
|
```toml
|
||||||
# Cargo.toml
|
# Cargo.toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
minifb = "0.10"
|
minifb = "0.11"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
|
3
build.rs
3
build.rs
|
@ -5,10 +5,13 @@ fn main() {
|
||||||
let env = env::var("TARGET").unwrap();
|
let env = env::var("TARGET").unwrap();
|
||||||
if env.contains("darwin") {
|
if env.contains("darwin") {
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
|
.flag("-mmacosx-version-min=10.10")
|
||||||
.file("src/native/macosx/MacMiniFB.m")
|
.file("src/native/macosx/MacMiniFB.m")
|
||||||
.file("src/native/macosx/OSXWindow.m")
|
.file("src/native/macosx/OSXWindow.m")
|
||||||
.file("src/native/macosx/OSXWindowFrameView.m")
|
.file("src/native/macosx/OSXWindowFrameView.m")
|
||||||
.compile("libminifb_native.a");
|
.compile("libminifb_native.a");
|
||||||
|
println!("cargo:rustc-link-lib=framework=Metal");
|
||||||
|
println!("cargo:rustc-link-lib=framework=MetalKit");
|
||||||
} else if env.contains("linux") {
|
} else if env.contains("linux") {
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.file("src/native/x11/X11MiniFB.c")
|
.file("src/native/x11/X11MiniFB.c")
|
||||||
|
|
|
@ -2,8 +2,56 @@
|
||||||
#include "OSXWindowFrameView.h"
|
#include "OSXWindowFrameView.h"
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <MetalKit/MetalKit.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern id<MTLDevice> g_metal_device;
|
||||||
|
extern id<MTLCommandQueue> g_command_queue;
|
||||||
|
extern id<MTLLibrary> g_library;
|
||||||
|
extern id<MTLRenderPipelineState> g_pipeline_state;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NSString* g_shadersSrc = @
|
||||||
|
" #include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
|
||||||
|
"struct VertexOutput {\n"
|
||||||
|
"float4 pos [[position]];\n"
|
||||||
|
"float2 texcoord;\n"
|
||||||
|
"};\n"
|
||||||
|
|
||||||
|
"vertex VertexOutput vertFunc(\n"
|
||||||
|
"unsigned int vID[[vertex_id]])\n"
|
||||||
|
"{\n"
|
||||||
|
"VertexOutput out;\n"
|
||||||
|
|
||||||
|
"out.pos.x = (float)(vID / 2) * 4.0 - 1.0;\n"
|
||||||
|
"out.pos.y = (float)(vID % 2) * 4.0 - 1.0;\n"
|
||||||
|
"out.pos.z = 0.0;\n"
|
||||||
|
"out.pos.w = 1.0;\n"
|
||||||
|
|
||||||
|
"out.texcoord.x = (float)(vID / 2) * 2.0;\n"
|
||||||
|
"out.texcoord.y = 1.0 - (float)(vID % 2) * 2.0;\n"
|
||||||
|
|
||||||
|
"return out;\n"
|
||||||
|
"}\n"
|
||||||
|
|
||||||
|
"fragment float4 fragFunc(VertexOutput input [[stage_in]],\n"
|
||||||
|
"texture2d<half> colorTexture [[ texture(0) ]])\n"
|
||||||
|
"{\n"
|
||||||
|
"constexpr sampler textureSampler(mag_filter::nearest, min_filter::nearest);\n"
|
||||||
|
|
||||||
|
// Sample the texture to obtain a color
|
||||||
|
"const half4 colorSample = colorTexture.sample(textureSampler, input.texcoord);\n"
|
||||||
|
|
||||||
|
// We return the color of the texture
|
||||||
|
"return float4(colorSample);\n"
|
||||||
|
//"return half4(input.texcoord.x, input.texcoord.y, 0.0, 1.0);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool s_init = false;
|
static bool s_init = false;
|
||||||
|
|
||||||
// window_handler.rs
|
// window_handler.rs
|
||||||
|
@ -49,6 +97,57 @@ void cursor_init() {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool create_shaders() {
|
||||||
|
// Error
|
||||||
|
NSError* nsError = NULL;
|
||||||
|
NSError** nsErrorPtr = &nsError;
|
||||||
|
|
||||||
|
id<MTLLibrary> library = [g_metal_device newLibraryWithSource:g_shadersSrc
|
||||||
|
options:[[MTLCompileOptions alloc] init]
|
||||||
|
error:nsErrorPtr];
|
||||||
|
|
||||||
|
// Error update
|
||||||
|
if (nsError || !library) {
|
||||||
|
NSLog(@"Unable to create shaders %@", nsError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"Names %@", [g_library functionNames]);
|
||||||
|
|
||||||
|
g_library = library;
|
||||||
|
|
||||||
|
id<MTLFunction> vertex_shader_func = [g_library newFunctionWithName:@"vertFunc"];
|
||||||
|
id<MTLFunction> fragment_shader_func = [g_library newFunctionWithName:@"fragFunc"];
|
||||||
|
|
||||||
|
if (!vertex_shader_func) {
|
||||||
|
printf("Unable to get vertFunc!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fragment_shader_func) {
|
||||||
|
printf("Unable to get fragFunc!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a reusable pipeline state
|
||||||
|
MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
|
pipelineStateDescriptor.label = @"MyPipeline";
|
||||||
|
pipelineStateDescriptor.vertexFunction = vertex_shader_func;
|
||||||
|
pipelineStateDescriptor.fragmentFunction = fragment_shader_func;
|
||||||
|
pipelineStateDescriptor.colorAttachments[0].pixelFormat = 80; //bgra8Unorm;
|
||||||
|
|
||||||
|
NSError *error = NULL;
|
||||||
|
g_pipeline_state = [g_metal_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
|
||||||
|
if (!g_pipeline_state)
|
||||||
|
{
|
||||||
|
NSLog(@"Failed to created pipeline state, error %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void* mfb_open(const char* name, int width, int height, uint32_t flags, int scale)
|
void* mfb_open(const char* name, int width, int height, uint32_t flags, int scale)
|
||||||
{
|
{
|
||||||
bool prev_init = s_init;
|
bool prev_init = s_init;
|
||||||
|
@ -60,6 +159,17 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
create_standard_menu();
|
create_standard_menu();
|
||||||
cursor_init();
|
cursor_init();
|
||||||
|
g_metal_device = MTLCreateSystemDefaultDevice();
|
||||||
|
|
||||||
|
if (!g_metal_device) {
|
||||||
|
printf("Your device/OS doesn't support Metal.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!create_shaders()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s_init = true;
|
s_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +196,40 @@ void* mfb_open(const char* name, int width, int height, uint32_t flags, int scal
|
||||||
if (!window->draw_buffer)
|
if (!window->draw_buffer)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Setup command queue
|
||||||
|
g_command_queue = [g_metal_device newCommandQueue];
|
||||||
|
|
||||||
|
|
||||||
|
WindowViewController* viewController = [WindowViewController new];
|
||||||
|
|
||||||
|
MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
|
||||||
|
|
||||||
|
// Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is
|
||||||
|
// an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0)
|
||||||
|
textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
|
|
||||||
|
// Set the pixel dimensions of the texture
|
||||||
|
textureDescriptor.width = width;
|
||||||
|
textureDescriptor.height = height;
|
||||||
|
|
||||||
|
// Create the texture from the device by using the descriptor
|
||||||
|
|
||||||
|
for (int i = 0; i < MaxBuffersInFlight; ++i) {
|
||||||
|
viewController->m_texture_buffers[i] = [g_metal_device newTextureWithDescriptor:textureDescriptor];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used for syncing the CPU and GPU
|
||||||
|
viewController->m_semaphore = dispatch_semaphore_create(MaxBuffersInFlight);
|
||||||
|
viewController->m_draw_buffer = window->draw_buffer;
|
||||||
|
viewController->m_width = width;
|
||||||
|
viewController->m_height = height;
|
||||||
|
|
||||||
|
MTKView* view = [[MTKView alloc] initWithFrame:rectangle];
|
||||||
|
view.device = g_metal_device;
|
||||||
|
view.delegate = viewController;
|
||||||
|
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||||
|
[window.contentView addSubview:view];
|
||||||
|
|
||||||
window->width = width;
|
window->width = width;
|
||||||
window->height = height;
|
window->height = height;
|
||||||
window->scale = scale;
|
window->scale = scale;
|
||||||
|
|
|
@ -144,10 +144,6 @@
|
||||||
object:self];
|
object:self];
|
||||||
|
|
||||||
frameView = [[[OSXWindowFrameView alloc] initWithFrame:bounds] autorelease];
|
frameView = [[[OSXWindowFrameView alloc] initWithFrame:bounds] autorelease];
|
||||||
frameView->width = width;
|
|
||||||
frameView->height = height;
|
|
||||||
frameView->draw_buffer = draw_buffer;
|
|
||||||
frameView->scale = scale;
|
|
||||||
[super setContentView:frameView];
|
[super setContentView:frameView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,14 +191,6 @@
|
||||||
|
|
||||||
- (void)updateSize
|
- (void)updateSize
|
||||||
{
|
{
|
||||||
OSXWindowFrameView* frameView = [super contentView];
|
|
||||||
if (frameView)
|
|
||||||
{
|
|
||||||
frameView->width = width;
|
|
||||||
frameView->height = height;
|
|
||||||
frameView->draw_buffer = draw_buffer;
|
|
||||||
frameView->scale = scale;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1,11 +1,32 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <MetalKit/MetalKit.h>
|
||||||
|
|
||||||
|
// Number of textures in flight (tripple buffered)
|
||||||
|
const int MaxBuffersInFlight = 3;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@interface WindowViewController : NSViewController<MTKViewDelegate>
|
||||||
|
{
|
||||||
|
@public id<MTLTexture> m_texture_buffers[MaxBuffersInFlight];
|
||||||
|
@public int m_current_buffer;
|
||||||
|
@public void* m_draw_buffer;
|
||||||
|
@public int m_width;
|
||||||
|
@public int m_height;
|
||||||
|
// Used for syncing with CPU/GPU
|
||||||
|
@public dispatch_semaphore_t m_semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@interface OSXWindowFrameView : NSView
|
@interface OSXWindowFrameView : NSView
|
||||||
{
|
{
|
||||||
@public int scale;
|
//@public int scale;
|
||||||
@public int width;
|
//@public int width;
|
||||||
@public int height;
|
//@public int height;
|
||||||
@public void* draw_buffer;
|
//@public void* draw_buffer;
|
||||||
@private NSTrackingArea* trackingArea;
|
@private NSTrackingArea* trackingArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,85 @@
|
||||||
#import "OSXWindowFrameView.h"
|
#import "OSXWindowFrameView.h"
|
||||||
#import "OSXWindow.h"
|
#import "OSXWindow.h"
|
||||||
|
#import <MetalKit/MetalKit.h>
|
||||||
|
|
||||||
|
id<MTLDevice> g_metal_device;
|
||||||
|
id<MTLCommandQueue> g_command_queue;
|
||||||
|
id<MTLLibrary> g_library;
|
||||||
|
id<MTLRenderPipelineState> g_pipeline_state;
|
||||||
|
|
||||||
|
@implementation WindowViewController
|
||||||
|
-(void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||||
|
{
|
||||||
|
(void)view;
|
||||||
|
(void)size;
|
||||||
|
// resize
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)drawInMTKView:(nonnull MTKView *)view
|
||||||
|
{
|
||||||
|
// Wait to ensure only MaxBuffersInFlight number of frames are getting proccessed
|
||||||
|
// by any stage in the Metal pipeline (App, Metal, Drivers, GPU, etc)
|
||||||
|
dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER);
|
||||||
|
|
||||||
|
// Iterate through our Metal buffers, and cycle back to the first when we've written to MaxBuffersInFlight
|
||||||
|
m_current_buffer = (m_current_buffer + 1) % MaxBuffersInFlight;
|
||||||
|
|
||||||
|
// Calculate the number of bytes per row of our image.
|
||||||
|
NSUInteger bytesPerRow = 4 * m_width;
|
||||||
|
MTLRegion region = { { 0, 0, 0 }, { m_width, m_height, 1 } };
|
||||||
|
|
||||||
|
// Copy the bytes from our data object into the texture
|
||||||
|
[m_texture_buffers[m_current_buffer] replaceRegion:region
|
||||||
|
mipmapLevel:0 withBytes:m_draw_buffer bytesPerRow:bytesPerRow];
|
||||||
|
|
||||||
|
// Create a new command buffer for each render pass to the current drawable
|
||||||
|
id<MTLCommandBuffer> commandBuffer = [g_command_queue commandBuffer];
|
||||||
|
commandBuffer.label = @"minifb_command_buffer";
|
||||||
|
|
||||||
|
// Add completion hander which signals _inFlightSemaphore when Metal and the GPU has fully
|
||||||
|
// finished processing the commands we're encoding this frame. This indicates when the
|
||||||
|
// dynamic buffers filled with our vertices, that we're writing to this frame, will no longer
|
||||||
|
// be needed by Metal and the GPU, meaning we can overwrite the buffer contents without
|
||||||
|
// corrupting the rendering.
|
||||||
|
__block dispatch_semaphore_t block_sema = m_semaphore;
|
||||||
|
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer)
|
||||||
|
{
|
||||||
|
(void)buffer;
|
||||||
|
dispatch_semaphore_signal(block_sema);
|
||||||
|
}];
|
||||||
|
|
||||||
|
MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor;
|
||||||
|
|
||||||
|
if (renderPassDescriptor != nil)
|
||||||
|
{
|
||||||
|
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Create a render command encoder so we can render into something
|
||||||
|
id<MTLRenderCommandEncoder> renderEncoder =
|
||||||
|
[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||||
|
renderEncoder.label = @"minifb_command_encoder";
|
||||||
|
|
||||||
|
// Set render command encoder state
|
||||||
|
[renderEncoder setRenderPipelineState:g_pipeline_state];
|
||||||
|
|
||||||
|
[renderEncoder setFragmentTexture:m_texture_buffers[m_current_buffer] atIndex:0];
|
||||||
|
|
||||||
|
// Draw the vertices of our quads
|
||||||
|
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
vertexStart:0
|
||||||
|
vertexCount:3];
|
||||||
|
|
||||||
|
// We're done encoding commands
|
||||||
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
|
// Schedule a present once the framebuffer is complete using the current drawable
|
||||||
|
[commandBuffer presentDrawable:view.currentDrawable];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize rendering here & push the command buffer to the GPU
|
||||||
|
[commandBuffer commit];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation OSXWindowFrameView
|
@implementation OSXWindowFrameView
|
||||||
|
|
||||||
|
@ -22,73 +102,6 @@
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
- (void)drawRect:(NSRect)rect
|
|
||||||
{
|
|
||||||
(void)rect;
|
|
||||||
CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
|
|
||||||
|
|
||||||
printf("drawRect\n");
|
|
||||||
|
|
||||||
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
|
||||||
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, draw_buffer, width * height * 4, NULL);
|
|
||||||
|
|
||||||
CGImageRef img = CGImageCreate(width, height, 8, 32, width * 4, space, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
|
||||||
provider, NULL, false, kCGRenderingIntentDefault);
|
|
||||||
|
|
||||||
CGColorSpaceRelease(space);
|
|
||||||
CGDataProviderRelease(provider);
|
|
||||||
|
|
||||||
CGContextDrawImage(context, CGRectMake(0, 0, width * scale, height * scale), img);
|
|
||||||
|
|
||||||
CGImageRelease(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/*
|
|
||||||
- (BOOL)wantsUpdateLayer
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
-(void)updateLayer
|
|
||||||
{
|
|
||||||
printf("update layer\n");
|
|
||||||
// Force the graphics context to clear to black so we don't get a flash of
|
|
||||||
// white until the app is ready to draw. In practice on modern macOS, this
|
|
||||||
// only gets called for window creation and other extraordinary events.
|
|
||||||
self.layer.backgroundColor = NSColor.blackColor.CGColor;
|
|
||||||
//NSGraphicsContext* context = [NSGraphicsContext currentContext];
|
|
||||||
//[context scheduleUpdate];
|
|
||||||
|
|
||||||
//(void)rect;
|
|
||||||
CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
|
|
||||||
|
|
||||||
//printf("drawRect\n");
|
|
||||||
|
|
||||||
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
|
||||||
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, draw_buffer, width * height * 4, NULL);
|
|
||||||
|
|
||||||
CGImageRef img = CGImageCreate(width, height, 8, 32, width * 4, space, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
|
||||||
provider, NULL, false, kCGRenderingIntentDefault);
|
|
||||||
|
|
||||||
CGColorSpaceRelease(space);
|
|
||||||
CGDataProviderRelease(provider);
|
|
||||||
|
|
||||||
CGContextDrawImage(context, CGRectMake(0, 0, width * scale, height * scale), img);
|
|
||||||
|
|
||||||
CGImageRelease(img);
|
|
||||||
|
|
||||||
//ScheduleContextUpdates((SDL_WindowData *) _sdlWindow->driverdata);
|
|
||||||
//SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
|
|
||||||
//[context scheduleUpdate];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
- (void)mouseDown:(NSEvent*)event
|
- (void)mouseDown:(NSEvent*)event
|
||||||
{
|
{
|
||||||
(void)event;
|
(void)event;
|
||||||
|
|
Loading…
Reference in a new issue