second commit
This commit is contained in:
+260
-50
@@ -93,6 +93,11 @@ Engine::Engine()
|
||||
glfwSetMouseButtonCallback(window->handle, mouse_button_callback);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// Start from the real framebuffer size (can differ from the requested size under DPI scaling)
|
||||
int fbw, fbh;
|
||||
glfwGetFramebufferSize(window->handle, &fbw, &fbh);
|
||||
framebuffer_size_callback(window->handle, fbw, fbh);
|
||||
|
||||
rendersystem = new RenderSystem();
|
||||
rendersystem->Initialize();
|
||||
physicsengine = new Physics();
|
||||
@@ -243,17 +248,6 @@ void Engine::Initiate()
|
||||
crosshair->Dot = true;
|
||||
crosshair->Apply();
|
||||
|
||||
TextBox* tb = new TextBox();
|
||||
tb->font = arial;
|
||||
tb->text = "ASDASD\nASDASD\nADSADSA";
|
||||
tb->fontsize = 0.5f;
|
||||
tb->Color = { 0.0f, 0.0f, 0.0f };
|
||||
tb->t2d.position = { 0.5f, 0.5f, 0.0f, 0.0f };
|
||||
tb->t2d.center = { 0.0f, 0.0f };
|
||||
tb->textCenter = { 0.0f, 0.5f };
|
||||
tb->t2d.size = { 0.2f, 0.1f, 0.0f, 0.0f };
|
||||
tb->BindToRenderSystem();
|
||||
|
||||
TextBox* fpsCounter = new TextBox();
|
||||
fpsCounter->font = arial;
|
||||
fpsCounter->text = "TEST1231231123";
|
||||
@@ -295,7 +289,7 @@ void Engine::Initiate()
|
||||
grappleText->t2d.position = { 0.5f, 1.0f, 0.0f, -20.0f };
|
||||
grappleText->t2d.center = { 0.5f, 1.0f };
|
||||
grappleText->textCenter = { 0.5f, 0.5f };
|
||||
grappleText->t2d.size = { 0.0f, 0.0f, 300.0f, 40.0f };
|
||||
grappleText->t2d.size = { 0.0f, 0.0f, 560.0f, 40.0f };
|
||||
grappleText->BindToRenderSystem();
|
||||
|
||||
ImageBox* testgui = new ImageBox();
|
||||
@@ -325,7 +319,7 @@ void Engine::Initiate()
|
||||
Mesh* debugcube = CreateCubeMesh();
|
||||
debugcube->name = "debugcube";
|
||||
debugcube->t.ScaleTo({ 0.8f, 0.8f, 0.8f });
|
||||
debugcube->BindToRenderSystem();
|
||||
// Punch hitbox only: intentionally not bound to the render system, so it isn't drawn
|
||||
mainf->AddChild(debugcube);
|
||||
|
||||
Mesh* floor = CreateCubeMesh();
|
||||
@@ -352,22 +346,6 @@ void Engine::Initiate()
|
||||
wallBody->friction = 0.0f;
|
||||
physicsengine->AddObject(wallBody);
|
||||
|
||||
Mesh* cube = CreateCubeMesh();
|
||||
cube->name = "cube";
|
||||
cube->meshTexture = blanktex;
|
||||
cube->t.ScaleTo({ 1.0f, 1.0f, 1.0f });
|
||||
cube->t.TranslateTo({ 5.0f, 4.0f, 6.5f });
|
||||
cube->BindToRenderSystem();
|
||||
mainf->AddChild(cube);
|
||||
|
||||
Mesh* cube2 = CreateCubeMesh();
|
||||
cube2->name = "cubee";
|
||||
cube2->meshTexture = blanktex;
|
||||
cube2->t.ScaleTo({ 1.0f, 1.0f, 1.0f });
|
||||
cube2->t.TranslateTo({ 10.0f, 4.0f, 10.5f });
|
||||
cube2->BindToRenderSystem();
|
||||
mainf->AddChild(cube2);
|
||||
|
||||
// Ground check
|
||||
auto IsGrounded = [&]() -> bool {
|
||||
Ray downRay;
|
||||
@@ -390,16 +368,16 @@ void Engine::Initiate()
|
||||
// body = 50 damage (two shots). Respawns the target when it dies.
|
||||
// Movement tuning
|
||||
const float airControl = 0.5f; // fraction of ground acceleration available in the air
|
||||
const float grappleRange = 4.0f; // metres from the player
|
||||
const float grappleRange = 8.0f; // metres from the player
|
||||
const float grappleSpeed = 28.0f; // launch speed toward the hit point
|
||||
const float grappleCooldownTime = 2.5f; // seconds
|
||||
float grappleCooldown = 0.0f;
|
||||
|
||||
// Slide (key C): locked direction, committed for slideDuration, speed eases from
|
||||
// Slide (key Left Ctrl): locked direction, committed for slideDuration, speed eases from
|
||||
// slideBoost x ground top speed down to 1x by slideFalloffTime.
|
||||
const float slideBoost = 2.0f;
|
||||
const float slideDuration = 0.8f;
|
||||
const float slideFalloffTime = 0.7f;
|
||||
const float slideDuration = 1.2f;
|
||||
const float slideFalloffTime = 1.05f;
|
||||
const float slideDropY = 0.65f; // standing centre height (0.9) minus lying (0.25)
|
||||
const float standEyeOffset = 0.7f; // eyes 0.7 above body centre (body centre 0.9, height 1.8)
|
||||
const float slideEyeOffset = 0.25f; // lying down, eyes just above the floor
|
||||
@@ -408,17 +386,119 @@ void Engine::Initiate()
|
||||
float slideTime = 0.0f;
|
||||
glm::vec3 slideDir(0.0f);
|
||||
|
||||
// Shockwave (key Q): projectile that explodes on the first surface it touches. The blast
|
||||
// launches the player, the NPC and loose props away from the impact point. No damage.
|
||||
const float shockSpeed = 30.0f;
|
||||
const float shockGravity = 6.0f;
|
||||
const float shockLifetime = 3.0f;
|
||||
const float shockRadius = 7.0f;
|
||||
const float shockPower = 26.0f; // launch speed at the centre of the blast
|
||||
const float shockCooldownTime = 6.0f;
|
||||
const float blastShowTime = 0.25f;
|
||||
const glm::vec3 hiddenPos(0.0f, -1000.0f, 0.0f);
|
||||
float shockCooldown = 0.0f;
|
||||
bool shockActive = false;
|
||||
float shockAge = 0.0f;
|
||||
float blastTime = 0.0f;
|
||||
glm::vec3 shockVel(0.0f);
|
||||
|
||||
Mesh* shockMesh = CreateCubeMesh();
|
||||
shockMesh->name = "shockwave";
|
||||
shockMesh->meshTexture = blanktex;
|
||||
shockMesh->t.ScaleTo({ 0.3f, 0.3f, 0.3f });
|
||||
shockMesh->t.TranslateTo(hiddenPos);
|
||||
shockMesh->BindToRenderSystem();
|
||||
mainf->AddChild(shockMesh);
|
||||
|
||||
Mesh* blastMesh = CreateCubeMesh();
|
||||
blastMesh->name = "shockblast";
|
||||
blastMesh->meshTexture = blanktex;
|
||||
blastMesh->t.TranslateTo(hiddenPos);
|
||||
blastMesh->BindToRenderSystem();
|
||||
mainf->AddChild(blastMesh);
|
||||
|
||||
// fromNet = another player's blast: we only launch ourselves (the other machines launch
|
||||
// themselves the same way, since remote players are just puppets on this machine).
|
||||
auto Explode = [&](const glm::vec3& center, bool fromNet = false,
|
||||
float radius = shockRadius, float power = shockPower) {
|
||||
auto launch = [&](const glm::vec3& pos, p* body) {
|
||||
const glm::vec3 offset = pos - center;
|
||||
const float dist = glm::length(offset);
|
||||
if (dist >= radius) return;
|
||||
// Away from the blast, biased upward so grounded targets actually lift off
|
||||
glm::vec3 dir = dist > 0.001f ? offset / dist : glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
dir.y = std::max(dir.y, 0.0f) + 0.6f;
|
||||
dir = glm::normalize(dir);
|
||||
const float falloff = 1.0f - 0.7f * (dist / radius); // 100% at centre, 30% at the edge
|
||||
body->linearvelocity += dir * power * falloff;
|
||||
body->WakeUp();
|
||||
|
||||
if (body == characterBody && sliding) {
|
||||
// The slide overrides horizontal velocity every frame, so end it and stand back up
|
||||
sliding = false;
|
||||
glm::vec3 p0 = testcharacter->body->t.GetTranslation();
|
||||
p0.y += slideDropY + 0.02f;
|
||||
testcharacter->body->t.TranslateTo(p0);
|
||||
}
|
||||
};
|
||||
launch(testcharacter->body->t.GetTranslation(), characterBody);
|
||||
if (!fromNet) {
|
||||
launch(npc->body->t.GetTranslation(), npcBody);
|
||||
for (p* obj : physicsengine->GetObjects()) {
|
||||
if (!obj->velocity || obj == characterBody || obj == npcBody) continue;
|
||||
launch(obj->pointer->t.GetTranslation(), obj);
|
||||
}
|
||||
|
||||
NetBlast nb;
|
||||
nb.center = center;
|
||||
nb.radius = radius;
|
||||
nb.power = power;
|
||||
if (lan && lan->IsActive()) lan->SendBlast(nb);
|
||||
|
||||
shockActive = false;
|
||||
shockMesh->t.TranslateTo(hiddenPos);
|
||||
}
|
||||
blastMesh->t.TranslateTo(center);
|
||||
blastMesh->t.ScaleTo(glm::vec3(0.5f));
|
||||
blastTime = blastShowTime;
|
||||
camera->AddScreenshake(0.25f);
|
||||
};
|
||||
|
||||
const int maxHealth = 100;
|
||||
const int bodyDamage = 50;
|
||||
const int punchDamage = 25;
|
||||
const float headFraction = 0.8f;
|
||||
|
||||
// Random respawn spot on the floor (NPC and player), kept out of the wall (x -9.5..-6.5, z -11..11)
|
||||
std::mt19937 respawnRng(std::random_device{}());
|
||||
auto RandomSpawn = [&]() -> glm::vec3 {
|
||||
std::uniform_real_distribution<float> spread(-20.0f, 20.0f);
|
||||
for (;;) {
|
||||
const float x = spread(respawnRng), z = spread(respawnRng);
|
||||
if (x > -9.5f && x < -6.5f && z > -11.0f && z < 11.0f) continue;
|
||||
return { x, 0.9f, z };
|
||||
}
|
||||
};
|
||||
|
||||
auto Shoot = [&]() {
|
||||
Ray ray;
|
||||
ray.origin = camera->t.GetTranslation();
|
||||
ray.direction = glm::normalize(camera->t.GetFrontVector());
|
||||
|
||||
auto targetHit = IsRayInT(ray, npc->body->t);
|
||||
if (!targetHit.has_value()) return;
|
||||
const float targetDist = glm::distance(ray.origin, targetHit.value());
|
||||
// Nearest shootable target along the ray: the NPC or any remote (LAN) player
|
||||
float targetDist = 1e9f;
|
||||
glm::vec3 targetPoint(0.0f);
|
||||
t* targetT = nullptr;
|
||||
int targetRemoteId = -1; // -1 = the NPC
|
||||
auto consider = [&](t& tr, int remoteId) {
|
||||
auto h = IsRayInT(ray, tr);
|
||||
if (!h.has_value()) return;
|
||||
const float d = glm::distance(ray.origin, h.value());
|
||||
if (d < targetDist) { targetDist = d; targetPoint = h.value(); targetT = &tr; targetRemoteId = remoteId; }
|
||||
};
|
||||
consider(npc->body->t, -1);
|
||||
for (auto& kv : remotes) consider(kv.second.character->body->t, kv.first);
|
||||
if (!targetT) return;
|
||||
|
||||
// Walls/props in front of the target block the shot
|
||||
for (p* obj : physicsengine->GetObjects()) {
|
||||
@@ -429,16 +509,27 @@ void Engine::Initiate()
|
||||
return;
|
||||
}
|
||||
|
||||
const float heightFrac = (targetHit->y - npc->body->t.GetTranslation().y)
|
||||
/ npc->body->t.GetScale().y + 0.5f;
|
||||
const float heightFrac = (targetPoint.y - targetT->GetTranslation().y)
|
||||
/ targetT->GetScale().y + 0.5f;
|
||||
const bool headshot = heightFrac >= headFraction;
|
||||
npc->body->Health -= headshot ? maxHealth : bodyDamage;
|
||||
std::cout << (headshot ? "HEADSHOT" : "BODY SHOT") << " - NPC HP " << npc->body->Health << "\n";
|
||||
const int damage = headshot ? maxHealth : bodyDamage;
|
||||
camera->AddScreenshake(0.05f);
|
||||
|
||||
if (targetRemoteId >= 0) {
|
||||
// Another player: their machine owns their health, so tell it
|
||||
NetHit hit;
|
||||
hit.damage = damage;
|
||||
if (lan && lan->IsActive()) lan->SendHit((uint8_t)targetRemoteId, hit);
|
||||
std::cout << (headshot ? "HEADSHOT" : "BODY SHOT") << " - player " << targetRemoteId << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
npc->body->Health -= damage;
|
||||
std::cout << (headshot ? "HEADSHOT" : "BODY SHOT") << " - NPC HP " << npc->body->Health << "\n";
|
||||
|
||||
if (npc->body->Health <= 0) {
|
||||
npc->body->Health = maxHealth;
|
||||
npc->body->t.TranslateTo({ 3.0f, 0.9f, 3.0f });
|
||||
npc->body->t.TranslateTo(RandomSpawn());
|
||||
npcBody->linearvelocity = glm::vec3(0.0f);
|
||||
npcBody->WakeUp();
|
||||
}
|
||||
@@ -454,7 +545,8 @@ void Engine::Initiate()
|
||||
|
||||
const glm::vec3 camFront = camera->t.GetFrontVector();
|
||||
const glm::vec3 camRight = camera->t.GetRightVector();
|
||||
const float movespeed = 3.0f * 1.3f;
|
||||
const float walkScale = 0.5f; // WASD speed relative to the original 3.9
|
||||
const float movespeed = 3.0f * 1.3f * walkScale;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Input � mouse
|
||||
@@ -516,10 +608,30 @@ void Engine::Initiate()
|
||||
npcBody->WakeUp();
|
||||
npcBody->linearvelocity += playerFront * 5.0f + glm::vec3(0.0f, 3.0f, 0.0f);
|
||||
camera->AddScreenshake(0.15f); // landing a punch feels impactful
|
||||
|
||||
npc->body->Health -= punchDamage;
|
||||
std::cout << "PUNCH - NPC HP " << npc->body->Health << "\n";
|
||||
if (npc->body->Health <= 0) {
|
||||
npc->body->Health = maxHealth;
|
||||
npc->body->t.TranslateTo(RandomSpawn());
|
||||
npcBody->linearvelocity = glm::vec3(0.0f);
|
||||
npcBody->WakeUp();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "MISSED\n";
|
||||
}
|
||||
|
||||
// Punch LAN players too: their machine applies the damage and knockback
|
||||
for (auto& kv : remotes) {
|
||||
if (!TInT(debugcube->t, kv.second.character->body->t).has_value()) continue;
|
||||
NetHit ph;
|
||||
ph.damage = punchDamage;
|
||||
ph.knockback = playerFront * 5.0f + glm::vec3(0.0f, 3.0f, 0.0f);
|
||||
if (lan && lan->IsActive()) lan->SendHit((uint8_t)kv.first, ph);
|
||||
camera->AddScreenshake(0.15f);
|
||||
std::cout << "PUNCH - player " << kv.first << "\n";
|
||||
}
|
||||
}
|
||||
if (buffer.GetCode() == GLFW_KEY_LEFT_SHIFT && buffer.IsPress() && !sliding) {
|
||||
glm::vec3 dashDir = glm::length(inputVel) > 0.0f
|
||||
@@ -529,7 +641,7 @@ void Engine::Initiate()
|
||||
characterBody->linearvelocity.z += dashDir.z * 18.0f;
|
||||
camera->AddScreenshake(0.04f);
|
||||
}
|
||||
if (buffer.GetCode() == 'C' && buffer.IsPress() && !sliding && IsGrounded()) {
|
||||
if (buffer.GetCode() == GLFW_KEY_LEFT_CONTROL && buffer.IsPress() && !sliding && IsGrounded()) {
|
||||
const glm::vec3 horizVel(characterBody->linearvelocity.x, 0.0f, characterBody->linearvelocity.z);
|
||||
if (glm::length(inputVel) > 0.0f || glm::length(horizVel) > 1.0f) {
|
||||
slideDir = glm::length(inputVel) > 0.0f ? glm::normalize(inputVel) : glm::normalize(horizVel);
|
||||
@@ -570,12 +682,21 @@ void Engine::Initiate()
|
||||
camera->AddScreenshake(0.1f);
|
||||
}
|
||||
}
|
||||
if (buffer.GetCode() == 'Q' && buffer.IsPress() && !shockActive && shockCooldown <= 0.0f) {
|
||||
const glm::vec3 front = glm::normalize(camFront);
|
||||
shockMesh->t.TranslateTo(camera->t.GetTranslation() + front * 0.6f);
|
||||
shockVel = front * shockSpeed;
|
||||
shockActive = true;
|
||||
shockAge = 0.0f;
|
||||
shockCooldown = shockCooldownTime;
|
||||
camera->AddScreenshake(0.05f);
|
||||
}
|
||||
if (buffer.GetCode() == 'G' && buffer.IsPress()) {
|
||||
camera->AddScreenshake(0.2f);
|
||||
}
|
||||
if (buffer.GetCode() == GLFW_KEY_SPACE && buffer.IsPress()) {
|
||||
if (!sliding && IsGrounded())
|
||||
characterBody->linearvelocity.y = 5.0f;
|
||||
characterBody->linearvelocity.y = 12.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,7 +715,7 @@ void Engine::Initiate()
|
||||
// Direction is locked; speed eases from boost x down to 1x (quadratic: drops fastest early)
|
||||
slideTime += deltatime;
|
||||
const float u = glm::clamp(slideTime / slideFalloffTime, 0.0f, 1.0f);
|
||||
const float speed = groundTopSpeed * (1.0f + (slideBoost - 1.0f) * (1.0f - u) * (1.0f - u));
|
||||
const float speed = (groundTopSpeed / walkScale) * (1.0f + (slideBoost - 1.0f) * (1.0f - u) * (1.0f - u));
|
||||
characterBody->linearvelocity.x = slideDir.x * speed;
|
||||
characterBody->linearvelocity.z = slideDir.z * speed;
|
||||
|
||||
@@ -634,6 +755,48 @@ void Engine::Initiate()
|
||||
debugcube->t.RotateToQuaternion(LookAt(-playerFront));
|
||||
}
|
||||
|
||||
// Shockwave projectile: arc forward, explode on the first collider along this frame's path
|
||||
shockCooldown = std::max(shockCooldown - deltatime, 0.0f);
|
||||
if (shockActive) {
|
||||
shockVel.y -= shockGravity * deltatime;
|
||||
shockAge += deltatime;
|
||||
const glm::vec3 from = shockMesh->t.GetTranslation();
|
||||
const glm::vec3 step = shockVel * deltatime;
|
||||
const float stepLen = glm::length(step);
|
||||
|
||||
Ray ray;
|
||||
ray.origin = from;
|
||||
ray.direction = step / stepLen;
|
||||
float bestDist = stepLen;
|
||||
glm::vec3 bestPoint(0.0f);
|
||||
bool found = false;
|
||||
for (p* obj : physicsengine->GetObjects()) {
|
||||
if (obj == characterBody || !obj->collision) continue;
|
||||
auto hit = IsRayInT(ray, obj->pointer->t);
|
||||
if (!hit.has_value()) continue;
|
||||
const float d = glm::distance(from, hit.value());
|
||||
if (d <= bestDist) { bestDist = d; bestPoint = hit.value(); found = true; }
|
||||
}
|
||||
|
||||
if (found) Explode(bestPoint);
|
||||
else if (shockAge >= shockLifetime) {
|
||||
shockActive = false;
|
||||
shockMesh->t.TranslateTo(hiddenPos);
|
||||
}
|
||||
else shockMesh->t.TranslateTo(from + step);
|
||||
}
|
||||
if (blastTime > 0.0f) {
|
||||
blastTime -= deltatime;
|
||||
if (blastTime <= 0.0f) {
|
||||
blastMesh->t.TranslateTo(hiddenPos);
|
||||
}
|
||||
else {
|
||||
// Expand to the full blast radius over its lifetime
|
||||
const float u = 1.0f - blastTime / blastShowTime;
|
||||
blastMesh->t.ScaleTo(glm::vec3(0.5f + (shockRadius * 2.0f - 0.5f) * u));
|
||||
}
|
||||
}
|
||||
|
||||
rain->t.TranslateTo(camera->t.GetTranslation() + glm::vec3(0.0f, 20.0f, 0.0f));
|
||||
for (int i = 0; i < 30; i++) rain->Emit();
|
||||
|
||||
@@ -647,8 +810,7 @@ void Engine::Initiate()
|
||||
camera->t.TranslateTo(testcharacter->body->t.GetTranslation() + glm::vec3(0.0f, eyeOffset, 0.0f));
|
||||
|
||||
Sound* music = static_cast<Sound*>(mainf->GetFirstChildOfName("music"));
|
||||
Mesh* cube = static_cast<Mesh*>(mainf->GetFirstChildOfName("cube"));
|
||||
music->Update3DPosition(cube->t.GetTranslation());
|
||||
music->Update3DPosition(5.0f, 4.0f, 6.5f); // where the old floating cube was
|
||||
|
||||
soundsystem->SetListenerPosition(
|
||||
camera->t.GetTranslation(),
|
||||
@@ -675,10 +837,21 @@ void Engine::Initiate()
|
||||
}
|
||||
fpsCounter->text = std::to_string(measuredFps) + " FPS";
|
||||
}
|
||||
// Player respawn: at 0 HP or after falling off the map, teleport to a random spot
|
||||
if (testcharacter->body->Health <= 0 || testcharacter->body->t.GetTranslation().y < -20.0f) {
|
||||
testcharacter->body->Health = maxHealth;
|
||||
testcharacter->body->t.TranslateTo(RandomSpawn());
|
||||
characterBody->linearvelocity = glm::vec3(0.0f);
|
||||
characterBody->WakeUp();
|
||||
sliding = false;
|
||||
}
|
||||
hpText->text = std::to_string(std::max(testcharacter->body->Health, 0)) + "/100 HP";
|
||||
grappleText->text = grappleCooldown > 0.0f
|
||||
? "GRAPPLE " + std::to_string(grappleCooldown).substr(0, 3) + "s"
|
||||
: "GRAPPLE READY";
|
||||
grappleText->text += shockCooldown > 0.0f
|
||||
? " | SHOCKWAVE " + std::to_string(shockCooldown).substr(0, 3) + "s"
|
||||
: " | SHOCKWAVE READY (Q)";
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Step systems
|
||||
@@ -702,7 +875,20 @@ void Engine::Initiate()
|
||||
|
||||
const double now = glfwGetTime();
|
||||
std::vector<NetUpdate> updates;
|
||||
lan->Receive(updates);
|
||||
std::vector<NetBlast> blasts;
|
||||
std::vector<NetHit> hits;
|
||||
lan->Receive(updates, &blasts, &hits);
|
||||
for (const NetBlast& b : blasts)
|
||||
Explode(b.center, true, b.radius, b.power);
|
||||
// Damage from other players (respawn handles dying, see the player respawn check)
|
||||
for (const NetHit& h : hits) {
|
||||
testcharacter->body->Health -= h.damage;
|
||||
characterBody->linearvelocity += h.knockback;
|
||||
characterBody->WakeUp();
|
||||
camera->AddScreenshake(0.15f);
|
||||
std::cout << "HIT by player " << (int)h.sender << " for " << h.damage
|
||||
<< " - HP " << testcharacter->body->Health << "\n";
|
||||
}
|
||||
for (const NetUpdate& u : updates) {
|
||||
auto it = remotes.find(u.id);
|
||||
if (it == remotes.end()) {
|
||||
@@ -757,10 +943,31 @@ void Engine::Initiate()
|
||||
// ============================================================================
|
||||
void framebuffer_size_callback(GLFWwindow* window, int w, int h)
|
||||
{
|
||||
if (w <= 0 || h <= 0) return; // minimised
|
||||
// Everything pixel-based (viewport, projection aspect, GUI layout, scissor) reads these
|
||||
::window->width = w;
|
||||
::window->height = h;
|
||||
glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
// F11: toggle fullscreen on the primary monitor, restoring the old window rect on exit
|
||||
if (key == GLFW_KEY_F11 && action == GLFW_PRESS) {
|
||||
static int wx = 100, wy = 100, ww = 1280, wh = 720;
|
||||
if (glfwGetWindowMonitor(window)) {
|
||||
glfwSetWindowMonitor(window, nullptr, wx, wy, ww, wh, 0);
|
||||
}
|
||||
else {
|
||||
glfwGetWindowPos(window, &wx, &wy);
|
||||
glfwGetWindowSize(window, &ww, &wh);
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
}
|
||||
glfwSwapInterval(1);
|
||||
}
|
||||
|
||||
if (action == GLFW_PRESS) keyboard->KeyDown(key);
|
||||
else if (action == GLFW_RELEASE) keyboard->KeyUp(key);
|
||||
}
|
||||
@@ -773,8 +980,11 @@ void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
|
||||
{
|
||||
mouse->OnMouseMove(static_cast<float>(xposIn), static_cast<float>(yposIn));
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwSetCursorPos(window, ::window->width / 2, ::window->height / 2);
|
||||
mouse->OnMouseMove(::window->width / 2.0f, ::window->height / 2.0f);
|
||||
// Cursor coordinates are in window units, which can differ from framebuffer pixels (DPI scaling)
|
||||
int ww, wh;
|
||||
glfwGetWindowSize(window, &ww, &wh);
|
||||
glfwSetCursorPos(window, ww / 2.0, wh / 2.0);
|
||||
mouse->OnMouseMove(ww / 2.0f, wh / 2.0f);
|
||||
}
|
||||
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
|
||||
Reference in New Issue
Block a user