Compare commits

...

4 Commits

Author SHA1 Message Date
bjorn c0dfb414d6 Per-stage default shaders; 2022-08-01 22:10:06 -07:00
bjorn 67b338a1d8 Change default window size; 2022-08-01 21:46:00 -07:00
bjorn 4bb3405ff0 Add missing shader; 2022-08-01 21:26:34 -07:00
bjorn 8a5c09ac1b tup: Add -fPIE; 2022-08-01 21:24:41 -07:00
6 changed files with 107 additions and 58 deletions

View File

@ -88,6 +88,7 @@ cc = 'clang'
cxx = 'clang++'
flags = {
'-fPIE',
config.debug and '-g' or '',
config.optimize and '-Os' or '',
config.supercharge and '-flto -march=native -DLOVR_UNCHECKED' or '',

View File

@ -37,8 +37,8 @@ function lovr.boot()
globals = true
},
window = {
width = 800,
height = 600,
width = 720,
height = 800,
fullscreen = false,
resizable = false,
title = 'LÖVR',
@ -171,21 +171,22 @@ function lovr.errhand(message, traceback)
lovr.graphics.submit()
lovr.graphics.setBackground(.11, .10, .14)
local scale = .3
local font = lovr.graphics.getDefaultFont()
local wrap = .7 * font:getPixelDensity()
local lines = font:getLines(message, wrap)
local width = math.min(font:getWidth(message), wrap)
local height = 2.6 + #lines
local width = math.min(font:getWidth(message), wrap) * scale
local height = .8 + #lines * font:getHeight() * scale
local x = -width / 2
local y = math.min(height / 2, 10)
local z = -20
local z = -10
font:setPixelDensity()
local function render(pass)
pass:setColor(.95, .95, .95)
pass:setBlendMode('alpha')
pass:text('Error', x, y, z, 1.6, 0, 0, 0, 0, nil, 'left', 'top')
pass:text(message, x, y - 2.6, z, 1, 0, 0, 0, 0, wrap, 'left', 'top')
pass:text('Error', x, y, z, scale * 1.6, 0, 0, 0, 0, nil, 'left', 'top')
pass:text(message, x, y - .8, z, scale, 0, 0, 0, 0, wrap, 'left', 'top')
end
return function()

View File

@ -0,0 +1,13 @@
#version 460
#extension GL_EXT_multiview : require
#extension GL_GOOGLE_include_directive : require
#include "lovr.glsl"
layout(set = 1, binding = 1) uniform texture2DArray ArrayTexture;
vec4 lovrmain() {
vec2 uv = vec2(2 * UV.x, UV.y);
vec3 uvw = vec3(uv, round(uv.x));
return Color * getPixel(ArrayTexture, uvw);
}

View File

@ -60,10 +60,11 @@ StringEntry lovrCullMode[] = {
StringEntry lovrDefaultShader[] = {
[SHADER_UNLIT] = ENTRY("unlit"),
[SHADER_CUBE] = ENTRY("cube"),
[SHADER_PANO] = ENTRY("pano"),
[SHADER_FILL] = ENTRY("fill"),
[SHADER_FONT] = ENTRY("font"),
[SHADER_CUBEMAP] = ENTRY("cubemap"),
[SHADER_EQUIRECT] = ENTRY("equirect"),
[SHADER_FILL] = ENTRY("fill"),
[SHADER_STEREOBLIT] = ENTRY("stereoblit"),
{ 0 }
};
@ -1047,7 +1048,7 @@ static int l_lovrGraphicsNewSampler(lua_State* L) {
return 1;
}
static ShaderSource luax_checkshadercode(lua_State* L, int index, ShaderStage stage, bool* allocated) {
static ShaderSource luax_checkshadersource(lua_State* L, int index, ShaderStage stage, bool* allocated) {
ShaderSource source;
if (lua_isstring(L, index)) {
size_t length;
@ -1057,9 +1058,19 @@ static ShaderSource luax_checkshadercode(lua_State* L, int index, ShaderStage st
source.size = length;
*allocated = false;
} else {
for (int i = 0; lovrDefaultShader[i].length; i++) {
if (lovrDefaultShader[i].length == length && !memcmp(lovrDefaultShader[i].string, string, length)) {
return lovrGraphicsGetDefaultShaderSource(i, stage);
}
}
source.code = luax_readfile(string, &source.size);
lovrAssert(source.code, "Could not read shader code from %s", string);
*allocated = true;
if (source.code) {
*allocated = true;
} else {
luaL_argerror(L, index, "single-line string was not filename or DefaultShader");
}
}
} else if (lua_istable(L, index)) {
int length = luax_len(L, index);
@ -1094,7 +1105,7 @@ static ShaderSource luax_checkshadercode(lua_State* L, int index, ShaderStage st
static int l_lovrGraphicsCompileShader(lua_State* L) {
ShaderStage stage = luax_checkenum(L, 1, ShaderStage, NULL);
bool allocated;
ShaderSource spirv = luax_checkshadercode(L, 2, stage, &allocated);
ShaderSource spirv = luax_checkshadersource(L, 2, stage, &allocated);
if (!allocated) {
lua_settop(L, 2);
return 1;
@ -1110,14 +1121,31 @@ static int l_lovrGraphicsNewShader(lua_State* L) {
bool allocated[2];
int index;
// If there's only one source given, it could be a DefaultShader or a compute shader
if (lua_gettop(L) == 1 || (lua_istable(L, 2) && luax_len(L, 2) == 0)) {
info.type = SHADER_COMPUTE;
info.source[0] = luax_checkshadercode(L, 1, STAGE_COMPUTE, &allocated[0]);
if (lua_type(L, 1) == LUA_TSTRING) {
size_t length;
const char* string = lua_tolstring(L, 1, &length);
for (int i = 0; lovrDefaultShader[i].length; i++) {
if (lovrDefaultShader[i].length == length && !memcmp(lovrDefaultShader[i].string, string, length)) {
info.source[0] = lovrGraphicsGetDefaultShaderSource(i, STAGE_VERTEX);
info.source[1] = lovrGraphicsGetDefaultShaderSource(i, STAGE_FRAGMENT);
info.type = SHADER_GRAPHICS;
break;
}
}
}
if (!info.source[0].code) {
info.type = SHADER_COMPUTE;
info.source[0] = luax_checkshadersource(L, 1, STAGE_COMPUTE, &allocated[0]);
}
index = 2;
} else {
info.type = SHADER_GRAPHICS;
info.source[0] = luax_checkshadercode(L, 1, STAGE_VERTEX, &allocated[0]);
info.source[1] = luax_checkshadercode(L, 2, STAGE_FRAGMENT, &allocated[1]);
info.source[0] = luax_checkshadersource(L, 1, STAGE_VERTEX, &allocated[0]);
info.source[1] = luax_checkshadersource(L, 2, STAGE_FRAGMENT, &allocated[1]);
index = 3;
}

View File

@ -1466,46 +1466,51 @@ static void lovrShaderInit(Shader* shader) {
}
}
ShaderSource lovrGraphicsGetDefaultShaderSource(DefaultShader type, ShaderStage stage) {
if (stage == STAGE_COMPUTE) {
return (ShaderSource) { NULL, 0 };
}
const ShaderSource sources[][2] = {
[SHADER_UNLIT] = {
{ lovr_shader_unlit_vert, sizeof(lovr_shader_unlit_vert) },
{ lovr_shader_unlit_frag, sizeof(lovr_shader_unlit_frag) }
},
[SHADER_FONT] = {
{ lovr_shader_unlit_vert, sizeof(lovr_shader_unlit_vert) },
{ lovr_shader_font_frag, sizeof(lovr_shader_font_frag) }
},
[SHADER_CUBEMAP] = {
{ lovr_shader_cubemap_vert, sizeof(lovr_shader_cubemap_vert) },
{ lovr_shader_cubemap_frag, sizeof(lovr_shader_cubemap_frag) }
},
[SHADER_EQUIRECT] = {
{ lovr_shader_cubemap_vert, sizeof(lovr_shader_cubemap_vert) },
{ lovr_shader_equirect_frag, sizeof(lovr_shader_equirect_frag) }
},
[SHADER_FILL] = {
{ lovr_shader_fill_vert, sizeof(lovr_shader_fill_vert) },
{ lovr_shader_unlit_frag, sizeof(lovr_shader_unlit_frag) }
},
[SHADER_STEREOBLIT] = {
{ lovr_shader_fill_vert, sizeof(lovr_shader_fill_vert) },
{ lovr_shader_stereoblit_frag, sizeof(lovr_shader_stereoblit_frag) }
}
};
return sources[type][stage];
}
Shader* lovrGraphicsGetDefaultShader(DefaultShader type) {
if (state.defaultShaders[type]) {
return state.defaultShaders[type];
}
ShaderInfo info = { .type = SHADER_GRAPHICS };
switch (type) {
case SHADER_UNLIT:
info.source[0] = (ShaderSource) { lovr_shader_unlit_vert, sizeof(lovr_shader_unlit_vert) };
info.source[1] = (ShaderSource) { lovr_shader_unlit_frag, sizeof(lovr_shader_unlit_frag) };
info.label = "unlit";
break;
case SHADER_CUBE:
info.source[0] = (ShaderSource) { lovr_shader_cubemap_vert, sizeof(lovr_shader_cubemap_vert) };
info.source[1] = (ShaderSource) { lovr_shader_cubemap_frag, sizeof(lovr_shader_cubemap_frag) };
info.label = "cubemap";
break;
case SHADER_PANO:
info.source[0] = (ShaderSource) { lovr_shader_cubemap_vert, sizeof(lovr_shader_cubemap_vert) };
info.source[1] = (ShaderSource) { lovr_shader_equirect_frag, sizeof(lovr_shader_equirect_frag) };
info.label = "equirect";
break;
case SHADER_FILL:
info.source[0] = (ShaderSource) { lovr_shader_fill_vert, sizeof(lovr_shader_fill_vert) };
info.source[1] = (ShaderSource) { lovr_shader_unlit_frag, sizeof(lovr_shader_unlit_frag) };
info.label = "fill";
break;
case SHADER_FONT:
info.source[0] = (ShaderSource) { lovr_shader_unlit_vert, sizeof(lovr_shader_unlit_vert) };
info.source[1] = (ShaderSource) { lovr_shader_font_frag, sizeof(lovr_shader_font_frag) };
info.label = "font";
break;
case SHADER_STEREOBLIT:
info.source[0] = (ShaderSource) { lovr_shader_fill_vert, sizeof(lovr_shader_fill_vert) };
info.source[1] = (ShaderSource) { lovr_shader_stereoblit_frag, sizeof(lovr_shader_stereoblit_frag) };
info.label = "stereoblit";
break;
default: lovrUnreachable();
}
ShaderInfo info = {
.type = SHADER_GRAPHICS,
.source[0] = lovrGraphicsGetDefaultShaderSource(type, STAGE_VERTEX),
.source[1] = lovrGraphicsGetDefaultShaderSource(type, STAGE_FRAGMENT)
};
return state.defaultShaders[type] = lovrShaderCreate(&info);
}
@ -4719,7 +4724,7 @@ void lovrPassSkybox(Pass* pass, Texture* texture) {
if (texture->info.type == TEXTURE_2D) {
lovrPassDraw(pass, &(Draw) {
.mode = MESH_TRIANGLES,
.shader = SHADER_PANO,
.shader = SHADER_EQUIRECT,
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
.vertex.format = VERTEX_EMPTY,
.count = 6
@ -4727,7 +4732,7 @@ void lovrPassSkybox(Pass* pass, Texture* texture) {
} else {
lovrPassDraw(pass, &(Draw) {
.mode = MESH_TRIANGLES,
.shader = SHADER_CUBE,
.shader = SHADER_CUBEMAP,
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
.vertex.format = VERTEX_EMPTY,
.count = 6

View File

@ -262,10 +262,10 @@ const SamplerInfo* lovrSamplerGetInfo(Sampler* sampler);
typedef enum {
SHADER_UNLIT,
SHADER_CUBE,
SHADER_PANO,
SHADER_FILL,
SHADER_FONT,
SHADER_CUBEMAP,
SHADER_EQUIRECT,
SHADER_FILL,
SHADER_STEREOBLIT,
DEFAULT_SHADER_COUNT
} DefaultShader;
@ -301,6 +301,7 @@ typedef struct {
} ShaderInfo;
ShaderSource lovrGraphicsCompileShader(ShaderStage stage, ShaderSource* source);
ShaderSource lovrGraphicsGetDefaultShaderSource(DefaultShader type, ShaderStage stage);
Shader* lovrGraphicsGetDefaultShader(DefaultShader type);
Shader* lovrShaderCreate(const ShaderInfo* info);
Shader* lovrShaderClone(Shader* parent, ShaderFlag* flags, uint32_t count);