Files
Seele/src/Engine/Graphics/Metal/Window.mm
T

193 lines
7.0 KiB
Plaintext
Raw Normal View History

2024-04-09 16:41:12 +02:00
#include "Window.h"
2024-04-15 13:48:34 +02:00
#include "Command.h"
2024-04-18 13:33:35 +02:00
#include "Foundation/NSAutoreleasePool.hpp"
2024-04-19 18:23:36 +02:00
#include "Foundation/NSString.hpp"
#include "Graphics/Enums.h"
2024-04-10 08:43:56 +02:00
#include "Graphics/Initializer.h"
#include "Graphics/Metal/Enums.h"
2024-04-09 16:41:12 +02:00
#include "Graphics/Texture.h"
2024-04-19 18:23:36 +02:00
#include "Metal/MTLCaptureManager.hpp"
2024-04-10 08:43:56 +02:00
#include "Metal/MTLTexture.hpp"
2024-04-15 13:48:34 +02:00
#include <GLFW/glfw3.h>
2024-04-19 18:23:36 +02:00
#include <fmt/core.h>
2024-04-15 13:48:34 +02:00
#include <iostream>
2024-04-09 16:41:12 +02:00
using namespace Seele;
using namespace Seele::Metal;
double currentFrameDelta = 0;
2024-04-15 13:48:34 +02:00
double Gfx::getCurrentFrameDelta() { return currentFrameDelta; }
2024-04-19 18:23:36 +02:00
uint32 currentFrameIndex = 0;
uint32 Gfx::getCurrentFrameIndex() { return currentFrameIndex; }
2024-04-15 13:48:34 +02:00
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier) {
if (key == -1) {
return;
}
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->keyPress((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseMove(xpos, ypos);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseButton((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->scroll(xoffset, yoffset);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->fileDrop(count, paths);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwCloseCallback(GLFWwindow* handle) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->close();
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->resize(width, height);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphics(graphics), preferences(createInfo) {
glfwSetErrorCallback([](int, const char* description) { std::cout << description << std::endl; });
float xscale = 1, yscale = 1;
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* handle =
glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
windowHandle = handle;
glfwSetWindowUserPointer(handle, this);
glfwSetKeyCallback(handle, &glfwKeyCallback);
glfwSetCursorPosCallback(handle, &glfwMouseMoveCallback);
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
glfwSetScrollCallback(handle, &glfwScrollCallback);
glfwSetDropCallback(handle, &glfwFileCallback);
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
glfwSetFramebufferSizeCallback(handle, &glfwFramebufferResizeCallback);
int width, height;
glfwGetFramebufferSize(handle, &width, &height);
framebufferWidth = width;
framebufferHeight = height;
metalWindow = glfwGetCocoaWindow(handle);
metalLayer = [CAMetalLayer layer];
metalLayer.device = (__bridge id<MTLDevice>)graphics->getDevice();
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
metalLayer.drawableSize = CGSizeMake(createInfo.width, createInfo.height);
metalWindow.contentView.layer = metalLayer;
metalWindow.contentView.wantsLayer = YES;
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
Window::~Window() { glfwDestroyWindow(static_cast<GLFWwindow*>(windowHandle)); }
2024-04-09 16:41:12 +02:00
2024-04-15 13:48:34 +02:00
void Window::pollInput() { glfwPollEvents(); }
2024-04-09 16:41:12 +02:00
2024-04-15 13:48:34 +02:00
void Window::beginFrame() {
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
createBackBuffer();
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Window::endFrame() {
graphics->getQueue()->getCommands()->present(drawable);
graphics->getQueue()->submitCommands();
2024-04-19 18:23:36 +02:00
currentFrameIndex++;
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Window::onWindowCloseEvent() {}
Gfx::PTexture2D Window::getBackBuffer() const { return PTexture2D(backBuffer); }
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) { keyCallback = callback; }
void Window::setMouseMoveCallback(std::function<void(double, double)> callback) { mouseMoveCallback = callback; }
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) {
mouseButtonCallback = callback;
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Window::setScrollCallback(std::function<void(double, double)> callback) { scrollCallback = callback; }
void Window::setFileCallback(std::function<void(int, const char**)> callback) { fileCallback = callback; }
void Window::setCloseCallback(std::function<void()> callback) { closeCallback = callback; }
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) { resizeCallback = callback; }
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) { keyCallback(code, action, modifier); }
void Window::mouseMove(double x, double y) { mouseMoveCallback(x, y); }
void Window::mouseButton(MouseButton button, InputAction action, KeyModifier modifier) {
mouseButtonCallback(button, action, modifier);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Window::scroll(double x, double y) { scrollCallback(x, y); }
2024-04-09 16:41:12 +02:00
2024-04-15 13:48:34 +02:00
void Window::fileDrop(int num, const char** files) { fileCallback(num, files); }
2024-04-09 16:41:12 +02:00
2024-04-15 13:48:34 +02:00
void Window::close() { closeCallback(); }
2024-04-09 16:41:12 +02:00
2024-04-15 13:48:34 +02:00
void Window::resize(int width, int height) {
if (width == 0 || height == 0) {
2024-04-09 16:41:12 +02:00
paused = true;
2024-04-15 13:48:34 +02:00
return;
}
paused = true;
metalLayer.drawableSize = CGSizeMake(width, height);
drawable->release();
framebufferWidth = width;
framebufferHeight = height;
// Deallocate the textures if they have been created
2024-04-18 13:33:35 +02:00
drawable = (__bridge CA::MetalDrawable*)[[metalLayer nextDrawable] autorelease];
2024-04-15 13:48:34 +02:00
createBackBuffer();
resizeCallback(width, height);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Window::createBackBuffer() {
MTL::Texture* buf = drawable->texture();
backBuffer = new Texture2D(graphics,
TextureCreateInfo{
.width = static_cast<uint32>(buf->width()),
.height = static_cast<uint32>(buf->height()),
.depth = static_cast<uint32>(buf->depth()),
.elements = static_cast<uint32>(buf->arrayLength()),
.mipLevels = static_cast<uint32>(buf->mipmapLevelCount()),
.format = cast(buf->pixelFormat()),
.usage = MTL::TextureUsageRenderTarget,
.samples = static_cast<uint32>(buf->sampleCount()),
},
buf);
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::Viewport(owner, createInfo) {
viewport.width = sizeX;
viewport.height = sizeY;
viewport.originX = offsetX;
viewport.originY = offsetY;
viewport.znear = 0.0f;
viewport.zfar = 1.0f;
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
Viewport::~Viewport() {}
void Viewport::resize(uint32 newX, uint32 newY) {
viewport.width = newX;
viewport.height = newY;
2024-04-09 16:41:12 +02:00
}
2024-04-15 13:48:34 +02:00
void Viewport::move(uint32 newOffset, uint32 newOffsetY) {
viewport.originX = newOffset;
viewport.originY = newOffsetY;
2024-04-09 16:41:12 +02:00
}