Add a make-shift player model (it's a snail xD)

fixes #780
This commit is contained in:
IntegratedQuantum 2024-11-22 21:57:36 +01:00
parent b271a416bc
commit 25bd05e0c3
7 changed files with 275 additions and 101 deletions

View File

@ -0,0 +1,183 @@
v 0.15625 -0.40625 0.59375
v 0.15625 0.09375 0.59375
v 0.15625 -0.40625 0.09375
v 0.15625 0.09375 0.09375
v -0.15625 0.09375 0.59375
v -0.15625 -0.40625 0.59375
v -0.15625 0.09375 0.09375
v -0.15625 -0.40625 0.09375
vt 0.125 0.875
vt 0.203125 0.875
vt 0.203125 0.75
vt 0.125 0.75
vt 0 0.875
vt 0.125 0.875
vt 0.125 0.75
vt 0 0.75
vt 0.328125 0.875
vt 0.40625 0.875
vt 0.40625 0.75
vt 0.328125 0.75
vt 0.203125 0.875
vt 0.328125 0.875
vt 0.328125 0.75
vt 0.203125 0.75
vt 0.203125 0.875
vt 0.125 0.875
vt 0.125 1
vt 0.203125 1
vt 0.28125 1
vt 0.203125 1
vt 0.203125 0.875
vt 0.28125 0.875
vn 0 1 0
vn 1 0 0
vn 0 -1 0
vn -1 0 0
vn 0 0 1
vn 0 0 -1
f 4/4/1 7/3/1 5/2/1 2/1/1
f 3/8/2 4/7/2 2/6/2 1/5/2
f 8/12/3 3/11/3 1/10/3 6/9/3
f 7/16/4 8/15/4 6/14/4 5/13/4
f 6/20/5 1/19/5 2/18/5 5/17/5
f 7/24/6 4/23/6 3/22/6 8/21/6
v 0.125 -0.4375 0.1875
v 0.125 0 0.1875
v 0.125 -0.4375 0
v 0.125 0 0
v -0.125 0 0.1875
v -0.125 -0.4375 0.1875
v -0.125 0 0
v -0.125 -0.4375 0
vt 0.109375 0.640625
vt 0.171875 0.640625
vt 0.171875 0.59375
vt 0.109375 0.59375
vt 0 0.640625
vt 0.109375 0.640625
vt 0.109375 0.59375
vt 0 0.59375
vt 0.28125 0.640625
vt 0.34375 0.640625
vt 0.34375 0.59375
vt 0.28125 0.59375
vt 0.171875 0.640625
vt 0.28125 0.640625
vt 0.28125 0.59375
vt 0.171875 0.59375
vt 0.171875 0.640625
vt 0.109375 0.640625
vt 0.109375 0.75
vt 0.171875 0.75
vt 0.234375 0.75
vt 0.171875 0.75
vt 0.171875 0.640625
vt 0.234375 0.640625
vn 0 1 0
vn 1 0 0
vn 0 -1 0
vn -1 0 0
vn 0 0 1
vn 0 0 -1
f 12/28/7 15/27/7 13/26/7 10/25/7
f 11/32/8 12/31/8 10/30/8 9/29/8
f 16/36/9 11/35/9 9/34/9 14/33/9
f 15/40/10 16/39/10 14/38/10 13/37/10
f 14/44/11 9/43/11 10/42/11 13/41/11
f 15/48/12 12/47/12 11/46/12 16/45/12
v 0.125 0 0.1875
v 0.125 0.4375 0.1875
v 0.125 0 0
v 0.125 0.4375 0
v -0.125 0.4375 0.1875
v -0.125 0 0.1875
v -0.125 0.4375 0
v -0.125 0 0
vt 0.453125 0.640625
vt 0.515625 0.640625
vt 0.515625 0.59375
vt 0.453125 0.59375
vt 0.34375 0.640625
vt 0.453125 0.640625
vt 0.453125 0.59375
vt 0.34375 0.59375
vt 0.625 0.640625
vt 0.6875 0.640625
vt 0.6875 0.59375
vt 0.625 0.59375
vt 0.515625 0.640625
vt 0.625 0.640625
vt 0.625 0.59375
vt 0.515625 0.59375
vt 0.515625 0.640625
vt 0.453125 0.640625
vt 0.453125 0.75
vt 0.515625 0.75
vt 0.578125 0.75
vt 0.515625 0.75
vt 0.515625 0.640625
vt 0.578125 0.640625
vn 0 1 0
vn 1 0 0
vn 0 -1 0
vn -1 0 0
vn 0 0 1
vn 0 0 -1
f 20/52/13 23/51/13 21/50/13 18/49/13
f 19/56/14 20/55/14 18/54/14 17/53/14
f 24/60/15 19/59/15 17/58/15 22/57/15
f 23/64/16 24/63/16 22/62/16 21/61/16
f 22/68/17 17/67/17 18/66/17 21/65/17
f 23/72/18 20/71/18 19/70/18 24/69/18
v 0.125 0.5345571419134454 0.5497221848584004
v 0.125 0.5345571419134454 0.5497221848584004
v 0.125 0.4375 0.1875
v 0.125 0.4375 0.1875
v -0.125 0.5345571419134454 0.5497221848584004
v -0.125 0.5345571419134454 0.5497221848584004
v -0.125 0.4375 0.1875
v -0.125 0.4375 0.1875
vt 0 0.59375
vt 0.0625 0.59375
vt 0.0625 0.5
vt 0 0.5
vt 0 0.59375
vt 0 0.59375
vt 0 0.5
vt 0 0.5
vt 0.0625 0.59375
vt 0.125 0.59375
vt 0.125 0.5
vt 0.0625 0.5
vt 0.0625 0.59375
vt 0.0625 0.59375
vt 0.0625 0.5
vt 0.0625 0.5
vt 0.0625 0.59375
vt 0 0.59375
vt 0 0.59375
vt 0.0625 0.59375
vt 0.125 0.59375
vt 0.0625 0.59375
vt 0.0625 0.59375
vt 0.125 0.59375
vn 0 0.9659258262890682 -0.25881904510252096
vn 1 0 0
vn 0 -0.9659258262890682 0.25881904510252096
vn -1 0 0
vn 0 0.25881904510252096 0.9659258262890682
vn 0 -0.25881904510252096 -0.9659258262890682
f 28/76/19 31/75/19 29/74/19 26/73/19
f 27/80/20 28/79/20 26/78/20 25/77/20
f 32/84/21 27/83/21 25/82/21 30/81/21
f 31/88/22 32/87/22 30/86/22 29/85/22
f 30/92/23 25/91/23 26/90/23 29/89/23
f 31/96/24 28/95/24 27/94/24 32/93/24

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -62,31 +62,6 @@ layout(std430, binding = 6) buffer _chunks
ChunkData chunks[];
};
const vec3[6] normals = vec3[6](
vec3(0, 0, 1),
vec3(0, 0, -1),
vec3(1, 0, 0),
vec3(-1, 0, 0),
vec3(0, 1, 0),
vec3(0, -1, 0)
);
const ivec3[6] textureX = ivec3[6](
ivec3(1, 0, 0),
ivec3(-1, 0, 0),
ivec3(0, -1, 0),
ivec3(0, 1, 0),
ivec3(1, 0, 0),
ivec3(-1, 0, 0)
);
const ivec3[6] textureY = ivec3[6](
ivec3(0, 1, 0),
ivec3(0, 1, 0),
ivec3(0, 0, -1),
ivec3(0, 0, -1),
ivec3(0, 0, -1),
ivec3(0, 0, -1)
);
void main() {
int faceID = gl_VertexID >> 2;
int vertexID = gl_VertexID & 3;
@ -142,4 +117,4 @@ void main() {
gl_Position = projectionMatrix*mvPos;
mvVertexPos = mvPos.xyz;
uv = quads[quadIndex].cornerUV[vertexID]*voxelSize;
}
}

