]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/interact.c
Add items
[dragonblocks_alpha.git] / src / client / interact.c
1 #include <linmath.h/linmath.h>
2 #include <stdio.h>
3 #include "client/camera.h"
4 #include "client/client_node.h"
5 #include "client/cube.h"
6 #include "client/debug_menu.h"
7 #include "client/frustum.h"
8 #include "client/gl_debug.h"
9 #include "client/gui.h"
10 #include "client/interact.h"
11 #include "client/mesh.h"
12 #include "client/raycast.h"
13 #include "client/shader.h"
14
15 struct InteractPointed interact_pointed;
16
17 static GLuint shader_prog;
18 static GLint loc_MVP;
19 static GLint loc_color;
20 static mat4x4 model;
21
22 typedef struct {
23         v3f32 position;
24 } __attribute__((packed)) SelectionVertex;
25 static Mesh selection_mesh = {
26         .layout = &(VertexLayout) {
27                 .attributes = (VertexAttribute[]) {
28                         {GL_FLOAT, 3, sizeof(v3f32)},
29                 },
30                 .count = 1,
31                 .size = sizeof(SelectionVertex),
32         },
33         .vao = 0,
34         .vbo = 0,
35         .data = NULL,
36         .count = 36,
37         .free_data = false,
38 };
39
40 bool interact_init()
41 {
42         if (!shader_program_create(RESSOURCE_PATH "shaders/3d/selection", &shader_prog, NULL)) {
43                 fprintf(stderr, "[error] failed to create selection shader program\n");
44                 return false;
45         }
46
47         loc_MVP = glGetUniformLocation(shader_prog, "MVP"); GL_DEBUG
48         loc_color = glGetUniformLocation(shader_prog, "color"); GL_DEBUG
49
50         SelectionVertex vertices[6][6];
51         for (int f = 0; f < 6; f++)
52                 for (int v = 0; v < 6; v++)
53                         vertices[f][v].position = v3f32_scale(cube_vertices[f][v].position, 1.1f);
54
55         selection_mesh.data = vertices;
56         mesh_upload(&selection_mesh);
57
58         gui_add(NULL, (GUIElementDef) {
59                 .pos = {0.5f, 0.5f},
60                 .z_index = 0.0f,
61                 .offset = {0, 0},
62                 .margin = {0, 0},
63                 .align = {0.5f, 0.5f},
64                 .scale = {1.0f, 1.0f},
65                 .scale_type = SCALE_IMAGE,
66                 .affect_parent_scale = false,
67                 .text = NULL,
68                 .image = texture_load(RESSOURCE_PATH "textures/crosshair.png", false),
69                 .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
70                 .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
71         });
72
73         return true;
74 }
75
76 void interact_deinit()
77 {
78         glDeleteProgram(shader_prog); GL_DEBUG
79         mesh_destroy(&selection_mesh);
80 }
81
82 void interact_tick()
83 {
84         bool old_exists = interact_pointed.exists;
85         v3s32 old_pointed = interact_pointed.pos;
86         if ((interact_pointed.exists = raycast(
87                                 (v3f64) {camera.eye  [0], camera.eye  [1], camera.eye  [2]}, 
88                                 (v3f64) {camera.front[0], camera.front[1], camera.front[2]},
89                                 5, &interact_pointed.pos, &interact_pointed.node)) 
90                         && !v3s32_equals(interact_pointed.pos, old_pointed)) {
91                 mat4x4_translate(model,
92                         interact_pointed.pos.x, interact_pointed.pos.y, interact_pointed.pos.z);
93                 v3f32 *color = &client_node_defs[interact_pointed.node].selection_color;
94                 glProgramUniform3f(shader_prog, loc_color, color->x, color->y, color->z); GL_DEBUG
95                 debug_menu_changed(ENTRY_POINTED);
96         }
97
98         if (old_exists && !interact_pointed.exists)
99                 debug_menu_changed(ENTRY_POINTED);      
100 }
101
102 void interact_render()
103 {
104         if (!interact_pointed.exists)
105                 return;
106
107         mat4x4 mvp;
108         mat4x4_mul(mvp, frustum, model);
109
110         glUseProgram(shader_prog); GL_DEBUG
111         glUniformMatrix4fv(loc_MVP, 1, GL_FALSE, mvp[0]); GL_DEBUG
112         mesh_render(&selection_mesh);
113 }