From: matthew <matthew@owens.tech>
Date: Mon, 8 Oct 2018 18:52:03 +0000 (+0100)
Subject: implemented dt for camera
X-Git-Url: https://git.owens.tech/assets/editable-focus.html/assets/editable-focus.html/git?a=commitdiff_plain;h=97678e1dbf9d4c9c229b01d2493f65c825a28296;p=csrpg.git

implemented dt for camera
---

diff --git a/gl/camera.c b/gl/camera.c
index 5f571dd..a1196c9 100644
--- a/gl/camera.c
+++ b/gl/camera.c
@@ -9,6 +9,10 @@ typedef struct
 {
 	vec3_t from, to, up;
 	mat4_t camera, perspective, worldToScreen;
+	float speed;
+
+	// Axis' to manouver across. If 0, no movement is occuring
+	vec3_t pan, yaw, roll;
 } Camera_t;
 
 ///TODO: figure out why this is failing
@@ -37,6 +41,7 @@ crpgCamera *crpgCameraNew(vec3_t from, vec3_t to, vec3_t up)
 	//ct->perspective = recalcPerspective(90.f, 1, 10);
 	ct->perspective = m4_perspective(60, aspectRatio, 1, 10);
 	ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
+	ct->speed = 1.0f;
 
 	crpgCamera *c = (crpgCamera *) ct;
 	return c;
@@ -51,16 +56,24 @@ void crpgCameraFree(crpgCamera *c)
 	}
 }
 
-void crpgCameraPan(crpgCamera *c, vec3_t pan)
+void crpgCameraSetSpeed(crpgCamera *c, float speedPerSecond)
 {
+	if(c == NULL) return;
+
 	Camera_t *ct = (Camera_t *) c;
-	ct->from.x += pan.x;
-	ct->from.y += pan.y;
-	ct->from.z += pan.z;
+	ct->speed = speedPerSecond;
+}
+
+// This function expects a vec3_t formatted with values of 1, 0 or -1.
+// to represent if the axis should be panned across and the direction
+void crpgCameraPan(crpgCamera *c, vec3_t panAxis)
+{
+	if(c == NULL)
+		return;
+
+	Camera_t *ct = (Camera_t *) c;
+	ct->pan = panAxis;
 
-	// recalc camera matrices
-	ct->camera = m4_look_at(ct->from, ct->to, ct->up);
-	ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
 }
 
 mat4_t *crpgCameraGetMat(crpgCamera *c)
@@ -68,3 +81,32 @@ mat4_t *crpgCameraGetMat(crpgCamera *c)
 	Camera_t *ct = (Camera_t *)c;
 	return &(ct->worldToScreen);
 }
+
+// expecting components as {from, to, up}
+void updatePan(vec3_t panAxis, vec3_t *components[3], float speed, float dtms)
+{
+	int axis[] = { panAxis.x, panAxis.y, panAxis.z };
+	float* fromArr[] = { &components[0]->x, &components[0]->y, &components[0]->z };
+	float* toArr[] = { &components[1]->x, &components[1]->y, &components[1]->z };
+
+	for(int i = 0; i < 3; ++i){
+		if(axis[i] != 0){	// if we should pan on this axis
+			int sign = 0;
+			sign = (axis[i] > 0) ? 1 : -1;
+			*fromArr[i] += sign * (speed/1000.f);
+			*toArr[i] += sign * (speed/1000.f);
+		}
+	}
+}
+
+void crpgCameraUpdate(crpgCamera *c, float dtms)
+{
+	Camera_t *ct = (Camera_t *)c;
+	vec3_t *components[] = { &(ct->from), &(ct->to), &(ct->up) };
+
+	updatePan(ct->pan, components, ct->speed, dtms);
+
+	// recalc camera matrices
+	ct->camera = m4_look_at(ct->from, ct->to, ct->up);
+	ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
+}
diff --git a/gl/camera.h b/gl/camera.h
index ed8d739..9e513b3 100644
--- a/gl/camera.h
+++ b/gl/camera.h
@@ -6,7 +6,9 @@ typedef struct {} crpgCamera;
 
 crpgCamera *crpgCameraNew(vec3_t from, vec3_t to, vec3_t up);
 void crpgCameraFree(crpgCamera *c);
-void crpgCameraPan(crpgCamera *c, vec3_t pan);
+void crpgCameraPan(crpgCamera *c, vec3_t panAxis);
 void crpgCameraSetAR(float ar);
 mat4_t *crpgCameraGetMat(crpgCamera *c);
