]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/client_inventory.c
Rework structure
[dragonblocks_alpha.git] / src / client / client_inventory.c
1 #include <asprintf.h>
2 #include <stdio.h>
3 #include <stdlib.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"
11
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;
17
18 void client_inventory_init()
19 {
20         char *_3d_shader_def;
21         asprintf(&_3d_shader_def, "#define VIEW_DISTANCE %lf\n", client_config.view_distance);
22         _3d_shader_prog = shader_program_create(ASSET_PATH "shaders/3d/item", _3d_shader_def);
23         free(_3d_shader_def);
24
25         _3d_loc_VP = glGetUniformLocation(_3d_shader_prog, "VP");
26         _3d_loc_depthOffset = glGetUniformLocation(_3d_shader_prog, "depthOffset");
27
28         _3d_model_shader.prog = _3d_shader_prog;
29         _3d_model_shader.loc_transform = glGetUniformLocation(_3d_shader_prog, "model"); GL_DEBUG
30
31         _3d_light_shader.prog = _3d_shader_prog;
32         light_shader_locate(&_3d_light_shader);
33
34         client_inventory_depth_offset(0.0f);
35 }
36
37 void client_inventory_deinit()
38 {
39         glDeleteProgram(_3d_shader_prog); GL_DEBUG
40 }
41
42 void client_inventory_update()
43 {
44         glProgramUniformMatrix4fv(_3d_shader_prog, _3d_loc_VP, 1, GL_FALSE, frustum[0]); GL_DEBUG
45         light_shader_update(&_3d_light_shader);
46 }
47
48 void client_inventory_depth_offset(f32 offset)
49 {
50         glProgramUniform1f(_3d_shader_prog, _3d_loc_depthOffset, offset);
51 }
52
53 static void wield_init(ModelNode *hand)
54 {
55         if (hand)
56                 model_node_add_mesh(hand, &(ModelMesh) {
57                         .mesh = NULL,
58                         .textures = NULL,
59                         .num_textures = 0,
60                         .shader = &_3d_model_shader,
61                 });
62 }
63
64 static void wield_update(ModelNode *hand, ModelNode *arm, ItemType item)
65 {
66         Mesh *mesh = client_item_mesh(item);
67
68         if (hand)
69                 ((ModelMesh *) hand->meshes.ptr)[0].mesh = mesh;
70
71         if (arm) {
72                 arm->rot.x = mesh ? -M_PI / 8.0 : 0.0;
73                 model_node_transform(arm);
74         }
75 }
76
77 void client_inventory_init_player(ClientEntity *entity)
78 {
79         ClientPlayerData *data = entity->extra;
80
81         pthread_mutex_init(&data->mtx_inv, NULL);
82
83         item_stack_initialize(&data->inventory.left);
84         item_stack_initialize(&data->inventory.right);
85
86         wield_init(data->bones.hand_left);
87         wield_init(data->bones.hand_right);
88 }
89
90 void client_inventory_deinit_player(ClientEntity *entity)
91 {
92         ClientPlayerData *data = entity->extra;
93
94         pthread_mutex_destroy(&data->mtx_inv);
95
96         item_stack_destroy(&data->inventory.left);
97         item_stack_destroy(&data->inventory.right);
98 }
99
100 void client_inventory_update_player(__attribute__((unused)) void *peer, ToClientPlayerInventory *pkt)
101 {
102         ClientEntity *entity = client_player_entity(pkt->id);
103         if (!entity)
104                 return;
105
106         ClientPlayerData *data = entity->extra;
107         pthread_mutex_lock(&data->mtx_inv);
108
109         item_stack_deserialize(&data->inventory.left, &pkt->left);
110         item_stack_deserialize(&data->inventory.right, &pkt->right);
111
112         wield_update(data->bones.hand_left,  data->bones.arm_left,  data->inventory.left.type);
113         wield_update(data->bones.hand_right, data->bones.arm_right, data->inventory.right.type);
114
115         pthread_mutex_unlock(&data->mtx_inv);
116         refcount_drp(&entity->rc);
117 }