mirror of https://github.com/bjornbytes/lovr.git
Projection updates;
- Rename/reorder some projection matrix functions. - Make perspective functions flip Y and use 0-1 NDC range. - Flip winding and font vertices based on handedness. This stuff is really confusing
This commit is contained in:
parent
1bc31b7751
commit
430f687add
|
@ -145,7 +145,7 @@ static int l_lovrFontGetVertices(lua_State* L) {
|
|||
lovrAssert(vertices, "Out of memory");
|
||||
uint32_t glyphCount, lineCount;
|
||||
Material* material;
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material);
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material, false);
|
||||
int vertexCount = glyphCount * 4;
|
||||
lua_createtable(L, vertexCount, 0);
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
|
|
|
@ -1874,24 +1874,32 @@ static int l_lovrMat4Scale(lua_State* L) {
|
|||
|
||||
static int l_lovrMat4Orthographic(lua_State* L) {
|
||||
mat4 m = luax_checkvector(L, 1, V_MAT4, NULL);
|
||||
float left = luax_checkfloat(L, 2);
|
||||
float right = luax_checkfloat(L, 3);
|
||||
float top = luax_checkfloat(L, 4);
|
||||
float bottom = luax_checkfloat(L, 5);
|
||||
float clipNear = luax_checkfloat(L, 6);
|
||||
float clipFar = luax_checkfloat(L, 7);
|
||||
mat4_orthographic(m, left, right, top, bottom, clipNear, clipFar);
|
||||
if (lua_gettop(L) <= 5) {
|
||||
float width = luax_checkfloat(L, 2);
|
||||
float height = luax_checkfloat(L, 3);
|
||||
float n = luax_optfloat(L, 4, -1.f);
|
||||
float f = luax_optfloat(L, 5, 1.f);
|
||||
mat4_orthographic(m, 0.f, width, 0.f, height, n, f);
|
||||
} else {
|
||||
float left = luax_checkfloat(L, 2);
|
||||
float right = luax_checkfloat(L, 3);
|
||||
float bottom = luax_checkfloat(L, 4);
|
||||
float top = luax_checkfloat(L, 5);
|
||||
float n = luax_checkfloat(L, 6);
|
||||
float f = luax_checkfloat(L, 7);
|
||||
mat4_orthographic(m, left, right, bottom, top, n, f);
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrMat4Perspective(lua_State* L) {
|
||||
mat4 m = luax_checkvector(L, 1, V_MAT4, NULL);
|
||||
float clipNear = luax_checkfloat(L, 2);
|
||||
float clipFar = luax_checkfloat(L, 3);
|
||||
float fov = luax_checkfloat(L, 4);
|
||||
float aspect = luax_checkfloat(L, 5);
|
||||
mat4_perspective(m, clipNear, clipFar, fov, aspect);
|
||||
float fovy = luax_checkfloat(L, 2);
|
||||
float aspect = luax_checkfloat(L, 3);
|
||||
float n = luax_checkfloat(L, 4);
|
||||
float f = luax_checkfloat(L, 5);
|
||||
mat4_perspective(m, fovy, aspect, n, f);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1902,9 +1910,9 @@ static int l_lovrMat4Fov(lua_State* L) {
|
|||
float right = luax_checkfloat(L, 3);
|
||||
float up = luax_checkfloat(L, 4);
|
||||
float down = luax_checkfloat(L, 5);
|
||||
float clipNear = luax_checkfloat(L, 6);
|
||||
float clipFar = luax_checkfloat(L, 7);
|
||||
mat4_fov(m, left, right, up, down, clipNear, clipFar);
|
||||
float n = luax_checkfloat(L, 6);
|
||||
float f = luax_checkfloat(L, 7);
|
||||
mat4_fov(m, left, right, up, down, n, f);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -590,56 +590,49 @@ MAF void mat4_getScale(mat4 m, vec3 scale) {
|
|||
vec3_set(scale, vec3_length(m + 0), vec3_length(m + 4), vec3_length(m + 8));
|
||||
}
|
||||
|
||||
MAF mat4 mat4_orthographic(mat4 m, float left, float right, float top, float bottom, float clipNear, float clipFar) {
|
||||
// Does not have a Y flip, maps z = [-n,-f] to [0,1]
|
||||
MAF mat4 mat4_orthographic(mat4 m, float left, float right, float bottom, float top, float n, float f) {
|
||||
float rl = right - left;
|
||||
float tb = top - bottom;
|
||||
float fn = clipFar - clipNear;
|
||||
float fn = f - n;
|
||||
memset(m, 0, 16 * sizeof(float));
|
||||
m[0] = 2 / rl;
|
||||
m[5] = 2 / tb;
|
||||
m[10] = -2 / fn;
|
||||
m[12] = -(left + right) / rl;
|
||||
m[0] = 2.f / rl;
|
||||
m[5] = 2.f / tb;
|
||||
m[10] = -1.f / fn;
|
||||
m[12] = -(right + left) / rl;
|
||||
m[13] = -(top + bottom) / tb;
|
||||
m[14] = -(clipFar + clipNear) / fn;
|
||||
m[15] = 1;
|
||||
m[14] = -n / fn;
|
||||
m[15] = 1.f;
|
||||
return m;
|
||||
}
|
||||
|
||||
MAF mat4 mat4_perspective(mat4 m, float clipNear, float clipFar, float fovy, float aspect) {
|
||||
float range = tanf(fovy * .5f) * clipNear;
|
||||
float sx = (2.f * clipNear) / (range * aspect + range * aspect);
|
||||
float sy = -clipNear / range;
|
||||
float sz = -clipFar / (clipFar - clipNear);
|
||||
float pz = (-clipFar * clipNear) / (clipFar - clipNear);
|
||||
// Flips Y and maps z = [-n,-f] to [0,1] after dividing by w
|
||||
MAF mat4 mat4_perspective(mat4 m, float fovy, float aspect, float n, float f) {
|
||||
float cotan = 1.f / tanf(fovy * .5f);
|
||||
memset(m, 0, 16 * sizeof(float));
|
||||
m[0] = sx;
|
||||
m[5] = sy;
|
||||
m[10] = sz;
|
||||
m[0] = cotan / aspect;
|
||||
m[5] = -cotan;
|
||||
m[10] = f / (n - f);
|
||||
m[11] = -1.f;
|
||||
m[14] = pz;
|
||||
m[14] = (n * f) / (n - f);
|
||||
m[15] = 0.f;
|
||||
return m;
|
||||
}
|
||||
|
||||
// This is currently specific to Vulkan
|
||||
MAF mat4 mat4_fov(mat4 m, float left, float right, float up, float down, float clipNear, float clipFar) {
|
||||
// Flips Y and maps z = [-n,-f] to [0,1] after dividing by w
|
||||
MAF mat4 mat4_fov(mat4 m, float left, float right, float up, float down, float n, float f) {
|
||||
left = -tanf(left);
|
||||
right = tanf(right);
|
||||
up = tanf(up);
|
||||
down = -tanf(down);
|
||||
float idx = 1.f / (right - left);
|
||||
float idy = 1.f / (down - up);
|
||||
float idz = 1.f / (clipFar - clipNear);
|
||||
float sx = right + left;
|
||||
float sy = down + up;
|
||||
memset(m, 0, 16 * sizeof(float));
|
||||
m[0] = 2.f * idx;
|
||||
m[5] = 2.f * idy;
|
||||
m[8] = sx * idx;
|
||||
m[9] = sy * idy;
|
||||
m[10] = -clipFar * idz;
|
||||
m[0] = 2.f / (right - left);
|
||||
m[5] = 2.f / (down - up);
|
||||
m[8] = (right + left) / (right - left);
|
||||
m[9] = (down + up) / (down - up);
|
||||
m[10] = f / (n - f);
|
||||
m[11] = -1.f;
|
||||
m[14] = -(clipFar * clipNear) * idz;
|
||||
m[14] = (n * f) / (n - f);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
|
|
@ -3073,7 +3073,7 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
|
|||
pass->cameras = tempAlloc(pass->cameraCount * sizeof(Camera));
|
||||
for (uint32_t i = 0; i < pass->cameraCount; i++) {
|
||||
mat4_identity(pass->cameras[i].view);
|
||||
mat4_perspective(pass->cameras[i].projection, .01f, 100.f, 1.0f, (float) main->width / main->height);
|
||||
mat4_perspective(pass->cameras[i].projection, 1.f, (float) main->width / main->height, .01f, 100.f);
|
||||
}
|
||||
pass->cameraDirty = true;
|
||||
|
||||
|
@ -3131,6 +3131,12 @@ void lovrPassSetProjection(Pass* pass, uint32_t index, float* projection) {
|
|||
lovrCheck(index < pass->cameraCount, "Invalid camera index '%d'", index);
|
||||
mat4_init(pass->cameras[index].projection, projection);
|
||||
pass->cameraDirty = true;
|
||||
|
||||
// If the handedness of the projection changes, flip the winding
|
||||
if (index == 0 && (projection[5] > 0.f != pass->cameras[0].projection[5] > 0.f)) {
|
||||
pass->pipeline->info.rasterizer.winding = !pass->pipeline->info.rasterizer.winding;
|
||||
pass->pipeline->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void lovrPassPush(Pass* pass, StackType stack) {
|
||||
|
@ -3456,6 +3462,7 @@ void lovrPassSetViewport(Pass* pass, float viewport[4], float depthRange[2]) {
|
|||
}
|
||||
|
||||
void lovrPassSetWinding(Pass* pass, Winding winding) {
|
||||
if (pass->cameras[0].projection[5] > 0.f) winding = !winding; // Handedness requires winding flip
|
||||
pass->pipeline->dirty |= pass->pipeline->info.rasterizer.winding != (gpu_winding) winding;
|
||||
pass->pipeline->info.rasterizer.winding = (gpu_winding) winding;
|
||||
}
|
||||
|
@ -4453,7 +4460,7 @@ static void aline(GlyphVertex* vertices, uint32_t head, uint32_t tail, float wid
|
|||
}
|
||||
}
|
||||
|
||||
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material) {
|
||||
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material, bool flip) {
|
||||
uint32_t vertexCount = 0;
|
||||
uint32_t lineStart = 0;
|
||||
uint32_t wordStart = 0;
|
||||
|
@ -4508,7 +4515,7 @@ void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, flo
|
|||
Glyph* glyph = lovrFontGetGlyph(font, codepoint, &resized);
|
||||
|
||||
if (resized) {
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, glyphCount, lineCount, material);
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, glyphCount, lineCount, material, flip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4538,10 +4545,17 @@ void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, flo
|
|||
// Vertices
|
||||
float* bb = glyph->box;
|
||||
uint16_t* uv = glyph->uv;
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], y + bb[3] }, { uv[0], uv[1] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[3] }, { uv[2], uv[1] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], y + bb[1] }, { uv[0], uv[3] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[1] }, { uv[2], uv[3] }, { r, g, b, a } };
|
||||
if (flip) {
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], -(y + bb[1]) }, { uv[0], uv[3] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], -(y + bb[1]) }, { uv[2], uv[3] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], -(y + bb[3]) }, { uv[0], uv[1] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], -(y + bb[3]) }, { uv[2], uv[1] }, { r, g, b, a } };
|
||||
} else {
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], y + bb[3] }, { uv[0], uv[1] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[3] }, { uv[2], uv[1] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[0], y + bb[1] }, { uv[0], uv[3] }, { r, g, b, a } };
|
||||
vertices[vertexCount++] = (GlyphVertex) { { x + bb[2], y + bb[1] }, { uv[2], uv[3] }, { r, g, b, a } };
|
||||
}
|
||||
(*glyphCount)++;
|
||||
|
||||
// Advance
|
||||
|
@ -4575,10 +4589,12 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
|
|||
wrap /= scale;
|
||||
|
||||
Material* material;
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material);
|
||||
bool flip = pass->cameras[0].projection[5] > 0.f;
|
||||
lovrFontGetVertices(font, strings, count, wrap, halign, valign, vertices, &glyphCount, &lineCount, &material, flip);
|
||||
|
||||
mat4_scale(transform, scale, scale, scale);
|
||||
mat4_translate(transform, 0.f, -ascent + valign / 2.f * (leading * lineCount), 0.f);
|
||||
float offset = -ascent + valign / 2.f * (leading * lineCount);
|
||||
mat4_translate(transform, 0.f, flip ? -offset : offset, 0.f);
|
||||
|
||||
GlyphVertex* vertexPointer;
|
||||
uint16_t* indices;
|
||||
|
|
|
@ -384,7 +384,7 @@ void lovrFontSetLineSpacing(Font* font, float spacing);
|
|||
float lovrFontGetKerning(Font* font, uint32_t first, uint32_t second);
|
||||
float lovrFontGetWidth(Font* font, ColoredString* strings, uint32_t count);
|
||||
void lovrFontGetLines(Font* font, ColoredString* strings, uint32_t count, float wrap, void (*callback)(void* context, const char* string, size_t length), void* context);
|
||||
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material);
|
||||
void lovrFontGetVertices(Font* font, ColoredString* strings, uint32_t count, float wrap, HorizontalAlign halign, VerticalAlign valign, GlyphVertex* vertices, uint32_t* glyphCount, uint32_t* lineCount, Material** material, bool flip);
|
||||
|
||||
// Model
|
||||
|
||||
|
|
Loading…
Reference in New Issue