#include // must come before glfw3 #include #include #include #include #include #include "map/node.h" #include "map/square.h" #define MAP_HEIGHT 10 #define MAP_WIDTH 10 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 bool draw_grid = true; // Renderer void renderHeightMap(Node ***nodes) { printf("Init colors...\n"); float colors[3][3] = { {0.0f, 1.0f, 0.0f}, // fairway green {0.5f, 1.0f, 0.5f}, // light green {0.0f, 0.5f, 0.0f}, // fairway green }; float scale_factor = 1.0f; printf("Init perspective...\n"); 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); printf("Init rendering...\n"); 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 = nodes[x][y]->elevation * scale_factor; float z0 = y; float x1 = x + 1; // Adjusted x1 float y1 = nodes[x+1][y]->elevation * scale_factor; // Adjusted indexing float z1 = y; float* color = colors[0]; if (y0 > 0.5f) { color = colors[2]; } if (y0 < -0.5f) { color = colors[1]; } glColor3fv(color); glVertex3f(x0, y0, z0); glVertex3f(x1, y1, z1); } glEnd(); } // draw grid printf("Init grid...\n"); if(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 - 1; x++) { for (int y = 0; y < MAP_HEIGHT - 1; y++) { glVertex3f(x, nodes[x][y]->elevation * scale_factor, y); glVertex3f(x, nodes[x][y + 1]->elevation * scale_factor, y + 1); } } // Draw horizontal grid lines for (int y = 0; y <= MAP_HEIGHT - 1; y++) { for (int x = 0; x < MAP_WIDTH - 1; x++) { glVertex3f(x, nodes[x][y]->elevation * scale_factor, y); glVertex3f(x + 1, nodes[x + 1][y]->elevation * scale_factor, y); } } } printf("Init end...\n"); glEnd(); } // Function to initialize nodes Node*** initialize_nodes(int X, int Y) { Node ***nodes = (Node ***)malloc(X * sizeof(Node **)); for (int i = 0; i < X; i++) { nodes[i] = (Node **)malloc(Y * sizeof(Node *)); for (int j = 0; j < Y; j++) { // Allocate memory for each Node nodes[i][j] = (Node *)malloc(sizeof(Node)); nodes[i][j]->x = i; nodes[i][j]->y = j; nodes[i][j]->elevation = 0.0f; } } return nodes; } // Function to initialize squares Square** initialize_squares(Node ***nodes, int X, int Y) { Square **squares = (Square **)malloc((X - 1) * sizeof(Square *)); for (int i = 0; i < X - 1; i++) { squares[i] = (Square *)malloc((Y - 1) * sizeof(Square)); for (int j = 0; j < Y - 1; j++) { // Assign pointers to nodes to create the Square squares[i][j].nodes[0] = nodes[i][j]; squares[i][j].nodes[1] = nodes[i][j+1]; squares[i][j].nodes[2] = nodes[i+1][j]; squares[i][j].nodes[3] = nodes[i+1][j+1]; squares[i][j].terrain = TERRAIN_ROUGH; } } return squares; } // TODO: Move into dedicated cleaner header // Function to free memory allocated for nodes void free_nodes(Node ***nodes, int X, int Y) { for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { free(nodes[i][j]); } free(nodes[i]); } free(nodes); } // TODO: Move into dedicated cleaner header // Function to free memory allocated for squares void free_squares(Square **squares, int X) { for (int i = 0; i < X - 1; i++) { free(squares[i]); } free(squares); } int main(int argc, char *argv[]) { printf("Initializing window...\n"); GLFWwindow* window; // initiate glfw library if (!glfwInit()){ printf("Failed to initiate GLFW.\n"); return -1; } // create glfw window printf("Creating window...\n"); 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 printf("Making window current...\n"); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; GLenum err = glewInit(); if (err != GLEW_OK) { printf("GLEW init error"); return -1; } glEnable(GL_DEPTH_TEST); // init grid and squares printf("Initializing nodes...\n"); Node ***nodes = initialize_nodes(MAP_WIDTH, MAP_HEIGHT); printf("Initializing squares...\n"); Square **squares = initialize_squares(nodes, MAP_WIDTH, MAP_HEIGHT); while (!glfwWindowShouldClose(window)) { printf("Entering main loop...\n"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); printf("Rendering...\n"); renderHeightMap(nodes); 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(); free_nodes(nodes, MAP_WIDTH, MAP_HEIGHT); free_squares(squares, MAP_WIDTH); return 0; }