+void crpgCameraSetSpeed(crpgCamera *c, float speedPerSecond);
+void crpgCameraUpdate(crpgCamera *c, float dtms);
 #endif//CAMERA_H
diff --git a/gl/main.c b/gl/main.c
index 83fdcaf..54ff28e 100644
--- a/gl/main.c
+++ b/gl/main.c
@@ -18,7 +18,7 @@ static SDL_GLContext *context = NULL;
 static int screen_width = 1280;
 static int screen_height = 720;
 static bool quit = false;
-static Uint32 itime;
+static Uint32 ltime, ctime, numframes, cftime, lftime;
 
 static float vertices[] = {
 	// positions		// colours		 	// texture coords
@@ -100,6 +100,7 @@ static void initView()
 {
 	crpgCameraSetAR((float)screen_width/(float)screen_height);
 	camera = crpgCameraNew(vec3(0,0,4), vec3(0,0,0), vec3(0,1,0));
+	crpgCameraSetSpeed(camera, 2);
 	crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
 	crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
 
@@ -148,22 +149,60 @@ static bool init()
 
 static void update()
 {
+	// measuring frame times
+	numframes++;
+	ctime = SDL_GetTicks();
+	if(ctime - ltime > 1000){	// if the last printf was more than a second ago
+		printf("%f ms/frame\n", 1000/(double)(numframes));
+		numframes = 0;
+		ltime = ctime;
+	}
+
+	// calculating delta time
+	cftime = SDL_GetTicks();
+	float dtms = cftime - lftime;
+
 	SDL_Event e;
 	while(SDL_PollEvent(&e) != 0){
 		if(e.type == SDL_QUIT){
 			quit = true;
 		}
 		if(e.type == SDL_KEYDOWN){
-			if(e.key.keysym.sym == SDLK_k){
-				blendVal += .2f;
-				crpgShaderSetFloat(shader, "blendVal", blendVal);
-			}
-			if(e.key.keysym.sym == SDLK_j){
-				blendVal -= .2f;
-				crpgShaderSetFloat(shader, "blendVal", blendVal);
+			switch(e.key.keysym.sym){
+				case SDLK_k:
+					blendVal += .2f;
+					crpgShaderSetFloat(shader, "blendVal", blendVal);
+					break;
+				case SDLK_j:
+					blendVal -= .2f;
+					crpgShaderSetFloat(shader, "blendVal", blendVal);
+					break;
+				case SDLK_w:
+					crpgCameraPan(camera, vec3(0,0,-1));
+					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
+					break;
+				case SDLK_s:
+					crpgCameraPan(camera, vec3(0,0,1));
+					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
+					break;
+				case SDLK_d:
+					crpgCameraPan(camera, vec3(1,0,0));
+					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
+					break;
+				case SDLK_a:
+					crpgCameraPan(camera, vec3(-1,0,0));
+					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
+					break;
 			}
 		}
 	}
+
+	crpgCameraUpdate(camera, dtms);
+	lftime = cftime;
 }
 
 static void render()
@@ -171,6 +210,11 @@ static void render()
 	glClearColor(0.2, 0.3, 0.3, 1.0);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
+	glEnable(GL_DEPTH_TEST);
+	crpgCubeRender(cubes[0]);
+	crpgCubeRender(cubes[1]);
+
+	// Rendering our wall
 	crpgShaderUse(shader);
 
 	glActiveTexture(GL_TEXTURE0);
@@ -178,15 +222,14 @@ static void render()
 	glActiveTexture(GL_TEXTURE1);
 	glBindTexture(GL_TEXTURE_2D, crpgTextureGetID(tex[1]));
 
+	// Bypassing depth checks to render 'on the screen'
+	glDisable(GL_DEPTH_TEST);
 	glEnable(GL_BLEND);
 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 	glBindVertexArray(vao);
 	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
 	glBindVertexArray(0);
 
-	crpgCubeRender(cubes[0]);
-	crpgCubeRender(cubes[1]);
-
 	SDL_GL_SwapWindow(window);
 }
 
@@ -197,7 +240,9 @@ int main()
 
 	initShapes();
 	initView();
-	itime = SDL_GetTicks();
+
+	ltime = SDL_GetTicks();
+	lftime = SDL_GetTicks();
 
 	while(!quit){
 		update();