mirror of https://github.com/bjornbytes/lovr.git
Compare commits
2 Commits
5c43ad0792
...
4021d4e893
Author | SHA1 | Date |
---|---|---|
bjorn | 4021d4e893 | |
bjorn | 75e8df58df |
|
@ -437,7 +437,7 @@ src += config.modules.thread and 'src/lib/tinycthread/*.c' or nil
|
|||
|
||||
-- embed resource files with xxd
|
||||
|
||||
res = { 'etc/*.lua', 'etc/*.ttf', 'etc/shaders/*.glsl' }
|
||||
res = { 'etc/boot.lua', 'etc/*.ttf', 'etc/shaders/*.glsl' }
|
||||
tup.foreach_rule(res, '^ XD %b^ xxd -i %f > %o', '%f.h')
|
||||
|
||||
for i, pattern in ipairs(res) do
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
|||
-- Usage: lovr etc/monkeycrush.lua > etc/monkey.h
|
||||
|
||||
local etc = lovr.filesystem.getSource()
|
||||
local success, model = assert(pcall(lovr.data.newModelData, 'monkey.glb'))
|
||||
|
||||
local min, max = lovr.math.newVec3(math.huge), lovr.math.newVec3(-math.huge)
|
||||
|
||||
for i = 1, model:getMeshVertexCount(1) do
|
||||
local x, y, z, nx, ny, nz = model:getMeshVertex(1, i)
|
||||
min.x, min.y, min.z = math.min(x, min.x), math.min(y, min.y), math.min(z, min.z)
|
||||
max.x, max.y, max.z = math.max(x, max.x), math.max(y, max.y), math.max(z, max.z)
|
||||
end
|
||||
|
||||
local size = lovr.math.newVec3(max - min)
|
||||
local scale = .5
|
||||
|
||||
min:mul(scale)
|
||||
max:mul(scale)
|
||||
size:mul(scale)
|
||||
|
||||
io.write(('float monkey_size[3] = { %ff, %ff, %ff };\n'):format(size:unpack()))
|
||||
io.write(('float monkey_offset[3] = { %ff, %ff, %ff };\n'):format(min:unpack()))
|
||||
io.write('\n')
|
||||
|
||||
io.write('uint8_t monkey_vertices[] = {\n')
|
||||
for i = 1, model:getMeshVertexCount(1) do
|
||||
local x, y, z, nx, ny, nz = model:getMeshVertex(1, i)
|
||||
local position = vec3(x, y, z):mul(scale)
|
||||
local normal = vec3(nx, ny, nz)
|
||||
|
||||
local qx, qy, qz = ((position - min) / size * 255 + .5):unpack()
|
||||
local qnx, qny, qnz = ((normal / 2 + .5) * 255 + .5):unpack()
|
||||
|
||||
qx, qy, qz = math.floor(qx), math.floor(qy), math.floor(qz)
|
||||
qnx, qny, qnz = math.floor(qnx), math.floor(qny), math.floor(qnz)
|
||||
|
||||
io.write((' %d, %d, %d, %d, %d, %d,\n'):format(qx, qy, qz, qnx, qny, qnz))
|
||||
|
||||
lovr.math.drain()
|
||||
end
|
||||
io.write('};\n\n')
|
||||
|
||||
io.write('uint16_t monkey_indices[] = {\n ')
|
||||
for i = 1, model:getMeshIndexCount(1) do
|
||||
local index = model:getMeshIndex(1, i)
|
||||
io.write((' %d,'):format(index))
|
||||
if i % 10 == 0 then
|
||||
io.write('\n ')
|
||||
end
|
||||
end
|
||||
io.write('\n};\n')
|
||||
|
||||
lovr.event.quit()
|
|
@ -336,9 +336,20 @@ static int l_lovrModelDataGetMeshVertex(lua_State* L) {
|
|||
ModelAttribute* attribute = mesh->attributes[i];
|
||||
if (!attribute) continue;
|
||||
|
||||
uint32_t stride = model->buffers[attribute->buffer].stride;
|
||||
|
||||
if (!stride) {
|
||||
switch (attribute->type) {
|
||||
case I8: case U8: stride = attribute->components * 1; break;
|
||||
case I16: case U16: stride = attribute->components * 2; break;
|
||||
case I32: case U32: case F32: stride = attribute->components * 4; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeData data = { .raw = model->buffers[attribute->buffer].data };
|
||||
data.u8 += attribute->offset;
|
||||
data.u8 += vertex * model->buffers[attribute->buffer].stride;
|
||||
data.u8 += vertex * stride;
|
||||
|
||||
for (uint32_t j = 0; j < attribute->components; j++) {
|
||||
switch (attribute->type) {
|
||||
|
|
|
@ -538,6 +538,19 @@ static int l_lovrPassTorus(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrPassCylinder(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
float transform[16];
|
||||
// TODO vec3+vec3
|
||||
int index = luax_readmat4(L, 2, transform, -2);
|
||||
bool capped = lua_isnoneornil(L, index) ? true : lua_toboolean(L, index++);
|
||||
float angle1 = luax_optfloat(L, index++, 0.f);
|
||||
float angle2 = luax_optfloat(L, index++, 2.f * (float) M_PI);
|
||||
uint32_t segments = luax_optu32(L, index++, 64);
|
||||
lovrPassCylinder(pass, transform, capped, angle1, angle2, segments);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrPassText(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
Font* font = luax_totype(L, 2, Font);
|
||||
|
@ -560,6 +573,14 @@ static int l_lovrPassFill(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrPassMonkey(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
float transform[16];
|
||||
luax_readmat4(L, 2, transform, 1);
|
||||
lovrPassMonkey(pass, transform);
|
||||
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);
|
||||
|
@ -809,8 +830,10 @@ const luaL_Reg lovrPass[] = {
|
|||
{ "circle", l_lovrPassCircle },
|
||||
{ "sphere", l_lovrPassSphere },
|
||||
{ "torus", l_lovrPassTorus },
|
||||
{ "cylinder", l_lovrPassCylinder },
|
||||
{ "text", l_lovrPassText },
|
||||
{ "fill", l_lovrPassFill },
|
||||
{ "monkey", l_lovrPassMonkey },
|
||||
{ "mesh", l_lovrPassMesh },
|
||||
{ "multimesh", l_lovrPassMultimesh },
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "core/spv.h"
|
||||
#include "core/os.h"
|
||||
#include "util.h"
|
||||
#include "monkey.h"
|
||||
#include "shaders.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -3047,6 +3048,83 @@ void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t s
|
|||
}
|
||||
}
|
||||
|
||||
void lovrPassCylinder(Pass* pass, float* transform, bool capped, float angle1, float angle2, uint32_t segments) {
|
||||
if (fabsf(angle1 - angle2) >= 2.f * (float) M_PI) {
|
||||
angle1 = 0.f;
|
||||
angle2 = 2.f * (float) M_PI;
|
||||
}
|
||||
|
||||
uint32_t vertexCount = 2 * (segments + 1);
|
||||
uint32_t indexCount = 6 * segments;
|
||||
ShapeVertex* vertices;
|
||||
uint16_t* indices;
|
||||
|
||||
if (capped) {
|
||||
vertexCount *= 2;
|
||||
vertexCount += 2;
|
||||
indexCount += 3 * segments * 2;
|
||||
}
|
||||
|
||||
lovrPassDraw(pass, &(Draw) {
|
||||
.mode = VERTEX_TRIANGLES,
|
||||
.transform = transform,
|
||||
.vertex.pointer = (void**) &vertices,
|
||||
.vertex.count = vertexCount,
|
||||
.index.pointer = (void**) &indices,
|
||||
.index.count = indexCount
|
||||
});
|
||||
|
||||
float angleShift = (angle2 - angle1) / segments;
|
||||
|
||||
// Tube
|
||||
for (uint32_t i = 0; i <= segments; i++) {
|
||||
float theta = angle1 + i * angleShift;
|
||||
float x = cosf(theta);
|
||||
float y = sinf(theta);
|
||||
*vertices++ = (ShapeVertex) { { x, y, -.5f }, { x, y, 0.f }, { x + .5f, .5f - y } };
|
||||
*vertices++ = (ShapeVertex) { { x, y, .5f }, { x, y, 0.f }, { x + .5f, .5f - y } };
|
||||
}
|
||||
|
||||
// Tube quads
|
||||
for (uint32_t i = 0; i < segments; i++) {
|
||||
uint16_t a = i * 2 + 0;
|
||||
uint16_t b = i * 2 + 1;
|
||||
uint16_t c = i * 2 + 2;
|
||||
uint16_t d = i * 2 + 3;
|
||||
uint16_t quad[] = { a, b, c, c, b, d };
|
||||
memcpy(indices, quad, sizeof(quad));
|
||||
indices += COUNTOF(quad);
|
||||
}
|
||||
|
||||
if (capped) {
|
||||
// Cap centers
|
||||
*vertices++ = (ShapeVertex) { { 0.f, 0.f, -.5f }, { 0.f, 0.f, -.5f }, { .5f, .5f } };
|
||||
*vertices++ = (ShapeVertex) { { 0.f, 0.f, .5f }, { 0.f, 0.f, .5f }, { .5f, .5f } };
|
||||
|
||||
// Caps
|
||||
for (uint32_t i = 0; i <= segments; i++) {
|
||||
float theta = angle1 + i * angleShift;
|
||||
float x = cosf(theta);
|
||||
float y = sinf(theta);
|
||||
*vertices++ = (ShapeVertex) { { x, y, -.5f }, { 0.f, 0.f, -.5f }, { x + .5f, y - .5f } };
|
||||
*vertices++ = (ShapeVertex) { { x, y, .5f }, { 0.f, 0.f, .5f }, { x + .5f, y - .5f } };
|
||||
}
|
||||
|
||||
// Cap wedges
|
||||
uint16_t base = 2 * (segments + 1);
|
||||
for (uint32_t i = 0; i < segments; i++) {
|
||||
uint16_t a = base + 0;
|
||||
uint16_t b = base + (i + 1) * 2;
|
||||
uint16_t c = base + (i + 2) * 2;
|
||||
uint16_t wedge1[] = { a + 0, b + 0, c + 0 };
|
||||
uint16_t wedge2[] = { a + 1, b + 1, c + 1 };
|
||||
memcpy(indices + 0, wedge1, sizeof(wedge1));
|
||||
memcpy(indices + 3, wedge2, sizeof(wedge2));
|
||||
indices += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t segmentsP) {
|
||||
float sx = vec3_length(transform + 0);
|
||||
float sy = vec3_length(transform + 4);
|
||||
|
@ -3419,6 +3497,32 @@ void lovrPassFill(Pass* pass, Texture* texture) {
|
|||
});
|
||||
}
|
||||
|
||||
void lovrPassMonkey(Pass* pass, float* transform) {
|
||||
uint32_t vertexCount = COUNTOF(monkey_vertices) / 6;
|
||||
|
||||
ShapeVertex* vertices;
|
||||
lovrPassDraw(pass, &(Draw) {
|
||||
.mode = VERTEX_TRIANGLES,
|
||||
.vertex.count = vertexCount,
|
||||
.vertex.pointer = (void**) &vertices,
|
||||
.index.count = COUNTOF(monkey_indices),
|
||||
.index.data = monkey_indices,
|
||||
.transform = transform
|
||||
});
|
||||
|
||||
// Manual vertex format conversion to avoid another format (and sn8x3 isn't always supported)
|
||||
for (uint32_t i = 0; i < vertexCount; i++) {
|
||||
vertices[i] = (ShapeVertex) {
|
||||
.position.x = monkey_vertices[6 * i + 0] / 255.f * monkey_size[0] + monkey_offset[0],
|
||||
.position.y = monkey_vertices[6 * i + 1] / 255.f * monkey_size[1] + monkey_offset[1],
|
||||
.position.z = monkey_vertices[6 * i + 2] / 255.f * monkey_size[2] + monkey_offset[2],
|
||||
.normal.x = monkey_vertices[6 * i + 3] / 255.f * 2.f - 1.f,
|
||||
.normal.y = monkey_vertices[6 * i + 4] / 255.f * 2.f - 1.f,
|
||||
.normal.z = monkey_vertices[6 * i + 5] / 255.f * 2.f - 1.f,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -480,9 +480,11 @@ void lovrPassPlane(Pass* pass, float* transform, DrawStyle style, uint32_t cols,
|
|||
void lovrPassBox(Pass* pass, float* transform, DrawStyle style);
|
||||
void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1, float angle2, uint32_t segments);
|
||||
void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t segmentsV);
|
||||
void lovrPassCylinder(Pass* pass, float* transform, bool capped, float angle1, float angle2, uint32_t segments);
|
||||
void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t segmentsP);
|
||||
void lovrPassText(Pass* pass, Font* font, const char* text, uint32_t length, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
|
||||
void lovrPassFill(Pass* pass, Texture* texture);
|
||||
void lovrPassMonkey(Pass* pass, float* transform);
|
||||
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances);
|
||||
void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* indirect, uint32_t count, uint32_t offset, uint32_t stride);
|
||||
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset);
|
||||
|
|
Loading…
Reference in New Issue