mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 16:41:09 +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 "gl/system/gl_framebuffer.h"
|
||||||
#include "vulkan/system/vk_framebuffer.h"
|
#include "vulkan/system/vk_framebuffer.h"
|
||||||
|
#include "rendering/polyrenderer/backend/poly_framebuffer.h"
|
||||||
|
|
||||||
|
|
||||||
@implementation NSWindow(ExitAppOnClose)
|
@implementation NSWindow(ExitAppOnClose)
|
||||||
|
@ -293,7 +294,13 @@ CocoaWindow* CreateWindow(const NSUInteger styleMask)
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSOpenGLPixelFormat* CreatePixelFormat()
|
enum class OpenGLProfile
|
||||||
|
{
|
||||||
|
Core,
|
||||||
|
Legacy
|
||||||
|
};
|
||||||
|
|
||||||
|
NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile)
|
||||||
{
|
{
|
||||||
NSOpenGLPixelFormatAttribute attributes[16];
|
NSOpenGLPixelFormatAttribute attributes[16];
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -305,9 +312,13 @@ NSOpenGLPixelFormat* CreatePixelFormat()
|
||||||
attributes[i++] = NSOpenGLPixelFormatAttribute(24);
|
attributes[i++] = NSOpenGLPixelFormatAttribute(24);
|
||||||
attributes[i++] = NSOpenGLPFAStencilSize;
|
attributes[i++] = NSOpenGLPFAStencilSize;
|
||||||
attributes[i++] = NSOpenGLPixelFormatAttribute(8);
|
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)
|
if (!vid_autoswitch)
|
||||||
{
|
{
|
||||||
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
||||||
|
@ -315,12 +326,14 @@ NSOpenGLPixelFormat* CreatePixelFormat()
|
||||||
|
|
||||||
attributes[i] = NSOpenGLPixelFormatAttribute(0);
|
attributes[i] = NSOpenGLPixelFormatAttribute(0);
|
||||||
|
|
||||||
|
assert(i < sizeof attributes / sizeof attributes[0]);
|
||||||
|
|
||||||
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
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)
|
if (nil == pixelFormat)
|
||||||
{
|
{
|
||||||
|
@ -364,13 +377,12 @@ public:
|
||||||
assert(ms_window == nil);
|
assert(ms_window == nil);
|
||||||
ms_window = CreateWindow(STYLE_MASK_WINDOWED);
|
ms_window = CreateWindow(STYLE_MASK_WINDOWED);
|
||||||
|
|
||||||
|
const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];
|
||||||
SystemBaseFrameBuffer *fb = nullptr;
|
SystemBaseFrameBuffer *fb = nullptr;
|
||||||
|
|
||||||
#ifdef HAVE_VULKAN
|
#ifdef HAVE_VULKAN
|
||||||
if (ms_isVulkanEnabled)
|
if (ms_isVulkanEnabled)
|
||||||
{
|
{
|
||||||
const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];
|
|
||||||
|
|
||||||
NSView* vulkanView = [[VulkanCocoaView alloc] initWithFrame:contentRect];
|
NSView* vulkanView = [[VulkanCocoaView alloc] initWithFrame:contentRect];
|
||||||
vulkanView.wantsLayer = YES;
|
vulkanView.wantsLayer = YES;
|
||||||
vulkanView.layer.backgroundColor = NSColor.blackColor.CGColor;
|
vulkanView.layer.backgroundColor = NSColor.blackColor.CGColor;
|
||||||
|
@ -417,13 +429,20 @@ public:
|
||||||
{
|
{
|
||||||
ms_isVulkanEnabled = false;
|
ms_isVulkanEnabled = false;
|
||||||
|
|
||||||
SetupOpenGLView(ms_window);
|
SetupOpenGLView(ms_window, OpenGLProfile::Core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#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)
|
if (fb == nullptr)
|
||||||
|
@ -603,9 +622,17 @@ void SystemBaseFrameBuffer::SetWindowedMode()
|
||||||
|
|
||||||
void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
|
void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
|
||||||
{
|
{
|
||||||
assert(m_window.screen != nil);
|
if ([m_window.contentView isKindOfClass:[OpenGLCocoaView class]])
|
||||||
assert(m_window.contentView.layer != nil);
|
{
|
||||||
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
|
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)
|
if (fullscreen)
|
||||||
{
|
{
|
||||||
|
@ -956,19 +983,90 @@ bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
TArray<uint8_t> polyPixelBuffer;
|
||||||
|
GLuint polyTexture;
|
||||||
|
|
||||||
|
int polyWidth = -1;
|
||||||
|
int polyHeight = -1;
|
||||||
|
int polyVSync = -1;
|
||||||
|
}
|
||||||
|
|
||||||
void I_PolyPresentInit()
|
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)
|
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)
|
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()
|
void I_PolyPresentDeinit()
|
||||||
{
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDeleteTextures(1, &polyTexture);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue