lovrPlatform: Window creation;

This commit is contained in:
bjorn 2018-11-16 02:26:56 -08:00
parent 6514492cb8
commit ba60e99890
6 changed files with 180 additions and 122 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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));
}