First commit (very unfinished)

This commit is contained in:
milkwx3
2026-06-13 22:02:49 +03:00
commit c60f598661
47 changed files with 9309 additions and 0 deletions
+591
View File
@@ -0,0 +1,591 @@
#include <vector>
#include <cstdint>
#include <cstring>
#include <algorithm>
#include "common.hpp"
#include <vector>
#include <cstdint>
#include <array>
#ifndef SERVER
#ifndef LEGACY_GL
MeshData GenerateChunkMesh(ChunkRenderData chunkRenderData, Chunk chunk, int chunkWorldX, int chunkWorldY, uint8_t sideMask)
{
MeshData out = {0};
out.vertexCount = 0; out.indexCount = 0;
std::vector<Vector3> positions;
std::vector<Vector3> normals;
std::vector<Vector2> uvs;
std::vector<Color> colors;
std::vector<unsigned short> indices;
int face = 0;
for (int x = 0; x < CHUNK_SIZE; ++x)
for (int y = 0; y < WORLD_HEIGHT; ++y)
for (int z = 0; z < CHUNK_SIZE; ++z)
{
int index = GetIndexChunk(x,y,z);
uint8_t crdata = chunkRenderData.sides[index];
if (crdata == 0) continue;
int this_block = fetch_block(chunk, x,y,z);
BlockDef definition = BLOCKS[this_block];
UVCorners UVside = GetUVTex(definition.textureSide);
UVCorners UVtop = GetUVTex(definition.textureTop);
UVCorners UVbtm = GetUVTex(definition.textureBottom);
bool left, right, up, down, back, front;
unpack6(crdata & sideMask, &left, &right, &up, &down, &back, &front);
bool shaded = chunk.highestBlock[GetIndexChunk2D(x, z)] != y;
Color color = {255, 255, 255, 255};
Color colorShaded = {128, 128, 172, 255};
float wx = (float)(chunkWorldX * CHUNK_SIZE + x);
float wy = (float)(y);
float wz = (float)(chunkWorldY * CHUNK_SIZE + z);
/*if(GetCloud(wx, wz)) {
color = ColorLerp(color, colorShaded, 0.5f);
}*/
if (left) {
Vector3 verts[4] = {
{wx - 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-left
{wx - 0.5f, wy - 0.5f, wz + 0.5f}, // bottom-right
{wx - 0.5f, wy + 0.5f, wz + 0.5f}, // top-right
{wx - 0.5f, wy + 0.5f, wz - 0.5f} // top-left
};
Vector3 normal = {-1.0f, 0.0f, 0.0f};
Vector2 corners[4] = {
UVside.corner0,
UVside.corner1,
UVside.corner2,
UVside.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
colors.push_back(colorShaded);
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
// Right face (+X)
if (right) {
Vector3 verts[4] = {
{wx + 0.5f, wy - 0.5f, wz + 0.5f}, // bottom-left (from +X side)
{wx + 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-right
{wx + 0.5f, wy + 0.5f, wz - 0.5f}, // top-right
{wx + 0.5f, wy + 0.5f, wz + 0.5f} // top-left
};
Vector3 normal = {1.0f, 0.0f, 0.0f};
Vector2 corners[4] = {
UVside.corner0,
UVside.corner1,
UVside.corner2,
UVside.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
colors.push_back(colorShaded);
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
// Down (-Y)
if (down) {
Vector3 verts[4] = {
{wx - 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-left
{wx + 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-right
{wx + 0.5f, wy - 0.5f, wz + 0.5f}, // top-right
{wx - 0.5f, wy - 0.5f, wz + 0.5f} // top-left
};
Vector3 normal = {0.0f, -1.0f, 0.0f};
Vector2 corners[4] = {
UVbtm.corner0,
UVbtm.corner1,
UVbtm.corner2,
UVbtm.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
colors.push_back(colorShaded);
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
// Up (+Y)
if (up) {
Vector3 verts[4] = {
{wx - 0.5f, wy + 0.5f, wz + 0.5f}, // bottom-left (from +Y side)
{wx + 0.5f, wy + 0.5f, wz + 0.5f}, // bottom-right
{wx + 0.5f, wy + 0.5f, wz - 0.5f}, // top-right
{wx - 0.5f, wy + 0.5f, wz - 0.5f} // top-left
};
Vector3 normal = {0.0f, 1.0f, 0.0f};
Vector2 corners[4] = {
UVtop.corner0,
UVtop.corner1,
UVtop.corner2,
UVtop.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
if(shaded) {
colors.push_back(colorShaded);
}
else {
colors.push_back(color);
}
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
// Front (+Z)
if (front) {
Vector3 verts[4] = {
{wx - 0.5f, wy - 0.5f, wz + 0.5f}, // bottom-left
{wx + 0.5f, wy - 0.5f, wz + 0.5f}, // bottom-right
{wx + 0.5f, wy + 0.5f, wz + 0.5f}, // top-right
{wx - 0.5f, wy + 0.5f, wz + 0.5f} // top-left
};
Vector3 normal = {0.0f, 0.0f, 1.0f};
Vector2 corners[4] = {
UVside.corner0,
UVside.corner1,
UVside.corner2,
UVside.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
colors.push_back(colorShaded);
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
// Back (-Z)
if (back) {
Vector3 verts[4] = {
{wx + 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-left (from -Z side)
{wx - 0.5f, wy - 0.5f, wz - 0.5f}, // bottom-right
{wx - 0.5f, wy + 0.5f, wz - 0.5f}, // top-right
{wx + 0.5f, wy + 0.5f, wz - 0.5f} // top-left
};
Vector3 normal = {0.0f, 0.0f, -1.0f};
Vector2 corners[4] = {
UVside.corner0,
UVside.corner1,
UVside.corner2,
UVside.corner3
};
positions.push_back(verts[0]);
positions.push_back(verts[1]);
positions.push_back(verts[2]);
positions.push_back(verts[3]);
normals.push_back(normal);
colors.push_back(colorShaded);
uvs.push_back(corners[0]);
uvs.push_back(corners[1]);
uvs.push_back(corners[2]);
uvs.push_back(corners[3]);
unsigned short indbase = face*4;
unsigned short tri[6] = {
indbase + 0, indbase + 1, indbase + 2,
indbase + 0, indbase + 2, indbase + 3
};
indices.insert(indices.end(), tri, tri + 6);
face++;
}
}
out.positions = (float*)malloc(sizeof(float) * 3 * positions.size());
out.uvs = (float*)malloc(sizeof(float) * 2 * uvs.size());
out.indices = (unsigned short*)malloc(sizeof(unsigned short) * indices.size());
out.normals = (float*)malloc(sizeof(float) * 3 * 4 * normals.size());
out.colors = (unsigned char*)malloc(sizeof(unsigned char) * 4 * 4 * colors.size());
int s = 0;
for (Vector3 v : positions)
{
out.positions[s] = v.x;
out.positions[s+1] = v.y;
out.positions[s+2] = v.z;
s += 3;
}
s = 0;
for (Vector3 n : normals)
{
for (size_t _ = 0; _ < 4; _++)
{
out.normals[s] = n.x;
out.normals[s+1] = n.y;
out.normals[s+2] = n.z;
s += 3;
}
}
s = 0;
for (Color c : colors)
{
for (size_t _ = 0; _ < 4; _++)
{
out.colors[s] = c.r;
out.colors[s+1] = c.g;
out.colors[s+2] = c.b;
out.colors[s+3] = c.a;
s += 4;
}
}
s = 0;
for (Vector2 uv : uvs)
{
out.uvs[s] = uv.x;
out.uvs[s+1] = uv.y;
s += 2;
}
s = 0;
for (unsigned short i : indices)
{
out.indices[s] = i;
s += 1;
}
out.vertexCount = positions.size();
out.indexCount = indices.size();
positions.clear();
normals.clear();
uvs.clear();
indices.clear();
return out;
}
MeshData MergeMeshData(const MeshData &a, const MeshData &b)
{
MeshData out = {0};
// initial counts
int aPosCount = a.positions ? (a.vertexCount * 3) : 0;
int aNormCount = a.normals ? (a.vertexCount * 3) : 0;
int aUvCount = a.uvs ? (a.vertexCount * 2) : 0;
int aColCount = a.colors ? (a.vertexCount * 4) : 0;
int aIdxCount = a.indices ? (a.indexCount) : 0;
int bPosCount = b.positions ? (b.vertexCount * 3) : 0;
int bNormCount = b.normals ? (b.vertexCount * 3) : 0;
int bUvCount = b.uvs ? (b.vertexCount * 2) : 0;
int bColCount = b.colors ? (b.vertexCount * 4) : 0;
int bIdxCount = b.indices ? (b.indexCount) : 0;
// allocate combined buffers
int totalVert = a.vertexCount + b.vertexCount;
int totalPos = totalVert * 3;
int totalNorm = totalVert * 3;
int totalUv = totalVert * 2;
int totalCol = totalVert * 4;
int totalIdx = a.indexCount + b.indexCount;
if (totalPos > 0) {
out.positions = (float*)malloc(totalPos * sizeof(float));
memcpy(out.positions, a.positions ? a.positions : nullptr, aPosCount * sizeof(float));
} else out.positions = nullptr;
if (totalNorm > 0) {
out.normals = (float*)malloc(totalNorm * sizeof(float));
memcpy(out.normals, a.normals ? a.normals : nullptr, aNormCount * sizeof(float));
} else out.normals = nullptr;
if (totalUv > 0) {
out.uvs = (float*)malloc(totalUv * sizeof(float));
memcpy(out.uvs, a.uvs ? a.uvs : nullptr, aUvCount * sizeof(float));
} else out.uvs = nullptr;
if (totalCol > 0) {
out.colors = (unsigned char*)malloc(totalCol * sizeof(unsigned char));
memcpy(out.colors, a.colors ? a.colors : nullptr, aColCount * sizeof(unsigned char));
} else out.colors = nullptr;
if (totalIdx > 0) {
out.indices = (unsigned short*)malloc(totalIdx * sizeof(unsigned short));
if (a.indices && aIdxCount > 0)
memcpy(out.indices, a.indices, aIdxCount * sizeof(unsigned short));
} else out.indices = nullptr;
// copy B data appending with index offset
// positions
if (bPosCount > 0) {
memcpy(out.positions + aPosCount, b.positions, bPosCount * sizeof(float));
}
// normals
if (bNormCount > 0) {
memcpy(out.normals + aNormCount, b.normals, bNormCount * sizeof(float));
}
// uvs
if (bUvCount > 0) {
memcpy(out.uvs + aUvCount, b.uvs, bUvCount * sizeof(float));
}
// colors
if (bColCount > 0) {
memcpy(out.colors + aColCount, b.colors, bColCount * sizeof(unsigned char));
}
// indices (need to offset b indices by a.vertexCount)
if (bIdxCount > 0) {
unsigned short idxOffset = (unsigned short)(a.vertexCount);
for (int i = 0; i < bIdxCount; ++i) {
out.indices[aIdxCount + i] = (unsigned short)(b.indices[i] + idxOffset);
}
}
out.vertexCount = totalVert;
out.indexCount = totalIdx;
return out;
}
MeshData CreateCubeMeshData(const BlockDef &def, float cx, float cy, float cz)
{
MeshData out = {0};
// 4 verts * 6 faces = 24 vertices
const int vertsPerFace = 4;
const int faces = 6;
const int totalVerts = vertsPerFace * faces;
const int totalPos = totalVerts * 3;
const int totalNorm = totalVerts * 3;
const int totalUv = totalVerts * 2;
const int totalCol = totalVerts * 4;
const int totalIdx = faces * 6;
out.vertexCount = totalVerts;
out.indexCount = totalIdx;
out.positions = (float*)malloc(totalPos * sizeof(float));
out.normals = (float*)malloc(totalNorm * sizeof(float));
out.uvs = (float*)malloc(totalUv * sizeof(float));
out.colors = (unsigned char*)malloc(totalCol * sizeof(unsigned char));
out.indices = (unsigned short*)malloc(totalIdx * sizeof(unsigned short));
int p = 0, n = 0, u = 0, c = 0, ix = 0;
Color baseColor = {255,255,255,255};
auto pushPos = [&](float x, float y, float z) {
out.positions[p++] = x; out.positions[p++] = y; out.positions[p++] = z;
};
auto pushNorm = [&](float x, float y, float z) {
out.normals[n++] = x; out.normals[n++] = y; out.normals[n++] = z;
};
auto pushUV = [&](float uu, float vv) {
out.uvs[u++] = uu; out.uvs[u++] = vv;
};
auto pushCol = [&](unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
out.colors[c++] = r; out.colors[c++] = g; out.colors[c++] = b; out.colors[c++] = a;
};
auto pushTriIdx = [&](unsigned short a, unsigned short b, unsigned short c2) {
out.indices[ix++] = a; out.indices[ix++] = b; out.indices[ix++] = c2;
};
// get UV corners for faces
UVCorners UVside = GetUVTex(def.textureSide);
UVCorners UVtop = GetUVTex(def.textureTop);
UVCorners UVbtm = GetUVTex(def.textureBottom);
// face builder: verts in CCW for the outside-facing side
auto buildFace = [&](const Vector3 faceVerts[4], const Vector3 &normal, const Vector2 faceUVs[4]) {
unsigned short base = (unsigned short)((p/3)); // current vertex index
Color clr = baseColor;
for (int i=0;i<4;i++) {
pushPos(faceVerts[i].x, faceVerts[i].y, faceVerts[i].z);
pushNorm(normal.x, normal.y, normal.z);
pushUV(faceUVs[i].x, faceUVs[i].y);
pushCol(clr.r, clr.g, clr.b, clr.a);
}
// two tris (0,1,2) (0,2,3)
pushTriIdx(base + 0, base + 1, base + 2);
pushTriIdx(base + 0, base + 2, base + 3);
};
float hx = 0.5f, hy = 0.5f, hz = 0.5f;
// Left (-X)
{
Vector3 verts[4] = {
{cx - hx, cy - hy, cz - hz},
{cx - hx, cy - hy, cz + hz},
{cx - hx, cy + hy, cz + hz},
{cx - hx, cy + hy, cz - hz}
};
Vector2 uvs[4] = { UVside.corner0, UVside.corner1, UVside.corner2, UVside.corner3 };
Vector3 normal = {-1,0,0};
buildFace(verts, normal, uvs);
}
// Right (+X)
{
Vector3 verts[4] = {
{cx + hx, cy - hy, cz + hz},
{cx + hx, cy - hy, cz - hz},
{cx + hx, cy + hy, cz - hz},
{cx + hx, cy + hy, cz + hz}
};
Vector2 uvs[4] = { UVside.corner0, UVside.corner1, UVside.corner2, UVside.corner3 };
Vector3 normal = {1,0,0};
buildFace(verts, normal, uvs);
}
// Down (-Y)
{
Vector3 verts[4] = {
{cx - hx, cy - hy, cz - hz},
{cx + hx, cy - hy, cz - hz},
{cx + hx, cy - hy, cz + hz},
{cx - hx, cy - hy, cz + hz}
};
Vector2 uvs[4] = { UVbtm.corner0, UVbtm.corner1, UVbtm.corner2, UVbtm.corner3 };
Vector3 normal = {0,-1,0};
buildFace(verts, normal, uvs);
}
// Up (+Y)
{
Vector3 verts[4] = {
{cx - hx, cy + hy, cz + hz},
{cx + hx, cy + hy, cz + hz},
{cx + hx, cy + hy, cz - hz},
{cx - hx, cy + hy, cz - hz}
};
Vector2 uvs[4] = { UVtop.corner0, UVtop.corner1, UVtop.corner2, UVtop.corner3 };
Vector3 normal = {0,1,0};
buildFace(verts, normal, uvs);
}
// Front (+Z)
{
Vector3 verts[4] = {
{cx - hx, cy - hy, cz + hz},
{cx + hx, cy - hy, cz + hz},
{cx + hx, cy + hy, cz + hz},
{cx - hx, cy + hy, cz + hz}
};
Vector2 uvs[4] = { UVside.corner0, UVside.corner1, UVside.corner2, UVside.corner3 };
Vector3 normal = {0,0,1};
buildFace(verts, normal, uvs);
}
// Back (-Z)
{
Vector3 verts[4] = {
{cx + hx, cy - hy, cz - hz},
{cx - hx, cy - hy, cz - hz},
{cx - hx, cy + hy, cz - hz},
{cx + hx, cy + hy, cz - hz}
};
Vector2 uvs[4] = { UVside.corner0, UVside.corner1, UVside.corner2, UVside.corner3 };
Vector3 normal = {0,0,-1};
buildFace(verts, normal, uvs);
}
return out;
}
Mesh GenChunkMesh(MeshData meshData)
{
Mesh mesh = { 0 };
mesh.indices = meshData.indices;
mesh.vertexCount = meshData.vertexCount;
mesh.triangleCount = meshData.indexCount / 3;
mesh.vertices = meshData.positions;
mesh.texcoords = meshData.uvs;
mesh.normals = meshData.normals;
mesh.colors = meshData.colors;
UploadMesh(&mesh, false);
return mesh;
}
#endif
#endif