95 lines
3.8 KiB
C
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;
|
|
}
|