mirror of https://github.com/AxioDL/boo.git
OS X event fixes and prep for Metal API
This commit is contained in:
parent
41cccf6b0d
commit
606e3676b1
|
@ -40,9 +40,9 @@ elseif(APPLE)
|
|||
list(APPEND PLAT_SRCS
|
||||
lib/mac/ApplicationCocoa.mm
|
||||
lib/mac/WindowCocoa.mm
|
||||
lib/mac/GLViewCocoa.mm
|
||||
lib/inputdev/HIDListenerIOKit.cpp
|
||||
lib/inputdev/HIDDeviceIOKit.cpp)
|
||||
lib/inputdev/HIDDeviceIOKit.cpp
|
||||
lib/graphicsdev/Metal.mm)
|
||||
|
||||
list(APPEND PLAT_HDRS
|
||||
include/boo/graphicsdev/Metal.hpp)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "IGraphicsDataFactory.hpp"
|
||||
#include "IGraphicsCommandQueue.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include "glew.h"
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
|
|
|
@ -2,12 +2,63 @@
|
|||
#define GDEV_METAL_HPP
|
||||
|
||||
#include "IGraphicsDataFactory.hpp"
|
||||
#include "IGraphicsCommandQueue.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
|
||||
class MetalDataFactory : public IGraphicsDataFactory
|
||||
{
|
||||
IGraphicsContext* m_parent;
|
||||
IGraphicsData* m_deferredData = nullptr;
|
||||
std::unordered_set<IGraphicsData*> m_committedData;
|
||||
public:
|
||||
MetalDataFactory(IGraphicsContext* parent);
|
||||
~MetalDataFactory() {}
|
||||
|
||||
Platform platform() const {return PlatformMetal;}
|
||||
const char* platformName() const {return "Metal";}
|
||||
|
||||
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||
IGraphicsBufferS* newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count);
|
||||
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
|
||||
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
const void* data, size_t sz);
|
||||
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
std::unique_ptr<uint8_t[]>&& data, size_t sz);
|
||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
||||
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
|
||||
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
|
||||
|
||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||
size_t texCount, const char** texNames,
|
||||
BlendFactor srcFac, BlendFactor dstFac,
|
||||
bool depthTest, bool depthWrite, bool backfaceCulling);
|
||||
|
||||
IShaderDataBinding*
|
||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||
IVertexFormat* vtxFormat,
|
||||
IGraphicsBuffer* vbo, IGraphicsBuffer* ebo,
|
||||
size_t ubufCount, IGraphicsBuffer** ubufs,
|
||||
size_t texCount, ITexture** texs);
|
||||
|
||||
void reset();
|
||||
IGraphicsData* commit();
|
||||
void destroyData(IGraphicsData*);
|
||||
void destroyAllData();
|
||||
};
|
||||
|
||||
struct MetalContext
|
||||
{
|
||||
struct Window
|
||||
{
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "boo/graphicsdev/GL.hpp"
|
||||
#include "boo/graphicsdev/glew.h"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,7 @@
|
|||
#include <thread>
|
||||
|
||||
#include "boo/IApplication.hpp"
|
||||
#include "boo/graphicsdev/Metal.hpp"
|
||||
|
||||
namespace boo {class ApplicationCocoa;}
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
@ -16,7 +17,7 @@ namespace boo {class ApplicationCocoa;}
|
|||
namespace boo
|
||||
{
|
||||
|
||||
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx);
|
||||
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx);
|
||||
|
||||
class ApplicationCocoa : public IApplication
|
||||
{
|
||||
|
@ -34,6 +35,8 @@ private:
|
|||
/* All windows */
|
||||
std::unordered_map<NSWindow*, IWindow*> m_windows;
|
||||
|
||||
MetalContext m_metalCtx;
|
||||
|
||||
void _deletedWindow(IWindow* window)
|
||||
{
|
||||
m_windows.erase((NSWindow*)window->getPlatformHandle());
|
||||
|
@ -86,7 +89,7 @@ public:
|
|||
NSText* aboutText = [[NSText alloc] initWithFrame:aboutCr];
|
||||
[aboutText setEditable:NO];
|
||||
[aboutText setAlignment:NSCenterTextAlignment];
|
||||
[aboutText setString:@"\nRWK Authors\n\nJackoalan\nAntidote\n"];
|
||||
[aboutText setString:@"\nBoo Authors\n\nJackoalan\nAntidote\n"];
|
||||
[aboutPanel setContentView:aboutText];
|
||||
appDelegate->aboutPanel = aboutPanel;
|
||||
}
|
||||
|
@ -142,7 +145,7 @@ public:
|
|||
|
||||
IWindow* newWindow(const std::string& title)
|
||||
{
|
||||
IWindow* newWindow = _WindowCocoaNew(title, m_lastGLCtx);
|
||||
IWindow* newWindow = _WindowCocoaNew(title, m_lastGLCtx, &m_metalCtx);
|
||||
m_windows[(NSWindow*)newWindow->getPlatformHandle()] = newWindow;
|
||||
return newWindow;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "boo/graphicsdev/GL.hpp"
|
||||
#include "boo/graphicsdev/glew.h"
|
||||
#include "boo/graphicsdev/Metal.hpp"
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <CoreVideo/CVDisplayLink.h>
|
||||
#include "boo/IApplication.hpp"
|
||||
|
@ -72,53 +74,110 @@ static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
|
|||
PF_RGBAF32_Z24_ATTRS
|
||||
};
|
||||
|
||||
namespace boo {class GraphicsContextCocoa;}
|
||||
@interface GraphicsContextCocoaInternal : NSOpenGLView
|
||||
namespace boo
|
||||
{
|
||||
class GraphicsContextCocoa : public IGraphicsContext
|
||||
{
|
||||
protected:
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
IWindow* m_parentWindow;
|
||||
CVDisplayLinkRef m_dispLink = nullptr;
|
||||
|
||||
GraphicsContextCocoa(EGraphicsAPI api, EPixelFormat pf, IWindow* parentWindow)
|
||||
: m_api(api), m_pf(pf), m_parentWindow(parentWindow) {}
|
||||
|
||||
std::mutex m_dlmt;
|
||||
std::condition_variable m_dlcv;
|
||||
|
||||
static CVReturn DLCallback(CVDisplayLinkRef CV_NONNULL displayLink,
|
||||
const CVTimeStamp * CV_NONNULL inNow,
|
||||
const CVTimeStamp * CV_NONNULL inOutputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags * CV_NONNULL flagsOut,
|
||||
GraphicsContextCocoa* CV_NULLABLE ctx)
|
||||
{
|
||||
ctx->m_dlcv.notify_one();
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
~GraphicsContextCocoa()
|
||||
{
|
||||
if (m_dispLink)
|
||||
{
|
||||
CVDisplayLinkStop(m_dispLink);
|
||||
CVDisplayLinkRelease(m_dispLink);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
IWindowCallback* m_callback = nullptr;
|
||||
void waitForRetrace()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_dlmt);
|
||||
m_dlcv.wait(lk);
|
||||
}
|
||||
};
|
||||
class GraphicsContextCocoaGL;
|
||||
class GraphicsContextCocoaMetal;
|
||||
}
|
||||
|
||||
@interface BooCocoaResponder : NSResponder
|
||||
{
|
||||
@public
|
||||
NSUInteger lastModifiers;
|
||||
boo::GraphicsContextCocoa* booContext;
|
||||
NSView* parentView;
|
||||
}
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx;
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view;
|
||||
@end
|
||||
|
||||
@interface GraphicsContextCocoaGLInternal : NSOpenGLView
|
||||
{
|
||||
BooCocoaResponder* resp;
|
||||
}
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoaGL*)bctx;
|
||||
@end
|
||||
|
||||
@interface GraphicsContextCocoaMetalInternal : NSView
|
||||
{
|
||||
BooCocoaResponder* resp;
|
||||
}
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoaMetal*)bctx;
|
||||
@end
|
||||
|
||||
namespace boo
|
||||
{
|
||||
static LogVisor::LogModule Log("boo::WindowCocoa");
|
||||
IGraphicsCommandQueue* _NewGLES3CommandQueue(IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, MetalContext::Window* windowCtx,
|
||||
IGraphicsContext* parent);
|
||||
void _CocoaUpdateLastGLCtx(NSOpenGLContext* lastGLCtx);
|
||||
|
||||
class GraphicsContextCocoa : public IGraphicsContext
|
||||
class GraphicsContextCocoaGL : public GraphicsContextCocoa
|
||||
{
|
||||
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
IWindow* m_parentWindow;
|
||||
GraphicsContextCocoaInternal* m_nsContext = nullptr;
|
||||
GraphicsContextCocoaGLInternal* m_nsContext = nullptr;
|
||||
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
NSOpenGLContext* m_loadCtx = nullptr;
|
||||
CVDisplayLinkRef m_dispLink = nullptr;
|
||||
|
||||
public:
|
||||
NSOpenGLContext* m_lastCtx = nullptr;
|
||||
IWindowCallback* m_callback = nullptr;
|
||||
|
||||
GraphicsContextCocoa(EGraphicsAPI api, IWindow* parentWindow, NSOpenGLContext* lastGLCtx)
|
||||
: m_api(api),
|
||||
m_pf(PF_RGBA8),
|
||||
m_parentWindow(parentWindow),
|
||||
m_lastCtx(lastGLCtx)
|
||||
{}
|
||||
GraphicsContextCocoaGL(EGraphicsAPI api, IWindow* parentWindow, NSOpenGLContext* lastGLCtx)
|
||||
: GraphicsContextCocoa(api, PF_RGBA8, parentWindow),
|
||||
m_lastCtx(lastGLCtx)
|
||||
{
|
||||
m_dataFactory = new GLDataFactory(this);
|
||||
}
|
||||
|
||||
~GraphicsContextCocoa()
|
||||
~GraphicsContextCocoaGL()
|
||||
{
|
||||
delete m_dataFactory;
|
||||
delete m_commandQueue;
|
||||
[m_nsContext release];
|
||||
[m_loadCtx release];
|
||||
CVDisplayLinkStop(m_dispLink);
|
||||
CVDisplayLinkRelease(m_dispLink);
|
||||
}
|
||||
|
||||
void _setCallback(IWindowCallback* cb)
|
||||
|
@ -143,35 +202,16 @@ public:
|
|||
m_pf = pf;
|
||||
}
|
||||
|
||||
std::mutex m_dlmt;
|
||||
std::condition_variable m_dlcv;
|
||||
|
||||
static CVReturn DLCallback(CVDisplayLinkRef CV_NONNULL displayLink,
|
||||
const CVTimeStamp * CV_NONNULL inNow,
|
||||
const CVTimeStamp * CV_NONNULL inOutputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags * CV_NONNULL flagsOut,
|
||||
GraphicsContextCocoa* CV_NULLABLE ctx)
|
||||
{
|
||||
ctx->m_dlcv.notify_one();
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
void waitForRetrace()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_dlmt);
|
||||
m_dlcv.wait(lk);
|
||||
}
|
||||
|
||||
void initializeContext()
|
||||
{
|
||||
m_nsContext = [[GraphicsContextCocoaInternal alloc] initWithBooContext:this];
|
||||
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
||||
if (!m_nsContext)
|
||||
Log.report(LogVisor::FatalError, "unable to make new NSOpenGLView");
|
||||
[(NSWindow*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
||||
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
||||
CVDisplayLinkStart(m_dispLink);
|
||||
m_commandQueue = _NewGLCommandQueue(this);
|
||||
}
|
||||
|
||||
void makeCurrent()
|
||||
|
@ -185,15 +225,11 @@ public:
|
|||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
if (!m_commandQueue)
|
||||
m_commandQueue = _NewGLES3CommandQueue(this);
|
||||
return m_commandQueue;
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
if (!m_dataFactory)
|
||||
m_dataFactory = new GLDataFactory(this);
|
||||
return m_dataFactory;
|
||||
}
|
||||
|
||||
|
@ -208,7 +244,7 @@ public:
|
|||
Log.report(LogVisor::FatalError, "unable to make load NSOpenGLContext");
|
||||
[m_loadCtx makeCurrentContext];
|
||||
}
|
||||
return getDataFactory();
|
||||
return m_dataFactory;
|
||||
}
|
||||
|
||||
void present()
|
||||
|
@ -218,8 +254,8 @@ public:
|
|||
|
||||
};
|
||||
|
||||
IGraphicsContext* _GraphicsContextCocoaNew(IGraphicsContext::EGraphicsAPI api,
|
||||
IWindow* parentWindow, NSOpenGLContext* lastGLCtx)
|
||||
IGraphicsContext* _GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI api,
|
||||
IWindow* parentWindow, NSOpenGLContext* lastGLCtx)
|
||||
{
|
||||
if (api != IGraphicsContext::API_OPENGL_3_3 && api != IGraphicsContext::API_OPENGL_4_2)
|
||||
return NULL;
|
||||
|
@ -252,42 +288,119 @@ IGraphicsContext* _GraphicsContextCocoaNew(IGraphicsContext::EGraphicsAPI api,
|
|||
if (api == IGraphicsContext::API_OPENGL_4_2)
|
||||
return NULL;
|
||||
|
||||
return new GraphicsContextCocoa(api, parentWindow, lastGLCtx);
|
||||
return new GraphicsContextCocoaGL(api, parentWindow, lastGLCtx);
|
||||
}
|
||||
|
||||
}
|
||||
class GraphicsContextCocoaMetal : public GraphicsContextCocoa
|
||||
{
|
||||
GraphicsContextCocoaMetalInternal* m_nsContext = nullptr;
|
||||
|
||||
@implementation GraphicsContextCocoaInternal
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
MetalContext* m_metalCtx;
|
||||
MetalContext::Window* m_metalWindowCtx;
|
||||
|
||||
public:
|
||||
|
||||
GraphicsContextCocoaMetal(EGraphicsAPI api, IWindow* parentWindow,
|
||||
MetalContext* metalCtx, MetalContext::Window* metalWindowCtx)
|
||||
: GraphicsContextCocoa(api, PF_RGBA8, parentWindow),
|
||||
m_metalCtx(metalCtx), m_metalWindowCtx(metalWindowCtx)
|
||||
{
|
||||
m_dataFactory = new MetalDataFactory(this);
|
||||
}
|
||||
|
||||
~GraphicsContextCocoaMetal()
|
||||
{
|
||||
delete m_dataFactory;
|
||||
delete m_commandQueue;
|
||||
[m_nsContext release];
|
||||
}
|
||||
|
||||
void _setCallback(IWindowCallback* cb)
|
||||
{
|
||||
m_callback = cb;
|
||||
}
|
||||
|
||||
EGraphicsAPI getAPI() const
|
||||
{
|
||||
return m_api;
|
||||
}
|
||||
|
||||
EPixelFormat getPixelFormat() const
|
||||
{
|
||||
return m_pf;
|
||||
}
|
||||
|
||||
void setPixelFormat(EPixelFormat pf)
|
||||
{
|
||||
if (pf > PF_RGBAF32_Z24)
|
||||
return;
|
||||
m_pf = pf;
|
||||
}
|
||||
|
||||
void initializeContext()
|
||||
{
|
||||
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
||||
if (!m_nsContext)
|
||||
Log.report(LogVisor::FatalError, "unable to make new NSView for Metal");
|
||||
[(NSWindow*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext];
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&m_dispLink);
|
||||
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
||||
CVDisplayLinkStart(m_dispLink);
|
||||
m_commandQueue = _NewMetalCommandQueue(m_metalCtx, m_metalWindowCtx, this);
|
||||
}
|
||||
|
||||
void makeCurrent()
|
||||
{
|
||||
}
|
||||
|
||||
void postInit()
|
||||
{
|
||||
}
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
return m_commandQueue;
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
return m_dataFactory;
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
return m_dataFactory;
|
||||
}
|
||||
|
||||
void present()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI api,
|
||||
IWindow* parentWindow,
|
||||
MetalContext* metalCtx,
|
||||
MetalContext::Window* metalWindowCtx)
|
||||
{
|
||||
if (api != IGraphicsContext::API_METAL)
|
||||
return nullptr;
|
||||
return new GraphicsContextCocoaMetal(api, parentWindow, metalCtx, metalWindowCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@implementation BooCocoaResponder
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view
|
||||
{
|
||||
lastModifiers = 0;
|
||||
booContext = bctx;
|
||||
boo::IGraphicsContext::EPixelFormat pf = bctx->getPixelFormat();
|
||||
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[pf]];
|
||||
self = [self initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:nspf];
|
||||
if (bctx->m_lastCtx)
|
||||
{
|
||||
NSOpenGLContext* sharedCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:bctx->m_lastCtx];
|
||||
[self setOpenGLContext:sharedCtx];
|
||||
[sharedCtx setView:self];
|
||||
}
|
||||
[nspf release];
|
||||
parentView = view;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)reshape
|
||||
{
|
||||
boo::SWindowRect rect = {{int(self.frame.origin.x), int(self.frame.origin.y)},
|
||||
{int(self.frame.size.width), int(self.frame.size.height)}};
|
||||
booContext->m_callback->resized(rect);
|
||||
[super reshape];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsTouchEvents
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
static inline boo::EModifierKey getMod(NSUInteger flags)
|
||||
{
|
||||
int ret = boo::MKEY_NONE;
|
||||
|
@ -318,9 +431,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -335,9 +448,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -352,9 +465,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -369,9 +482,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -389,9 +502,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
boo::EMouseButton button = getButton(theEvent);
|
||||
if (!button)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -408,9 +521,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
boo::EMouseButton button = getButton(theEvent);
|
||||
if (!button)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -424,25 +537,31 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
boo::SWindowCoord coord =
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
if (theEvent.window == [parentView window] && NSPointInRect(liw, parentView.frame))
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
{(unsigned)liw.x, (unsigned)liw.y},
|
||||
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
|
||||
};
|
||||
booContext->m_callback->mouseMove(coord);
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
{(unsigned)liw.x, (unsigned)liw.y},
|
||||
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
|
||||
};
|
||||
booContext->m_callback->mouseMove(coord);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent*)theEvent
|
||||
{
|
||||
[self mouseMoved:theEvent];
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent*)theEvent
|
||||
{
|
||||
[self mouseMoved:theEvent];
|
||||
}
|
||||
|
||||
- (void)otherMouseDragged:(NSEvent*)theEvent
|
||||
{
|
||||
[self mouseMoved:theEvent];
|
||||
|
@ -452,9 +571,9 @@ static inline boo::EMouseButton getButton(NSEvent* event)
|
|||
{
|
||||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[self window] backingScaleFactor];
|
||||
NSRect frame = [self frame];
|
||||
NSPoint liw = [parentView convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
float pixelFactor = [[parentView window] backingScaleFactor];
|
||||
NSRect frame = [parentView frame];
|
||||
boo::SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
|
||||
|
@ -641,7 +760,9 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSString* chars = theEvent.characters;
|
||||
if ([chars length] == 0)
|
||||
if ([chars length] == 0 ||
|
||||
[chars characterAtIndex:0] == '\n' ||
|
||||
[chars characterAtIndex:0] == '\r')
|
||||
booContext->m_callback->specialKeyDown(translateKeycode(theEvent.keyCode),
|
||||
getMod(theEvent.modifierFlags),
|
||||
theEvent.isARepeat);
|
||||
|
@ -669,20 +790,19 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
if (!booContext->m_callback)
|
||||
return;
|
||||
NSUInteger modFlags = theEvent.modifierFlags;
|
||||
bool isRepeat = theEvent.isARepeat;
|
||||
if (modFlags != lastModifiers)
|
||||
{
|
||||
NSUInteger changedFlags = modFlags ^ lastModifiers;
|
||||
|
||||
NSUInteger downFlags = changedFlags & modFlags;
|
||||
if (downFlags & NSControlKeyMask)
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_CTRL, isRepeat);
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_CTRL, false);
|
||||
if (downFlags & NSAlternateKeyMask)
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_ALT, isRepeat);
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_ALT, false);
|
||||
if (downFlags & NSShiftKeyMask)
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_SHIFT, isRepeat);
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_SHIFT, false);
|
||||
if (downFlags & NSCommandKeyMask)
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_COMMAND, isRepeat);
|
||||
booContext->m_callback->modKeyDown(boo::MKEY_COMMAND, false);
|
||||
|
||||
NSUInteger upFlags = changedFlags & ~modFlags;
|
||||
if (upFlags & NSControlKeyMask)
|
||||
|
@ -698,6 +818,94 @@ static boo::ESpecialKey translateKeycode(short code)
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)acceptsTouchEvents
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GraphicsContextCocoaGLInternal
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoaGL*)bctx
|
||||
{
|
||||
resp = [[BooCocoaResponder alloc] initWithBooContext:bctx View:self];
|
||||
boo::IGraphicsContext::EPixelFormat pf = bctx->getPixelFormat();
|
||||
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[pf]];
|
||||
self = [self initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:nspf];
|
||||
if (bctx->m_lastCtx)
|
||||
{
|
||||
NSOpenGLContext* sharedCtx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:bctx->m_lastCtx];
|
||||
[self setOpenGLContext:sharedCtx];
|
||||
[sharedCtx setView:self];
|
||||
}
|
||||
[nspf release];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[resp release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)reshape
|
||||
{
|
||||
boo::SWindowRect rect = {{int(self.frame.origin.x), int(self.frame.origin.y)},
|
||||
{int(self.frame.size.width), int(self.frame.size.height)}};
|
||||
resp->booContext->m_callback->resized(rect);
|
||||
[super reshape];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsTouchEvents
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSResponder*)nextResponder
|
||||
{
|
||||
return resp;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GraphicsContextCocoaMetalInternal
|
||||
- (id)initWithBooContext:(boo::GraphicsContextCocoaMetal*)bctx
|
||||
{
|
||||
resp = [[BooCocoaResponder alloc] initWithBooContext:bctx View:self];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[resp release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsTouchEvents
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSResponder*)nextResponder
|
||||
{
|
||||
return resp;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace boo
|
||||
|
@ -711,12 +919,12 @@ class WindowCocoa : public IWindow
|
|||
|
||||
public:
|
||||
|
||||
WindowCocoa(const std::string& title, NSOpenGLContext* lastGLCtx)
|
||||
WindowCocoa(const std::string& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx)
|
||||
{
|
||||
dispatch_sync(dispatch_get_main_queue(),
|
||||
^{
|
||||
m_nsWindow = [[WindowCocoaInternal alloc] initWithBooWindow:this title:title];
|
||||
m_gfxCtx = _GraphicsContextCocoaNew(IGraphicsContext::API_OPENGL_3_3, this, lastGLCtx);
|
||||
m_gfxCtx = _GraphicsContextCocoaGLNew(IGraphicsContext::API_OPENGL_3_3, this, lastGLCtx);
|
||||
m_gfxCtx->initializeContext();
|
||||
});
|
||||
}
|
||||
|
@ -840,6 +1048,33 @@ public:
|
|||
return TOUCH_TRACKPAD;
|
||||
}
|
||||
|
||||
void setStyle(EWindowStyle style)
|
||||
{
|
||||
if (style & STYLE_TITLEBAR)
|
||||
m_nsWindow.titleVisibility = NSWindowTitleVisible;
|
||||
else
|
||||
m_nsWindow.titleVisibility = NSWindowTitleHidden;
|
||||
|
||||
if (style & STYLE_CLOSE)
|
||||
m_nsWindow.styleMask |= NSClosableWindowMask;
|
||||
else
|
||||
m_nsWindow.styleMask &= ~NSClosableWindowMask;
|
||||
|
||||
if (style & STYLE_RESIZE)
|
||||
m_nsWindow.styleMask |= NSResizableWindowMask;
|
||||
else
|
||||
m_nsWindow.styleMask &= ~NSResizableWindowMask;
|
||||
}
|
||||
|
||||
EWindowStyle getStyle() const
|
||||
{
|
||||
int retval = 0;
|
||||
retval |= m_nsWindow.titleVisibility == NSWindowTitleVisible ? STYLE_TITLEBAR : 0;
|
||||
retval |= (m_nsWindow.styleMask & NSClosableWindowMask) ? STYLE_CLOSE : 0;
|
||||
retval |= (m_nsWindow.styleMask & NSResizableWindowMask) ? STYLE_RESIZE: 0;
|
||||
return EWindowStyle(retval);
|
||||
}
|
||||
|
||||
void waitForRetrace()
|
||||
{
|
||||
static_cast<GraphicsContextCocoa*>(m_gfxCtx)->waitForRetrace();
|
||||
|
@ -867,9 +1102,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx)
|
||||
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx)
|
||||
{
|
||||
return new WindowCocoa(title, lastGLCtx);
|
||||
return new WindowCocoa(title, lastGLCtx, metalCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ int main(int argc, const boo::SystemChar** argv)
|
|||
LogVisor::RegisterConsoleLogger();
|
||||
boo::TestApplicationCallback appCb;
|
||||
int ret = ApplicationRun(boo::IApplication::PLAT_AUTO,
|
||||
appCb, _S("rwk"), _S("RWK"), argc, argv);
|
||||
appCb, _S("boo"), _S("Boo"), argc, argv);
|
||||
printf("IM DYING!!\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue