diff options
Diffstat (limited to 'height-map-display/src')
-rw-r--r-- | height-map-display/src/main.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/height-map-display/src/main.c b/height-map-display/src/main.c new file mode 100644 index 0000000..5ad5c78 --- /dev/null +++ b/height-map-display/src/main.c @@ -0,0 +1,185 @@ +#include <GL/glew.h> // must come before glfw3 +#include <GLFW/glfw3.h> +#include <stdio.h> +#include <math.h> + +#define MAP_HEIGHT 10 +#define MAP_WIDTH 10 + +int height_map[MAP_WIDTH][MAP_HEIGHT] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 3, 3, 3, 3, 3, 3, 1, 0}, + {0, 1, 3, 5, 5, 5, 5, 3, 1, 0}, + {0, 1, 3, 5, 8, 8, 5, 3, 1, 0}, + {0, 1, 3, 5, 8, 8, 5, 3, 1, 0}, + {0, 1, 3, 5, 5, 5, 5, 3, 1, 0}, + {0, 1, 3, 3, 3, 3, 3, 3, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +// TODO: move into dedicated camera struct +// Define the perspective projection matrix +void perspective(float fov, float aspect, float near, float far, float *mat) { + float f = 1.0f / tan(fov * 0.5f); + mat[0] = f / aspect; + mat[1] = 0.0f; + mat[2] = 0.0f; + mat[3] = 0.0f; + mat[4] = 0.0f; + mat[5] = f; + mat[6] = 0.0f; + mat[7] = 0.0f; + mat[8] = 0.0f; + mat[9] = 0.0f; + mat[10] = (far + near) / (near - far); + mat[11] = -1.0f; + mat[12] = 0.0f; + mat[13] = 0.0f; + mat[14] = (2.0f * far * near) / (near - far); + mat[15] = 0.0f; +} + +float camera_pos_x = 0.0f; +float camera_pos_y = 0.0f; +float camera_pos_z = 0.0f; +float camera_yaw = 0.0f; // rotation around y-axis +float camera_pitch = 0.0f; // rotation aroudn x-axis + +void renderHeightMap() { + float colors[3][3] = { + {0.0f, 1.0f, 0.0f}, // Green + {0.5f, 0.5f, 0.5f}, // Gray + {1.0f, 1.0f, 1.0f} // White + }; + + float scale_factor = 1.0f; + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(-camera_pos_x, -camera_pos_y, -camera_pos_z); + glRotatef(-camera_pitch, 1.0f, 0.0f, 0.0f); + glRotatef(-camera_yaw, 0.0f, 1.0f, 0.0f); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-10.0, 10.0, -10.0, 10.0, -20.0, 20.0); + + for (int x = 0; x < MAP_WIDTH - 1; x++) { // Adjusted loop bounds + + glBegin(GL_TRIANGLE_STRIP); + + for (int y = 0; y < MAP_HEIGHT; y++) { + + float x0 = x; + float y0 = height_map[x][y] * scale_factor; + float z0 = y; + + float x1 = x + 1; // Adjusted x1 + float y1 = height_map[x+1][y] * scale_factor; // Adjusted indexing + float z1 = y; + + float* color = colors[0]; + if (y0 < 1.0f) { color = colors[1]; } + if (y0 < 0.5f) { color = colors[2]; } + glColor3fv(color); + + glVertex3f(x0, y0, z0); + glVertex3f(x1, y1, z1); + + } + glEnd(); + + } + + // draw grid + + glColor3f(0.0f, 0.0f, 0.0f); + glLineWidth(1.0f); + glBegin(GL_LINES); + + // Draw vertical grid lines + for (int x = 0; x <= MAP_WIDTH; x++) { + for (int y = 0; y < MAP_HEIGHT; y++) { + glVertex3f(x, height_map[x][y] * scale_factor, y); + glVertex3f(x, height_map[x][y + 1] * scale_factor, y + 1); + } + } + + // Draw horizontal grid lines + for (int y = 0; y <= MAP_HEIGHT; y++) { + for (int x = 0; x < MAP_WIDTH; x++) { + glVertex3f(x, height_map[x][y] * scale_factor, y); + glVertex3f(x + 1, height_map[x + 1][y] * scale_factor, y); + } + } + + glEnd(); + +} + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + + const float camera_speed = 0.5f; + + if (key == GLFW_KEY_W && action == GLFW_PRESS) { camera_pos_z -= camera_speed; } + else if (key == GLFW_KEY_S && action == GLFW_PRESS) { camera_pos_z += camera_speed; } + else if (key == GLFW_KEY_A && action == GLFW_PRESS) { camera_pos_x -= camera_speed; } + else if (key == GLFW_KEY_D && action == GLFW_PRESS) { camera_pos_x += camera_speed; } + else if (key == GLFW_KEY_Q && action == GLFW_PRESS) { camera_pitch -= camera_speed; } + else if (key == GLFW_KEY_E && action == GLFW_PRESS) { camera_pitch += camera_speed; } + else if (key == GLFW_KEY_Z && action == GLFW_PRESS) { camera_yaw -= camera_speed; } + else if (key == GLFW_KEY_C && action == GLFW_PRESS) { camera_yaw += camera_speed; } + +} + +int main(int argc, char *argv[]) { + GLFWwindow* window; + + // initiate glfw library + if (!glfwInit()){ + printf("Failed to initiate GLFW.\n"); + return -1; + } + + // create glfw window + GLFWmonitor* primary = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(primary); + window = glfwCreateWindow(mode->width, mode->height, "raycaster", primary, NULL); + if (!window){ + printf("Failed to create GLFW window.\n"); + glfwTerminate(); + return -1; + } + + // make window current + glfwMakeContextCurrent(window); + glewExperimental = GL_TRUE; + GLenum err = glewInit(); + if (err != GLEW_OK) { + printf("GLEW init error"); + return -1; + } + + // enable depth testing + glEnable(GL_DEPTH_TEST); + + glfwSetKeyCallback(window, key_callback); + + while (!glfwWindowShouldClose(window)) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderHeightMap(); + + glfwSwapBuffers(window); // Swap buffers to display the rendered image + + // Poll for and process events, wait for events if none are pending + glfwWaitEventsTimeout(0.01); // Add a slight delay to reduce CPU usage + } + + printf("Terminating GLFW...\n"); + glfwTerminate(); + return 0; +} |