243 lines
5.6 KiB
C++
243 lines
5.6 KiB
C++
#include "rendering.h"
|
|
#include "tier0/platform.h"
|
|
#include "tier1/utlvector.h"
|
|
#include "console.h"
|
|
#include "tier1/commandline.h"
|
|
#include "input.h"
|
|
|
|
#define NS_PRIVATE_IMPLEMENTATION
|
|
#define MTL_PRIVATE_IMPLEMENTATION
|
|
#define MTK_PRIVATE_IMPLEMENTATION
|
|
#define CA_PRIVATE_IMPLEMENTATION
|
|
|
|
#include "tier0/minmax_off.h"
|
|
#include "QuartzCore/CAMetalLayer.hpp"
|
|
#include "Metal/Metal.hpp"
|
|
|
|
#include "SDL3/SDL.h"
|
|
#include "SDL3/SDL_keycode.h"
|
|
#include "SDL3/SDL_metal.h"
|
|
#include "SDL3/SDL_events.h"
|
|
#include "tier0/minmax.h"
|
|
#include "ml_video.h"
|
|
|
|
char g_bConfigNotify = 0;
|
|
uint32_t g_nWindowWidth = 1280;
|
|
uint32_t g_nWindowHeight = 720;
|
|
|
|
SDL_Window *g_window;
|
|
SDL_MetalView g_mlView;
|
|
CA::MetalLayer *g_mlLayer;
|
|
MTL::Device *g_mlDevice;
|
|
MTL::CommandQueue *g_mlCommandQueue;
|
|
MTL::CommandBuffer *g_mlCommandBuffer;
|
|
NS::AutoreleasePool *g_mlPool;
|
|
MTL::Texture *g_mlDrawableTexture;
|
|
|
|
MTL::PixelFormat g_swapchainFormat;
|
|
|
|
|
|
#if defined(__APPLE__) && defined(__MACH__)
|
|
#include "TargetConditionals.h"
|
|
#if TARGET_OS_IPHONE
|
|
// iOS
|
|
#define SDL_METAL_VIEW UI::View
|
|
#define STBI_NO_THREAD_LOCALS
|
|
#else
|
|
// macOS
|
|
#define SDL_METAL_VIEW NS::View
|
|
#endif
|
|
#else
|
|
// Other platforms
|
|
#endif
|
|
|
|
void IInput::SetMouseMode( EMouseMode mode )
|
|
{
|
|
switch (mode)
|
|
{
|
|
case MOUSE_MODE_GAME:
|
|
SDL_SetWindowRelativeMouseMode(g_window, true);
|
|
return;
|
|
default:
|
|
SDL_SetWindowRelativeMouseMode(g_window, false);
|
|
return;
|
|
}
|
|
}
|
|
|
|
EInputKey ISDL_KeyName(SDL_Keycode key)
|
|
{
|
|
switch(key)
|
|
{
|
|
case SDLK_ESCAPE: return KEY_ESCAPE;
|
|
|
|
case SDLK_1: return KEY_1;
|
|
case SDLK_2: return KEY_2;
|
|
case SDLK_3: return KEY_3;
|
|
case SDLK_4: return KEY_4;
|
|
case SDLK_5: return KEY_5;
|
|
case SDLK_6: return KEY_6;
|
|
case SDLK_7: return KEY_7;
|
|
case SDLK_8: return KEY_8;
|
|
case SDLK_9: return KEY_9;
|
|
case SDLK_0: return KEY_0;
|
|
|
|
case SDLK_A: return KEY_A;
|
|
case SDLK_B: return KEY_B;
|
|
case SDLK_C: return KEY_C;
|
|
case SDLK_D: return KEY_D;
|
|
case SDLK_E: return KEY_E;
|
|
case SDLK_F: return KEY_F;
|
|
case SDLK_G: return KEY_G;
|
|
case SDLK_H: return KEY_H;
|
|
case SDLK_I: return KEY_I;
|
|
case SDLK_J: return KEY_J;
|
|
case SDLK_K: return KEY_K;
|
|
case SDLK_L: return KEY_L;
|
|
case SDLK_M: return KEY_M;
|
|
case SDLK_N: return KEY_N;
|
|
case SDLK_O: return KEY_O;
|
|
case SDLK_P: return KEY_P;
|
|
case SDLK_Q: return KEY_Q;
|
|
case SDLK_R: return KEY_R;
|
|
case SDLK_S: return KEY_S;
|
|
case SDLK_T: return KEY_T;
|
|
case SDLK_U: return KEY_U;
|
|
case SDLK_V: return KEY_V;
|
|
case SDLK_W: return KEY_W;
|
|
case SDLK_X: return KEY_X;
|
|
case SDLK_Y: return KEY_Y;
|
|
case SDLK_Z: return KEY_Z;
|
|
}
|
|
return KEY_NONE;
|
|
};
|
|
|
|
void IVideo_HandleEvents()
|
|
{
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event))
|
|
{
|
|
SDL_KeyboardEvent *key = &event.key;
|
|
SDL_MouseMotionEvent *motion = &event.motion;
|
|
switch (event.type)
|
|
{
|
|
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
|
g_nWindowWidth = event.window.data1;
|
|
g_nWindowHeight = event.window.data2;
|
|
g_bConfigNotify = 2;
|
|
break;
|
|
case SDL_EVENT_KEY_DOWN:
|
|
if (!key->repeat)
|
|
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN);
|
|
break;
|
|
case SDL_EVENT_KEY_UP:
|
|
key = &event.key;
|
|
if (!key->repeat)
|
|
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP);
|
|
break;
|
|
case SDL_EVENT_MOUSE_MOTION:
|
|
IInput::AxisEvent(AXIS_MOUSE_X, motion->yrel*0.022);
|
|
IInput::AxisEvent(AXIS_MOUSE_Y, -motion->xrel*0.022);
|
|
break;
|
|
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
|
{
|
|
SDL_GamepadAxis axis = (SDL_GamepadAxis)event.gaxis.axis;
|
|
float value = event.gaxis.value / 32768.0f;
|
|
if (abs(event.gaxis.value)<1000)
|
|
value = 0;
|
|
SDL_JoystickID id = event.gaxis.which;
|
|
|
|
if (axis == SDL_GAMEPAD_AXIS_RIGHTY)
|
|
{
|
|
IInput::AxisEvent(AXIS_CONTROLLER_PITCH, value);
|
|
}
|
|
if (axis == SDL_GAMEPAD_AXIS_RIGHTX)
|
|
{
|
|
IInput::AxisEvent(AXIS_CONTROLLER_YAW, -value);
|
|
}
|
|
}
|
|
break;
|
|
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
|
break;
|
|
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
void APPLE_ConfigureLayer(CA::MetalLayer* pMetalLayer);
|
|
void IVideo::Init()
|
|
{
|
|
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "0");
|
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD);
|
|
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_METAL | SDL_WINDOW_HIGH_PIXEL_DENSITY);
|
|
|
|
int nNumGamepads = 0;
|
|
SDL_JoystickID *pGamepads = SDL_GetGamepads(&nNumGamepads);
|
|
for ( uint32_t i = 0; i < nNumGamepads; i++ )
|
|
{
|
|
SDL_OpenGamepad(pGamepads[i]);
|
|
}
|
|
|
|
g_mlView = SDL_Metal_CreateView(g_window);
|
|
g_mlLayer = (CA::MetalLayer*)SDL_Metal_GetLayer(g_mlView);
|
|
|
|
|
|
|
|
g_mlDevice = MTL::CreateSystemDefaultDevice();
|
|
|
|
g_mlLayer->setDevice(g_mlDevice);
|
|
g_mlLayer->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
|
|
g_swapchainFormat = MTL::PixelFormatBGRA8Unorm;
|
|
|
|
g_mlCommandQueue = g_mlDevice->newCommandQueue();
|
|
|
|
g_mlLayer->setDrawableSize(CGSizeMake(1280, 720));
|
|
g_mlLayer->setFramebufferOnly(false);
|
|
|
|
IMetal::Init();
|
|
|
|
}
|
|
|
|
void IVideo::Frame( float fDelta )
|
|
{
|
|
IVideo_HandleEvents();
|
|
|
|
NS::AutoreleasePool *pool = NS::AutoreleasePool::alloc()->init();
|
|
g_mlLayer->setDrawableSize(CGSizeMake(g_nWindowWidth, g_nWindowHeight));
|
|
|
|
CA::MetalDrawable *drawable = g_mlLayer->nextDrawable();
|
|
if (!drawable)
|
|
return;
|
|
g_mlDrawableTexture = drawable->texture();
|
|
|
|
g_mlCommandBuffer = g_mlCommandQueue->commandBuffer();
|
|
IMetal::Frame();
|
|
|
|
g_mlCommandBuffer->presentDrawable(drawable);
|
|
g_mlCommandBuffer->commit();
|
|
g_mlCommandBuffer->waitUntilCompleted();
|
|
for (auto &image: g_destroyImageBuffer)
|
|
{
|
|
image->release();
|
|
}
|
|
for (auto &buffer: g_destroyBuffersBuffer)
|
|
{
|
|
buffer->release();
|
|
}
|
|
g_destroyImageBuffer = {};
|
|
g_destroyBuffersBuffer = {};
|
|
pool->release();
|
|
g_bConfigNotify = 0;
|
|
}
|
|
|
|
void IVideo::Deinit()
|
|
{
|
|
g_mlCommandQueue->release();
|
|
g_mlDevice->release();
|
|
};
|
|
|
|
void IVideo::CreatePipelines( )
|
|
{
|
|
IMetal::CreatePipelines();
|
|
}
|