summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2020-05-22 15:19:55 -0500
committersanine-a <sanine.not@pm.me>2020-05-22 15:19:55 -0500
commite02ac3c921d816945324f1a887a0ed1db12f342e (patch)
tree125ce51b1038b786810a1fcb7cf7f536369350ae
parent5379b4214696e64902c5e10b3d4ef3d503fddcc4 (diff)
create basic honey_camera
-rw-r--r--CMakeLists.txt2
-rw-r--r--demo.c107
-rw-r--r--demo.fs4
-rw-r--r--include/camera.h93
-rw-r--r--include/honey.h1
-rw-r--r--include/shader.h2
-rw-r--r--src/camera.c137
-rw-r--r--src/honey.c4
-rw-r--r--src/shader.c4
-rw-r--r--src/texture.c2
10 files changed, 301 insertions, 55 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9222cc3..a0f9d68 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ add_executable(honey_engine_demo demo.c)
set(CMAKE_C_FLAGS "-g")
-add_library(honey src/honey.c src/mesh.c src/primitives.c src/shader.c src/texture.c)
+add_library(honey src/honey.c src/camera.c src/mesh.c src/primitives.c src/shader.c src/texture.c)
add_library(glad src/glad.c)
add_library(stb_image src/stb_image.c)
diff --git a/demo.c b/demo.c
index e2ef74a..d7df41b 100644
--- a/demo.c
+++ b/demo.c
@@ -5,14 +5,9 @@ honey_window window;
unsigned int screen_width = 640;
unsigned int screen_height = 480;
-vec3 cameraPosition, cameraFacing, cameraUp;
-
-vec3 cameraPosition = { 0, 0, 3 };
-vec3 cameraFacing = { 0, 0, -1 };
-vec3 cameraUp = { 0, 1, 0 };
-float cameraSpeed = 2.0;
-float cameraPitch = 0;
-float cameraYaw = 0;
+honey_camera camera;
+float cameraSpeed = 3.0;
+float camera_roll_speed = 1.0;
const float cameraMouseSensitivity = 0.1;
honey_mesh cube;
@@ -51,24 +46,31 @@ void mouseCallback(GLFWwindow* window, double x, double y) {
xOffset *= cameraMouseSensitivity;
yOffset *= cameraMouseSensitivity;
- cameraYaw += xOffset;
- cameraPitch -= yOffset;
+ float yaw = glm_deg(camera.angle[1]) + xOffset;
+ float pitch = glm_deg(camera.angle[0]) - yOffset;
- if (cameraPitch > 89) { cameraPitch = 89; }
- if (cameraPitch < -89) { cameraPitch = -89; }
+ if (pitch > 89) { pitch = 89; }
+ if (pitch < -89) { pitch = -89; }
- cameraFacing[0] = cos(glm_rad(cameraYaw))*cos(glm_rad(cameraPitch));
- cameraFacing[1] = sin(glm_rad(cameraPitch));
- cameraFacing[2] = sin(glm_rad(cameraYaw)) * cos(glm_rad(cameraPitch));
- glm_vec3_normalize(cameraFacing);
+ camera.angle[0] = glm_rad(pitch);
+ camera.angle[1] = glm_rad(yaw);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+void print_vec3(vec3 v) {
+ printf("(%f, %f, %f)\n", v[0], v[1], v[2]);
+}
+
void update(float dt) {
glfwPollEvents();
- glm_rotate_x(model, glm_rad(10*dt), model);
+ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+ print_vec3(camera.look_direction);
+ print_vec3(camera.up);
+ print_vec3(camera.right);
+
+ //glm_rotate_x(model, glm_rad(10*dt), model);
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
@@ -85,28 +87,31 @@ void update(float dt) {
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
vec3 step;
- glm_vec3_scale(cameraFacing, cameraSpeed*dt, step);
- glm_vec3_add(cameraPosition, step, cameraPosition);
+ glm_vec3_scale(camera.look_direction, cameraSpeed*dt, step);
+ glm_vec3_add(camera.position, step, camera.position);
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
vec3 step;
- glm_vec3_scale(cameraFacing, -cameraSpeed*dt, step);
- glm_vec3_add(cameraPosition, step, cameraPosition);
+ glm_vec3_scale(camera.look_direction, -cameraSpeed*dt, step);
+ glm_vec3_add(camera.position, step, camera.position);
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
- vec3 direction, step;
- glm_vec3_cross(cameraFacing, cameraUp, direction);
- glm_vec3_normalize(direction);
- glm_vec3_scale(direction, -cameraSpeed*dt, step);
- glm_vec3_add(cameraPosition, step, cameraPosition);
+ vec3 step;
+ glm_vec3_scale(camera.right, cameraSpeed*dt, step);
+ glm_vec3_add(camera.position, step, camera.position);
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
- vec3 direction, step;
- glm_vec3_cross(cameraFacing, cameraUp, direction);
- glm_vec3_normalize(direction);
- glm_vec3_scale(direction, cameraSpeed*dt, step);
- glm_vec3_add(cameraPosition, step, cameraPosition);
+ vec3 step;
+ glm_vec3_scale(camera.right, -cameraSpeed*dt, step);
+ glm_vec3_add(camera.position, step, camera.position);
+ }
+ if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {
+ camera.angle[2] += camera_roll_speed*dt;
}
+ if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
+ camera.angle[2] -= camera_roll_speed*dt;
+ }
+
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -122,20 +127,16 @@ void draw() {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
- glm_perspective_default(((float)screen_width)/screen_height, projection);
- honey_shader_set_matrix_4fv(shader, "projection", (float*) projection);
-
- vec3 cameraDirection;
- glm_vec3_add(cameraPosition, cameraFacing, cameraDirection);
- glm_lookat(cameraPosition, cameraDirection, cameraUp, view);
- honey_shader_set_matrix_4fv(shader, "view", (float*) view);
+ honey_camera_calculate_view(&camera);
+ honey_shader_set_mat4(shader, "view", camera.view);
- honey_shader_set_matrix_4fv(shader, "model", (float*) model);
+ honey_shader_set_mat4(shader, "model", model);
honey_texture_use(container, 0);
honey_texture_use(happy_face, 1);
honey_mesh_draw(cube, shader);
+ honey_mesh_draw(cube, shader);
glfwSwapBuffers(window);
}
@@ -171,16 +172,24 @@ int main() {
honey_shader_set_int(shader, "happy_texture", 1);
glm_mat4_identity(model);
- glm_rotate_x(model, glm_rad(-55), model);
- honey_shader_set_matrix_4fv(shader, "model", (float*) model);
-
- glm_lookat(cameraPosition, cameraFacing, cameraUp, view);
- honey_shader_set_matrix_4fv(shader, "view", (float*) view);
-
- glm_mat4_identity(projection);
- /* glm_perspective(glm_rad(90), float(screen_width)/screen_height, 0.1, 100); */
- glm_perspective_default(((float)screen_width)/screen_height, projection);
- honey_shader_set_matrix_4fv(shader, "projection", (float*) projection);
+ //glm_rotate_x(model, glm_rad(-55), model);
+ honey_shader_set_mat4(shader, "model", model);
+
+ vec3 camera_pos = { 4, 0, 0 };
+ vec3 camera_angle = { 0, glm_rad(180), 0 };
+ float camera_near = 0.1;
+ float camera_far = 100;
+ float camera_fov = glm_rad(45);
+ float camera_aspect_ratio = ((float) screen_width)/screen_height;
+ honey_camera_new_perspective(&camera,
+ camera_pos,
+ camera_angle,
+ camera_aspect_ratio,
+ camera_near, camera_far,
+ camera_fov);
+
+ honey_shader_set_mat4(shader, "view", camera.view);
+ honey_shader_set_mat4(shader, "projection", camera.projection);
glEnable(GL_DEPTH_TEST);
diff --git a/demo.fs b/demo.fs
index 84ed0fd..03159de 100644
--- a/demo.fs
+++ b/demo.fs
@@ -9,5 +9,7 @@ out vec4 FragColor;
void main()
{
- FragColor = mix(texture(box_texture, texture_coordinate), texture(happy_texture, vec2(1,1)-texture_coordinate), 0.2);
+ FragColor = mix(texture(box_texture, texture_coordinate),
+ vec4(texture(happy_texture, texture_coordinate).xyz, 1.0),
+ 0.2);
}
diff --git a/include/camera.h b/include/camera.h
new file mode 100644
index 0000000..983dae8
--- /dev/null
+++ b/include/camera.h
@@ -0,0 +1,93 @@
+#ifndef HONEY_CAMERA_H
+#define HONEY_CAMERA_H
+
+/* @file camera.h
+ *
+ * @brief Define the basic honey_camera struct, associated functions,
+ * and common camera variants.
+ */
+
+#include "common.h"
+
+enum honey_camera_projection {
+ HONEY_PERSPECTIVE,
+ HONEY_ORTHOGRAPHIC,
+};
+
+typedef struct {
+ vec3 position;
+ vec3 angle; /* pitch, yaw, roll */
+ vec3 look_direction;
+ vec3 up;
+ vec3 right;
+ mat4 view;
+ mat4 projection;
+ enum honey_camera_projection projection_type;
+ float aspect_ratio;
+ float near, far;
+ float fov;
+ float ortho_left;
+ float ortho_right;
+ float ortho_top;
+ float ortho_bottom;
+} honey_camera;
+
+/** @brief Create a new camera.
+ *
+ * @param[out] camera Pointer to the destination honey_camera.
+ * @param[in] position The position of the camera.
+ * @param[in] angle The Euler angles (pitch, yaw, roll) of the camera.
+ * @param[in] projection The type of projection to use.
+ * @param[in] projection_parameters The parameters to use for the projection matrix.
+ * Use honey_perspective_parameters for a perspective projection and
+ * honey_orthographic_parameters for an orthographic projection.
+ */
+void honey_camera_new(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ enum honey_camera_projection projection_type,
+ float aspect_ratio,
+ float near, float far,
+ float fov,
+ float left, float right, float top, float bottom);
+
+void honey_camera_new_perspective(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ float aspect_ratio,
+ float near, float far,
+ float fov);
+
+void honey_camera_new_orthographic(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ float near, float far,
+ float left, float right, float top, float bottom);
+
+/** @brief (Re-)Calculate a camera's look_direction.
+ *
+ * @param[in] Pointer to the camera to re-calculate.
+ */
+void honey_camera_calculate_look_direction(honey_camera* camera);
+
+void honey_camera_calculate_up(honey_camera* camera);
+void honey_camera_calculate_right(honey_camera* camera);
+
+/** @brief (Re-)Calculate a camera's view matrix.
+ *
+ * This function need only be called when the camera has been moved in some way.
+ *
+ * @param[in] camera Pointer to the camera to re-calculate.
+ */
+void honey_camera_calculate_view(honey_camera* camera);
+
+/** @brief (Re-)Calculate a camera's projection matrix.
+ *
+ * This function need only be called when the projection has changes in some way.
+ * Most commonly, this would be changing the FOV.
+ *
+ * @param[in] camera Pointer to the camera to re-calculate.
+ */
+void honey_camera_calculate_projection(honey_camera* camera);
+
+#endif
diff --git a/include/honey.h b/include/honey.h
index 3cddabc..3dbc5ab 100644
--- a/include/honey.h
+++ b/include/honey.h
@@ -6,6 +6,7 @@
* @brief Defines the basic loading and callback functions.
*/
+#include "camera.h"
#include "common.h"
#include "mesh.h"
#include "primitives.h"
diff --git a/include/shader.h b/include/shader.h
index 610322e..cbef3de 100644
--- a/include/shader.h
+++ b/include/shader.h
@@ -52,7 +52,7 @@ void honey_shader_set_int(honey_shader shader,
*/
void honey_shader_set_mat4(honey_shader shader,
char* matrix_name,
- float* matrix);
+ mat4 matrix);
/** @brief Use a shader.
*/
diff --git a/src/camera.c b/src/camera.c
new file mode 100644
index 0000000..95636e9
--- /dev/null
+++ b/src/camera.c
@@ -0,0 +1,137 @@
+#include "include/camera.h"
+
+void honey_camera_new(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ enum honey_camera_projection projection_type,
+ float aspect_ratio,
+ float near, float far,
+ float fov,
+ float left, float right, float top, float bottom) {
+ glm_vec3_copy(position, camera->position);
+ glm_vec3_copy(angle, camera->angle);
+
+ camera->projection_type = projection_type;
+
+ camera->aspect_ratio = aspect_ratio;
+ camera->near = near;
+ camera->far = far;
+
+ if (projection_type == HONEY_PERSPECTIVE) {
+ camera->fov = fov;
+ }
+ else if (projection_type == HONEY_ORTHOGRAPHIC) {
+ camera->ortho_left = left;
+ camera->ortho_right = right;
+ camera->ortho_top = top;
+ camera->ortho_bottom = bottom;
+ }
+
+ honey_camera_calculate_view(camera);
+ honey_camera_calculate_projection(camera);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_new_perspective(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ float aspect_ratio,
+ float near, float far,
+ float fov) {
+ honey_camera_new(camera,
+ position, angle,
+ HONEY_PERSPECTIVE,
+ aspect_ratio, near, far, fov,
+ 0, 0, 0, 0);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_new_orthographic(honey_camera* camera,
+ vec3 position,
+ vec3 angle,
+ float near, float far,
+ float left, float right, float top, float bottom) {
+ honey_camera_new(camera,
+ position, angle,
+ HONEY_ORTHOGRAPHIC,
+ 0,
+ near, far,
+ 0,
+ left, right, top, bottom);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_calculate_look_direction(honey_camera* camera) {
+ float pitch = camera->angle[0];
+ float yaw = camera->angle[1];
+
+ float x = cos(pitch) * cos(yaw);
+ float y = sin(pitch);
+ float z = cos(pitch) * sin(yaw);
+
+ camera->look_direction[0] = x;
+ camera->look_direction[1] = y;
+ camera->look_direction[2] = z;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_calculate_up(honey_camera* camera) {
+ float pitch = camera->angle[0];
+ float yaw = camera->angle[1];
+ float roll = camera->angle[2];
+
+ camera->up[0] = 0;
+ camera->up[1] = 1;
+ camera->up[2] = 0;
+
+ mat3 rot3;
+ mat4 rot4;
+ glm_mat4_identity(rot4);
+ glm_rotate(rot4, roll, camera->look_direction);
+ glm_mat4_pick3(rot4, rot3);
+
+ glm_mat3_mulv(rot3, camera->up, camera->up);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_calculate_right(honey_camera* camera) {
+ glm_vec3_cross(camera->up, camera->look_direction, camera->right);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_calculate_view(honey_camera* camera) {
+ honey_camera_calculate_look_direction(camera);
+ honey_camera_calculate_up(camera);
+ honey_camera_calculate_right(camera);
+
+ glm_look(camera->position, camera->look_direction, camera->up, camera->view);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+void honey_camera_calculate_projection(honey_camera* camera) {
+ if (camera->projection_type == HONEY_PERSPECTIVE) {
+ glm_mat4_identity(camera->projection);
+ glm_perspective(camera->fov,
+ camera->aspect_ratio,
+ camera->near,
+ camera->far,
+ camera->projection);
+ }
+ else if (camera->projection_type == HONEY_ORTHOGRAPHIC) {
+ glm_mat4_identity(camera->projection);
+ glm_ortho(camera->ortho_left,
+ camera->ortho_right,
+ camera->ortho_bottom,
+ camera->ortho_top,
+ camera->near,
+ camera->far,
+ camera->projection);
+ }
+}
diff --git a/src/honey.c b/src/honey.c
index b6f783f..e9396f1 100644
--- a/src/honey.c
+++ b/src/honey.c
@@ -28,6 +28,10 @@ honey_window honey_setup(int screen_width, int screen_height, char* window_title
return NULL;
}
+ // Enable blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
return window;
}
diff --git a/src/shader.c b/src/shader.c
index b9e13da..d726523 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -101,10 +101,10 @@ void honey_shader_set_int(honey_shader shader,
void honey_shader_set_mat4(honey_shader shader,
char* matrix_name,
- float* matrix) {
+ mat4 matrix) {
glUseProgram(shader);
unsigned int matrix_location = glGetUniformLocation(shader, matrix_name);
- glUniformMatrix4fv(matrix_location, 1, GL_FALSE, matrix);
+ glUniformMatrix4fv(matrix_location, 1, GL_FALSE, (float*) matrix);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
diff --git a/src/texture.c b/src/texture.c
index c1a5843..dfdbdd2 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -20,7 +20,7 @@ enum honey_texture_result honey_texture_new(honey_texture* texture,
}
if (alpha_channel) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data);