mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
- added support for softpoly backend on macOS
Grabbed most of code from old Cocoa backend with separate code path for software rendering
This commit is contained in:
parent
75248cffd0
commit
e4587138bb
1 changed files with 112 additions and 14 deletions
|
@ -57,6 +57,7 @@
|
|||
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
#include "rendering/polyrenderer/backend/poly_framebuffer.h"
|
||||
|
||||
|
||||
@implementation NSWindow(ExitAppOnClose)
|
||||
|
@ -293,7 +294,13 @@ CocoaWindow* CreateWindow(const NSUInteger styleMask)
|
|||
return window;
|
||||
}
|
||||
|
||||
NSOpenGLPixelFormat* CreatePixelFormat()
|
||||
enum class OpenGLProfile
|
||||
{
|
||||
Core,
|
||||
Legacy
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attributes[16];
|
||||
size_t i = 0;
|
||||
|
@ -305,9 +312,13 @@ NSOpenGLPixelFormat* CreatePixelFormat()
|
|||
attributes[i++] = NSOpenGLPixelFormatAttribute(24);
|
||||
attributes[i++] = NSOpenGLPFAStencilSize;
|
||||
attributes[i++] = NSOpenGLPixelFormatAttribute(8);
|
||||
attributes[i++] = NSOpenGLPFAOpenGLProfile;
|
||||
attributes[i++] = NSOpenGLProfileVersion3_2Core;
|
||||
|
||||
|
||||
if (profile == OpenGLProfile::Core)
|
||||
{
|
||||
attributes[i++] = NSOpenGLPFAOpenGLProfile;
|
||||
attributes[i++] = NSOpenGLProfileVersion3_2Core;
|
||||
}
|
||||
|
||||
if (!vid_autoswitch)
|
||||
{
|
||||
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
||||
|
@ -315,12 +326,14 @@ NSOpenGLPixelFormat* CreatePixelFormat()
|
|||
|
||||
attributes[i] = NSOpenGLPixelFormatAttribute(0);
|
||||
|
||||
assert(i < sizeof attributes / sizeof attributes[0]);
|
||||
|
||||
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||
}
|
||||
|
||||
void SetupOpenGLView(CocoaWindow* window)
|
||||
void SetupOpenGLView(CocoaWindow* const window, const OpenGLProfile profile)
|
||||
{
|
||||
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat();
|
||||
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat(profile);
|
||||
|
||||
if (nil == pixelFormat)
|
||||
{
|
||||
|
@ -364,13 +377,12 @@ public:
|
|||
assert(ms_window == nil);
|
||||
ms_window = CreateWindow(STYLE_MASK_WINDOWED);
|
||||
|
||||
const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];
|
||||
SystemBaseFrameBuffer *fb = nullptr;
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
if (ms_isVulkanEnabled)
|
||||
{
|
||||
const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];
|
||||
|
||||
NSView* vulkanView = [[VulkanCocoaView alloc] initWithFrame:contentRect];
|
||||
vulkanView.wantsLayer = YES;
|
||||
vulkanView.layer.backgroundColor = NSColor.blackColor.CGColor;
|
||||
|
@ -417,13 +429,20 @@ public:
|
|||
{
|
||||
ms_isVulkanEnabled = false;
|
||||
|
||||
SetupOpenGLView(ms_window);
|
||||
SetupOpenGLView(ms_window, OpenGLProfile::Core);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (vid_preferbackend == 2)
|
||||
{
|
||||
SetupOpenGLView(ms_window);
|
||||
SetupOpenGLView(ms_window, OpenGLProfile::Legacy);
|
||||
|
||||
fb = new PolyFrameBuffer(nullptr, fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupOpenGLView(ms_window, OpenGLProfile::Core);
|
||||
}
|
||||
|
||||
if (fb == nullptr)
|
||||
|
@ -603,9 +622,17 @@ void SystemBaseFrameBuffer::SetWindowedMode()
|
|||
|
||||
void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
|
||||
{
|
||||
assert(m_window.screen != nil);
|
||||
assert(m_window.contentView.layer != nil);
|
||||
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
|
||||
if ([m_window.contentView isKindOfClass:[OpenGLCocoaView class]])
|
||||
{
|
||||
NSOpenGLView* const glView = [m_window contentView];
|
||||
[glView setWantsBestResolutionOpenGLSurface:hiDPI];
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(m_window.screen != nil);
|
||||
assert(m_window.contentView.layer != nil);
|
||||
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
|
||||
}
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
|
@ -956,19 +983,90 @@ bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
TArray<uint8_t> polyPixelBuffer;
|
||||
GLuint polyTexture;
|
||||
|
||||
int polyWidth = -1;
|
||||
int polyHeight = -1;
|
||||
int polyVSync = -1;
|
||||
}
|
||||
|
||||
void I_PolyPresentInit()
|
||||
{
|
||||
ogl_LoadFunctions();
|
||||
|
||||
glGenTextures(1, &polyTexture);
|
||||
assert(polyTexture != 0);
|
||||
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, polyTexture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
uint8_t *I_PolyPresentLock(int w, int h, bool vsync, int &pitch)
|
||||
{
|
||||
return nullptr;
|
||||
static const int PIXEL_BYTES = 4;
|
||||
|
||||
if (polyPixelBuffer.Size() == 0 || w != polyWidth || h != polyHeight)
|
||||
{
|
||||
polyPixelBuffer.Resize(w * h * PIXEL_BYTES);
|
||||
|
||||
polyWidth = w;
|
||||
polyHeight = h;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, w, h, 0.0, -1.0, 1.0);
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
if (vsync != polyVSync)
|
||||
{
|
||||
const GLint value = vsync ? 1 : 0;
|
||||
|
||||
[[NSOpenGLContext currentContext] setValues:&value
|
||||
forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
pitch = w * PIXEL_BYTES;
|
||||
|
||||
return &polyPixelBuffer[0];
|
||||
}
|
||||
|
||||
void I_PolyPresentUnlock(int x, int y, int w, int h)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, &polyPixelBuffer[0]);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(0.0f, 0.0f);
|
||||
glTexCoord2f(w, 0.0f);
|
||||
glVertex2f(w, 0.0f);
|
||||
glTexCoord2f(w, h);
|
||||
glVertex2f(w, h);
|
||||
glTexCoord2f(0.0f, h);
|
||||
glVertex2f(0.0f, h);
|
||||
glEnd();
|
||||
|
||||
glFlush();
|
||||
|
||||
[[NSOpenGLContext currentContext] flushBuffer];
|
||||
}
|
||||
|
||||
void I_PolyPresentDeinit()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &polyTexture);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue