#include "block.h" #include "_internal/private_block.h" #include "texture_atlas_mapper.h" /** * Retrieves the rendering data and metadata for a specific block identifier. * * This function acts as a safe accessor for the global block library. It * performs bounds checking on the provided identifier to ensure it exists * within the library's memory range. If the identifier is invalid or * out of bounds, it returns the data for 'block_air' as a safe default * to prevent segmentation faults or undefined rendering behavior. * * @param id_to_look_up The unique identifier of the block to retrieve. * @return The rendering data structure corresponding to the block identifier. */ block_render_data_struct get_block_data(block_id_struct id_to_look_up) { if (id_to_look_up < 0 || id_to_look_up >= block_type_count) { return _block_library[block_air]; } return _block_library[id_to_look_up]; } /** * Calculates the texture coordinates (UVs) for a specific face of a block. * This function maps a block's texture index to a 2D position within a 16x16 * texture atlas and handles the V-axis inversion required for OpenGL. */ void get_block_face_texture_coordinates(block_id_struct block_id, int32_t face_direction, float texture_coordinates[4][2]) { const int32_t texture_atlas_size = 16; int32_t texture_index = 0; /* Retrieve the specific texture index for the requested face */ switch (face_direction) { case face_top: texture_index = get_block_data(block_id).texture.top; break; case face_bottom: texture_index = get_block_data(block_id).texture.bottom; break; case face_front: texture_index = get_block_data(block_id).texture.front; break; case face_back: texture_index = get_block_data(block_id).texture.back; break; case face_left: texture_index = get_block_data(block_id).texture.left; break; case face_right: texture_index = get_block_data(block_id).texture.right; break; } /* Determine the grid position within the atlas */ const int32_t atlas_column = texture_index % texture_atlas_size; const int32_t atlas_row = texture_index / texture_atlas_size; /* Calculate the normalized coordinate steps */ const float coordinate_step = 1.0f / (float)texture_atlas_size; const float horizontal_start = (float)atlas_column * coordinate_step; const float vertical_start = (float)atlas_row * coordinate_step; /* Invert the vertical axis to align with OpenGL's bottom-left origin */ const float vertical_minimum = 1.0f - (vertical_start + coordinate_step); const float vertical_maximum = 1.0f - vertical_start; const float horizontal_end = horizontal_start + coordinate_step; /* Assign coordinates to the four vertices of the face quad */ // Top-Left vertex texture_coordinates[0][0] = horizontal_start; texture_coordinates[0][1] = vertical_maximum; // Top-Right vertex texture_coordinates[1][0] = horizontal_end; texture_coordinates[1][1] = vertical_maximum; // Bottom-Right vertex texture_coordinates[2][0] = horizontal_end; texture_coordinates[2][1] = vertical_minimum; // Bottom-Left vertex texture_coordinates[3][0] = horizontal_start; texture_coordinates[3][1] = vertical_minimum; }