From: matthew Date: Mon, 8 Oct 2018 18:52:03 +0000 (+0100) Subject: implemented dt for camera X-Git-Url: https://git.owens.tech/style.css/style.css/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();