Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ dev
- Add `sleep` callback to `World:setCallbacks`.
- Add `linearDamping` and `angularDamping` settings to `lovr.physics.newWorld`.
- Add `lovr.headset.getHandPosition/Orientation/Pose`.
- Add `Material:get/setNumber`, `Material:get/setColor`, and `Material:get/setTexture`.
- Add `Material:get/setQuad`.
- Add `Material:is/setDoubleSided`.

### Change

Expand Down
13 changes: 6 additions & 7 deletions etc/shaders/lovr.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,17 @@ layout(set = 0, binding = 2) uniform DrawBuffer { layout(row_major) Draw Draws[2
layout(set = 0, binding = 3) uniform sampler Sampler;

struct MaterialData {
vec4 color;
vec4 glow;
vec2 uvShift;
vec2 uvScale;
vec2 sdfRange;
float metalness;
float roughness;
float clearcoat;
float clearcoatRoughness;
float occlusionStrength;
float normalScale;
float alphaCutoff;
vec4 color;
vec4 glow;
vec4 quad;
vec2 sdfRange;
};

layout(set = 1, binding = 0) uniform MaterialBuffer {
Expand Down Expand Up @@ -558,8 +557,8 @@ void main() {
#endif

if (flag_uvTransform) {
UV *= Material.uvScale;
UV += Material.uvShift;
UV *= Material.quad.zw;
UV += Material.quad.xy;
}
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ extern StringEntry lovrHorizontalAlign[];
extern StringEntry lovrJointType[];
extern StringEntry lovrKeyboardKey[];
extern StringEntry lovrLayerType[];
extern StringEntry lovrMaterialColor[];
extern StringEntry lovrMaterialNumber[];
extern StringEntry lovrMaterialTexture[];
extern StringEntry lovrMeshStorage[];
extern StringEntry lovrModelDrawMode[];
extern StringEntry lovrMotorMode[];
Expand Down
21 changes: 10 additions & 11 deletions src/api/l_data_modelData.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,19 +602,16 @@ static int l_lovrModelDataGetMaterial(lua_State* L) {
lua_rawseti(L, -2, 4);
lua_setfield(L, -2, "glow");

lua_createtable(L, 2, 0);
lua_pushnumber(L, material->uvShift[0]);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, material->uvShift[1]);
lua_rawseti(L, -2, 2);
lua_setfield(L, -2, "uvShift");

lua_createtable(L, 2, 0);
lua_pushnumber(L, material->uvScale[0]);
lua_createtable(L, 4, 0);
lua_pushnumber(L, material->quad[0]);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, material->uvScale[1]);
lua_pushnumber(L, material->quad[1]);
lua_rawseti(L, -2, 2);
lua_setfield(L, -2, "uvScale");
lua_pushnumber(L, material->quad[2]);
lua_rawseti(L, -2, 3);
lua_pushnumber(L, material->quad[3]);
lua_rawseti(L, -2, 4);
lua_setfield(L, -2, "quad");

lua_pushnumber(L, material->metalness), lua_setfield(L, -2, "metalness");
lua_pushnumber(L, material->roughness), lua_setfield(L, -2, "roughness");
Expand All @@ -633,6 +630,8 @@ static int l_lovrModelDataGetMaterial(lua_State* L) {
PUSH_IMAGE(occlusionTexture);
PUSH_IMAGE(normalTexture);

lua_pushboolean(L, material->doubleSided), lua_setfield(L, -2, "doubleSided");

return 1;
}

Expand Down
207 changes: 111 additions & 96 deletions src/api/l_graphics.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,34 @@ StringEntry lovrHorizontalAlign[] = {
{ 0 }
};

StringEntry lovrMaterialColor[] = {
[COLOR_BASE] = ENTRY("base"),
[COLOR_GLOW] = ENTRY("glow"),
{ 0 }
};

StringEntry lovrMaterialNumber[] = {
[NUMBER_METALNESS] = ENTRY("metalness"),
[NUMBER_ROUGHNESS] = ENTRY("roughness"),
[NUMBER_CLEARCOAT] = ENTRY("clearcoat"),
[NUMBER_CLEARCOAT_ROUGHNESS] = ENTRY("clearcoatroughness"),
[NUMBER_OCCLUSION_STRENGTH] = ENTRY("occlusionstrength"),
[NUMBER_NORMAL_SCALE] = ENTRY("normalscale"),
[NUMBER_ALPHA_CUTOFF] = ENTRY("alphacutoff"),
{ 0 }
};

StringEntry lovrMaterialTexture[] = {
[TEXTURE_COLOR] = ENTRY("color"),
[TEXTURE_GLOW] = ENTRY("glow"),
[TEXTURE_METALNESS] = ENTRY("metalness"),
[TEXTURE_ROUGHNESS] = ENTRY("roughness"),
[TEXTURE_CLEARCOAT] = ENTRY("clearcoat"),
[TEXTURE_OCCLUSION] = ENTRY("occlusion"),
[TEXTURE_NORMAL] = ENTRY("normal"),
{ 0 }
};

StringEntry lovrMeshStorage[] = {
[MESH_CPU] = ENTRY("cpu"),
[MESH_GPU] = ENTRY("gpu"),
Expand Down Expand Up @@ -1459,112 +1487,99 @@ static Texture* luax_opttexture(lua_State* L, int index) {
}

static int l_lovrGraphicsNewMaterial(lua_State* L) {
MaterialInfo info;
memset(&info, 0, sizeof(info));

luaL_checktype(L, 1, LUA_TTABLE);

lua_getfield(L, 1, "color");
luax_optcolor(L, -1, info.data.color);
lua_pop(L, 1);

lua_getfield(L, 1, "glow");
if (lua_isnil(L, -1)) {
memset(info.data.glow, 0, sizeof(info.data.glow));
} else {
luax_optcolor(L, -1, info.data.glow);
}
lua_pop(L, 1);

lua_getfield(L, 1, "uvShift");
if (lua_type(L, -1) == LUA_TNUMBER) {
float shift = lua_tonumber(L, -1);
info.data.uvShift[0] = shift;
info.data.uvShift[1] = shift;
} else if (lua_type(L, -1) == LUA_TTABLE) {
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
info.data.uvShift[0] = luax_optfloat(L, -2, 0.f);
info.data.uvShift[1] = luax_optfloat(L, -1, 0.f);
lua_pop(L, 2);
}
lua_pop(L, 1);

lua_getfield(L, 1, "uvScale");
if (lua_isnil(L, -1)) {
info.data.uvScale[0] = 1.f;
info.data.uvScale[1] = 1.f;
} else if (lua_isnumber(L, -1)) {
float scale = lua_tonumber(L, -1);
info.data.uvScale[0] = scale;
info.data.uvScale[1] = scale;
} else if (lua_type(L, -1) == LUA_TTABLE) {
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
info.data.uvScale[0] = luax_optfloat(L, -2, 1.f);
info.data.uvScale[1] = luax_optfloat(L, -1, 1.f);
lua_pop(L, 2);
}
lua_pop(L, 1);

lua_getfield(L, 1, "metalness");
info.data.metalness = luax_optfloat(L, -1, 1.f);
lua_pop(L, 1);

lua_getfield(L, 1, "roughness");
info.data.roughness = luax_optfloat(L, -1, 1.f);
lua_pop(L, 1);

lua_getfield(L, 1, "clearcoat");
info.data.clearcoat = luax_optfloat(L, -1, 0.f);
lua_pop(L, 1);

lua_getfield(L, 1, "clearcoatRoughness");
info.data.clearcoatRoughness = luax_optfloat(L, -1, 0.f);
lua_pop(L, 1);

lua_getfield(L, 1, "occlusionStrength");
info.data.occlusionStrength = luax_optfloat(L, -1, 1.f);
lua_pop(L, 1);
Material* material = lovrMaterialCreate(luax_totype(L, 1, Texture));
luax_assert(L, material);

lua_getfield(L, 1, "normalScale");
info.data.normalScale = luax_optfloat(L, -1, 1.f);
lua_pop(L, 1);
if (lua_istable(L, 1)) {
for (uint32_t i = 0; i < NUMBER_COUNT; i++) {
lua_pushlstring(L, lovrMaterialNumber[i].string, lovrMaterialNumber[i].length);
lua_gettable(L, 1);
if (!lua_isnil(L, -1)) lovrMaterialSetNumber(material, i, luax_checkfloat(L, -1));
lua_pop(L, 1);
}

lua_getfield(L, 1, "alphaCutoff");
info.data.alphaCutoff = luax_optfloat(L, -1, 0.f);
lua_pop(L, 1);
for (uint32_t i = 0; i < COLOR_COUNT; i++) {
if (i == 0) {
lua_pushliteral(L, "color");
} else {
lua_pushlstring(L, lovrMaterialColor[i].string, lovrMaterialColor[i].length);
}

lua_getfield(L, 1, "texture");
info.texture = luax_opttexture(L, -1);
lua_pop(L, 1);
lua_gettable(L, 1);
if (!lua_isnil(L, -1)) {
float color[4];
luax_optcolor(L, -1, color);
lovrMaterialSetColor(material, i, color);
}
lua_pop(L, 1);
}

lua_getfield(L, 1, "glowTexture");
info.glowTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
for (uint32_t i = 0; i < TEXTURE_COUNT; i++) {
if (i == 0) {
lua_pushliteral(L, "texture");
} else {
char key[64];
size_t length = lovrMaterialTexture[i].length;
memcpy(key, lovrMaterialTexture[i].string, length);
memcpy(key + length, "Texture", strlen("Texture"));
lua_pushlstring(L, key, length + strlen("Texture"));
}
lua_gettable(L, 1);
if (!lua_isnil(L, -1)) {
Texture* texture = luax_checktype(L, -1, Texture);
if (!lovrMaterialSetTexture(material, i, texture)) {
lovrRelease(material, lovrMaterialDestroy);
luax_throw(L);
}
}
lua_pop(L, 1);
}

lua_getfield(L, 1, "metalnessTexture");
info.metalnessTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
float quad[4] = { 0.f, 0.f, 1.f, 1.f };

lua_getfield(L, 1, "roughnessTexture");
info.roughnessTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
// Deprecated
lua_getfield(L, 1, "uvShift");
if (lua_istable(L, -1)) {
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
quad[0] = luax_optfloat(L, -2, 0.f);
quad[1] = luax_optfloat(L, -1, 0.f);
lua_pop(L, 2);
} else if (lua_type(L, -1) == LUA_TNUMBER) {
quad[0] = quad[1] = lua_tonumber(L, -1);
}
lua_pop(L, 1);

lua_getfield(L, 1, "clearcoatTexture");
info.clearcoatTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
// Deprecated
lua_getfield(L, 1, "uvScale");
if (lua_istable(L, -1)) {
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
quad[2] = luax_optfloat(L, -2, 1.f);
quad[3] = luax_optfloat(L, -1, 1.f);
lua_pop(L, 2);
} else if (lua_type(L, -1) == LUA_TNUMBER) {
quad[2] = quad[3] = lua_tonumber(L, -1);
}
lua_pop(L, 1);

lua_getfield(L, 1, "occlusionTexture");
info.occlusionTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
lua_getfield(L, 1, "quad");
if (lua_istable(L, -1)) {
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
lua_rawgeti(L, -3, 3);
lua_rawgeti(L, -4, 4);
quad[0] = luax_optfloat(L, -4, 0.f);
quad[1] = luax_optfloat(L, -3, 0.f);
quad[2] = luax_optfloat(L, -2, 1.f);
quad[3] = luax_optfloat(L, -1, 1.f);
lua_pop(L, 4);
}
lua_pop(L, 1);

lua_getfield(L, 1, "normalTexture");
info.normalTexture = luax_opttexture(L, -1);
lua_pop(L, 1);
lovrMaterialSetQuad(material, quad[0], quad[1], quad[2], quad[3]);
}

Material* material = lovrMaterialCreate(&info);
luax_assert(L, material);
luax_pushtype(L, Material, material);
lovrRelease(material, lovrMaterialDestroy);
return 1;
Expand Down
Loading
Loading