initial appkit window/glcontext implementation

This commit is contained in:
Jack Andersen 2015-05-04 13:37:28 -10:00
parent cf9e12c650
commit afe93bee38
9 changed files with 401 additions and 131 deletions

View File

@ -1,21 +1,7 @@
#ifndef BOO_HPP #ifndef BOO_HPP
#define BOO_HPP #define BOO_HPP
#if defined(_WIN32) #include "windowsys/IWindow.hpp"
#include "win/CWGLContext.hpp"
namespace boo {typedef CWGLContext CGraphicsContext;}
#elif defined(__APPLE__)
#include "mac/CCGLContext.hpp"
namespace boo {typedef CCGLContext CGraphicsContext;}
#elif defined(__GNUC__) || defined(__clang__)
#include "x11/CGLXContext.hpp"
namespace boo {typedef CGLXContext CGraphicsContext;}
#endif
#include "IGraphicsContext.hpp"
#include "inputdev/CDeviceFinder.hpp" #include "inputdev/CDeviceFinder.hpp"
#include "inputdev/CDolphinSmashAdapter.hpp" #include "inputdev/CDolphinSmashAdapter.hpp"

View File

@ -1,34 +0,0 @@
#ifndef CCGLCONTEXT_HPP
#define CCGLCONTEXT_HPP
#ifdef __APPLE__
#include "IGraphicsContext.hpp"
#include <OpenGL/OpenGL.h>
namespace boo
{
class CCGLContext final : public IGraphicsContext
{
public:
CCGLContext();
virtual ~CCGLContext();
bool create();
void setMinVersion (const int& min) override;
void setMajorVersion(const int& maj) override;
const std::string version() const override;
const std::string name() const override;
int depthSize() const override;
int redDepth() const override;
int greenDepth() const override;
int blueDepth() const override;
private:
int m_minVersion;
int m_majVersion;
};
}
#endif // __APPLE__
#endif // CCGLCONTEXT_HPP

View File

@ -0,0 +1,52 @@
#ifndef IGRAPHICSCONTEXT_HPP
#define IGRAPHICSCONTEXT_HPP
namespace boo
{
class IGraphicsContext
{
public:
enum EGraphicsAPI
{
API_NONE = 0,
API_OPENGL_3_3 = 1,
API_OPENGL_4_2 = 2,
API_OPENGLES_3 = 3,
API_VULKAN = 4,
API_D3D11 = 5,
API_METAL = 6
};
enum EPixelFormat
{
PF_NONE = 0,
PF_RGBA8 = 1, /* Default */
PF_RGBA8_Z24 = 2,
PF_RGBAF32 = 3,
PF_RGBAF32_Z24 = 4
};
virtual ~IGraphicsContext() {}
virtual EGraphicsAPI getAPI() const=0;
virtual EPixelFormat getPixelFormat() const=0;
virtual void setPixelFormat(EPixelFormat pf)=0;
virtual void setPlatformWindowHandle(void* handle)=0;
virtual void initializeContext()=0;
virtual IGraphicsContext* makeShareContext() const=0;
virtual void makeCurrent()=0;
virtual void clearCurrent()=0;
/* Note: *all* contexts are double-buffered with
* v-sync interval; please call this */
virtual void swapBuffer()=0;
};
IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api);
}
#endif // IGRAPHICSCONTEXT_HPP

View File

@ -0,0 +1,34 @@
#ifndef IWINDOW_HPP
#define IWINDOW_HPP
#include <string>
namespace boo
{
class IWindow
{
public:
virtual ~IWindow() {}
virtual void showWindow()=0;
virtual void hideWindow()=0;
virtual std::string getTitle()=0;
virtual void setTitle(const std::string& title)=0;
virtual void setWindowFrameDefault()=0;
virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0;
virtual void setWindowFrame(float x, float y, float w, float h)=0;
virtual bool isFullscreen() const=0;
virtual void setFullscreen(bool fs)=0;
};
IWindow* IWindowNew();
}
#endif // IWINDOW_HPP

View File

