mirror of https://github.com/bjornbytes/lovr.git
lovrPlatform: Window creation;
This commit is contained in:
parent
6514492cb8
commit
ba60e99890
|
@ -259,14 +259,47 @@ static int l_lovrGraphicsPresent(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrGraphicsCreateWindow(lua_State* L) {
|
||||
int width = luaL_optnumber(L, 1, 1080);
|
||||
int height = luaL_optnumber(L, 2, 600);
|
||||
bool fullscreen = !lua_isnoneornil(L, 3) && lua_toboolean(L, 3);
|
||||
int msaa = luaL_optnumber(L, 4, 0);
|
||||
const char* title = luaL_optstring(L, 5, "LÖVR");
|
||||
const char* icon = luaL_optstring(L, 6, NULL);
|
||||
lovrGraphicsCreateWindow(width, height, fullscreen, msaa, title, icon);
|
||||
static int l_lovrGraphicsSetWindow(lua_State* L) {
|
||||
if (lua_isnoneornil(L, 1)) {
|
||||
lovrGraphicsSetWindow(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WindowFlags flags = { 0 };
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
|
||||
lua_getfield(L, 1, "width");
|
||||
flags.width = luaL_optinteger(L, -1, 1080);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "height");
|
||||
flags.height = luaL_optinteger(L, -1, 600);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "fullscreen");
|
||||
flags.fullscreen = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "msaa");
|
||||
flags.msaa = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "title");
|
||||
flags.title = luaL_optstring(L, -1, "LÖVR");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "icon");
|
||||
TextureData* textureData = NULL;
|
||||
if (!lua_isnil(L, -1)) {
|
||||
textureData = luax_checktexturedata(L, -1, true);
|
||||
flags.icon.data = textureData->blob.data;
|
||||
flags.icon.width = textureData->width;
|
||||
flags.icon.height = textureData->height;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lovrGraphicsSetWindow(&flags);
|
||||
lovrRelease(textureData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1270,7 +1303,7 @@ static const luaL_Reg lovrGraphics[] = {
|
|||
|
||||
// Base
|
||||
{ "present", l_lovrGraphicsPresent },
|
||||
{ "createWindow", l_lovrGraphicsCreateWindow },
|
||||
{ "setWindow", l_lovrGraphicsSetWindow },
|
||||
{ "getWidth", l_lovrGraphicsGetWidth },
|
||||
{ "getHeight", l_lovrGraphicsGetHeight },
|
||||
{ "getDimensions", l_lovrGraphicsGetDimensions },
|
||||
|
@ -1377,37 +1410,10 @@ int luaopen_lovr_graphics(lua_State* L) {
|
|||
|
||||
lovrGraphicsInit(gammaCorrect);
|
||||
|
||||
// Create window if needed
|
||||
lua_getfield(L, -1, "window");
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_getfield(L, -1, "width");
|
||||
int width = luaL_checkinteger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "height");
|
||||
int height = luaL_checkinteger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "fullscreen");
|
||||
bool fullscreen = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "msaa");
|
||||
int msaa = luaL_checkinteger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "title");
|
||||
const char* title = luaL_checkstring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "icon");
|
||||
const char* icon = luaL_optstring(L, -1, NULL);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lovrGraphicsCreateWindow(width, height, fullscreen, msaa, title, icon);
|
||||
}
|
||||
|
||||
lua_pop(L, 2);
|
||||
lua_pushcfunction(L, l_lovrGraphicsSetWindow);
|
||||
lua_getfield(L, -2, "window");
|
||||
lua_call(L, 1, 0);
|
||||
|
||||
lua_pop(L, 1); // conf
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "event/event.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "util.h"
|
||||
#include "lib/glfw.h"
|
||||
#include "lib/math.h"
|
||||
#include "lib/stb/stb_image.h"
|
||||
#define _USE_MATH_DEFINES
|
||||
|
@ -12,26 +11,15 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef LOVR_USE_OCULUS_MOBILE
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#endif
|
||||
|
||||
static GraphicsState state;
|
||||
|
||||
#ifndef NO_WINDOW
|
||||
static void onCloseWindow(GLFWwindow* window) {
|
||||
if (window == state.window) {
|
||||
lovrEventPush((Event) { .type = EVENT_QUIT, .data.quit = { false, 0 } });
|
||||
}
|
||||
static void onCloseWindow() {
|
||||
lovrEventPush((Event) { .type = EVENT_QUIT, .data.quit = { false, 0 } });
|
||||
}
|
||||
#endif
|
||||
|
||||
static void onResizeWindow(GLFWwindow* window, int width, int height) {
|
||||
if (window == state.window) {
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
}
|
||||
static void onResizeWindow(int width, int height) {
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
}
|
||||
|
||||
// Base
|
||||
|
@ -59,71 +47,27 @@ void lovrGraphicsDestroy() {
|
|||
}
|
||||
|
||||
void lovrGraphicsPresent() {
|
||||
#ifndef NO_WINDOW
|
||||
glfwSwapBuffers(state.window);
|
||||
#endif
|
||||
lovrPlatformSwapBuffers();
|
||||
lovrGpuPresent();
|
||||
}
|
||||
|
||||
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon) {
|
||||
lovrAssert(!state.window && !state.initialized, "Window is already created");
|
||||
void lovrGraphicsSetWindow(WindowFlags* flags) {
|
||||
lovrAssert(!state.initialized, "Window is already created");
|
||||
|
||||
#ifndef NO_WINDOW
|
||||
if ((state.window = glfwGetCurrentContext()) == NULL) {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_SAMPLES, msaa);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_SRGB_CAPABLE, state.gammaCorrect);
|
||||
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
if (fullscreen) {
|
||||
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
|
||||
}
|
||||
|
||||
state.window = glfwCreateWindow(w ? w : mode->width, h ? h : mode->height, title, fullscreen ? monitor : NULL, NULL);
|
||||
if (!state.window) {
|
||||
glfwTerminate();
|
||||
lovrThrow("Could not create window");
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
GLFWimage image;
|
||||
size_t size;
|
||||
lovrAssert(lovrFilesystemIsFile(icon), "Could not read icon from %s", icon);
|
||||
void* data = lovrFilesystemRead(icon, &size);
|
||||
lovrAssert(data, "Could not read icon from %s", icon);
|
||||
image.pixels = stbi_load_from_memory(data, size, &image.width, &image.height, NULL, 4);
|
||||
lovrAssert(image.pixels, "Could not read icon from %s", icon);
|
||||
glfwSetWindowIcon(state.window, 1, &image);
|
||||
free(image.pixels);
|
||||
free(data);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(state.window);
|
||||
glfwSetWindowCloseCallback(state.window, onCloseWindow);
|
||||
glfwSetWindowSizeCallback(state.window, onResizeWindow);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(defined(EMSCRIPTEN) || defined(LOVR_USE_OCULUS_MOBILE))
|
||||
glfwSwapInterval(0);
|
||||
#endif
|
||||
|
||||
glfwGetFramebufferSize(state.window, &state.width, &state.height);
|
||||
|
||||
#if LOVR_USE_OCULUS_MOBILE
|
||||
getGpuProcProc getProcAddress = eglGetProcAddress;
|
||||
if (flags) {
|
||||
flags->srgb = state.gammaCorrect;
|
||||
#ifdef EMSCRIPTEN
|
||||
flags->vsync = 1;
|
||||
#else
|
||||
getGpuProcProc getProcAddress = glfwGetProcAddress;
|
||||
flags->vsync = 0;
|
||||
#endif
|
||||
lovrGpuInit(state.gammaCorrect, getProcAddress);
|
||||
}
|
||||
|
||||
lovrAssert(lovrPlatformSetWindow(flags), "Could not create window");
|
||||
lovrPlatformOnWindowClose(onCloseWindow);
|
||||
lovrPlatformOnWindowResize(onResizeWindow);
|
||||
lovrPlatformGetWindowSize(&state.width, &state.height);
|
||||
lovrGpuInit(state.gammaCorrect, lovrGetProcAddress);
|
||||
|
||||
VertexFormat format;
|
||||
vertexFormatInit(&format);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "graphics/texture.h"
|
||||
#include "math/math.h"
|
||||
#include "util.h"
|
||||
#include "platform.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -140,7 +141,6 @@ typedef struct {
|
|||
bool gammaCorrect;
|
||||
int width;
|
||||
int height;
|
||||
void* window;
|
||||
Camera camera;
|
||||
Shader* defaultShaders[MAX_DEFAULT_SHADERS];
|
||||
Material* defaultMaterial;
|
||||
|
@ -231,10 +231,7 @@ void lovrGraphicsFill(Texture* texture, float u, float v, float w, float h);
|
|||
|
||||
// GPU
|
||||
|
||||
typedef void (*gpuProc)(void);
|
||||
typedef gpuProc (*getGpuProcProc)(const char*);
|
||||
|
||||
void lovrGpuInit(bool srgb, getGpuProcProc getProcAddress);
|
||||
void lovrGpuInit(bool srgb, getProcAddressProc getProcAddress);
|
||||
void lovrGpuDestroy();
|
||||
void lovrGpuBindPipeline(Pipeline* pipeline);
|
||||
void lovrGpuSetViewports(float* viewports, int count);
|
||||
|
|
|
@ -607,7 +607,7 @@ static void lovrGpuUseProgram(uint32_t program) {
|
|||
|
||||
// GPU
|
||||
|
||||
void lovrGpuInit(bool srgb, getGpuProcProc getProcAddress) {
|
||||
void lovrGpuInit(bool srgb, getProcAddressProc getProcAddress) {
|
||||
#ifndef EMSCRIPTEN
|
||||
gladLoadGLLoader((GLADloadproc) getProcAddress);
|
||||
state.features.computeShaders = GLAD_GL_ARB_compute_shader;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -16,8 +17,35 @@
|
|||
#define lovrWarnv(...) vfprintf(stderr, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
bool fullscreen;
|
||||
bool srgb;
|
||||
int vsync;
|
||||
int msaa;
|
||||
const char* title;
|
||||
struct {
|
||||
void* data;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} icon;
|
||||
} WindowFlags;
|
||||
|
||||
typedef void (*windowCloseCallback)();
|
||||
typedef void (*windowResizeCallback)(uint32_t width, uint32_t height);
|
||||
|
||||
typedef void (*gpuProc)(void);
|
||||
typedef gpuProc (*getProcAddressProc)(const char*);
|
||||
extern getProcAddressProc lovrGetProcAddress;
|
||||
|
||||
void lovrPlatformPollEvents();
|
||||
double lovrPlatformGetTime();
|
||||
void lovrPlatformSetTime(double t);
|
||||
bool lovrPlatformSetWindow(WindowFlags* flags);
|
||||
void lovrPlatformGetWindowSize(uint32_t* width, uint32_t* height);
|
||||
void lovrPlatformOnWindowClose(windowCloseCallback callback);
|
||||
void lovrPlatformOnWindowResize(windowResizeCallback callback);
|
||||
void lovrPlatformSwapBuffers();
|
||||
void lovrSleep(double seconds);
|
||||
int lovrGetExecutablePath(char* dest, uint32_t size);
|
||||
|
|
|
@ -4,6 +4,26 @@
|
|||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
getProcAddressProc lovrGetProcAddress = glfwGetProcAddress;
|
||||
|
||||
static struct {
|
||||
GLFWwindow* window;
|
||||
windowCloseCallback onWindowClose;
|
||||
windowResizeCallback onWindowResize;
|
||||
} state;
|
||||
|
||||
static void onWindowClose(GLFWwindow* window) {
|
||||
if (state.onWindowClose) {
|
||||
state.onWindowClose();
|
||||
}
|
||||
}
|
||||
|
||||
static void onWindowResize(GLFWwindow* window, int width, int height) {
|
||||
if (state.onWindowResize) {
|
||||
state.onWindowResize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void lovrPlatformPollEvents() {
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
@ -16,6 +36,69 @@ void lovrPlatformSetTime(double t) {
|
|||
glfwSetTime(t);
|
||||
}
|
||||
|
||||
bool lovrPlatformSetWindow(WindowFlags* flags) {
|
||||
if (state.window) {
|
||||
return true;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_SAMPLES, flags->msaa);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_SRGB_CAPABLE, flags->srgb);
|
||||
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
uint32_t width = flags->width ? flags->width : mode->width;
|
||||
uint32_t height = flags->height ? flags->height : mode->height;
|
||||
|
||||
if (flags->fullscreen) {
|
||||
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
|
||||
}
|
||||
|
||||
state.window = glfwCreateWindow(width, height, flags->title, flags->fullscreen ? monitor : NULL, NULL);
|
||||
|
||||
if (!state.window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags->icon.data) {
|
||||
glfwSetWindowIcon(state.window, 1, &(GLFWimage) {
|
||||
.pixels = flags->icon.data,
|
||||
.width = flags->icon.width,
|
||||
.height = flags->icon.height
|
||||
});
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(state.window);
|
||||
glfwSwapInterval(flags->vsync);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lovrPlatformGetWindowSize(uint32_t* width, uint32_t* height) {
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(state.window, &w, &h);
|
||||
*width = w;
|
||||
*height = h;
|
||||
}
|
||||
|
||||
void lovrPlatformOnWindowClose(windowCloseCallback callback) {
|
||||
glfwSetWindowCloseCallback(state.window, callback);
|
||||
}
|
||||
|
||||
void lovrPlatformOnWindowResize(windowResizeCallback callback) {
|
||||
glfwSetWindowSizeCallback(state.window, callback);
|
||||
}
|
||||
|
||||
void lovrPlatformSwapBuffers() {
|
||||
glfwSwapBuffers(state.window);
|
||||
}
|
||||
|
||||
void lovrSleep(double seconds) {
|
||||
Sleep((unsigned int) (seconds * 1000));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue