1 #include <asprintf/asprintf.h>
4 #include "client/client_config.h"
5 #include "client/client_inventory.h"
6 #include "client/client_item.h"
7 #include "client/gl_debug.h"
8 #include "client/frustum.h"
9 #include "client/light.h"
10 #include "client/shader.h"
12 static GLuint _3d_shader_prog;
13 static GLint _3d_loc_VP;
14 static GLint _3d_loc_depthOffset;
15 static ModelShader _3d_model_shader;
16 static LightShader _3d_light_shader;
18 bool client_inventory_init()
21 asprintf(&_3d_shader_def, "#define VIEW_DISTANCE %lf\n", client_config.view_distance);
23 if (!shader_program_create(RESSOURCE_PATH "shaders/3d/item", &_3d_shader_prog, _3d_shader_def)) {
24 fprintf(stderr, "[error] failed to create 3D item shader program\n");
30 _3d_loc_VP = glGetUniformLocation(_3d_shader_prog, "VP");
31 _3d_loc_depthOffset = glGetUniformLocation(_3d_shader_prog, "depthOffset");
33 _3d_model_shader.prog = _3d_shader_prog;
34 _3d_model_shader.loc_transform = glGetUniformLocation(_3d_shader_prog, "model"); GL_DEBUG
36 _3d_light_shader.prog = _3d_shader_prog;
37 light_shader_locate(&_3d_light_shader);
39 client_inventory_depth_offset(0.0f);
44 void client_inventory_deinit()
46 glDeleteProgram(_3d_shader_prog); GL_DEBUG
49 void client_inventory_update()
51 glProgramUniformMatrix4fv(_3d_shader_prog, _3d_loc_VP, 1, GL_FALSE, frustum[0]); GL_DEBUG
52 light_shader_update(&_3d_light_shader);
55 void client_inventory_depth_offset(f32 offset)
57 glProgramUniform1f(_3d_shader_prog, _3d_loc_depthOffset, offset);
60 static void wield_init(ModelNode *hand)
63 model_node_add_mesh(hand, &(ModelMesh) {
67 .shader = &_3d_model_shader,
71 static void wield_update(ModelNode *hand, ModelNode *arm, ItemType item)
73 Mesh *mesh = client_item_mesh(item);
76 ((ModelMesh *) hand->meshes.ptr)[0].mesh = mesh;
79 arm->rot.x = mesh ? -M_PI / 8.0 : 0.0;
80 model_node_transform(arm);
84 void client_inventory_init_player(ClientEntity *entity)
86 ClientPlayerData *data = entity->extra;
88 pthread_mutex_init(&data->mtx_inv, NULL);
90 item_stack_initialize(&data->inventory.left);
91 item_stack_initialize(&data->inventory.right);
93 wield_init(data->bones.hand_left);
94 wield_init(data->bones.hand_right);
97 void client_inventory_deinit_player(ClientEntity *entity)
99 ClientPlayerData *data = entity->extra;
101 pthread_mutex_destroy(&data->mtx_inv);
103 item_stack_destroy(&data->inventory.left);
104 item_stack_destroy(&data->inventory.right);
107 void client_inventory_update_player(__attribute__((unused)) void *peer, ToClientPlayerInventory *pkt)
109 ClientEntity *entity = client_player_entity(pkt->id);
113 ClientPlayerData *data = entity->extra;
114 pthread_mutex_lock(&data->mtx_inv);
116 item_stack_deserialize(&data->inventory.left, &pkt->left);
117 item_stack_deserialize(&data->inventory.right, &pkt->right);
119 wield_update(data->bones.hand_left, data->bones.arm_left, data->inventory.left.type);
120 wield_update(data->bones.hand_right, data->bones.arm_right, data->inventory.right.type);
122 pthread_mutex_unlock(&data->mtx_inv);
123 refcount_drp(&entity->rc);