mirror of https://github.com/bjornbytes/lovr.git
Per-stage default shaders;
This commit is contained in:
parent
67b338a1d8
commit
c0dfb414d6
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue