Files
2026-03-26 14:46:39 -05:00

95 lines
3.8 KiB
C

#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;
}