--- /dev/null
+#include <math.h>
+
+#include <gmath/gmath.h>
+
+#include "camera.h"
+
+Camera::Camera() {}
+Camera::~Camera() {}
+
+OrbitCamera::OrbitCamera()
+{
+ phi = theta = distance = 0;
+}
+
+OrbitCamera::~OrbitCamera() {}
+
+void OrbitCamera::set_orbit_params(float theta, float phi, float distance)
+{
+ this->phi = phi;
+ this->theta = theta;
+ this->distance = distance;
+}
+
+Mat4 OrbitCamera::get_view_matrix() const
+{
+ Mat4 view_matrix;
+ view_matrix.translation(-position);
+ view_matrix.rotate_y(theta * (float)M_PI / 180);
+ view_matrix.rotate_x(phi * (float)M_PI / 180);
+ view_matrix.translate(Vec3(0, 0, -distance));
+
+ return view_matrix;
+}
+
+Mat4 calc_projection_matrix(float fov_deg, float aspect, float n, float f)
+{
+ float fov = fov_deg / 180 * M_PI;
+
+ float tmp;
+ tmp = 1 / tan(fov / 2.0);
+
+ /* near - far clipping planes */
+ float range = n - f;
+
+ Mat4 pmat = Mat4(
+ tmp/aspect, 0, 0, 0,
+ 0, tmp, 0, 0,
+ 0, 0, (f + n) / range, -1,
+ 0, 0, 2 * n * f / range, 0
+ );
+
+ return pmat;
+}
+
+void OrbitCamera::set_position(float x, float y, float z)
+{
+ position.x = x;
+ position.y = y;
+ position.z = z;
+}
--- /dev/null
+#ifndef CAMERA_H_
+#define CAMERA_H_
+
+#include <gmath/gmath.h>
+
+class Camera {
+public:
+ Camera();
+ virtual ~Camera();
+
+ virtual Mat4 get_view_matrix() const = 0;
+};
+
+class OrbitCamera : public Camera {
+protected:
+ float theta;
+ float phi;
+ float distance;
+
+ Vec3 position;
+
+public:
+ OrbitCamera();
+ virtual ~OrbitCamera();
+
+ virtual Mat4 get_view_matrix() const override;
+
+ void set_orbit_params(float theta, float phi, float distance);
+ void set_position(float x, float y, float z);
+};
+
+Mat4 calc_projection_matrix(float fov_deg, float aspect, float n, float f);
+
+#endif // CAMERA_H_
#include <stdlib.h>
#include <string.h>
+#include <gmath/gmath.h>
+
+/* extern "C": vulkan framework */
#include "vk.h"
#include "util.h"
+/* C++ */
+#include "camera.h"
+/**************************/
/* static glfw callbacks */
+/**************************/
static void
clb_key(GLFWwindow *win, int key, int scancode, int action, int mods);
static void
clb_reshape(GLFWwindow *win, int width, int height);
+static void
+clb_motion(GLFWwindow *win, double x, double y);
+
+static void
+clb_mouse(GLFWwindow *win, int button, int action, int mods);
+
+/**************************/
/* static functions */
+/**************************/
+
+/* init, cleanup, display */
static bool
-init(void);
+init();
static void
-cleanup(void);
+cleanup();
static void
-display(void);
+display();
+/* vulkan, glfw */
+
+static bool
+vk_init();
+
+static void
+vk_cleanup();
+
+/**************************/
/* static variables */
+/**************************/
static GLFWwindow *win;
static bool redraw_pending;
+static bool move_camera;
+
+/* camera */
+static float cam_phi = 25;
+static float cam_theta = 0;
+static float cam_dist = 16;
+static Vec3 cam_pos;
+
+static float aspect;
+static OrbitCamera *camera;
static bool vk_enable_layers = true;
{
atexit(cleanup);
+ if (!glfwInit()) {
+ fprintf(stderr, "Failed to initialize GLFW.\n");
+ return 1;
+ }
+
if (!init()) {
return 1;
}
}
}
+#if 0
+ while(!glfwWindowShouldClose(win)) {
+ display();
+
+ glfwSwapBuffers(win);
+ glfwPollEvents();
+ }
+#endif
+
return 0;
}
/* static functions */
static bool
-init(void)
+vk_init()
{
char *vsdr = 0;
char *fsdr = 0;
int vsz, fsz;
- /* initialize GLFW */
-
- if (!glfwInit()) {
- fprintf(stderr, "Failed to initialize GLFW.\n");
- return false;
- }
-
if (glfwVulkanSupported() != GLFW_TRUE) {
fprintf(stderr, "Vulkan is not supported on this device.\n");
return false;
/* set GLFW callbacks */
- /* glfwSetWindowSizeCallback(win, clb_reshape); */
+ glfwSetWindowSizeCallback(win, clb_reshape);
- /*
glfwSetCursorPosCallback(win, clb_motion);
glfwSetMouseButtonCallback(win, clb_mouse);
- */
return true;
return false;
}
+static bool
+init()
+{
+ if (!vk_init()) {
+ fprintf(stderr, "Failed to initialize Vulkan structs.\n");
+ return false;
+ }
+
+ camera = new OrbitCamera;
+ return true;
+}
+
static void
-display(void)
+cleanup()
+{
+ vk_cleanup();
+}
+
+static void
+display()
{
uint32_t img_idx;
VkSubmitInfo sinfo;
}
static void
-cleanup(void)
+vk_cleanup()
{
vkQueueWaitIdle(vk_core.queue);
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(win, GLFW_TRUE);
return;
+ case ' ':
+ move_camera = !move_camera;
+ break;
+ default:
+ break;
}
}
}
static void
-clb_reshape(GLFWwindow *win, int width, int height)
+clb_reshape(GLFWwindow *win,
+ int width,
+ int height)
+{
+}
+
+static double prev_x, prev_y;
+static bool button[8];
+
+static void
+clb_motion(GLFWwindow *win,
+ double x,
+ double y)
+{
+ double dx = x - prev_x;
+ double dy = y - prev_y;
+
+ prev_x = x;
+ prev_y = y;
+
+ if(button[0]) {
+ cam_theta += dx * 0.5;
+ cam_phi += dy * 0.5;
+
+ if(cam_phi < 0)
+ cam_phi = 0;
+ if(cam_phi > 90)
+ cam_phi = 90;
+ }
+
+ if(button[1]) {
+ cam_dist += dy * 0.1;
+ if(cam_dist < 0.0) {
+ cam_dist = 0.0;
+ }
+ }
+}
+
+static void
+clb_mouse(GLFWwindow *win,
+ int button,
+ int action,
+ int mods)
{
}