View File

@ -3,26 +3,19 @@
in vec2 outTexCoord;
in vec3 mvVertexPos;
in vec3 outLight;
flat in vec3 normal;
out vec4 fragColor;
uniform sampler2D texture_sampler;
uniform bool materialHasTexture;
vec4 ambientC;
uniform float contrast;
void setupColors(bool materialHasTexture, vec2 textCoord) {
if (materialHasTexture)
{
ambientC = texture(texture_sampler, textCoord);
}
else
{
ambientC = vec4(1, 1, 1, 1);
}
float lightVariation(vec3 normal) {
const vec3 directionalPart = vec3(0, contrast/2, contrast);
const float baseLighting = 1 - contrast;
return baseLighting + dot(normal, directionalPart);
}
void main() {
setupColors(materialHasTexture, outTexCoord);
fragColor = ambientC*vec4(outLight, 1);
fragColor = texture(texture_sampler, outTexCoord)*vec4(outLight*lightVariation(normal), 1);
}

View File

@ -1,13 +1,9 @@
#version 430
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
layout (location=2) in vec3 vertexNormal;
out vec2 outTexCoord;
out vec3 mvVertexPos;
out float outSelected;
out vec3 outLight;
flat out vec3 normal;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
@ -15,12 +11,23 @@ uniform vec3 ambientLight;
uniform vec3 directionalLight;
uniform int light;
struct QuadInfo {
vec3 normal;
vec3 corners[4];
vec2 cornerUV[4];
uint textureSlot;
};
layout(std430, binding = 11) buffer _quads
{
QuadInfo quads[];
};
vec3 calcLight(int srgb) {
float s = (srgb >> 24) & 255;
float r = (srgb >> 16) & 255;
float g = (srgb >> 8) & 255;
float b = (srgb >> 0) & 255;
s = s*(1 - dot(directionalLight, vertexNormal));
r = max(s*ambientLight.x, r);
g = max(s*ambientLight.y, g);
b = max(s*ambientLight.z, b);
@ -28,9 +35,16 @@ vec3 calcLight(int srgb) {
}
void main() {
vec4 mvPos = viewMatrix * vec4(position, 1);
gl_Position = projectionMatrix * mvPos;
outTexCoord = texCoord;
int faceID = gl_VertexID >> 2;
int vertexID = gl_VertexID & 3;
normal = quads[faceID].normal;
vec3 position = quads[faceID].corners[vertexID];
vec4 mvPos = viewMatrix*vec4(position, 1);
gl_Position = projectionMatrix*mvPos;
mvVertexPos = mvPos.xyz;
outTexCoord = quads[faceID].cornerUV[vertexID];
outLight = calcLight(light);
}
}

View File

@ -54,7 +54,7 @@ pub const ClientEntity = struct {
}
pub fn getRenderPosition(self: *const ClientEntity) Vec3d {
return Vec3d{self.pos[0], self.pos[1], self.pos[2] + self.height/2};
return Vec3d{self.pos[0], self.pos[1], self.pos[2]};
}
pub fn updatePosition(self: *ClientEntity, pos: *const [6]f64, vel: *const [6]f64, time: i16) void {
@ -79,11 +79,14 @@ pub const ClientEntityManager = struct {
projectionMatrix: c_int,
viewMatrix: c_int,
texture_sampler: c_int,
materialHasTexture: c_int,
light: c_int,
contrast: c_int,
ambientLight: c_int,
directionalLight: c_int,
} = undefined;
var modelBuffer: main.graphics.SSBO = undefined;
var modelSize: c_int = 0;
var modelTexture: main.graphics.Texture = undefined;
var shader: graphics.Shader = undefined; // Entities are sometimes small and sometimes big. Therefor it would mean a lot of work to still use smooth lighting. Therefor the non-smooth shader is used for those.
pub var entities: main.VirtualList(ClientEntity, 1 << 20) = undefined;
pub var mutex: std.Thread.Mutex = std.Thread.Mutex{};
@ -91,6 +94,18 @@ pub const ClientEntityManager = struct {
pub fn init() void {
entities = .init();
shader = graphics.Shader.initAndGetUniforms("assets/cubyz/shaders/entity_vertex.vs", "assets/cubyz/shaders/entity_fragment.fs", "", &uniforms);
modelTexture = main.graphics.Texture.initFromFile("assets/cubyz/entity/textures/snail_player.png");
const modelFile = main.files.read(main.stackAllocator, "assets/cubyz/entity/models/snail_player.obj") catch |err| blk: {
std.log.err("Error while reading player model: {s}", .{@errorName(err)});
break :blk &.{};
};
defer main.stackAllocator.free(modelFile);
const quadInfos = main.models.Model.loadRawModelDataFromObj(main.stackAllocator, modelFile);
defer main.stackAllocator.free(quadInfos);
modelBuffer = .initStatic(main.models.QuadInfo, quadInfos);
modelBuffer.bind(11);
modelSize = @intCast(quadInfos.len);
}
pub fn deinit() void {
@ -149,34 +164,34 @@ pub const ClientEntityManager = struct {
defer mutex.unlock();
update();
shader.bind();
c.glBindVertexArray(main.renderer.chunk_meshing.vao);
c.glUniformMatrix4fv(uniforms.projectionMatrix, 1, c.GL_TRUE, @ptrCast(&projMatrix));
modelTexture.bindTo(0);
c.glUniform1i(uniforms.texture_sampler, 0);
c.glUniform3fv(uniforms.ambientLight, 1, @ptrCast(&ambientLight));
c.glUniform3fv(uniforms.directionalLight, 1, @ptrCast(&directionalLight));
c.glUniform1f(uniforms.contrast, 0.12);
for(entities.items()) |ent| {
if(ent.id == game.Player.id) continue; // don't render local player
// TODO: Entity meshes.
// TODO: c.glBindVertexArray(vao);
c.glUniform1i(uniforms.materialHasTexture, c.GL_TRUE);
c.glUniform1i(uniforms.light, @bitCast(@as(u32, 0xffffffff))); // TODO: Lighting
const pos: Vec3d = ent.getRenderPosition() - playerPos;
const modelMatrix = (
Mat4f.identity() // TODO: .scale(scale);
.mul(Mat4f.rotationZ(-ent.rot[2]))
.mul(Mat4f.rotationY(-ent.rot[1]))
.mul(Mat4f.rotationX(-ent.rot[0]))
Mat4f.identity()
.mul(Mat4f.translation(Vec3f{
@floatCast(pos[0]),
@floatCast(pos[1]),
@floatCast(pos[2]),
@floatCast(pos[2] - 1.0 + 0.09375),
}))
.mul(Mat4f.rotationZ(-ent.rot[2]))
//.mul(Mat4f.rotationY(-ent.rot[1]))
//.mul(Mat4f.rotationX(-ent.rot[0]))
);
const modelViewMatrix = modelMatrix.mul(game.camera.viewMatrix);
const modelViewMatrix = game.camera.viewMatrix.mul(modelMatrix);
c.glUniformMatrix4fv(uniforms.viewMatrix, 1, c.GL_TRUE, @ptrCast(&modelViewMatrix));
// TODO: c.glDrawElements(...);
c.glDrawElements(c.GL_TRIANGLES, 6*modelSize, c.GL_UNSIGNED_INT, null);
}
}

View File

@ -177,6 +177,28 @@ pub const Model = struct {
}
pub fn loadModel(data: []const u8) u16 {
const quadInfos = loadRawModelDataFromObj(main.stackAllocator, data);
defer main.stackAllocator.free(quadInfos);
for(quadInfos) |*quad| {
var minUv: Vec2f = @splat(std.math.inf(f32));
for(0..4) |i| {
quad.cornerUV[i] *= @splat(4);
minUv = @min(minUv, quad.cornerUV[i]);
}
quad.textureSlot = @as(u32, @intFromFloat(@floor(minUv[1]))) * 4 + @as(u32, @intFromFloat(@floor(minUv[0])));
if (minUv[0] < 0 or minUv[0] > 4 or minUv[1] < 0 or minUv[1] > 4) {
std.log.err("Uv value for model is outside of 0-1 range", .{});
}
for(0..4) |i| {
quad.cornerUV[i] -= minUv;
}
}
return Model.init(quadInfos);
}
pub fn loadRawModelDataFromObj(allocator: main.utils.NeverFailingAllocator, data: []const u8) []QuadInfo {
var vertices = main.List(Vec3f).init(main.stackAllocator);
defer vertices.deinit();
@ -236,8 +258,6 @@ pub const Model = struct {
while (coordsIter.next()) |coord| : (i += 1) {
uv[i] = std.fmt.parseFloat(f32, coord) catch |e| blk: { std.log.err("Failed parsing {s} into float: {any}", .{coord, e}); break :blk 0; };
}
uv[0] *= 4;
uv[1] *= 4;
uvs.append(.{uv[0], uv[1]});
} else if (std.mem.eql(u8, line[0..2], "f ")) {
var coordsIter = std.mem.splitScalar(u8, line[2..], ' ');
@ -276,29 +296,16 @@ pub const Model = struct {
}
}
var quadInfos = main.List(QuadInfo).init(main.stackAllocator);
var quadInfos = main.List(QuadInfo).initCapacity(allocator, tris.items.len + quads.items.len);
defer quadInfos.deinit();
for (tris.items) |face| {
const normal: Vec3f = normals.items[face.normal];
var uvA: Vec2f = uvs.items[face.uvs[0]];
var uvB: Vec2f = uvs.items[face.uvs[2]];
var uvC: Vec2f = uvs.items[face.uvs[1]];
const uvA: Vec2f = uvs.items[face.uvs[0]];
const uvB: Vec2f = uvs.items[face.uvs[2]];
const uvC: Vec2f = uvs.items[face.uvs[1]];
const minUv = @floor(@min(@min(uvA, uvB), uvC));
if (minUv[0] < 0 or minUv[0] > 4 or minUv[1] < 0 or minUv[1] > 4) {
std.log.err("Uv value for model is outside of 0-1 range", .{});
continue;
}
const textureSlot = @as(u32, @intFromFloat(@floor(minUv[1]))) * 4 + @as(u32, @intFromFloat(@floor(minUv[0])));
uvA -= minUv;
uvB -= minUv;
uvC -= minUv;
const cornerA: Vec3f = vertices.items[face.vertex[0]];
const cornerB: Vec3f = vertices.items[face.vertex[2]];
const cornerC: Vec3f = vertices.items[face.vertex[1]];
@ -307,30 +314,17 @@ pub const Model = struct {
.normal = normal,
.corners = .{cornerA, cornerB, cornerC, cornerB},
.cornerUV = .{uvA, uvB, uvC, uvB},
.textureSlot = textureSlot,
.textureSlot = 0,
});
}
for (quadFaces.items) |face| {
const normal: Vec3f = normals.items[face.normal];
var uvA: Vec2f = uvs.items[face.uvs[1]];
var uvB: Vec2f = uvs.items[face.uvs[0]];
var uvC: Vec2f = uvs.items[face.uvs[2]];
var uvD: Vec2f = uvs.items[face.uvs[3]];
const minUv = @floor(@min(@min(uvA, uvB), @min(uvC, uvD)));
const textureSlot = @as(u32, @intFromFloat(@floor(minUv[1]))) * 4 + @as(u32, @intFromFloat(@floor(minUv[0])));
if (minUv[0] < 0 or minUv[0] > 4 or minUv[1] < 0 or minUv[1] > 4) {
std.log.err("Uv value for model is outside of 0-1 range", .{});
continue;
}
uvA -= minUv;
uvB -= minUv;
uvC -= minUv;
uvD -= minUv;
const uvA: Vec2f = uvs.items[face.uvs[1]];
const uvB: Vec2f = uvs.items[face.uvs[0]];
const uvC: Vec2f = uvs.items[face.uvs[2]];
const uvD: Vec2f = uvs.items[face.uvs[3]];
const cornerA: Vec3f = vertices.items[face.vertex[1]];
const cornerB: Vec3f = vertices.items[face.vertex[0]];
@ -341,11 +335,11 @@ pub const Model = struct {
.normal = normal,
.corners = .{cornerA, cornerB, cornerC, cornerD},
.cornerUV = .{uvA, uvB, uvC, uvD},
.textureSlot = textureSlot,
.textureSlot = 0,
});
}
return Model.init(quadInfos.items);
return quadInfos.toOwnedSlice();
}
fn deinit(self: *const Model) void {