Start work on editor
This commit is contained in:
parent
0b41057244
commit
4865df8fd9
16 changed files with 273 additions and 311 deletions
|
@ -47,8 +47,8 @@ void main()
|
|||
tc.x = (v_texcoord.x)+u_campos.x/1000.0; //mod(u_campos.x/1024.0, 10.0);
|
||||
tc.y = (v_texcoord.y)+u_campos.z/1000.0; //mod(u_campos.z/1024.0, 10.0);
|
||||
|
||||
tc.x *= 64.0;
|
||||
tc.y *= 64.0;
|
||||
tc.x *= 1000.0;
|
||||
tc.y *= 1000.0;
|
||||
|
||||
vec4 tex = texture(u_texture, tc);
|
||||
vec3 norm = normalize(v_normal);
|
||||
|
@ -59,27 +59,4 @@ void main()
|
|||
float a = dist(v_position.xy, vec2(0.0, 0.0)) * 2.0f;
|
||||
|
||||
v_output = vec4(tex.rgb, tex.a - a);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
vec3 col;
|
||||
vec4 tex = texture(u_texture, v_texcoord);
|
||||
vec3 norm = normalize(v_normal);
|
||||
vec3 dir = normalize(vec3(5.0, 0.25, -5.0) - v_position);
|
||||
float diff = max(dot(norm, dir), 0.0);
|
||||
float alpha = get_fog_factor(distance(u_campos, v_position));
|
||||
|
||||
vec3 diffuse = diff * vec3(0.8, 0.75, 0.7);
|
||||
float ff = 1.75;
|
||||
if (diffuse.x > 0.0) diffuse.x *= ff;
|
||||
if (diffuse.y > 0.0) diffuse.y *= ff;
|
||||
if (diffuse.z > 0.0) diffuse.z *= ff;
|
||||
vec3 ambient = vec3(0.3, 0.3, 0.3);
|
||||
col = (ambient + diffuse) * tex.rgb;
|
||||
col *= mix(vec4(1.0), vec4(0.0f, 0.0, 0.0, 1.0), alpha-0.2).xyz;
|
||||
|
||||
*/
|
||||
// vec4 tex = texture(u_texture, v_texcoord);
|
||||
// v_output = tex * vec4(vec3(1.5), 1.0);
|
||||
}
|
BIN
Data/resources/textures/.kp3d/map_grid.png
Normal file
BIN
Data/resources/textures/.kp3d/map_grid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 250 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -1 +1 @@
|
|||
{"mix":{"channels":32,"chunk_size":1024,"sample_rate":44100},"sdl":{"fullscreen":0,"startup_height":768,"startup_width":1366,"title":"KP3D Sandbox","vsync":1}}
|
||||
{"mix":{"channels":32,"chunk_size":1024,"sample_rate":44100},"sdl":{"fullscreen":0,"startup_height":768,"startup_width":1366,"title":"KP3Dii Sandbox","vsync":1}}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
[00:48:43 AM] Info: Starting...
|
||||
[03:16:52 AM] Info: Starting...
|
||||
|
||||
KP3D version 2
|
||||
===============================
|
||||
Copyright (C) kpworld.xyz 2018-2024
|
||||
Contact me! @kp_cftsz
|
||||
|
||||
[00:48:43 AM] Info: Initializing SDL
|
||||
[00:48:43 AM] Info: Initializing OpenGL
|
||||
[00:48:43 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
|
||||
[00:48:43 AM] Info: Initializing GLEW
|
||||
[00:48:43 AM] Info: Initializing SDL_mixer
|
||||
[00:48:43 AM] Info: Reticulating splines...
|
||||
[00:48:43 AM] Info: Ready!
|
||||
[00:50:29 AM] Info: Stopping...
|
||||
[03:16:52 AM] Info: Initializing SDL
|
||||
[03:16:52 AM] Info: Initializing OpenGL
|
||||
[03:16:52 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
|
||||
[03:16:52 AM] Info: Initializing GLEW
|
||||
[03:16:52 AM] Info: Initializing SDL_mixer
|
||||
[03:16:52 AM] Info: Reticulating splines...
|
||||
[03:16:52 AM] Info: Ready!
|
||||
|
|
|
@ -50,102 +50,13 @@ std::vector<std::vector<Vec2>> SplitComplexPolygon(std::vector<Vec2> polygon)
|
|||
output.push_back(polygon_excerpt);
|
||||
}
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::vector<std::vector<Vec2>> ClipPolygonHoles(std::vector<Vec2> polygon, std::vector<std::vector<Vec2>> holes)
|
||||
{
|
||||
if (holes.empty())
|
||||
{
|
||||
return { polygon };
|
||||
}
|
||||
|
||||
for (std::vector<Vec2>& hole : holes)
|
||||
{
|
||||
polygon.push_back(polygon[0]);
|
||||
for (Vec2 point: hole)
|
||||
polygon.push_back(point);
|
||||
polygon.push_back(hole[0]);
|
||||
}
|
||||
//polygon.push_back(polygon[0]);
|
||||
|
||||
//polygon.erase(std::unique(polygon.begin(), polygon.end()), polygon.end());
|
||||
|
||||
return SplitComplexPolygon(polygon);
|
||||
|
||||
#if 0
|
||||
using namespace Clipper2Lib;
|
||||
|
||||
if (holes.empty())
|
||||
{
|
||||
return {polygon};
|
||||
}
|
||||
if (holes.size() > 1)
|
||||
holes.pop_back();
|
||||
|
||||
//ClipperD c;
|
||||
PathsD solution;
|
||||
|
||||
// PolyPathD tree;
|
||||
PathD complex_polygon;
|
||||
for (const Vec2& v: polygon)
|
||||
{
|
||||
complex_polygon.push_back({v.x, v.y});
|
||||
}
|
||||
// PolyTreeD cp(&tree, complex_polygon);
|
||||
PathsD subjects;
|
||||
subjects.push_back(complex_polygon);
|
||||
PathsD clips;
|
||||
KP3D_LOG_INFO("# holes: {}", holes.size());
|
||||
for (const auto& vl: holes)
|
||||
{
|
||||
PathD clip;
|
||||
for (const Vec2& v : vl) {
|
||||
clip.push_back({ v.x, v.y });
|
||||
//complex_polygon.push_back({v.x, v.y});
|
||||
}
|
||||
clips.push_back(clip);
|
||||
// cp.AddChild(clip);
|
||||
//tree.AddChild(clip);
|
||||
|
||||
}
|
||||
|
||||
// tree.AddChild(complex_polygon); ?
|
||||
//c.AddSubject({complex_polygon});
|
||||
//c.AddSubject(clips);
|
||||
//c.AddClip(clips);
|
||||
//c.AddClip(clips);
|
||||
// PolyTreeD clipper_output;
|
||||
//PathsD clipper_output;
|
||||
//c.Execute(ClipType::Difference, FillRule::NonZero, clipper_output);
|
||||
PathsD clipper_output = Difference(subjects, clips, FillRule::EvenOdd);
|
||||
|
||||
std::vector<std::vector<Vec2>> output;
|
||||
|
||||
for (auto& o: clipper_output)
|
||||
{
|
||||
std::vector<Vec2> polygon_excerpt;
|
||||
for (const auto& point: o)
|
||||
polygon_excerpt.push_back({(float) point.x, (float) point.y});
|
||||
output.push_back(polygon_excerpt);
|
||||
}
|
||||
|
||||
if (output.size() > 0)
|
||||
{
|
||||
KP3D_LOG_INFO("Split ({}):", output.size());
|
||||
for (int i = 0; i < output.size(); i++)
|
||||
KP3D_LOG_INFO("{} size: {}", i, output[i].size());
|
||||
}
|
||||
|
||||
if (output.empty())
|
||||
{
|
||||
return { polygon };
|
||||
}
|
||||
|
||||
return output;
|
||||
#endif
|
||||
|
||||
// Tried doing this with Clipper but SHIT DON'T WORK! So here. You just get your input. That's all you get. Fuck you.
|
||||
return {polygon};
|
||||
}
|
||||
|
||||
} // namespace kp3d
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner) {
|
||||
|
||||
bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner)
|
||||
{
|
||||
using namespace Clipper2Lib;
|
||||
using namespace kp3d;
|
||||
|
||||
|
@ -27,12 +27,11 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner) {
|
|||
for (const Wall& l: inner.walls)
|
||||
inner_path.push_back({l.start.x, l.start.y});
|
||||
|
||||
|
||||
bool completely_inside = false;
|
||||
bool partially_inside = false;
|
||||
int count = 0;
|
||||
int partial_count = 0;
|
||||
for (auto& p : inner_path)
|
||||
for (PointD& p: inner_path)
|
||||
{
|
||||
PointInPolygonResult status = Clipper2Lib::PointInPolygon(p, outer_path);
|
||||
if (status == PointInPolygonResult::IsInside)
|
||||
|
@ -45,67 +44,9 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner) {
|
|||
if (partial_count > 0 && count > 0)
|
||||
partially_inside = true;
|
||||
|
||||
// KP3D_LOG_INFO("COMPLETE: {}, PARTIAL: {} / {}", count, partial_count, child_path.size());
|
||||
if (completely_inside)
|
||||
{
|
||||
|
||||
//s.children.push_back(&s2);
|
||||
//s2.parents.push_back(s.id);
|
||||
}
|
||||
|
||||
return completely_inside || (count > 0 && partial_count < 4);
|
||||
return completely_inside || (count > 0 && partial_count < 4); // stupid
|
||||
}
|
||||
|
||||
using namespace kp3d;
|
||||
|
||||
// Function to find the barycentric coordinates of a point within a triangle
|
||||
void Barycentric(const Vec2& p, const Vec2& a, const Vec2& b, const Vec2& c, float& u, float& v, float& w) {
|
||||
Vec2 v0 = { b.x - a.x, b.y - a.y };
|
||||
Vec2 v1 = { c.x - a.x, c.y - a.y };
|
||||
Vec2 v2 = { p.x - a.x, p.y - a.y };
|
||||
float d00 = v0.x * v0.x + v0.y * v0.y;
|
||||
float d01 = v0.x * v1.x + v0.y * v1.y;
|
||||
float d11 = v1.x * v1.x + v1.y * v1.y;
|
||||
float d20 = v2.x * v0.x + v2.y * v0.y;
|
||||
float d21 = v2.x * v1.x + v2.y * v1.y;
|
||||
float denom = d00 * d11 - d01 * d01;
|
||||
v = (d11 * d20 - d01 * d21) / denom;
|
||||
w = (d00 * d21 - d01 * d20) / denom;
|
||||
u = 1.0f - v - w;
|
||||
}
|
||||
|
||||
// Function to interpolate Y value
|
||||
float InterpolateY(const Vec2& p, const Vertex3D& a, const Vertex3D& b, const Vertex3D& c) {
|
||||
float u, v, w;
|
||||
Vec2 pa = { a.position.x, a.position.z };
|
||||
Vec2 pb = { b.position.x, b.position.z };
|
||||
Vec2 pc = { c.position.x, c.position.z };
|
||||
Barycentric(p, pa, pb, pc, u, v, w);
|
||||
return u * a.position.y + v * b.position.y + w * c.position.y;
|
||||
}
|
||||
|
||||
// Sample floor vertices
|
||||
float SampleY(const std::vector<Vertex3D>& floor_vertices, const Vec2& sample_pos) {
|
||||
for (size_t i = 0; i < floor_vertices.size(); i += 3) {
|
||||
const Vertex3D& v0 = floor_vertices[i];
|
||||
const Vertex3D& v1 = floor_vertices[i + 1];
|
||||
const Vertex3D& v2 = floor_vertices[i + 2];
|
||||
|
||||
Vec2 pa = { v0.position.x, v0.position.z };
|
||||
Vec2 pb = { v1.position.x, v1.position.z };
|
||||
Vec2 pc = { v2.position.x, v2.position.z };
|
||||
|
||||
// Check if the sample position is inside the triangle
|
||||
float u, v, w;
|
||||
Barycentric(sample_pos, pa, pb, pc, u, v, w);
|
||||
if (u >= 0 && v >= 0 && w >= 0) {
|
||||
return InterpolateY(sample_pos, v0, v1, v2);
|
||||
}
|
||||
}
|
||||
return 0.0f; // Default value if the point is not found in any triangle (should not happen if inputs are correct)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace kp3d {
|
||||
|
@ -392,49 +333,32 @@ void Map::Init()
|
|||
sectors.clear();
|
||||
m_mesh.Reset();
|
||||
|
||||
XYf points[7] = {
|
||||
{1, 1 },
|
||||
{6, 4 },
|
||||
{11, 1 },
|
||||
{11, 13},
|
||||
{4, 14},
|
||||
{4, 12},
|
||||
{1, 12}, // Main sector
|
||||
};
|
||||
|
||||
XYf points2[] = {
|
||||
{4,5},{7,5},{7,6},{8,6},{8,10},{4,10} // Middle area
|
||||
};
|
||||
|
||||
XYf points3[] = {
|
||||
{7,5},{8,5},{8,6},{7,6} // Column (neighboring/outside middle area, not within)
|
||||
};
|
||||
|
||||
XYf points4[] = {
|
||||
{points3[0].x, points3[0].y + 4},
|
||||
{points3[1].x, points3[1].y + 4},
|
||||
{points3[2].x, points3[2].y + 4},
|
||||
{points3[3].x, points3[3].y + 4} // Column (within middle area)
|
||||
};
|
||||
|
||||
XYf points5[] = {
|
||||
{11,4},{14,4},{14,2},{16,2},{16,10},{11,10} // Neighbor of main sector
|
||||
};
|
||||
|
||||
XYf points6[] = {
|
||||
{1, 4},{3,4}, { 3,7 },{1,7}
|
||||
};
|
||||
|
||||
BuildSkybox("skybox_16.jpg");
|
||||
BuildGrid();
|
||||
|
||||
static kp3d::Texture tex, tex2, tex3, tex4;
|
||||
static Texture tex, tex2, tex3, tex4;
|
||||
tex.Load("GRASS2.png");
|
||||
tex2.Load("floor0.png");
|
||||
tex3.Load("FLAT5_7.png");
|
||||
tex4.Load("block.png");
|
||||
m_dot.Load("dot.png");
|
||||
|
||||
auto build_sector = [&](Texture* wall, Texture* floor, Texture* ceil, float floor_height, float ceil_height, int id, XYf* points, size_t num_points, bool inverted = false) {
|
||||
// Build a stupid little test map
|
||||
// ------------------------------
|
||||
// Main sector
|
||||
XYf points[7] = {{1, 1}, {6, 4}, {11, 1}, {11, 13}, {4, 14}, {4, 12}, {1, 12}};
|
||||
// Middle area
|
||||
XYf points2[] = {{4, 5}, {7, 5}, {7, 6}, {8, 6}, {8, 10}, {4, 10}};
|
||||
// Column (neighboring/outside middle area, not within)
|
||||
XYf points3[] = {{7, 5}, {8, 5}, {8, 6}, {7, 6}};
|
||||
// Column (within middle area)
|
||||
XYf points4[] = {{points3[0].x, points3[0].y + 4}, {points3[1].x, points3[1].y + 4}, {points3[2].x, points3[2].y + 4}, {points3[3].x, points3[3].y + 4}};
|
||||
// Neighbor of main sector
|
||||
XYf points5[] = {{11, 4}, {14, 4}, {14, 2}, {16, 2}, {16, 10}, {11, 10}};
|
||||
// Platform above main sector (room over room testing)
|
||||
XYf points6[] = {{1, 4}, {3, 4}, {3, 7}, {1, 7}};
|
||||
auto build_sector = [&](Texture* wall, Texture* floor, Texture* ceil, float floor_height, float ceil_height, int id, XYf* points, size_t num_points, bool inverted = false)
|
||||
{
|
||||
Sector s;
|
||||
s.ceiling.texture = ceil;
|
||||
s.floor.texture = floor;
|
||||
|
@ -446,39 +370,29 @@ void Map::Init()
|
|||
s.inverted = inverted;
|
||||
float scl = 1.0f;
|
||||
for (size_t i = 0; i < num_points; i++)
|
||||
{
|
||||
XYf start = points[i];
|
||||
XYf end = points[(i + 1) % num_points];
|
||||
s.walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, start, end, Wall::NO_FLAGS, (uint)i });
|
||||
}
|
||||
s.walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, points[i], points[(i + 1) % num_points], Wall::NO_FLAGS, (uint)i });
|
||||
sectors.push_back(s);
|
||||
|
||||
};
|
||||
|
||||
build_sector(&tex3, &tex, &tex2, -1.0f, 5.0f, 1, points, std::size(points));
|
||||
build_sector(&tex4, &tex2, &tex2, -1.5f, 4.0f, 2, points2, std::size(points2));
|
||||
build_sector(&tex4, &tex, &tex2, -1.5f, 5.0f, 3, points3, std::size(points3), true);
|
||||
build_sector(&tex4, &tex, &tex2, -1.5f, 4.0f, 4, points4, std::size(points4), true);
|
||||
//build_sector(&tex3, &tex, &tex2, -1.2f, 3.0f, 5, points5, std::size(points5));
|
||||
build_sector(&tex3, &tex, &tex2, test_u, test_l, 5, points5, std::size(points5), false);
|
||||
build_sector(&tex4, &tex4, &tex4, 1.0f, 1.4f, 6, points6, std::size(points6), true);
|
||||
|
||||
|
||||
// Correct sectors with counter-clockwise linedef order using the shoelace formula,
|
||||
// also while we're at it grab the sector areas (will be useful later) and reset old data.
|
||||
std::unordered_map<int, float> sector_areas;
|
||||
int i = 0;
|
||||
for (Sector& s: sectors)
|
||||
{
|
||||
// Since we're regenerating the map, we don't want to re-use this data, it may be old.
|
||||
s.parents.clear();
|
||||
s.children.clear();
|
||||
s.flags = Sector::NO_FLAGS;
|
||||
s.parent_id = 0;
|
||||
s.id = ++i;
|
||||
|
||||
// Now perform the swap + save the area
|
||||
float area = 0.0f;
|
||||
|
||||
for (Wall& l: s.walls)
|
||||
{
|
||||
bool touched = l.flags & Wall::FLAG_TOUCHED;
|
||||
|
@ -492,36 +406,35 @@ void Map::Init()
|
|||
area += l.start.x * l.end.y;
|
||||
area -= l.end.x * l.start.y;
|
||||
}
|
||||
|
||||
area *= 0.5f;
|
||||
sector_areas.emplace(s.id, fabsf(area));
|
||||
|
||||
if (area <= 0.0f)
|
||||
{
|
||||
std::reverse(s.walls.begin(), s.walls.end());
|
||||
for (Wall& l: s.walls)
|
||||
std::swap(l.start, l.end);
|
||||
}
|
||||
|
||||
s.area = fabsf(area);
|
||||
}
|
||||
|
||||
std::sort(sectors.begin(), sectors.end(), [](const Sector& a, const Sector& b) {
|
||||
return a.area < b.area;
|
||||
});
|
||||
for (auto& sector: sectors) {
|
||||
for (auto& potentialParent: sectors) {
|
||||
if (sector.id == potentialParent.id)
|
||||
// Now perform the process of "parenting" sectors; this essentially takes in our flat list of sectors and creates a hierarchy.
|
||||
std::sort(sectors.begin(), sectors.end(), [](const Sector& a, const Sector& b) { return a.area < b.area; });
|
||||
for (Sector& sector: sectors)
|
||||
{
|
||||
for (Sector& potential_parent: sectors)
|
||||
{
|
||||
if (sector.id == potential_parent.id)
|
||||
continue;
|
||||
if (SectorContains(potentialParent, sector)) {
|
||||
potentialParent.children.push_back(§or);
|
||||
sector.parent_id = potentialParent.id;
|
||||
if (SectorContains(potential_parent, sector))
|
||||
{
|
||||
potential_parent.children.push_back(§or);
|
||||
sector.parent_id = potential_parent.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Debug: Print out the sector hierachy
|
||||
KP3D_LOG_INFO("SECTOR HIERARCHY");
|
||||
for (Sector& s: sectors)
|
||||
{
|
||||
|
@ -530,21 +443,16 @@ void Map::Init()
|
|||
KP3D_LOG_INFO(" - {}", s.parent_id ? std::to_string(s.parent_id) : "[NO PARENT]");
|
||||
KP3D_LOG_INFO(" Children: ");
|
||||
for (Sector* c: s.children)
|
||||
{
|
||||
KP3D_LOG_INFO(" - {}", c->id);
|
||||
|
||||
}
|
||||
if (s.children.empty())
|
||||
KP3D_LOG_INFO(" - [NO CHILDREN]");
|
||||
KP3D_LOG_INFO("-----");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Preproc
|
||||
// Preproc (really just part of the test map building process again)
|
||||
for (Sector& s: sectors)
|
||||
{
|
||||
// KP3D_LOG_INFO("BUILDING SECTOR: {}", s.id);
|
||||
|
||||
// Build up "steiner points" for terrain only
|
||||
// We'll do this along a grid for now; it should be noted that this will be expected to be part of the sector data later
|
||||
int num_steiners_along_xy = 50;
|
||||
|
@ -579,47 +487,21 @@ void Map::Init()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
JoinSectors(s);
|
||||
}
|
||||
|
||||
for (Sector& s : sectors)
|
||||
// Build level geometry
|
||||
for (Sector& s: sectors)
|
||||
JoinSectors(s);
|
||||
for (Sector& s: sectors)
|
||||
{
|
||||
// Build level geometry
|
||||
BuildFlat(s, s.floor, false);
|
||||
BuildFlat(s, s.ceiling, true);
|
||||
}
|
||||
for (Sector& s : sectors)
|
||||
for (Wall& ld : s.walls)
|
||||
for (Sector& s: sectors)
|
||||
for (Wall& ld: s.walls)
|
||||
BuildWall(s, ld);
|
||||
|
||||
// Go through all of the vertices and align them to a grid (very roughly; might want to revisit this later)
|
||||
#if 0
|
||||
const float grid_size = 1.0f / (texture_scale - 1.0f), tolerance = (1.0f / texture_scale);
|
||||
for (RenderBatch3D& b: m_mesh.GetBatchesRef())
|
||||
{
|
||||
for (Vertex3D& v: b.vertex_data)
|
||||
{
|
||||
v.position.x = std::round(v.position.x / grid_size) * grid_size;
|
||||
v.position.y = std::round(v.position.y / grid_size) * grid_size;
|
||||
v.position.z = std::round(v.position.z / grid_size) * grid_size;
|
||||
bool snapped = false;
|
||||
for (const auto& unique_point: unique_points)
|
||||
{
|
||||
if (std::abs(v.position.x - unique_point.x) <= tolerance &&
|
||||
std::abs(v.position.y - unique_point.y) <= tolerance &&
|
||||
std::abs(v.position.z - unique_point.z) <= tolerance)
|
||||
{
|
||||
v.position = unique_point;
|
||||
snapped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!snapped)
|
||||
unique_points.insert(v.position);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Invert the map on the Z axis; not doing this for any other reason besides compatibility with KP3D 1.0
|
||||
for (RenderBatch3D& b : m_mesh.GetBatchesRef())
|
||||
{
|
||||
for (size_t i = 0; i < b.vertex_data.size(); i += 3)
|
||||
|
@ -637,6 +519,7 @@ void Map::Init()
|
|||
|
||||
void Map::Rebuild(NormalGenType gen_normals)
|
||||
{
|
||||
// This routine is really just here for me to test smooth normal generation; in the future, everything in Init() should go here
|
||||
m_mesh.Finalize(gen_normals);
|
||||
}
|
||||
|
||||
|
@ -654,10 +537,9 @@ void Map::Render()
|
|||
kp3d::Renderer3D::DrawMesh(m_mesh, m_transform);
|
||||
kp3d::Renderer3D::PopShader();
|
||||
|
||||
for (Vec3 v : m_dots)
|
||||
{
|
||||
// Debug dots
|
||||
for (Vec3 v: m_dots)
|
||||
kp3d::Renderer3D::DrawBillboard(m_dot, {v.x, v.y, -v.z}, {0.1f, 0.1f}, true);
|
||||
}
|
||||
|
||||
// Optional wireframe copy
|
||||
if (!render_wireframe)
|
||||
|
@ -725,16 +607,43 @@ void Map::BuildSkybox(const std::string& texture_path, float scale)
|
|||
m_skybox_data.mesh.Reset();
|
||||
m_skybox_data.mesh.AddBatch(&m_skybox_data.texture, skybox_vertex_data, true);
|
||||
m_skybox_data.mesh.Finalize();
|
||||
m_skybox_data.transform.scale = kp3d::Vec3(scale);
|
||||
m_skybox_data.transform.scale = Vec3(scale);
|
||||
}
|
||||
|
||||
void Map::RenderSkybox()
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
kp3d::Renderer3D::PushShader(kp3d::Renderer3D::GetDefaultShader());
|
||||
m_skybox_data.transform.translation = kp3d::Renderer3D::GetPrimaryCamera()->position;
|
||||
kp3d::Renderer3D::DrawMesh(m_skybox_data.mesh, m_skybox_data.transform);
|
||||
Renderer3D::PushShader(Renderer3D::GetDefaultShader());
|
||||
m_skybox_data.transform.translation = Renderer3D::GetPrimaryCamera()->position;
|
||||
Renderer3D::DrawMesh(m_skybox_data.mesh, m_skybox_data.transform);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void Map::BuildGrid()
|
||||
{
|
||||
m_grid_shader.Load(".kp3d/map_grid_v.glsl", ".kp3d/map_grid_f.glsl");
|
||||
m_grid_texture.Load(".kp3d/map_grid.png", false, kp3d::Texture::FILTER_LINEAR);
|
||||
m_grid_mesh.AddBatch(&m_grid_texture, {
|
||||
Vertex3D(Vec3(-0.5f, -0.5f, 0.0f), Vec2(0.0f, 1.0f)),
|
||||
Vertex3D(Vec3(-0.5f, 0.5f, 0.0f), Vec2(0.0f, 0.0f)),
|
||||
Vertex3D(Vec3( 0.5f, -0.5f, 0.0f), Vec2(1.0f, 1.0f)),
|
||||
Vertex3D(Vec3(-0.5f, 0.5f, 0.0f), Vec2(0.0f, 0.0f)),
|
||||
Vertex3D(Vec3( 0.5f, 0.5f, 0.0f), Vec2(1.0f, 0.0f)),
|
||||
Vertex3D(Vec3( 0.5f, -0.5f, 0.0f), Vec2(1.0f, 1.0f))
|
||||
}, true);
|
||||
m_grid_mesh.Finalize();
|
||||
}
|
||||
|
||||
void Map::RenderGrid()
|
||||
{
|
||||
Renderer3D::PushShader(m_grid_shader);
|
||||
Vec3 camera_pos = Renderer3D::GetPrimaryCamera()->position;
|
||||
camera_pos.y = 0.0f;
|
||||
Transform grid_transform(camera_pos, {ToRadians(90.0f), 0.0, 0.0}, {1000.0, 1000.0, 0.0});
|
||||
glDisable(GL_CULL_FACE);
|
||||
Renderer3D::DrawMesh(m_grid_mesh, grid_transform);
|
||||
glEnable(GL_CULL_FACE);
|
||||
Renderer3D::PopShader();
|
||||
}
|
||||
|
||||
} // namespace kp3d
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "KP3D_Texture.h"
|
||||
#include "KP3D_StaticMesh.h"
|
||||
#include "KP3D_Transform.h"
|
||||
#include "KP3D_Shader.h"
|
||||
|
||||
namespace kp3d {
|
||||
|
||||
|
@ -81,7 +82,6 @@ struct Sector
|
|||
bool inverted = false;
|
||||
|
||||
std::vector<Sector*> children;
|
||||
std::vector<int> parents;
|
||||
|
||||
float area = 0.0f;
|
||||
|
||||
|
@ -118,6 +118,9 @@ public:
|
|||
void BuildSkybox(const std::string& texture_path, float scale = 128.0f);
|
||||
void RenderSkybox();
|
||||
|
||||
void BuildGrid();
|
||||
void RenderGrid();
|
||||
|
||||
public:
|
||||
std::vector<Sector> sectors;
|
||||
bool render_wireframe = true;
|
||||
|
@ -127,6 +130,9 @@ public:
|
|||
|
||||
private:
|
||||
StaticMesh m_mesh;
|
||||
StaticMesh m_grid_mesh;
|
||||
Shader m_grid_shader;
|
||||
Texture m_grid_texture;
|
||||
Skybox m_skybox_data;
|
||||
Transform m_transform;
|
||||
Texture m_dot;
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Editor.cpp" />
|
||||
<ClCompile Include="src\Main.cpp" />
|
||||
<ClCompile Include="src\Sandbox.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -142,6 +143,7 @@
|
|||
<None Include=".clang-format" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Editor.h" />
|
||||
<ClInclude Include="src\Sandbox.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="src\Main.cpp" />
|
||||
<ClCompile Include="src\Sandbox.cpp" />
|
||||
<ClCompile Include="src\Editor.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".clang-format" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Sandbox.h" />
|
||||
<ClInclude Include="src\Editor.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
75
Sandbox/src/Editor.cpp
Normal file
75
Sandbox/src/Editor.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "Editor.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "KP3D_Renderer3D.h"
|
||||
|
||||
#include "Sandbox.h"
|
||||
|
||||
namespace {
|
||||
constexpr float MIN_DISTANCE_FROM_PLAYER = 0.1f;
|
||||
constexpr float MAX_DISTANCE_FROM_PLAYER = 100.0f;
|
||||
}
|
||||
|
||||
Editor::Editor()
|
||||
{
|
||||
m_stem.Load("editor/stem.png");
|
||||
}
|
||||
|
||||
Editor::~Editor()
|
||||
{
|
||||
}
|
||||
|
||||
void Editor::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void Editor::RenderMap()
|
||||
{
|
||||
sandbox->map.RenderGrid();
|
||||
RenderStem({5.0f, 0.0f, 0.0f});
|
||||
}
|
||||
|
||||
void Editor::RenderStem(kp3d::Vec3 position)
|
||||
{
|
||||
using namespace kp3d;
|
||||
Vec2 size = {
|
||||
1.0f,
|
||||
(float)m_stem.GetHeight() / (float)m_stem.GetWidth()
|
||||
};
|
||||
const Camera* camera = Renderer3D::GetPrimaryCamera();
|
||||
kp3d::Vec3 player_distance = position - camera->position;
|
||||
float vec_distance = sqrtf(
|
||||
player_distance.x * player_distance.x +
|
||||
player_distance.y * player_distance.y +
|
||||
player_distance.z * player_distance.z
|
||||
);
|
||||
|
||||
float scale = vec_distance;
|
||||
scale *= 0.1f;
|
||||
|
||||
if (scale < MIN_DISTANCE_FROM_PLAYER)
|
||||
scale = MIN_DISTANCE_FROM_PLAYER;
|
||||
if (scale > MAX_DISTANCE_FROM_PLAYER)
|
||||
scale = MAX_DISTANCE_FROM_PLAYER;
|
||||
|
||||
size.x *= scale;
|
||||
size.y *= scale;
|
||||
|
||||
Renderer3D::DrawBillboard(m_stem, {position.x, position.y + size.y * 0.5f, position.z}, size);
|
||||
}
|
||||
|
||||
void Editor::RenderUI()
|
||||
{
|
||||
ImGui::BeginMainMenuBar();
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Exit")) exit(0);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Edit"))
|
||||
{
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
20
Sandbox/src/Editor.h
Normal file
20
Sandbox/src/Editor.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "KP3D_Texture.h"
|
||||
#include "KP3D_Math.h"
|
||||
|
||||
class Editor
|
||||
{
|
||||
public:
|
||||
Editor();
|
||||
~Editor();
|
||||
|
||||
void Init();
|
||||
void RenderMap();
|
||||
void RenderStem(kp3d::Vec3 position);
|
||||
void RenderUI();
|
||||
|
||||
private:
|
||||
kp3d::Texture m_stem;
|
||||
|
||||
};
|
|
@ -6,9 +6,10 @@
|
|||
|
||||
#include "Sandbox.h"
|
||||
|
||||
std::unique_ptr<Sandbox> sandbox;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
kp3d::Vec3 vec(1.0f, 2.0f, 3.0f);
|
||||
|
||||
return Sandbox(kp3d::sys::InitDataDir("../Data/", false)).Run();
|
||||
sandbox.reset(new Sandbox(kp3d::sys::InitDataDir("../Data/", false)));
|
||||
return sandbox->Run();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ Sandbox::Sandbox(const std::string& path):
|
|||
points.push_back({x, y});
|
||||
return {CELL_VOID};
|
||||
}});
|
||||
|
||||
m_mode = MODE_MENU;
|
||||
}
|
||||
|
||||
Sandbox::~Sandbox()
|
||||
|
@ -37,9 +39,14 @@ void Sandbox::Update()
|
|||
if (IsKeyDown(kp3d::KEY_GRAVE))
|
||||
{
|
||||
kp3d::console::open ^= 1;
|
||||
SetMouseLockEnabled(!GetMouseLockEnabled());
|
||||
if (GetMouseLockEnabled())
|
||||
SetMouseLockEnabled(false);
|
||||
KeyReset(kp3d::KEY_GRAVE);
|
||||
}
|
||||
|
||||
if (kp3d::console::open || m_mode == MODE_MENU)
|
||||
return;
|
||||
|
||||
if (IsKeyDown(kp3d::KEY_F1))
|
||||
{
|
||||
map.render_wireframe ^= 1;
|
||||
|
@ -95,21 +102,57 @@ void Sandbox::Update()
|
|||
|
||||
void Sandbox::Render()
|
||||
{
|
||||
glClearColor(0.0f, 0.1f, 0.3f, 1.0f);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// 3D scene
|
||||
kp3d::Renderer3D::Begin(m_camera, m_projection);
|
||||
map.Render();
|
||||
kp3d::Renderer3D::DrawBillboard(tex, {}, {1, 1});
|
||||
kp3d::Renderer3D::End();
|
||||
if (m_mode == MODE_GAME || m_mode == MODE_EDIT)
|
||||
{
|
||||
// 3D scene
|
||||
kp3d::Renderer3D::Begin(m_camera, m_projection);
|
||||
map.Render();
|
||||
if (m_mode == MODE_EDIT)
|
||||
editor.RenderMap();
|
||||
kp3d::Renderer3D::DrawBillboard(tex, {}, { 1, 1 });
|
||||
kp3d::Renderer3D::End();
|
||||
|
||||
// 2D scene
|
||||
kp3d::Renderer2D::Begin();
|
||||
for (auto& p: points)
|
||||
kp3d::Renderer2D::DrawTexture(tex, p.x, p.y, 50, 50);
|
||||
kp3d::Renderer2D::End();
|
||||
// 2D scene
|
||||
kp3d::Renderer2D::Begin();
|
||||
for (auto& p : points)
|
||||
kp3d::Renderer2D::DrawTexture(tex, p.x, p.y, 50, 50);
|
||||
kp3d::Renderer2D::End();
|
||||
|
||||
if (m_mode == MODE_EDIT)
|
||||
editor.RenderUI();
|
||||
}
|
||||
else if (m_mode == MODE_MENU)
|
||||
{
|
||||
RenderMenu();
|
||||
}
|
||||
|
||||
// UI
|
||||
kp3d::console::Render();
|
||||
}
|
||||
|
||||
void Sandbox::RenderMenu()
|
||||
{
|
||||
// SOUL utilitarian Cube 2: Sauerbraten-esque sorry ass excuse for a main menu (swag)
|
||||
ImGui::SetNextWindowPos({(float) GetWidth() * 0.5f - 320.0f * 0.5f, (float) GetHeight() * 0.5f - 240.0f * 0.5f});
|
||||
ImGui::SetNextWindowSize({320, 240});
|
||||
ImGui::Begin("KP3D", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Image(
|
||||
ImTextureID(tex.GetGLID()),
|
||||
{ImGui::GetWindowSize().x - 20, (ImGui::GetWindowSize().x - 20) / ((float) tex.GetWidth() / (float) tex.GetHeight())}
|
||||
);
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Launch game"))
|
||||
m_mode = MODE_GAME;
|
||||
if (ImGui::Button("Launch editor"))
|
||||
m_mode = MODE_EDIT;
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Exit"))
|
||||
Exit(kp3d::SUCCESS);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Version %.02f", KP3D_VERSION);
|
||||
ImGui::Text("Copyright 2018-2024 kpworld.xyz");
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <KP3D_Game.h>
|
||||
#include <KP3D_Math.h>
|
||||
#include <KP3D_Camera.h>
|
||||
#include <KP3D_Map.h>
|
||||
|
||||
#include "Editor.h"
|
||||
|
||||
enum Mode
|
||||
{
|
||||
MODE_MENU,
|
||||
MODE_GAME,
|
||||
MODE_EDIT
|
||||
};
|
||||
|
||||
class Sandbox: public kp3d::Game
|
||||
{
|
||||
public:
|
||||
|
@ -14,13 +25,19 @@ public:
|
|||
void Update() override;
|
||||
void Render() override;
|
||||
|
||||
void RenderMenu();
|
||||
|
||||
public:
|
||||
// Temp
|
||||
kp3d::Map map;
|
||||
Editor editor;
|
||||
|
||||
private:
|
||||
// KP3D essentials
|
||||
kp3d::Mat4 m_projection;
|
||||
kp3d::Camera m_camera;
|
||||
int m_mode;
|
||||
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Sandbox> sandbox;
|
||||
|
|
Loading…
Reference in a new issue