Transform stack;

This commit is contained in:
bjorn 2022-05-06 17:26:38 -07:00
parent 7ac9f357d8
commit 1fde5a36d0
5 changed files with 121 additions and 0 deletions

View File

@ -53,6 +53,7 @@ extern StringEntry lovrSampleFormat[];
extern StringEntry lovrShaderType[];
extern StringEntry lovrShapeType[];
extern StringEntry lovrSmoothMode[];
extern StringEntry lovrStackType[];
extern StringEntry lovrStencilAction[];
extern StringEntry lovrTextureFeature[];
extern StringEntry lovrTextureFormat[];

View File

@ -75,6 +75,12 @@ StringEntry lovrPassType[] = {
{ 0 }
};
StringEntry lovrStackType[] = {
[STACK_TRANSFORM] = ENTRY("transform"),
[STACK_PIPELINE] = ENTRY("pipeline"),
{ 0 }
};
StringEntry lovrTextureFeature[] = {
[0] = ENTRY("sample"),
[1] = ENTRY("filter"),

View File

@ -11,7 +11,66 @@ static int l_lovrPassGetType(lua_State* L) {
return 1;
}
static int l_lovrPassPush(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
StackType stack = luax_checkenum(L, 2, StackType, "transform");
lovrPassPush(pass, stack);
return 0;
}
static int l_lovrPassPop(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
StackType stack = luax_checkenum(L, 2, StackType, "transform");
lovrPassPop(pass, stack);
return 0;
}
static int l_lovrPassOrigin(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
lovrPassOrigin(pass);
return 0;
}
static int l_lovrPassTranslate(lua_State* L) {
float translation[4];
Pass* pass = luax_checktype(L, 2, Pass);
luax_readvec3(L, 1, translation, NULL);
lovrPassTranslate(pass, translation);
return 0;
}
static int l_lovrPassRotate(lua_State* L) {
float rotation[4];
Pass* pass = luax_checktype(L, 1, Pass);
luax_readquat(L, 2, rotation, NULL);
lovrPassRotate(pass, rotation);
return 0;
}
static int l_lovrPassScale(lua_State* L) {
float scale[4];
Pass* pass = luax_checktype(L, 1, Pass);
luax_readscale(L, 2, scale, 3, NULL);
lovrPassScale(pass, scale);
return 0;
}
static int l_lovrPassTransform(lua_State* L) {
float transform[16];
Pass* pass = luax_checktype(L, 1, Pass);
luax_readmat4(L, 2, transform, 3);
lovrPassTransform(pass, transform);
return 0;
}
const luaL_Reg lovrPass[] = {
{ "getType", l_lovrPassGetType },
{ "push", l_lovrPassPush },
{ "pop", l_lovrPassPop },
{ "origin", l_lovrPassOrigin },
{ "translate", l_lovrPassTranslate },
{ "rotate", l_lovrPassRotate },
{ "scale", l_lovrPassScale },
{ "transform", l_lovrPassTransform },
{ NULL, NULL }
};

View File

@ -1,6 +1,7 @@
#include "graphics/graphics.h"
#include "data/image.h"
#include "core/gpu.h"
#include "core/maf.h"
#include "core/os.h"
#include "util.h"
#include <math.h>
@ -34,6 +35,9 @@ struct Pass {
uint32_t ref;
PassInfo info;
gpu_stream* stream;
float* transform;
uint32_t transformIndex;
float transforms[16][16];
};
typedef struct {
@ -523,6 +527,43 @@ const PassInfo* lovrPassGetInfo(Pass* pass) {
return &pass->info;
}
void lovrPassPush(Pass* pass, StackType stack) {
lovrCheck(pass->info.type == PASS_RENDER, "This function can only be called on a render pass");
if (stack == STACK_TRANSFORM) {
pass->transform = pass->transforms[++pass->transformIndex];
lovrCheck(pass->transformIndex < COUNTOF(pass->transforms), "Transform stack overflow (more pushes than pops?)");
mat4_init(pass->transforms[pass->transformIndex], pass->transforms[pass->transformIndex - 1]);
}
}
void lovrPassPop(Pass* pass, StackType stack) {
lovrCheck(pass->info.type == PASS_RENDER, "This function can only be called on a render pass");
if (stack == STACK_TRANSFORM) {
pass->transform = pass->transforms[--pass->transformIndex];
lovrCheck(pass->transformIndex < COUNTOF(pass->transforms), "Transform stack underflow (more pops than pushes?)");
}
}
void lovrPassOrigin(Pass* pass) {
mat4_identity(pass->transform);
}
void lovrPassTranslate(Pass* pass, vec3 translation) {
mat4_translate(pass->transform, translation[0], translation[1], translation[2]);
}
void lovrPassRotate(Pass* pass, quat rotation) {
mat4_rotateQuat(pass->transform, rotation);
}
void lovrPassScale(Pass* pass, vec3 scale) {
mat4_scale(pass->transform, scale[0], scale[1], scale[2]);
}
void lovrPassTransform(Pass* pass, mat4 transform) {
mat4_mul(pass->transform, transform);
}
// Helpers
static void* tempAlloc(size_t size) {

View File

@ -236,6 +236,11 @@ typedef enum {
PASS_TRANSFER
} PassType;
typedef enum {
STACK_TRANSFORM,
STACK_PIPELINE
} StackType;
typedef enum {
LOAD_KEEP,
LOAD_CLEAR,
@ -266,3 +271,12 @@ typedef struct {
Pass* lovrGraphicsGetPass(PassInfo* info);
void lovrPassDestroy(void* ref);
const PassInfo* lovrPassGetInfo(Pass* pass);
// Render
void lovrPassPush(Pass* pass, StackType stack);
void lovrPassPop(Pass* pass, StackType stack);
void lovrPassOrigin(Pass* pass);
void lovrPassTranslate(Pass* pass, float* translation);
void lovrPassRotate(Pass* pass, float* rotation);
void lovrPassScale(Pass* pass, float* scale);
void lovrPassTransform(Pass* pass, float* transform);