@ -1,12 +1,7 @@
HEADERS += \ HEADERS += \
$$PWD/include/boo.hpp \ $$PWD/include/boo.hpp \
$$PWD/include/IGraphicsContext.hpp \ $$PWD/include/windowsys/IWindow.hpp \
$$PWD/include/ISurface.hpp \ $$PWD/include/windowsys/IGraphicsContext.hpp \
$$PWD/include/CSurface.hpp \
$$PWD/include/IRetraceWaiter.hpp \
$$PWD/include/IInputWaiter.hpp \
$$PWD/include/CInputRelay.hpp \
$$PWD/include/CInputDeferredRelay.hpp \
$$PWD/include/inputdev/CDolphinSmashAdapter.hpp \ $$PWD/include/inputdev/CDolphinSmashAdapter.hpp \
$$PWD/include/inputdev/CRevolutionPad.hpp \ $$PWD/include/inputdev/CRevolutionPad.hpp \
$$PWD/include/inputdev/CCafeProPad.hpp \ $$PWD/include/inputdev/CCafeProPad.hpp \
@ -36,7 +31,6 @@ SOURCES += \
unix:!macx { unix:!macx {
HEADERS += \ HEADERS += \
$$PWD/include/x11/CGLXContext.hpp $$PWD/include/x11/CGLXContext.hpp
SOURCES += \ SOURCES += \
$$PWD/src/x11/CGLXContext.cpp $$PWD/src/x11/CGLXContext.cpp
} }
@ -45,21 +39,17 @@ linux {
SOURCES += \ SOURCES += \
$$PWD/src/inputdev/CHIDListenerUdev.cpp \ $$PWD/src/inputdev/CHIDListenerUdev.cpp \
$$PWD/src/inputdev/CHIDDeviceUdev.cpp $$PWD/src/inputdev/CHIDDeviceUdev.cpp
LIBS += -ludev LIBS += -ludev
} }
macx { macx {
HEADERS += \
$$PWD/include/mac/CCGLContext.hpp
SOURCES += \ SOURCES += \
$$PWD/src/mac/CCGLContext.cpp \
$$PWD/src/inputdev/CHIDDeviceIOKit.cpp \ $$PWD/src/inputdev/CHIDDeviceIOKit.cpp \
$$PWD/src/inputdev/CHIDListenerIOKit.cpp $$PWD/src/inputdev/CHIDListenerIOKit.cpp
OBJECTIVE_SOURCES += \ OBJECTIVE_SOURCES += \
$$PWD/src/mac/CCGLCocoaView.mm $$PWD/src/windowsys/CWindowCocoa.mm \
$$PWD/src/windowsys/CGraphicsContextCocoa.mm
LIBS += -framework AppKit
} }
win32 { win32 {

View File

@ -1,67 +0,0 @@
#ifdef __APPLE__
#include "CCGLContext.hpp"
#include <iostream>
namespace boo
{
CCGLContext::CCGLContext()
: m_minVersion(3),
m_majVersion(3)
{
std::cout << "Hello from CGL" << std::endl;
}
CCGLContext::~CCGLContext()
{
}
bool CCGLContext::create()
{
return true;
}
void CCGLContext::setMinVersion(const int& min)
{
m_minVersion = min;
}
void CCGLContext::setMajorVersion(const int& maj)
{
m_majVersion = maj;
}
const std::string CCGLContext::version() const
{
return "Invalid version";
}
const std::string CCGLContext::name() const
{
return "GLX Context";
}
int CCGLContext::depthSize() const
{
return -1;
}
int CCGLContext::redDepth() const
{
return -1;
}
int CCGLContext::greenDepth() const
{
return -1;
}
int CCGLContext::blueDepth() const
{
return -1;
}
}
#endif

View File

@ -0,0 +1,207 @@
#import <AppKit/AppKit.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h>
#include "windowsys/IGraphicsContext.hpp"
static const NSOpenGLPixelFormatAttribute PF_RGBA8_ATTRS[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
};
static const NSOpenGLPixelFormatAttribute PF_RGBA8_Z24_ATTRS[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
};
static const NSOpenGLPixelFormatAttribute PF_RGBAF32_ATTRS[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorFloat,
NSOpenGLPFAColorSize, 96,
NSOpenGLPFAAlphaSize, 32,
};
static const NSOpenGLPixelFormatAttribute PF_RGBAF32_Z24_ATTRS[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorFloat,
NSOpenGLPFAColorSize, 96,
NSOpenGLPFAAlphaSize, 32,
NSOpenGLPFADepthSize, 24,
};
static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
{
NULL,
PF_RGBA8_ATTRS,
PF_RGBA8_Z24_ATTRS,
PF_RGBAF32_ATTRS,
PF_RGBAF32_Z24_ATTRS
};
namespace boo {class CGraphicsContextCocoa;}
@interface CGraphicsContextCocoaInternal : NSOpenGLView
- (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx;
@end
namespace boo
{
class CGraphicsContextCocoa final : public IGraphicsContext
{
EGraphicsAPI m_api;
EPixelFormat m_pf;
NSWindow* m_parentWindow;
CGraphicsContextCocoaInternal* m_nsContext;
NSOpenGLContext* m_nsShareContext;
public:
CGraphicsContextCocoa(EGraphicsAPI api)
: m_api(api),
m_pf(PF_RGBA8),
m_parentWindow(NULL),
m_nsContext(NULL),
m_nsShareContext(NULL)
{}
~CGraphicsContextCocoa()
{
[m_nsContext release];
[m_nsShareContext release];
}
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 setPlatformWindowHandle(void* handle)
{
m_parentWindow = (NSWindow*)handle;
}
void initializeContext()
{
if (m_nsShareContext)
return;
m_nsContext = [[CGraphicsContextCocoaInternal alloc] initWithBooContext:this];
[m_parentWindow setContentView:m_nsContext];
}
IGraphicsContext* makeShareContext() const
{
NSOpenGLContext* nsctx;
if (m_nsContext)
{
nsctx = [[NSOpenGLContext alloc] initWithFormat:[m_nsContext pixelFormat]
shareContext:[m_nsContext openGLContext]];
}
else if (m_nsShareContext)
{
nsctx = [[NSOpenGLContext alloc] initWithFormat:[m_nsShareContext pixelFormat]
shareContext:m_nsShareContext];
}
else
return NULL;
if (!nsctx)
return NULL;
CGraphicsContextCocoa* newCtx = new CGraphicsContextCocoa(m_api);
newCtx->m_nsShareContext = nsctx;
return newCtx;
}
void makeCurrent()
{
if (m_nsContext)
[[m_nsContext openGLContext] makeCurrentContext];
else if (m_nsShareContext)
[m_nsShareContext makeCurrentContext];
}
void clearCurrent()
{
[NSOpenGLContext clearCurrentContext];
}
void swapBuffer()
{
[[m_nsContext openGLContext] flushBuffer];
}
};
IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api)
{
if (api != IGraphicsContext::API_OPENGL_3_3 && api != IGraphicsContext::API_OPENGL_4_2)
return NULL;
/* Create temporary context to query GL version */
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_RGBA8_ATTRS];
if (!nspf)
return NULL;
NSOpenGLContext* nsctx = [[NSOpenGLContext alloc] initWithFormat:nspf shareContext:nil];
[nspf release];
if (!nsctx)
return NULL;
[nsctx makeCurrentContext];
const char* glVersion = (char*)glGetString(GL_VERSION);
unsigned major = 0;
unsigned minor = 0;
if (glVersion)
{
major = glVersion[0] - '0';
minor = glVersion[2] - '0';
}
[NSOpenGLContext clearCurrentContext];
[nsctx release];
if (!glVersion)
return NULL;
if (major > 4 || (major == 4 && minor >= 2))
api = IGraphicsContext::API_OPENGL_4_2;
else if (major == 3 && minor >= 3)
if (api == IGraphicsContext::API_OPENGL_4_2)
return NULL;
return new CGraphicsContextCocoa(api);
}
}
@implementation CGraphicsContextCocoaInternal
- (id)initWithBooContext:(boo::CGraphicsContextCocoa*)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];
[nspf release];
return self;
}
@end

