Initial commit
This commit is contained in:
172
main.cpp
Normal file
172
main.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef USE_D3D11
|
||||
#include <mpv/render_dxgi.h>
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#include <GLFW/glfw3native.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
static ID3D11Device* d3dDevice = nullptr;
|
||||
static ID3D11DeviceContext* d3dDeviceContext = nullptr;
|
||||
static IDXGISwapChain* d3dSwapChain = nullptr;
|
||||
static ID3D11RenderTargetView* d3dRenderTargetView = nullptr;
|
||||
|
||||
// Forward declarations of helper functions
|
||||
bool InitD3D(HWND hWnd);
|
||||
void CleanupD3D();
|
||||
bool ResizeD3D(GLFWwindow* window, int width, int height);
|
||||
#else
|
||||
#include <mpv/render_gl.h>
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
|
||||
extern "C" void userAppInit() {
|
||||
socketInitializeDefault();
|
||||
nxlinkStdio();
|
||||
appletSetWirelessPriorityMode(AppletWirelessPriorityMode_OptimizedForWlan);
|
||||
plInitialize(PlServiceType_User);
|
||||
}
|
||||
|
||||
extern "C" void userAppExit() {
|
||||
plExit();
|
||||
socketExit();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int osdShow = 0;
|
||||
|
||||
static void die(const char* msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Main code
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) die("missing file path");
|
||||
|
||||
if (!glfwInit()) die("init glfw failed");
|
||||
|
||||
// Create window with graphics context
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, argv[1], nullptr, nullptr);
|
||||
if (!window) {
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||
if (action == GLFW_PRESS) {
|
||||
if (key == GLFW_KEY_ESCAPE)
|
||||
glfwSetWindowShouldClose(window, 1);
|
||||
else if (key == GLFW_KEY_ENTER)
|
||||
osdShow = !osdShow;
|
||||
}
|
||||
});
|
||||
#ifdef USE_D3D11
|
||||
// Initialize Direct3D
|
||||
HWND hwnd = glfwGetWin32Window(window);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
if (!InitD3D(hwnd)) die("init dx11 failed");
|
||||
glfwSetFramebufferSizeCallback(window, (GLFWframebuffersizefun)ResizeD3D);
|
||||
#else
|
||||
glfwMakeContextCurrent(window);
|
||||
// Load OpenGL routines using glad
|
||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||
glfwSwapInterval(1);
|
||||
glfwSetTime(0);
|
||||
#endif
|
||||
int fbw = 0, fbh = 0;
|
||||
// Main loop
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwGetFramebufferSize(window, &fbw, &fbh);
|
||||
#ifdef USE_D3D11
|
||||
float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f};
|
||||
d3dDeviceContext->OMSetRenderTargets(1, &d3dRenderTargetView, nullptr);
|
||||
d3dDeviceContext->ClearRenderTargetView(d3dRenderTargetView, clear_color);
|
||||
d3dSwapChain->Present(1, 0); // Present with vsync
|
||||
#else
|
||||
glViewport(0, 0, fbw, fbh);
|
||||
glfwSwapBuffers(window);
|
||||
#endif
|
||||
glfwWaitEvents();
|
||||
}
|
||||
|
||||
#ifdef USE_D3D11
|
||||
CleanupD3D();
|
||||
#endif
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_D3D11
|
||||
|
||||
bool InitD3D(HWND hWnd) {
|
||||
static const D3D_DRIVER_TYPE driverAttempts[] = {
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
D3D_DRIVER_TYPE_WARP,
|
||||
D3D_DRIVER_TYPE_REFERENCE,
|
||||
};
|
||||
|
||||
static const D3D_FEATURE_LEVEL levelAttempts[] = {
|
||||
D3D_FEATURE_LEVEL_11_1, // Direct3D 11.1 SM 6
|
||||
D3D_FEATURE_LEVEL_11_0, // Direct3D 11.0 SM 5
|
||||
D3D_FEATURE_LEVEL_10_1, // Direct3D 10.1 SM 4
|
||||
};
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 2;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
|
||||
for (size_t i = 0; i < ARRAYSIZE(driverAttempts); i++) {
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverAttempts[i], nullptr, 0, levelAttempts,
|
||||
ARRAYSIZE(levelAttempts), D3D11_SDK_VERSION, &sd, &d3dSwapChain, &d3dDevice, nullptr, &d3dDeviceContext);
|
||||
if (SUCCEEDED(hr)) break;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
CleanupD3D();
|
||||
return false;
|
||||
}
|
||||
return ResizeD3D(nullptr, 0, 0);
|
||||
}
|
||||
|
||||
void CleanupD3D() {
|
||||
if (d3dRenderTargetView) d3dRenderTargetView->Release();
|
||||
if (d3dSwapChain) d3dSwapChain->Release();
|
||||
if (d3dDeviceContext) d3dDeviceContext->Release();
|
||||
if (d3dDevice) d3dDevice->Release();
|
||||
}
|
||||
|
||||
bool ResizeD3D(GLFWwindow* window, int width, int height) {
|
||||
ID3D11Texture2D* backBuffer = nullptr;
|
||||
HRESULT hr = S_OK;
|
||||
if (d3dRenderTargetView) d3dRenderTargetView->Release();
|
||||
// Resize render target buffers
|
||||
if (width > 0 && height > 0) {
|
||||
hr = d3dSwapChain->ResizeBuffers(2, width, height, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
|
||||
if (FAILED(hr)) return false;
|
||||
}
|
||||
hr = d3dSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
|
||||
if (FAILED(hr)) return false;
|
||||
hr = d3dDevice->CreateRenderTargetView(backBuffer, nullptr, &d3dRenderTargetView);
|
||||
backBuffer->Release();
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user