Ajout de Jolt Physics + 1ere version des factory entitecomposants - camera, transform, rigidbody, collider, renderer
This commit is contained in:
38
lib/All/JoltPhysics/TestFramework/Window/ApplicationWindow.h
Normal file
38
lib/All/JoltPhysics/TestFramework/Window/ApplicationWindow.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
// Responsible for opening the main window
|
||||
class ApplicationWindow
|
||||
{
|
||||
public:
|
||||
/// Destructor
|
||||
virtual ~ApplicationWindow() = default;
|
||||
|
||||
/// Initialize the window
|
||||
virtual void Initialize(const char *inTitle) = 0;
|
||||
|
||||
/// Get window size
|
||||
int GetWindowWidth() { return mWindowWidth; }
|
||||
int GetWindowHeight() { return mWindowHeight; }
|
||||
|
||||
/// Set callback when the window resizes
|
||||
using WindowResizeListener = std::function<void()>;
|
||||
void SetWindowResizeListener(const WindowResizeListener &inListener) { mWindowResizeListener = inListener; }
|
||||
|
||||
/// Enter the main loop and keep rendering frames until the window is closed
|
||||
using RenderCallback = std::function<bool()>;
|
||||
virtual void MainLoop(RenderCallback inRenderCallback) = 0;
|
||||
|
||||
/// Function that will trigger the callback
|
||||
void OnWindowResized(int inWidth, int inHeight) { mWindowWidth = inWidth; mWindowHeight = inHeight; if (mWindowResizeListener) { mWindowResizeListener(); } }
|
||||
|
||||
protected:
|
||||
int mWindowWidth = 1920;
|
||||
int mWindowHeight = 1080;
|
||||
WindowResizeListener mWindowResizeListener;
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <TestFramework.h>
|
||||
|
||||
#include <Window/ApplicationWindowLinux.h>
|
||||
#include <Utils/Log.h>
|
||||
|
||||
ApplicationWindowLinux::~ApplicationWindowLinux()
|
||||
{
|
||||
if (mDisplay)
|
||||
{
|
||||
XDestroyWindow(mDisplay, mWindow);
|
||||
XCloseDisplay(mDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationWindowLinux::Initialize(const char *inTitle)
|
||||
{
|
||||
// Open connection to X server
|
||||
mDisplay = XOpenDisplay(nullptr);
|
||||
if (!mDisplay)
|
||||
FatalError("Failed to open X display");
|
||||
|
||||
// Create a simple window
|
||||
int screen = DefaultScreen(mDisplay);
|
||||
mWindow = XCreateSimpleWindow(mDisplay, RootWindow(mDisplay, screen), 0, 0, mWindowWidth, mWindowHeight, 1, BlackPixel(mDisplay, screen), WhitePixel(mDisplay, screen));
|
||||
|
||||
// Select input events
|
||||
XSelectInput(mDisplay, mWindow, ExposureMask | StructureNotifyMask | KeyPressMask);
|
||||
|
||||
// Set window title
|
||||
XStoreName(mDisplay, mWindow, inTitle);
|
||||
|
||||
// Register WM_DELETE_WINDOW to handle the close button
|
||||
mWmDeleteWindow = XInternAtom(mDisplay, "WM_DELETE_WINDOW", false);
|
||||
XSetWMProtocols(mDisplay, mWindow, &mWmDeleteWindow, 1);
|
||||
|
||||
// Map the window (make it visible)
|
||||
XMapWindow(mDisplay, mWindow);
|
||||
|
||||
// Flush the display to ensure commands are executed
|
||||
XFlush(mDisplay);
|
||||
}
|
||||
|
||||
void ApplicationWindowLinux::MainLoop(RenderCallback inRenderCallback)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
while (XPending(mDisplay) > 0)
|
||||
{
|
||||
XEvent event;
|
||||
XNextEvent(mDisplay, &event);
|
||||
|
||||
if (event.type == ClientMessage && static_cast<Atom>(event.xclient.data.l[0]) == mWmDeleteWindow)
|
||||
{
|
||||
// Handle quit events
|
||||
return;
|
||||
}
|
||||
else if (event.type == ConfigureNotify)
|
||||
{
|
||||
// Handle window resize events
|
||||
XConfigureEvent xce = event.xconfigure;
|
||||
if (xce.width != mWindowWidth || xce.height != mWindowHeight)
|
||||
OnWindowResized(xce.width, xce.height);
|
||||
}
|
||||
else
|
||||
mEventListener(event);
|
||||
}
|
||||
|
||||
// Call the render callback
|
||||
if (!inRenderCallback())
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Window/ApplicationWindow.h>
|
||||
|
||||
// Responsible for opening the main window
|
||||
class ApplicationWindowLinux : public ApplicationWindow
|
||||
{
|
||||
public:
|
||||
/// Destructor
|
||||
~ApplicationWindowLinux();
|
||||
|
||||
/// Initialize the window
|
||||
virtual void Initialize(const char *inTitle) override;
|
||||
|
||||
/// Access to the window handle
|
||||
Display * GetDisplay() const { return mDisplay; }
|
||||
Window GetWindow() const { return mWindow; }
|
||||
|
||||
/// Event listener for the keyboard handler
|
||||
using EventListener = std::function<void(const XEvent &)>;
|
||||
void SetEventListener(const EventListener &inListener) { mEventListener = inListener; }
|
||||
|
||||
/// Enter the main loop and keep rendering frames until the window is closed
|
||||
void MainLoop(RenderCallback inRenderCallback) override;
|
||||
|
||||
protected:
|
||||
Display * mDisplay;
|
||||
Window mWindow;
|
||||
Atom mWmDeleteWindow;
|
||||
EventListener mEventListener;
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Window/ApplicationWindow.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
@class MTKView;
|
||||
@class CAMetalLayer;
|
||||
#else
|
||||
typedef void MTKView;
|
||||
typedef void CAMetalLayer;
|
||||
#endif
|
||||
|
||||
// Responsible for opening the main window
|
||||
class ApplicationWindowMacOS : public ApplicationWindow
|
||||
{
|
||||
public:
|
||||
/// Destructor
|
||||
virtual ~ApplicationWindowMacOS() override;
|
||||
|
||||
/// Initialize the window
|
||||
virtual void Initialize(const char *inTitle) override;
|
||||
|
||||
/// Access to the metal objects
|
||||
MTKView * GetMetalView() const { return mMetalView; }
|
||||
CAMetalLayer * GetMetalLayer() const;
|
||||
|
||||
/// Enter the main loop and keep rendering frames until the window is closed
|
||||
virtual void MainLoop(RenderCallback inRenderCallback) override;
|
||||
|
||||
/// Call the render callback
|
||||
bool RenderCallback() { return mRenderCallback && mRenderCallback(); }
|
||||
|
||||
/// Subscribe to mouse move callbacks that supply window coordinates
|
||||
using MouseMovedCallback = function<void(int, int)>;
|
||||
void SetMouseMovedCallback(MouseMovedCallback inCallback) { mMouseMovedCallback = inCallback; }
|
||||
void OnMouseMoved(int inX, int inY) { mMouseMovedCallback(inX, inY); }
|
||||
|
||||
protected:
|
||||
MTKView * mMetalView = nullptr;
|
||||
ApplicationWindow::RenderCallback mRenderCallback;
|
||||
MouseMovedCallback mMouseMovedCallback;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <TestFramework.h>
|
||||
|
||||
#include <Window/ApplicationWindowMacOS.h>
|
||||
|
||||
#import <MetalKit/MetalKit.h>
|
||||
|
||||
// This class implements a metal view
|
||||
@interface MetalView : MTKView <MTKViewDelegate>
|
||||
@end
|
||||
|
||||
@implementation MetalView
|
||||
{
|
||||
ApplicationWindowMacOS *mWindow;
|
||||
}
|
||||
|
||||
- (MetalView *)init:(ApplicationWindowMacOS *)window
|
||||
{
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
self = [super initWithFrame: NSMakeRect(0, 0, window->GetWindowWidth(), window->GetWindowHeight()) device: device];
|
||||
[device release];
|
||||
|
||||
mWindow = window;
|
||||
|
||||
self.delegate = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyView
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)event
|
||||
{
|
||||
NSPoint location_in_view = [self convertPoint: event.locationInWindow fromView: nil];
|
||||
NSPoint location_in_backing = [self convertPointToBacking: location_in_view];
|
||||
mWindow->OnMouseMoved(location_in_backing.x, -location_in_backing.y);
|
||||
}
|
||||
|
||||
- (void)drawInMTKView:(MTKView *)view
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
mWindow->RenderCallback();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||
{
|
||||
mWindow->OnWindowResized(size.width, size.height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// This is the main application delegate that tells us if we're starting / stopping
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
// Add the Quit button to the first menu item on the toolbar
|
||||
NSMenu *app_menu = [[NSApp mainMenu] itemAtIndex: 0].submenu;
|
||||
NSMenuItem *quit_item = [[NSMenuItem alloc] initWithTitle: @"Quit" action: @selector(terminate:) keyEquivalent: @"q"];
|
||||
[app_menu addItem: quit_item];
|
||||
}
|
||||
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
// Close the app when the window is closed
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
ApplicationWindowMacOS::~ApplicationWindowMacOS()
|
||||
{
|
||||
[mMetalView release];
|
||||
}
|
||||
|
||||
void ApplicationWindowMacOS::Initialize(const char *inTitle)
|
||||
{
|
||||
// Create metal view
|
||||
MetalView *view = [[MetalView alloc] init: this];
|
||||
view.clearColor = MTLClearColorMake(0.098f, 0.098f, 0.439f, 1.000f);
|
||||
view.depthStencilPixelFormat = MTLPixelFormatDepth32Float;
|
||||
view.clearDepth = 0.0f;
|
||||
mMetalView = view;
|
||||
|
||||
// Create window
|
||||
NSWindow *window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, mWindowWidth, mWindowHeight)
|
||||
styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
|
||||
backing: NSBackingStoreBuffered
|
||||
defer: NO];
|
||||
window.contentView = view;
|
||||
[window setAcceptsMouseMovedEvents: YES];
|
||||
[window setTitle: [NSString stringWithCString: inTitle encoding: NSUTF8StringEncoding]];
|
||||
[window makeKeyAndOrderFront: nil];
|
||||
}
|
||||
|
||||
void ApplicationWindowMacOS::MainLoop(ApplicationWindow::RenderCallback inRenderCallback)
|
||||
{
|
||||
mRenderCallback = inRenderCallback;
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
AppDelegate *delegate = [[AppDelegate alloc] init];
|
||||
[app setDelegate: delegate];
|
||||
[app run];
|
||||
[delegate release];
|
||||
}
|
||||
}
|
||||
|
||||
CAMetalLayer *ApplicationWindowMacOS::GetMetalLayer() const
|
||||
{
|
||||
return (CAMetalLayer *)mMetalView.layer;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <TestFramework.h>
|
||||
|
||||
#include <Window/ApplicationWindowWin.h>
|
||||
#include <Utils/Log.h>
|
||||
#include <shellscalingapi.h>
|
||||
|
||||
static ApplicationWindowWin *sWindow = nullptr;
|
||||
|
||||
// Called every time the application receives a message
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_PAINT:
|
||||
BeginPaint(hWnd, &ps);
|
||||
EndPaint(hWnd, &ps);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if (sWindow != nullptr)
|
||||
{
|
||||
// Get new window size
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
int width = max<int>(rc.right - rc.left, 8);
|
||||
int height = max<int>(rc.bottom - rc.top, 8);
|
||||
sWindow->OnWindowResized(width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ApplicationWindowWin::Initialize(const char *inTitle)
|
||||
{
|
||||
// Prevent this window from auto scaling
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
|
||||
// Register class
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = GetModuleHandle(nullptr);
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = nullptr;
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = TEXT("TestFrameworkClass");
|
||||
wcex.hIconSm = nullptr;
|
||||
if (!RegisterClassEx(&wcex))
|
||||
FatalError("Failed to register window class");
|
||||
|
||||
// Create window
|
||||
RECT rc = { 0, 0, mWindowWidth, mWindowHeight };
|
||||
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
mhWnd = CreateWindow(TEXT("TestFrameworkClass"), inTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, wcex.hInstance, nullptr);
|
||||
if (!mhWnd)
|
||||
FatalError("Failed to create window");
|
||||
|
||||
// Show window
|
||||
ShowWindow(mhWnd, SW_SHOW);
|
||||
|
||||
// Store the window pointer for the message loop
|
||||
sWindow = this;
|
||||
}
|
||||
|
||||
void ApplicationWindowWin::MainLoop(RenderCallback inRenderCallback)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
// Main message loop
|
||||
MSG msg = {};
|
||||
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
// Handle quit events
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Call the render callback
|
||||
if (!inRenderCallback())
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Window/ApplicationWindow.h>
|
||||
|
||||
// Responsible for opening the main window
|
||||
class ApplicationWindowWin : public ApplicationWindow
|
||||
{
|
||||
public:
|
||||
/// Initialize the window
|
||||
virtual void Initialize(const char *inTitle) override;
|
||||
|
||||
/// Access to the window handle
|
||||
HWND GetWindowHandle() const { return mhWnd; }
|
||||
|
||||
/// Enter the main loop and keep rendering frames until the window is closed
|
||||
virtual void MainLoop(RenderCallback inRenderCallback) override;
|
||||
|
||||
protected:
|
||||
HWND mhWnd;
|
||||
};
|
||||
Reference in New Issue
Block a user