View File

@ -0,0 +1,102 @@
#import <AppKit/AppKit.h>
#include "windowsys/IWindow.hpp"
#include "windowsys/IGraphicsContext.hpp"
@interface CWindowCocoaInternal : NSWindow
@end
namespace boo
{
class CWindowCocoa final : public IWindow
{
CWindowCocoaInternal* m_nsWindow;
IGraphicsContext* m_gfxCtx;
public:
CWindowCocoa()
{
m_nsWindow = [CWindowCocoaInternal new];
m_gfxCtx = IGraphicsContextNew(IGraphicsContext::API_OPENGL_3_3);
m_gfxCtx->setPlatformWindowHandle(m_nsWindow);
m_gfxCtx->initializeContext();
}
~CWindowCocoa()
{
[m_nsWindow orderOut:nil];
[m_nsWindow release];
delete m_gfxCtx;
}
void showWindow()
{
[m_nsWindow makeKeyAndOrderFront:nil];
}
void hideWindow()
{
[m_nsWindow orderOut:nil];
}
std::string getTitle()
{
return [[m_nsWindow title] UTF8String];
}
void setTitle(const std::string& title)
{
[m_nsWindow setTitle:[NSString stringWithUTF8String:title.c_str()]];
}
void setWindowFrameDefault()
{
NSScreen* mainScreen = [NSScreen mainScreen];
NSRect scrFrame = mainScreen.frame;
float x_off = scrFrame.size.width / 3.0;
float y_off = scrFrame.size.height / 3.0;
[m_nsWindow setFrame:NSMakeRect(x_off, y_off, x_off * 2.0, y_off * 2.0) display:NO];
}
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
{
NSRect wFrame = m_nsWindow.frame;
xOut = wFrame.origin.x;
yOut = wFrame.origin.y;
wOut = wFrame.size.width;
hOut = wFrame.size.height;
}
void setWindowFrame(float x, float y, float w, float h)
{
NSRect wFrame = NSMakeRect(x, y, w, h);
[m_nsWindow setFrame:wFrame display:NO];
}
bool isFullscreen() const
{
return ([m_nsWindow styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask;
}
void setFullscreen(bool fs)
{
if ((fs && !isFullscreen()) || (!fs && isFullscreen()))
[m_nsWindow toggleFullScreen:nil];
}
};
IWindow* IWindowNew()
{
return new CWindowCocoa;
}
}
@implementation CWindowCocoaInternal
{
}
@end