mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-09-05 17:58:14 +00:00
Sort of get FPS controls working
not really though, holy cow
This commit is contained in:
@@ -150,7 +150,7 @@ public:
|
||||
// renderComponent = &rc;
|
||||
}
|
||||
|
||||
void Tick(float deltaSeconds) override {
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
x += deltaSeconds;
|
||||
// position.X = 2.0f * HMM_SINF(x);
|
||||
|
||||
|
@@ -19,7 +19,7 @@ public:
|
||||
children.push_back(e);
|
||||
}
|
||||
|
||||
virtual void Tick(float deltaSeconds) {}
|
||||
virtual void Tick(float deltaSeconds, Input previousInput, Input input) {}
|
||||
|
||||
RenderComponent *renderComponent = NULL;
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <tgmath.h>
|
||||
|
||||
#ifndef HMME_FPSCAM_H
|
||||
#define HMME_FPSCAM_H
|
||||
@@ -14,9 +15,14 @@ public:
|
||||
FollowCam cam = FollowCam(0); // TODO: Why on earth is this necessary?? Remove this and fix the error.
|
||||
Entity target;
|
||||
|
||||
// all angles in radians
|
||||
float yaw = 0;
|
||||
float pitch = 0;
|
||||
float sensitivity = 0.002f;
|
||||
|
||||
FPSCam() {
|
||||
target = Entity();
|
||||
target.position = HMM_Vec3(1.0f, 0.0f, 0.0f);
|
||||
target.position = HMM_Vec3(0.0f, 0.0f, -1.0f);
|
||||
|
||||
cam = FollowCam(&target);
|
||||
|
||||
@@ -24,11 +30,32 @@ public:
|
||||
AddChild(&cam);
|
||||
}
|
||||
|
||||
float x = 0;
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
double deltaX = input.mouseX - previousInput.mouseX;
|
||||
double deltaY = input.mouseY - previousInput.mouseY;
|
||||
|
||||
void Tick(float deltaSeconds) override {
|
||||
x += deltaSeconds;
|
||||
rotation *= HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), deltaSeconds * HMM_ToRadians(45.0f));
|
||||
// HACK: Pitch is being weird for reasons I don't understand. It works fine for
|
||||
// 360 degrees, then does something silly for 360 degrees, then repeats. I suspect
|
||||
// I'm just doing something wrong with quaternions because I know they encode twice
|
||||
// the angle or whatever. In any case, I've hacked around it for now to splice
|
||||
// together ranges that work.
|
||||
|
||||
yaw = yaw + (-deltaX * sensitivity);
|
||||
pitch = HMM_Clamp(-HMM_PI32 / 2, pitch + (-deltaY * sensitivity), HMM_PI32 / 2);
|
||||
|
||||
// HACK: MEGAHACK: why the heck is the apparent rotation twice what it should be?
|
||||
float hackyPitch = HMM_PI32;
|
||||
if (pitch > 0) {
|
||||
hackyPitch = HMM_PI32 + pitch / 2;
|
||||
} else if (pitch < 0) {
|
||||
hackyPitch = 2 * HMM_PI32 + pitch / 2;
|
||||
}
|
||||
printf("%f\t%f\n", pitch, hackyPitch);
|
||||
|
||||
hmm_quaternion rotationYaw = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), yaw);
|
||||
hmm_quaternion rotationPitch = HMM_QuaternionFromAxisAngle(HMM_Vec3(1.0f, 0.0f, 0.0f), hackyPitch);
|
||||
|
||||
rotation = rotationPitch * rotationYaw;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -16,7 +16,7 @@ public:
|
||||
target = t;
|
||||
}
|
||||
|
||||
void Tick(float deltaSeconds) override {
|
||||
void Tick(float deltaSeconds, Input previousInput, Input input) override {
|
||||
// TODO: Find a way to do this rotation routine in a single quaternion. Maybe that
|
||||
// just means finding a correct method, then doing some quaternion multiplication
|
||||
// on paper to see how the axis and angle shake out.
|
||||
|
@@ -8,9 +8,11 @@ in vec2 fragmentUV;
|
||||
out vec3 color;
|
||||
|
||||
void main() {
|
||||
vec3 ambient = vec3(0.1, 0.1, 0.1);
|
||||
|
||||
vec3 toLight_world = normalize(vec3(1, 1, 1));
|
||||
|
||||
float cosTheta = clamp(dot(normalize(fragmentNormal_world), toLight_world), 0.1, 1);
|
||||
|
||||
color = cosTheta * fragmentColor;
|
||||
color = cosTheta * fragmentColor + ambient;
|
||||
}
|
||||
|
19
example/src/input.h
Normal file
19
example/src/input.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifndef HMME_INPUT_H
|
||||
#define HMME_INPUT_H
|
||||
|
||||
struct Input {
|
||||
double mouseX;
|
||||
double mouseY;
|
||||
};
|
||||
|
||||
Input GetInput(GLFWwindow *window) {
|
||||
Input i;
|
||||
|
||||
glfwGetCursorPos(window, &i.mouseX, &i.mouseY);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,11 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <HandmadeMath.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "shaders.h"
|
||||
|
||||
#include "Entity.h"
|
||||
@@ -13,13 +15,16 @@
|
||||
#include "MeshRenderComponent.h"
|
||||
#include "FPSCam.h"
|
||||
|
||||
void TickTree(Entity *e, float deltaSeconds);
|
||||
void TickTree(Entity *e, float deltaSeconds, Input previousInput, Input input);
|
||||
void ComputeModelMatrices(Entity *ep, hmm_mat4 parentModelMatrix);
|
||||
void HandleMouseMove(GLFWwindow *window, double mouseX, double mouseY);
|
||||
|
||||
using std::chrono::high_resolution_clock;
|
||||
|
||||
int main()
|
||||
{
|
||||
#define WIDTH 1024
|
||||
#define HEIGHT 768
|
||||
|
||||
int main() {
|
||||
// Initialise GLFW
|
||||
glewExperimental = true; // Needed for core profile
|
||||
if (!glfwInit()) {
|
||||
@@ -35,7 +40,7 @@ int main()
|
||||
|
||||
// Open a window and create its OpenGL context
|
||||
GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity)
|
||||
window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL);
|
||||
window = glfwCreateWindow(WIDTH, HEIGHT, "Handmade Math Example", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
|
||||
glfwTerminate();
|
||||
@@ -51,6 +56,14 @@ int main()
|
||||
// Ensure we can capture the escape key being pressed below
|
||||
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
|
||||
|
||||
// Hide the mouse cursor
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
// glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
|
||||
// glfwSetCursorPosCallback(window, [](GLFWwindow *window, double mouseX, double mouseY) {
|
||||
// printf("%f\t%f\n", mouseX, mouseY);
|
||||
// // glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
|
||||
// });
|
||||
|
||||
// Create and compile our GLSL program from the shaders
|
||||
GLuint programID = LoadShaders("src/vertex.glsl", "src/fragment.glsl");
|
||||
if (!programID) {
|
||||
@@ -74,8 +87,12 @@ int main()
|
||||
monkey.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
||||
monkey.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
||||
|
||||
Entity backmonkey = Entity();
|
||||
backmonkey.position = HMM_Vec3(0.0f, 0.0f, 5.0f);
|
||||
backmonkey.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
||||
|
||||
FPSCam fpsCam = FPSCam();
|
||||
fpsCam.position = HMM_Vec3(-3.0f, 1.0f, 1.0f);
|
||||
fpsCam.position = HMM_Vec3(-1.0f, 1.0f, 3.0f);
|
||||
|
||||
Entity *cam = &fpsCam.cam;
|
||||
|
||||
@@ -89,6 +106,7 @@ int main()
|
||||
Entity root = Entity();
|
||||
root.AddChild(&c1);
|
||||
root.AddChild(&fpsCam);
|
||||
root.AddChild(&backmonkey);
|
||||
|
||||
Entity axes = Entity();
|
||||
axes.renderComponent = new MeshRenderComponent("Axes.obj");
|
||||
@@ -97,18 +115,24 @@ int main()
|
||||
bool hasTicked = false;
|
||||
high_resolution_clock::time_point lastTickTime;
|
||||
|
||||
Input previousInput = GetInput(window);
|
||||
|
||||
do {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Get inputs
|
||||
Input input = GetInput(window);
|
||||
|
||||
// Tick
|
||||
auto now = high_resolution_clock::now();
|
||||
if (hasTicked) {
|
||||
auto elapsedNanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now - lastTickTime).count();
|
||||
float elapsedSeconds = elapsedNanoseconds / 1000000000.0f;
|
||||
TickTree(&root, elapsedSeconds);
|
||||
TickTree(&root, elapsedSeconds, previousInput, input);
|
||||
}
|
||||
lastTickTime = now;
|
||||
hasTicked = true;
|
||||
previousInput = input;
|
||||
|
||||
// Compute model positions for rendering
|
||||
ComputeModelMatrices(&root, HMM_Mat4d(1.0f));
|
||||
@@ -148,11 +172,11 @@ int main()
|
||||
);
|
||||
}
|
||||
|
||||
void TickTree(Entity *e, float deltaSeconds) {
|
||||
e->Tick(deltaSeconds);
|
||||
void TickTree(Entity *e, float deltaSeconds, Input previousInput, Input input) {
|
||||
e->Tick(deltaSeconds, previousInput, input);
|
||||
|
||||
for (auto child : e->children) {
|
||||
TickTree(child, deltaSeconds);
|
||||
TickTree(child, deltaSeconds, previousInput, input);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user