Pass:mesh; Pass:setMeshMode;

This commit is contained in:
bjorn 2022-06-09 23:05:32 -07:00
parent 2abf1a4a0c
commit fc616f92c2
5 changed files with 75 additions and 9 deletions

View File

@ -49,6 +49,7 @@ extern StringEntry lovrKeyboardKey[];
extern StringEntry lovrMaterialColor[];
extern StringEntry lovrMaterialScalar[];
extern StringEntry lovrMaterialTexture[];
extern StringEntry lovrMeshMode[];
extern StringEntry lovrPassType[];
extern StringEntry lovrPermission[];
extern StringEntry lovrSampleFormat[];

View File

@ -97,6 +97,13 @@ StringEntry lovrFilterMode[] = {
{ 0 }
};
StringEntry lovrMeshMode[] = {
[MESH_POINTS] = ENTRY("points"),
[MESH_LINES] = ENTRY("lines"),
[MESH_TRIANGLES] = ENTRY("triangles"),
{ 0 }
};
StringEntry lovrPassType[] = {
[PASS_RENDER] = ENTRY("render"),
[PASS_COMPUTE] = ENTRY("compute"),
@ -682,7 +689,7 @@ static int l_lovrGraphicsGetBuffer(lua_State* L) {
switch (lua_type(L, 1)) {
case LUA_TNUMBER: info.length = lua_tointeger(L, 1); break;
case LUA_TTABLE: info.length = luax_len(L, -1); break;
case LUA_TTABLE: info.length = luax_len(L, 1); break;
default: {
Blob* blob = luax_totype(L, 1, Blob);
if (blob) {

View File

@ -238,6 +238,13 @@ static int l_lovrPassSetDepthClamp(lua_State* L) {
return 0;
}
static int l_lovrPassSetMeshMode(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
MeshMode mode = luax_checkenum(L, 2, MeshMode, NULL);
lovrPassSetMeshMode(pass, mode);
return 0;
}
static int l_lovrPassSetSampler(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
if (lua_type(L, 2) != LUA_TUSERDATA) {
@ -499,6 +506,19 @@ static int l_lovrPassCircle(lua_State* L) {
return 0;
}
static int l_lovrPassMesh(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* vertices = !lua_toboolean(L, 2) ? NULL : luax_totype(L, 2, Buffer);
Buffer* indices = luax_totype(L, 3, Buffer);
float transform[16];
int index = luax_readmat4(L, indices ? 4 : 3, transform, 1);
uint32_t start = luax_optu32(L, index++, 1) - 1;
uint32_t count = luax_optu32(L, index++, ~0u);
uint32_t instances = luax_optu32(L, index, 1);
lovrPassMesh(pass, vertices, indices, transform, start, count, instances);
return 0;
}
static int l_lovrPassCompute(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Buffer* buffer = luax_totype(L, 2, Buffer);
@ -681,6 +701,7 @@ const luaL_Reg lovrPass[] = {
{ "setDepthWrite", l_lovrPassSetDepthWrite },
{ "setDepthOffset", l_lovrPassSetDepthOffset },
{ "setDepthClamp", l_lovrPassSetDepthClamp },
{ "setMeshMode", l_lovrPassSetMeshMode },
{ "setSampler", l_lovrPassSetSampler },
{ "setScissor", l_lovrPassSetScissor },
{ "setShader", l_lovrPassSetShader },
@ -698,6 +719,7 @@ const luaL_Reg lovrPass[] = {
{ "cube", l_lovrPassCube },
{ "box", l_lovrPassBox },
{ "circle", l_lovrPassCircle },
{ "mesh", l_lovrPassMesh },
{ "compute", l_lovrPassCompute },

View File

@ -113,6 +113,7 @@ typedef struct {
float viewport[4];
float depthRange[2];
uint32_t scissor[4];
MeshMode drawMode;
bool dirty;
} Pipeline;
@ -173,7 +174,7 @@ typedef struct {
} ShapeVertex;
typedef struct {
gpu_draw_mode mode;
MeshMode mode;
DefaultShader shader;
float* transform;
struct {
@ -1450,6 +1451,7 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
memcpy(pass->pipeline->color, defaultColor, sizeof(defaultColor));
pass->pipeline->formatHash = 0;
pass->pipeline->shader = NULL;
pass->pipeline->drawMode = MESH_TRIANGLES;
pass->pipeline->dirty = true;
pass->samplerDirty = true;
@ -1700,6 +1702,10 @@ void lovrPassSetDepthClamp(Pass* pass, bool clamp) {
}
}
void lovrPassSetMeshMode(Pass* pass, MeshMode mode) {
pass->pipeline->drawMode = mode;
}
void lovrPassSetSampler(Pass* pass, Sampler* sampler) {
if (sampler != pass->pipeline->sampler) {
lovrRetain(sampler);
@ -1940,8 +1946,8 @@ void lovrPassSendValue(Pass* pass, const char* name, size_t length, void** data,
static void flushPipeline(Pass* pass, Draw* draw, Shader* shader) {
Pipeline* pipeline = pass->pipeline;
if (pipeline->info.drawMode != draw->mode) {
pipeline->info.drawMode = draw->mode;
if (pipeline->info.drawMode != (gpu_draw_mode) draw->mode) {
pipeline->info.drawMode = (gpu_draw_mode) draw->mode;
pipeline->dirty = true;
}
@ -2174,7 +2180,7 @@ static void lovrPassDraw(Pass* pass, Draw* draw) {
void lovrPassPoints(Pass* pass, uint32_t count, float** points) {
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_POINTS,
.mode = MESH_POINTS,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) points,
.vertex.count = count
@ -2185,7 +2191,7 @@ void lovrPassLine(Pass* pass, uint32_t count, float** points) {
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_LINES,
.mode = MESH_LINES,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) points,
.vertex.count = count,
@ -2207,7 +2213,7 @@ void lovrPassPlane(Pass* pass, float* transform, uint32_t cols, uint32_t rows) {
uint32_t indexCount = (cols * rows) * 6;
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -2281,7 +2287,7 @@ void lovrPassBox(Pass* pass, float* transform) {
};
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = COUNTOF(vertexData),
@ -2306,7 +2312,7 @@ void lovrPassCircle(Pass* pass, float* transform, float angle1, float angle2, ui
uint32_t indexCount = segments * 3;
lovrPassDraw(pass, &(Draw) {
.mode = GPU_DRAW_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -2332,6 +2338,28 @@ void lovrPassCircle(Pass* pass, float* transform, float angle1, float angle2, ui
}
}
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances) {
if (count == ~0u) {
count = (indices ? indices : vertices)->info.length - start;
}
if (indices) {
lovrCheck(count <= indices->info.length - start, "Mesh draw range exceeds index buffer size");
} else {
lovrCheck(count <= vertices->info.length - start, "Mesh draw range exceeds vertex buffer size");
}
lovrPassDraw(pass, &(Draw) {
.mode = pass->pipeline->drawMode,
.vertex.buffer = vertices,
.index.buffer = indices,
.transform = transform,
.start = start,
.count = count,
.instances = instances
});
}
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset) {
lovrCheck(pass->info.type == PASS_COMPUTE, "This function can only be called on a compute pass");

View File

@ -315,6 +315,12 @@ typedef enum {
CULL_BACK
} CullMode;
typedef enum {
MESH_POINTS,
MESH_LINES,
MESH_TRIANGLES
} MeshMode;
typedef enum {
STENCIL_KEEP,
STENCIL_ZERO,
@ -381,6 +387,7 @@ void lovrPassSetDepthTest(Pass* pass, CompareMode test);
void lovrPassSetDepthWrite(Pass* pass, bool write);
void lovrPassSetDepthOffset(Pass* pass, float offset, float sloped);
void lovrPassSetDepthClamp(Pass* pass, bool clamp);
void lovrPassSetMeshMode(Pass* pass, MeshMode mode);
void lovrPassSetSampler(Pass* pass, Sampler* sampler);
void lovrPassSetScissor(Pass* pass, uint32_t scissor[4]);
void lovrPassSetShader(Pass* pass, Shader* shader);
@ -398,6 +405,7 @@ void lovrPassLine(Pass* pass, uint32_t count, float** vertices);
void lovrPassPlane(Pass* pass, float* transform, uint32_t cols, uint32_t rows);
void lovrPassBox(Pass* pass, float* transform);
void lovrPassCircle(Pass* pass, float* transform, float angle1, float angle2, uint32_t segments);
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances);
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset);
void lovrPassClearBuffer(Pass* pass, Buffer* buffer, uint32_t offset, uint32_t extent);
void lovrPassClearTexture(Pass* pass, Texture* texture, float value[4], uint32_t layer, uint32_t layerCount, uint32_t level, uint32_t levelCount);