]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
You can now see other players
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 17 Apr 2022 11:35:41 +0000 (13:35 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 17 Apr 2022 11:35:41 +0000 (13:35 +0200)
77 files changed:
models/player.txt
shaders/3d/entity/fragment.glsl [new file with mode: 0755]
shaders/3d/entity/vertex.glsl [new file with mode: 0755]
shaders/3d/terrain/fragment.glsl [new file with mode: 0755]
shaders/3d/terrain/vertex.glsl [new file with mode: 0755]
shaders/gui/font/fragment.glsl
shaders/gui/font/vertex.glsl
shaders/gui/image/fragment.glsl
shaders/gui/image/vertex.glsl
shaders/sky/clouds/fragment.glsl
shaders/sky/clouds/vertex.glsl
shaders/sky/skybox/fragment.glsl
shaders/sky/skybox/vertex.glsl
shaders/sky/sun/fragment.glsl
shaders/sky/sun/vertex.glsl
shaders/terrain/fragment.glsl [deleted file]
shaders/terrain/vertex.glsl [deleted file]
snapshot.sh
src/CMakeLists.txt
src/client/client.c
src/client/client_entity.c
src/client/client_entity.h
src/client/client_player.c
src/client/client_player.h
src/client/client_terrain.c
src/client/debug_menu.c
src/client/font.c
src/client/game.c
src/client/gl_debug.c [new file with mode: 0644]
src/client/gl_debug.h [new file with mode: 0644]
src/client/gui.c
src/client/gui.h
src/client/input.c
src/client/light.c [new file with mode: 0644]
src/client/light.h [new file with mode: 0644]
src/client/mesh.c
src/client/model.c
src/client/model.h
src/client/shader.c
src/client/sky.c
src/client/terrain_gfx.c
src/client/texture.c
src/client/window.c
src/debug.sh
src/server/schematic.c
src/server/server.c
src/server/server_player.c
src/server/server_player.h
src/server/server_terrain.c
src/server/voxelctx.c
src/terrain.c
src/types.def
src/version.cmake
textures/models/player/arm/back.png
textures/models/player/arm/bottom.png
textures/models/player/arm/front.png
textures/models/player/arm/left.png
textures/models/player/arm/right.png
textures/models/player/arm/top.png
textures/models/player/chest/back.png
textures/models/player/chest/bottom.png
textures/models/player/chest/front.png
textures/models/player/chest/left.png
textures/models/player/chest/right.png
textures/models/player/chest/top.png
textures/models/player/head/back.png
textures/models/player/head/bottom.png
textures/models/player/head/front.png
textures/models/player/head/left.png
textures/models/player/head/right.png
textures/models/player/head/top.png
textures/models/player/leg/back.png
textures/models/player/leg/bottom.png
textures/models/player/leg/front.png
textures/models/player/leg/left.png
textures/models/player/leg/right.png
textures/models/player/leg/top.png

index 0fe8485d79f91cd096463edbeaac70f7d828eb7a..ee482f86fd28ba931f07e730d051ad4485b03008 100644 (file)
@@ -1,7 +1,10 @@
 name player scale 1 1.8 1
-       name head pos 0 0.875 0 scale 0.45 0.25 0.45 cube head
-       name body scale 0.48 0.75 0.36
-               name upper pos 0 1.0 0 scale 1 0.5 1 
+       name nametag pos 0 1.1 0
+       name neck pos 0 0.75 0 scale 0.45 0.25 0.45
+               name head pos 0 +0.5 0 cube head
+                       name eyes pos 0 0 +0.5
+       name body scale 0.48 0.75 0.225
+               name upper pos 0 1.0 0 scale 1 0.5 1
                        name chest pos 0 -0.5 0 cube chest
                        name shoulders scale 0.5 1 1
                                name left pos -1.5 0 0
diff --git a/shaders/3d/entity/fragment.glsl b/shaders/3d/entity/fragment.glsl
new file mode 100755 (executable)
index 0000000..2cd4768
--- /dev/null
@@ -0,0 +1,19 @@
+in vec3 fragmentPosition;
+in vec3 fragmentNormal;
+in vec3 fragmentTextureCoordinates;
+in float fragmentLight;
+
+out vec4 outColor;
+
+uniform vec3 fogColor;
+uniform vec3 cameraPos;
+uniform samplerCube texture0;
+
+void main()
+{
+       outColor = texture(texture0, fragmentTextureCoordinates) * vec4(vec3(fragmentLight), 1.0);
+       outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / VIEW_DISTANCE, 0.0, 1.0));
+
+       if (outColor.a == 0.0)
+               discard;
+}
diff --git a/shaders/3d/entity/vertex.glsl b/shaders/3d/entity/vertex.glsl
new file mode 100755 (executable)
index 0000000..ca8684a
--- /dev/null
@@ -0,0 +1,26 @@
+layout(location = 0) in vec3 vertexPosition;
+layout(location = 1) in vec3 vertexNormal;
+
+out vec3 fragmentPosition;
+out vec3 fragmentNormal;
+out vec3 fragmentTextureCoordinates;
+out float fragmentLight;
+
+uniform mat4 model;
+uniform mat4 VP;
+uniform float daylight;
+uniform float ambientLight;
+uniform vec3 lightDir;
+
+void main()
+{
+       vec4 worldSpace = model * vec4(vertexPosition, 1.0);
+       gl_Position = VP * worldSpace;
+
+       fragmentPosition = worldSpace.xyz;
+       fragmentNormal = vertexNormal;
+       fragmentTextureCoordinates = vertexPosition;
+
+       float diffuseLight = 0.3 * daylight * clamp(dot(normalize(fragmentNormal), normalize(lightDir)), 0.0, 1.0);
+       fragmentLight = ambientLight + diffuseLight;
+}
diff --git a/shaders/3d/terrain/fragment.glsl b/shaders/3d/terrain/fragment.glsl
new file mode 100755 (executable)
index 0000000..62ee89b
--- /dev/null
@@ -0,0 +1,20 @@
+in vec3 fragmentPosition;
+in vec3 fragmentNormal;
+in vec2 fragmentTextureCoordinates;
+in float fragmentTextureIndex;
+in vec3 fragmentColor;
+
+out vec4 outColor;
+
+uniform vec3 fogColor;
+uniform vec3 cameraPos;
+uniform sampler2D textures[MAX_TEXTURE_UNITS];
+
+void main()
+{
+       outColor = texture(textures[int(fragmentTextureIndex + 0.5)], fragmentTextureCoordinates) * vec4(fragmentColor, 1.0);
+       outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / VIEW_DISTANCE, 0.0, 1.0));
+
+       if (outColor.a == 0.0)
+               discard;
+}
diff --git a/shaders/3d/terrain/vertex.glsl b/shaders/3d/terrain/vertex.glsl
new file mode 100755 (executable)
index 0000000..abef047
--- /dev/null
@@ -0,0 +1,34 @@
+layout(location = 0) in vec3 vertexPosition;
+layout(location = 1) in vec3 vertexNormal;
+layout(location = 2) in vec2 vertexTextureCoordinates;
+layout(location = 3) in float vertexTextureIndex;
+layout(location = 4) in vec3 vertexColor;
+
+out vec3 fragmentPosition;
+out vec3 fragmentNormal;
+out vec2 fragmentTextureCoordinates;
+out float fragmentTextureIndex;
+out vec3 fragmentColor;
+
+uniform mat4 model;
+uniform mat4 VP;
+uniform float daylight;
+uniform float ambientLight;
+uniform vec3 lightDir;
+
+void main()
+{
+       vec4 worldSpace = model * vec4(vertexPosition, 1.0);
+       gl_Position = VP * worldSpace;
+
+       fragmentPosition = worldSpace.xyz;
+       fragmentNormal = vertexNormal;
+       fragmentTextureCoordinates = vertexTextureCoordinates;
+       fragmentTextureIndex = vertexTextureIndex;
+       fragmentColor = vertexColor;
+
+       float diffuseLight = 0.3 * daylight * clamp(dot(normalize(fragmentNormal), normalize(lightDir)), 0.0, 1.0);
+       float light = ambientLight + diffuseLight;
+
+       fragmentColor *= light;
+}
index 02f9186b1227585079132e7f1a7b1e9f04735c79..883a012f077e6475d20abfad859fd96ec0b8c1f5 100755 (executable)
@@ -1,4 +1,4 @@
-in vec2 fragmentTextureCoords;
+in vec2 fragmentTextureCoordinates;
 
 out vec4 outColor;
 
@@ -7,5 +7,5 @@ uniform vec4 color;
 
 void main()
 {
-       outColor = vec4(1.0, 1.0, 1.0, texture(texture0, fragmentTextureCoords).r) * color;
+       outColor = vec4(1.0, 1.0, 1.0, texture(texture0, fragmentTextureCoordinates).r) * color;
 }
index 3072c1b84f6cdf9320ffb0ab257325a3b36387cb..50bcd6e5cca5e4c219c1a77cdf3374104933bb6a 100644 (file)
@@ -1,7 +1,7 @@
 layout(location = 0) in vec2 vertexPosition;
-layout(location = 1) in vec2 vertexTextureCoords;
+layout(location = 1) in vec2 vertexTextureCoordinates;
 
-out vec2 fragmentTextureCoords;
+out vec2 fragmentTextureCoordinates;
 
 uniform mat4 model;
 uniform mat4 projection;
@@ -9,5 +9,5 @@ uniform mat4 projection;
 void main()
 {
        gl_Position = projection * model * vec4(vertexPosition, 0.0, 1.0);
-       fragmentTextureCoords = vertexTextureCoords;
+       fragmentTextureCoordinates = vertexTextureCoordinates;
 }
index 3cb7c7e89baa9eb5648992fe211ce620e156bd6a..bc8e428a360725761fad6c89aa564b97f0b25573 100755 (executable)
@@ -1,4 +1,4 @@
-in vec2 fragmentTextureCoords;
+in vec2 fragmentTextureCoordinates;
 
 out vec4 outColor;
 
@@ -6,5 +6,5 @@ uniform sampler2D texture0;
 
 void main()
 {
-       outColor = texture(texture0, fragmentTextureCoords);
+       outColor = texture(texture0, fragmentTextureCoordinates);
 }
index 3072c1b84f6cdf9320ffb0ab257325a3b36387cb..50bcd6e5cca5e4c219c1a77cdf3374104933bb6a 100755 (executable)
@@ -1,7 +1,7 @@
 layout(location = 0) in vec2 vertexPosition;
-layout(location = 1) in vec2 vertexTextureCoords;
+layout(location = 1) in vec2 vertexTextureCoordinates;
 
-out vec2 fragmentTextureCoords;
+out vec2 fragmentTextureCoordinates;
 
 uniform mat4 model;
 uniform mat4 projection;
@@ -9,5 +9,5 @@ uniform mat4 projection;
 void main()
 {
        gl_Position = projection * model * vec4(vertexPosition, 0.0, 1.0);
-       fragmentTextureCoords = vertexTextureCoords;
+       fragmentTextureCoordinates = vertexTextureCoordinates;
 }
index f22dc6709182d3f1b72fc9c38ee212a70270def7..32fc25b0c33e4a2b8ac0d7cc060be4c0a430e6ef 100755 (executable)
@@ -1,4 +1,4 @@
-in vec3 fragmentTextureCoords;
+in vec3 fragmentTextureCoordinates;
 
 out vec4 outColor;
 
@@ -17,13 +17,13 @@ float strengthen(float value, float exponent, float max)
 
 void main()
 {
-       float height = normalize(fragmentTextureCoords).y;
+       float height = normalize(fragmentTextureCoordinates).y;
 
        vec4 topColor = texture(texture0, vec3(0.0, 1.0, 0.0));
        vec4 bottomColor = texture(texture0, vec3(1.0, 0.11, 0.5));
        vec4 expectedColor = mix(bottomColor, topColor, height);
 
-       vec4 dayColor = texture(texture0, fragmentTextureCoords);
+       vec4 dayColor = texture(texture0, fragmentTextureCoordinates);
 
        float cloudFactor = reverseMix(length(dayColor.rg - expectedColor.rg), 0.15, length(vec2(1.0)));
 
index 6aab0416af0192c01b0649e9bdaa3ea1be2c57b8..1b361b71784a054dc6f75ec751eef0ceedfa41cd 100755 (executable)
@@ -1,6 +1,6 @@
 layout(location = 0) in vec3 vertexPosition;
 
-out vec3 fragmentTextureCoords;
+out vec3 fragmentTextureCoordinates;
 
 uniform mat4 VP;
 
@@ -8,5 +8,5 @@ void main()
 {
        gl_Position = VP * vec4(vertexPosition, 1.0);
        gl_Position.z = gl_Position.w;
-       fragmentTextureCoords = vertexPosition;
+       fragmentTextureCoordinates = vertexPosition;
 }
index ce1bac4fa2168ca15e3c34494e7f8de166e49c12..e6c61b42963a966e71482fafadfd36c0eefb4aa4 100755 (executable)
@@ -1,4 +1,4 @@
-in vec3 fragmentTextureCoords;
+in vec3 fragmentTextureCoordinates;
 
 out vec4 outColor;
 
@@ -10,8 +10,8 @@ void main()
        vec4 topColor = texture(textures[0], vec3(0.0, 1.0, 0.0));
        vec4 bottomColor = texture(textures[0], vec3(1.0, 0.11, 0.5));
 
-       vec4 dayColor = mix(bottomColor, topColor, normalize(fragmentTextureCoords).y);
-       vec4 nightColor = texture(textures[1], fragmentTextureCoords);
+       vec4 dayColor = mix(bottomColor, topColor, normalize(fragmentTextureCoordinates).y);
+       vec4 nightColor = texture(textures[1], fragmentTextureCoordinates);
 
        outColor = mix(nightColor, dayColor, daylight);
 }
index 6aab0416af0192c01b0649e9bdaa3ea1be2c57b8..1b361b71784a054dc6f75ec751eef0ceedfa41cd 100755 (executable)
@@ -1,6 +1,6 @@
 layout(location = 0) in vec3 vertexPosition;
 
-out vec3 fragmentTextureCoords;
+out vec3 fragmentTextureCoordinates;
 
 uniform mat4 VP;
 
@@ -8,5 +8,5 @@ void main()
 {
        gl_Position = VP * vec4(vertexPosition, 1.0);
        gl_Position.z = gl_Position.w;
-       fragmentTextureCoords = vertexPosition;
+       fragmentTextureCoordinates = vertexPosition;
 }
index 3cb7c7e89baa9eb5648992fe211ce620e156bd6a..bc8e428a360725761fad6c89aa564b97f0b25573 100755 (executable)
@@ -1,4 +1,4 @@
-in vec2 fragmentTextureCoords;
+in vec2 fragmentTextureCoordinates;
 
 out vec4 outColor;
 
@@ -6,5 +6,5 @@ uniform sampler2D texture0;
 
 void main()
 {
-       outColor = texture(texture0, fragmentTextureCoords);
+       outColor = texture(texture0, fragmentTextureCoordinates);
 }
index f6bf7cefc18a022e9c71fcfb19f3eeb157fb3deb..243d17fde5ce984d81a152c2c9d1d4be17bd0809 100755 (executable)
@@ -1,7 +1,7 @@
 layout(location = 0) in vec3 vertexPosition;
-layout(location = 1) in vec2 vertexTextureCoords;
+layout(location = 1) in vec2 vertexTextureCoordinates;
 
-out vec2 fragmentTextureCoords;
+out vec2 fragmentTextureCoordinates;
 
 uniform mat4 MVP;
 
@@ -9,5 +9,5 @@ void main()
 {
        gl_Position = MVP * vec4(vertexPosition, 1.0);
        gl_Position.z = gl_Position.w;
-       fragmentTextureCoords = vertexTextureCoords;
+       fragmentTextureCoordinates = vertexTextureCoordinates;
 }
diff --git a/shaders/terrain/fragment.glsl b/shaders/terrain/fragment.glsl
deleted file mode 100755 (executable)
index 533c91c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-in vec3 fragmentPosition;
-in vec3 fragmentNormal;
-in vec2 fragmentTextureCoords;
-in float fragmentTextureIndex;
-in vec3 fragmentColor;
-
-out vec4 outColor;
-
-uniform vec3 fogColor;
-uniform vec3 cameraPos;
-uniform sampler2D textures[MAX_TEXTURE_UNITS];
-
-void main()
-{
-       outColor = texture(textures[int(fragmentTextureIndex + 0.5)], fragmentTextureCoords) * vec4(fragmentColor, 1.0);
-       outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / VIEW_DISTANCE, 0.0, 1.0));
-
-       if (outColor.a == 0.0)
-               discard;
-}
diff --git a/shaders/terrain/vertex.glsl b/shaders/terrain/vertex.glsl
deleted file mode 100755 (executable)
index 7104497..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-layout(location = 0) in vec3 vertexPosition;
-layout(location = 1) in vec3 vertexNormal;
-layout(location = 2) in vec2 vertexTextureCoords;
-layout(location = 3) in float vertexTextureIndex;
-layout(location = 4) in vec3 vertexColor;
-
-out vec3 fragmentPosition;
-out vec3 fragmentNormal;
-out vec2 fragmentTextureCoords;
-out float fragmentTextureIndex;
-out vec3 fragmentColor;
-
-uniform mat4 model;
-uniform mat4 VP;
-uniform float daylight;
-uniform float ambientLight;
-uniform vec3 lightDir;
-
-void main()
-{
-       vec4 worldSpace = model * vec4(vertexPosition, 1.0);
-       gl_Position = VP * worldSpace;
-
-       fragmentPosition = worldSpace.xyz;
-       fragmentNormal = vertexNormal;
-       fragmentTextureCoords = vertexTextureCoords;
-       fragmentTextureIndex = vertexTextureIndex;
-       fragmentColor = vertexColor;
-
-       float diffuseLight = 0.3 * daylight * clamp(dot(normalize(fragmentNormal), normalize(lightDir)), 0.0, 1.0);
-       float light = ambientLight + diffuseLight;
-
-       fragmentColor *= light;
-}
index 66b6882c656541b0f059a5ff372db2edb19806e8..9c1098fc482e74c3cfdcc7c174f8753af72db74c 100755 (executable)
@@ -9,7 +9,7 @@ cp -r * .build/
 cd .build/
 mkdir build
 cd build
-if ! (cmake -B . -S ../src -DCMAKE_BUILD_TYPE=Release -DRESSOURCE_PATH="\"\"" && make clean && make -j$(nproc)); then
+if ! (cmake -B . -S ../src -DCMAKE_BUILD_TYPE=Release -DRESSOURCE_PATH="\"\"" -DCMAKE_C_FLAGS="-Ofast" && make clean && make -j$(nproc)); then
        cd ../..
        rm -rf .build
        exit 1
index 0a9c49684f374918aae85f0679d1a8bfb145400f..e8d1b542acd5808a5ff5e635e514351f38c0a06c 100644 (file)
@@ -22,6 +22,10 @@ find_package(Freetype REQUIRED)
 
 # Options
 
+if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+       add_compile_definitions("ENABLE_GL_DEBUG")
+endif()
+
 add_compile_definitions("USE_DRAGONNET")
 add_compile_definitions("RESSOURCE_PATH=\"${RESSOURCE_PATH}\"")
 
@@ -38,12 +42,12 @@ include_directories(BEFORE ${CMAKE_SOURCE_DIR})
 
 # System specific options
 
-if ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
        link_directories("/usr/local/lib")
        include_directories("/usr/local/include")
 endif()
 
-if ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
        link_directories("/usr/X11R6/lib")
        include_directories("/usr/X11R6/include")
 endif()
@@ -98,8 +102,10 @@ add_executable(dragonblocks
        client/font.c
        client/frustum.c
        client/game.c
+       client/gl_debug.c
        client/gui.c
        client/input.c
+       client/light.c
        client/mesh.c
        client/model.c
        client/shader.c
index 0dd8626a28623d056c6eda73c3ff78d459c756eb..c0160d083669113be1fbd6ff0b5e61d97a8d5db0 100644 (file)
@@ -144,7 +144,6 @@ int main(int argc, char **argv)
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityAdd          ] = (void *) &client_entity_add;
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityRemove       ] = (void *) &client_entity_remove;
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityUpdatePosRot ] = (void *) &client_entity_update_pos_rot;
-       client->on_recv_type[DRAGONNET_TYPE_ToClientEntityUpdateBoxEye ] = (void *) &client_entity_update_box_eye;
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityUpdateNametag] = (void *) &client_entity_update_nametag;
 
        flag_ini(&finish);
index 2c34b6823afcd6233444d78d8413397f2d28165f..97173e8165c847dfb7e7f985a56cb52f6e4fc2bc 100644 (file)
@@ -1,12 +1,46 @@
+#include <asprintf/asprintf.h>
 #include <dragonstd/map.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "client/cube.h"
+#include "client/client_config.h"
 #include "client/client_entity.h"
 #include "client/client_player.h"
+#include "client/frustum.h"
+#include "client/gl_debug.h"
+#include "client/light.h"
+#include "client/shader.h"
+#include "client/window.h"
 
 ClientEntityType client_entity_types[COUNT_ENTITY];
 
+ModelShader client_entity_shader;
+typedef struct {
+       v3f32 position;
+       v3f32 normal;
+} __attribute__((packed)) EntityVertex;
+Mesh client_entity_cube = {
+       .layout = &(VertexLayout) {
+               .attributes = (VertexAttribute[]) {
+                       {GL_FLOAT, 3, sizeof(v3f32)}, // position
+                       {GL_FLOAT, 3, sizeof(v3f32)}, // normal
+               },
+               .count = 2,
+               .size = sizeof(EntityVertex),
+       },
+       .vao = 0,
+       .vbo = 0,
+       .data = NULL,
+       .count = 36,
+       .free_data = false,
+};
+
+static GLuint shader_prog;
+static GLint loc_VP;
+static LightShader light_shader;
 static Map entities;
+static List nametagged;
+static pthread_mutex_t mtx_nametagged;
 
 // any thread
 // called when adding, getting or removing an entity from the map
@@ -22,6 +56,14 @@ static void entity_drop(ClientEntity *entity)
        if (entity->type->remove)
                entity->type->remove(entity);
 
+       if (entity->nametag) {
+               pthread_mutex_lock(&mtx_nametagged);
+               list_del(&nametagged, &entity->rc, &cmp_ref, &refcount_drp, NULL, NULL);
+               pthread_mutex_unlock(&mtx_nametagged);
+
+               entity->nametag->visible = false;
+       }
+
        refcount_drp(&entity->rc);
 }
 
@@ -38,17 +80,78 @@ static void entity_delete(ClientEntity *entity)
                free(entity->data.nametag);
 
        pthread_rwlock_init(&entity->lock_pos_rot, NULL);
-       pthread_rwlock_init(&entity->lock_box_eye, NULL);
        pthread_rwlock_init(&entity->lock_nametag, NULL);
+       pthread_rwlock_init(&entity->lock_box_off, NULL);
 
        free(entity);
 }
 
+static void update_nametag(ClientEntity *entity)
+{
+       if (entity->nametag) {
+               gui_text(entity->nametag, entity->data.nametag);
+
+               if (!entity->data.nametag)
+                       entity->nametag->visible = false;
+       } else if (entity->data.nametag) {
+               entity->nametag = gui_add(NULL, (GUIElementDefinition) {
+                       .pos = {-1.0f, -1.0f},
+                       .z_index = 0.1f,
+                       .offset = {0, 0},
+                       .margin = {4, 4},
+                       .align = {0.5f, 0.5f},
+                       .scale = {1.0f, 1.0f},
+                       .scale_type = SCALE_TEXT,
+                       .affect_parent_scale = false,
+                       .text = entity->data.nametag,
+                       .image = NULL,
+                       .text_color = (v4f32) {1.0f, 1.0f, 1.0f, 1.0f},
+                       .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.5f},
+               });
+
+               pthread_mutex_lock(&mtx_nametagged);
+               list_apd(&nametagged, refcount_inc(&entity->rc));
+               pthread_mutex_unlock(&mtx_nametagged);
+       }
+}
+
+static void update_nametag_pos(ClientEntity *entity)
+{
+       if (!entity->data.nametag)
+               return;
+
+       pthread_rwlock_rdlock(&entity->lock_pos_rot);
+       pthread_rwlock_rdlock(&entity->lock_box_off);
+
+       mat4x4 mvp;
+       if (entity->nametag_offset)
+               mat4x4_mul(mvp, frustum, *entity->nametag_offset);
+       else
+               mat4x4_dup(mvp, frustum);
+
+       vec4 dst, src = {0.0f, 0.0f, 0.0f, 1.0f};
+       mat4x4_mul_vec4(dst, mvp, src);
+
+       dst[0] /= dst[3];
+       dst[1] /= dst[3];
+       dst[2] /= dst[3];
+
+       if ((entity->nametag->visible = dst[2] >= -1.0f && dst[2] <= 1.0f)) {
+               entity->nametag->def.pos = (v2f32) {dst[0] * 0.5f + 0.5f, 1.0f - (dst[1] * 0.5f + 0.5f)};
+               gui_transform(entity->nametag);
+       }
+
+       pthread_rwlock_unlock(&entity->lock_box_off);
+       pthread_rwlock_unlock(&entity->lock_pos_rot);
+}
+
 // main thread
 // called on startup
 void client_entity_init()
 {
        map_ini(&entities);
+       list_ini(&nametagged);
+       pthread_mutex_init(&mtx_nametagged, NULL);
 }
 
 // main thead
@@ -57,6 +160,58 @@ void client_entity_deinit()
 {
        // forget all entities
        map_cnl(&entities, &refcount_drp, NULL, NULL, 0);
+       list_clr(&nametagged, &refcount_drp, NULL, NULL);
+       pthread_mutex_destroy(&mtx_nametagged);
+}
+
+bool client_entity_gfx_init()
+{
+       char *shader_defs;
+       asprintf(&shader_defs, "#define VIEW_DISTANCE %lf\n", client_config.view_distance);
+
+       if (!shader_program_create(RESSOURCE_PATH "shaders/3d/entity", &shader_prog, shader_defs)) {
+               fprintf(stderr, "[error] failed to create entity shader program\n");
+               return false;
+       }
+
+       free(shader_defs);
+
+       loc_VP = glGetUniformLocation(shader_prog, "VP"); GL_DEBUG
+
+       EntityVertex vertices[6][6];
+       for (int f = 0; f < 6; f++) {
+               for (int v = 0; v < 6; v++) {
+                       vertices[f][v].position = cube_vertices[f][v].position;
+                       vertices[f][v].normal = cube_vertices[f][v].normal;
+               }
+       }
+
+       client_entity_cube.data = vertices;
+       mesh_upload(&client_entity_cube);
+
+       client_entity_shader.prog = shader_prog;
+       client_entity_shader.loc_transform = glGetUniformLocation(shader_prog, "model"); GL_DEBUG
+
+       light_shader.prog = shader_prog;
+       light_shader_locate(&light_shader);
+
+       return true;
+}
+
+void client_entity_gfx_deinit()
+{
+       glDeleteProgram(shader_prog); GL_DEBUG
+       mesh_destroy(&client_entity_cube);
+}
+
+void client_entity_gfx_update()
+{
+       glProgramUniformMatrix4fv(shader_prog, loc_VP, 1, GL_FALSE, frustum[0]); GL_DEBUG
+       light_shader_update(&light_shader);
+
+       pthread_mutex_lock(&mtx_nametagged);
+       list_itr(&nametagged, &update_nametag_pos, NULL, &refcount_obj);
+       pthread_mutex_unlock(&mtx_nametagged);
 }
 
 ClientEntity *client_entity_grab(u64 id)
@@ -69,8 +224,8 @@ void client_entity_transform(ClientEntity *entity)
        if (!entity->model)
                return;
 
-       entity->model->root->pos = (v3f32) {entity->data.pos.x, entity->data.pos.y, entity->data.pos.z};
-       entity->model->root->rot = (v3f32) {entity->data.rot.x, entity->data.rot.y, entity->data.rot.z};
+       entity->model->root->pos = v3f64_to_f32(entity->data.pos); // ToDo: the render pipeline needs to be updated to handle 64-bit positions
+       entity->model->root->rot = entity->data.rot;
 
        if (entity->type->transform)
                entity->type->transform(entity);
@@ -92,14 +247,17 @@ void client_entity_add(__attribute__((unused)) DragonnetPeer *peer, ToClientEnti
        pkt->data.nametag = NULL;
 
        entity->model = NULL;
-
-       pthread_rwlock_init(&entity->lock_pos_rot, NULL);
-       pthread_rwlock_init(&entity->lock_box_eye, NULL);
-       pthread_rwlock_init(&entity->lock_nametag, NULL);
+       entity->nametag = NULL;
 
        if (entity->type->add)
                entity->type->add(entity);
 
+       update_nametag(entity);
+
+       pthread_rwlock_init(&entity->lock_pos_rot, NULL);
+       pthread_rwlock_init(&entity->lock_nametag, NULL);
+       pthread_rwlock_init(&entity->lock_box_off, NULL);
+
        if (!map_add(&entities, &entity->data.id, &entity->rc, &cmp_entity, &refcount_inc))
                fprintf(stderr, "[warning] failed to add entity %lu\n", entity->data.id);
 
@@ -126,27 +284,9 @@ void client_entity_update_pos_rot(__attribute__((unused)) DragonnetPeer *peer, T
        if (entity->type->update_pos_rot)
                entity->type->update_pos_rot(entity);
 
-       pthread_rwlock_unlock(&entity->lock_pos_rot);
+       client_entity_transform(entity);
 
-       refcount_drp(&entity->rc);
-}
-
-void client_entity_update_box_eye(__attribute__((unused)) DragonnetPeer *peer, ToClientEntityUpdateBoxEye *pkt)
-{
-       ClientEntity *entity = client_entity_grab(pkt->id);
-
-       if (!entity)
-               return;
-
-       pthread_rwlock_wrlock(&entity->lock_box_eye);
-
-       entity->data.box = pkt->box;
-       entity->data.eye = pkt->eye;
-
-       if (entity->type->update_box_eye)
-               entity->type->update_box_eye(entity);
-
-       pthread_rwlock_unlock(&entity->lock_box_eye);
+       pthread_rwlock_unlock(&entity->lock_pos_rot);
 
        refcount_drp(&entity->rc);
 }
@@ -169,6 +309,7 @@ void client_entity_update_nametag(__attribute__((unused)) DragonnetPeer *peer, T
        if (entity->type->update_nametag)
                entity->type->update_nametag(entity);
 
+       update_nametag(entity);
        pthread_rwlock_unlock(&entity->lock_nametag);
 
        refcount_drp(&entity->rc);
index 05651c4daafd86a79afda8165652cffa56db6231..53125dbbfe9a7c3cc212d5b9b323498f23ec2b5e 100644 (file)
@@ -4,6 +4,7 @@
 #include <dragonnet/peer.h>
 #include <dragonstd/refcount.h>
 #include <pthread.h>
+#include "client/gui.h"
 #include "client/model.h"
 #include "entity.h"
 #include "types.h"
@@ -14,27 +15,42 @@ typedef struct {
        Refcount rc;
 
        Model *model;
+       GUIElement *nametag;
+       void *extra;
+
+       aabb3f32 box_collision;
+       aabb3f32 box_culling;   // ToDo
+       mat4x4 *nametag_offset;
 
        pthread_rwlock_t lock_pos_rot;
-       pthread_rwlock_t lock_box_eye;
        pthread_rwlock_t lock_nametag;
+       pthread_rwlock_t lock_box_off;
 } ClientEntity;
 
+// Entity is pronounced N-Tiddy, hmmmm...
+
 typedef struct ClientEntityType {
        void (*add   )(ClientEntity *entity); // called when server sent addition of entity
        void (*remove)(ClientEntity *entity); // called when server sent removal of entity
        void (*free  )(ClientEntity *entity); // called when entity is garbage collected
 
        void (*update_pos_rot)(ClientEntity *entity);
-       void (*update_box_eye)(ClientEntity *entity);
        void (*update_nametag)(ClientEntity *entity);
 
        void (*transform)(ClientEntity *entity);
 } ClientEntityType;
 
+extern ClientEntityType client_entity_types[];
+extern Mesh client_entity_cube;
+extern ModelShader client_entity_shader;
+
 void client_entity_init();
 void client_entity_deinit();
 
+bool client_entity_gfx_init();
+void client_entity_gfx_deinit();
+void client_entity_gfx_update();
+
 ClientEntity *client_entity_grab(u64 id);
 void client_entity_drop(ClientEntity *entity);
 
@@ -43,9 +59,6 @@ void client_entity_transform(ClientEntity *entity);
 void client_entity_add(DragonnetPeer *peer, ToClientEntityAdd *pkt);
 void client_entity_remove(DragonnetPeer *peer, ToClientEntityRemove *pkt);
 void client_entity_update_pos_rot(DragonnetPeer *peer, ToClientEntityUpdatePosRot *pkt);
-void client_entity_update_box_eye(DragonnetPeer *peer, ToClientEntityUpdateBoxEye *pkt);
 void client_entity_update_nametag(DragonnetPeer *peer, ToClientEntityUpdateNametag *pkt);
 
-extern ClientEntityType client_entity_types[];
-
 #endif // _CLIENT_ENTITY_H_
index 08b9adb10bf5c070f1c498082ea7aea24cf6129c..3bc1b46a3743819b59fc126870a80658432b5e35 100644 (file)
 #include "environment.h"
 #include "physics.h"
 
+typedef struct {
+       ModelNode *nametag;
+       ModelNode *neck;
+       ModelNode *eyes;
+       ModelNode *shoulder_left;
+       ModelNode *shoulder_right;
+       ModelNode *hip_left;
+       ModelNode *hip_right;
+} PlayerModelBones;
+
 struct ClientPlayer client_player;
 
 static ClientEntity *player_entity;
 static pthread_rwlock_t lock_player_entity;
 
+static Model *player_model;
+
 // updat epos/rot box/eye functions
 
-static void update_eye_pos_camera()
+static void update_camera()
 {
-       v3f64 pos = player_entity->data.pos;
-       v3f32 eye = player_entity->data.eye;
+       vec4 dst, src = {0.0f, 0.0f, 0.0f, 1.0f};
+
+       PlayerModelBones *bones = player_entity->extra;
 
-       camera_set_position((v3f32) {pos.x + eye.x, pos.y + eye.y, pos.z + eye.z});
+       if (bones->eyes)
+               mat4x4_mul_vec4(dst, bones->eyes->abs, src);
+       else
+               vec4_dup(dst, src);
+
+       camera_set_position((v3f32) {dst[0], dst[1], dst[2]});
 }
 
 static void update_pos()
 {
-       pthread_rwlock_rdlock(&player_entity->lock_box_eye);
-       update_eye_pos_camera();
-       pthread_rwlock_unlock(&player_entity->lock_box_eye);
-
        debug_menu_changed(ENTRY_POS);
        debug_menu_changed(ENTRY_HUMIDITY);
        debug_menu_changed(ENTRY_TEMPERATURE);
@@ -38,7 +52,7 @@ static void update_pos()
 
 static void update_rot()
 {
-       camera_set_angle(player_entity->data.rot.x, player_entity->data.rot.y);
+       camera_set_angle(M_PI / 2 - player_entity->data.rot.y, -player_entity->data.rot.x);
        debug_menu_changed(ENTRY_YAW);
        debug_menu_changed(ENTRY_PITCH);
 }
@@ -46,66 +60,111 @@ static void update_rot()
 static void update_transform()
 {
        client_entity_transform(player_entity);
+       update_camera();
 }
 
 static void send_pos_rot()
 {
+       update_transform();
+
        dragonnet_peer_send_ToServerPosRot(client, &(ToServerPosRot) {
                .pos = player_entity->data.pos,
                .rot = player_entity->data.rot,
        });
-
-       update_transform();
 }
 
 static void recv_pos_rot()
 {
+       update_transform();
+
        update_pos();
        update_rot();
-
-       update_transform();
 }
 
 // entity callbacks
 
 static void on_add(ClientEntity *entity)
+{
+       entity->model = model_clone(player_model);
+       entity->model->extra = refcount_grb(&entity->rc);
+
+       PlayerModelBones *bones = entity->extra = malloc(sizeof *bones);
+       *bones = (PlayerModelBones) {NULL};
+       model_get_bones(entity->model, (ModelBoneMapping[]) {
+               {"player.nametag",                    &bones->nametag       },
+               {"player.neck",                       &bones->neck          },
+               {"player.neck.head.eyes",             &bones->eyes          },
+               {"player.body.upper.shoulders.left",  &bones->shoulder_left },
+               {"player.body.upper.shoulders.right", &bones->shoulder_right},
+               {"player.body.lower.hips.left",       &bones->hip_left      },
+               {"player.body.lower.hips.right",      &bones->hip_right     },
+       }, 7);
+
+       entity->nametag_offset = bones->nametag ? &bones->nametag->abs : NULL;
+       entity->box_collision = (aabb3f32) {{-0.3f, 0.0f, -0.3f}, {0.3f, 1.8f, 0.3f}};
+
+       model_scene_add(entity->model);
+       client_entity_transform(entity);
+}
+
+static void on_remove(ClientEntity *entity)
+{
+       entity->model->flags.delete = 1;
+       entity->model = NULL;
+}
+
+static void on_free(ClientEntity *entity)
+{
+       free(entity->extra);
+}
+
+static void on_transform(ClientEntity *entity)
+{
+       PlayerModelBones *bones = entity->extra;
+
+       entity->model->root->rot.x = entity->model->root->rot.z = 0.0f;
+
+       if (bones->neck) {
+               bones->neck->rot.x = entity->data.rot.x;
+               model_node_transform(bones->neck);
+       }
+}
+
+static void local_on_add(ClientEntity *entity)
 {
        pthread_rwlock_wrlock(&lock_player_entity);
 
        if (player_entity) {
                fprintf(stderr, "[error] attempt to re-add localplayer entity\n");
                exit(EXIT_FAILURE);
-       } else {
-               player_entity = refcount_grb(&entity->rc);
-               recv_pos_rot();
-
-               entity->type->update_nametag(entity);
        }
 
+       on_add(entity);
+
+       player_entity = refcount_grb(&entity->rc);
+       recv_pos_rot();
+
+       entity->type->update_nametag(entity);
+
        pthread_rwlock_unlock(&lock_player_entity);
 }
 
-static void on_remove(ClientEntity *entity)
+static void local_on_remove(ClientEntity *entity)
 {
        pthread_rwlock_wrlock(&lock_player_entity);
        refcount_drp(&entity->rc);
        player_entity = NULL;
        pthread_rwlock_unlock(&lock_player_entity);
-}
 
-static void on_update_pos_rot(__attribute__((unused)) ClientEntity *entity)
-{
-       recv_pos_rot();
+       on_remove(entity);
 }
 
-static void on_update_box_eye(__attribute__((unused)) ClientEntity *entity)
+static void local_on_update_pos_rot(__attribute__((unused)) ClientEntity *entity)
 {
-       pthread_rwlock_rdlock(&lock_player_entity);
-       update_eye_pos_camera();
-       pthread_rwlock_unlock(&lock_player_entity);
+       recv_pos_rot();
 }
 
-static void on_update_nametag(ClientEntity *entity)
+static void local_on_update_nametag(ClientEntity *entity)
 {
        if (entity->data.nametag) {
                free(entity->data.nametag);
@@ -113,9 +172,16 @@ static void on_update_nametag(ClientEntity *entity)
        }
 }
 
-static void on_transform(ClientEntity *entity)
+static void __attribute__((unused)) on_model_step(Model *model, __attribute__((unused)) f64 dtime)
 {
-       entity->model->root->rot.y = entity->model->root->rot.z = 0.0f;
+       PlayerModelBones *bones = ((ClientEntity *) model->extra)->extra;
+       (void) bones;
+}
+
+static void on_model_delete(Model *model)
+{
+       if (model->extra)
+               refcount_drp(&((ClientEntity *) model->extra)->rc);
 }
 
 // called on startup
@@ -129,23 +195,21 @@ void client_player_init()
                .gravity = 0.0f,
        };
 
-       client_entity_types[ENTITY_LOCALPLAYER] = (ClientEntityType) {
+       client_entity_types[ENTITY_PLAYER] = (ClientEntityType) {
                .add = &on_add,
                .remove = &on_remove,
-               .free = NULL,
-               .update_pos_rot = &on_update_pos_rot,
-               .update_box_eye = &on_update_box_eye,
-               .update_nametag = &on_update_nametag,
+               .free = &on_free,
+               .update_pos_rot = NULL,
+               .update_nametag = NULL,
                .transform = &on_transform,
        };
 
-       client_entity_types[ENTITY_PLAYER] = (ClientEntityType) {
-               .add = NULL,
-               .remove = NULL,
-               .free = NULL,
-               .update_pos_rot = NULL,
-               .update_box_eye = NULL,
-               .update_nametag = NULL,
+       client_entity_types[ENTITY_LOCALPLAYER] = (ClientEntityType) {
+               .add = &local_on_add,
+               .remove = &local_on_remove,
+               .free = &on_free,
+               .update_pos_rot = &local_on_update_pos_rot,
+               .update_nametag = &local_on_update_nametag,
                .transform = &on_transform,
        };
 
@@ -162,6 +226,21 @@ void client_player_deinit()
        pthread_rwlock_destroy(&lock_player_entity);
 }
 
+void client_player_gfx_init()
+{
+       player_model = model_load(
+               RESSOURCE_PATH "models/player.txt", RESSOURCE_PATH "textures/models/player",
+               &client_entity_cube, &client_entity_shader);
+
+       player_model->callbacks.step = &on_model_step;
+       player_model->callbacks.delete = &on_model_delete;
+}
+
+void client_player_gfx_deinit()
+{
+       model_delete(player_model);
+}
+
 ClientEntity *client_player_entity()
 {
        ClientEntity *entity = NULL;
@@ -198,33 +277,6 @@ void client_player_update_rot(ClientEntity *entity)
        pthread_rwlock_unlock(&lock_player_entity);
 }
 
-/*
-// create mesh object and info hud
-void client_player_add_to_scene()
-{
-       client_player.obj = object_create();
-       client_player.obj->scale = (v3f32) {0.6, 1.75, 0.6};
-       client_player.obj->visible = false;
-
-       object_set_texture(client_player.obj, texture_load(RESSOURCE_PATH "textures/player.png", true));
-
-       for (int f = 0; f < 6; f++) {
-               for (int v = 0; v < 6; v++) {
-                       Vertex3D vertex = cube_vertices[f][v];
-                       vertex.position.y += 0.5;
-                       object_add_vertex(client_player.obj, &vertex);
-               }
-       }
-
-       pthread_rwlock_rdlock(&client_player.rwlock);
-       update_pos();
-       pthread_rwlock_unlock(&client_player.rwlock);
-
-       debug_menu_update_yaw();
-       debug_menu_update_pitch();
-}
-*/
-
 // jump if possible
 void client_player_jump()
 {
@@ -233,18 +285,18 @@ void client_player_jump()
                return;
 
        pthread_rwlock_rdlock(&entity->lock_pos_rot);
-       pthread_rwlock_rdlock(&entity->lock_box_eye);
+       pthread_rwlock_rdlock(&entity->lock_box_off);
 
        if (physics_ground(
                client_terrain,
                client_player.movement.collision,
-               entity->data.box,
+               entity->box_collision,
                &entity->data.pos,
                &client_player.velocity
        ))
                client_player.velocity.y += client_player.movement.jump;
 
-       pthread_rwlock_unlock(&entity->lock_box_eye);
+       pthread_rwlock_unlock(&entity->lock_box_off);
        pthread_rwlock_unlock(&entity->lock_pos_rot);
 
        refcount_drp(&entity->rc);
@@ -259,12 +311,12 @@ void client_player_tick(f64 dtime)
 
        pthread_rwlock_rdlock(&client_player.lock_movement);
        pthread_rwlock_wrlock(&entity->lock_pos_rot);
-       pthread_rwlock_rdlock(&entity->lock_box_eye);
+       pthread_rwlock_rdlock(&entity->lock_box_off);
 
        if (physics_step(
                client_terrain,
                client_player.movement.collision,
-               entity->data.box,
+               entity->box_collision,
                &entity->data.pos,
                &client_player.velocity,
                &(v3f64) {
@@ -276,7 +328,7 @@ void client_player_tick(f64 dtime)
        ))
                client_player_update_pos(entity);
 
-       pthread_rwlock_unlock(&entity->lock_box_eye);
+       pthread_rwlock_unlock(&entity->lock_box_off);
        pthread_rwlock_unlock(&entity->lock_pos_rot);
        pthread_rwlock_unlock(&client_player.lock_movement);
 
index f2ea0e4167f6f11c25f59ae309dcb2d6edc095ab..5ddefa058e261c870ed8414fef882966d08db70f 100644 (file)
@@ -14,6 +14,9 @@ extern struct ClientPlayer {
 void client_player_init();                           // called on startup
 void client_player_deinit();                         // called on shutdown
 
+void client_player_gfx_init();
+void client_player_gfx_deinit();
+
 ClientEntity *client_player_entity();                // grab and return client entity
 
 void client_player_jump();                           // jump if possible
index f60dbb141417884db00a79fb6616ade4aa5640dc..c9c0ff1af0a2448457ba9711294501af54123ba3 100644 (file)
@@ -39,7 +39,7 @@ static TerrainChunk *set_dequeued(TerrainChunk *chunk)
 // mesh generator step
 static void meshgen_step()
 {
-       TerrainChunk *chunk = queue_deq(&meshgen_tasks, (void *) &set_dequeued);
+       TerrainChunk *chunk = queue_deq(&meshgen_tasks, &set_dequeued);
 
        if (chunk)
                terrain_gfx_make_chunk_model(chunk);
index 83857078e252bbf122e5e83fca8339f6bfe78b1a..8e60bdbdd29e879d3c23f729a189589576724227 100644 (file)
@@ -3,12 +3,14 @@
 #include <GL/gl.h>
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <pthread.h>
 #include "client/client_config.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 #include "client/debug_menu.h"
 #include "client/game.h"
+#include "client/gl_debug.h"
 #include "client/gui.h"
 #include "client/window.h"
 #include "day.h"
@@ -73,27 +75,27 @@ static char *get_entry_text(DebugMenuEntry entry)
 
        char *str;
        switch (entry) {
-               case ENTRY_VERSION:       asprintf(&str, "Dragonblocks Alpha %s", VERSION                                    ); break;
-               case ENTRY_FPS:           asprintf(&str, "%d FPS", game_fps                                                  ); break;
-               case ENTRY_POS:           asprintf(&str, "(%.1f %.1f %.1f)", pos.x, pos.y, pos.z                             ); break;
-               case ENTRY_YAW:           asprintf(&str, "yaw = %.1f", rot.x / M_PI * 180.0                                  ); break;
-               case ENTRY_PITCH:         asprintf(&str, "pitch = %.1f", rot.y / M_PI * 180.0                                ); break;
-               case ENTRY_TIME:          asprintf(&str, "%02d:%02d", hours, minutes                                         ); break;
-               case ENTRY_DAYLIGHT:      asprintf(&str, "daylight = %.2f", get_daylight()                                   ); break;
-               case ENTRY_SUN_ANGLE:     asprintf(&str, "sun angle = %.1f", fmod(get_sun_angle() / M_PI * 180.0, 360.0)     ); break;
-               case ENTRY_HUMIDITY:      asprintf(&str, "humidity = %.2f", get_humidity((v3s32) {pos.x, pos.y, pos.z})      ); break;
-               case ENTRY_TEMPERATURE:   asprintf(&str, "temperature = %.2f", get_temperature((v3s32) {pos.x, pos.y, pos.z})); break;
-               case ENTRY_SEED:          asprintf(&str, "seed = %d", seed                                                   ); break;
-               case ENTRY_FLIGHT:        asprintf(&str, "flight: %s", flight ? "enabled" : "disabled"                       ); break;
-               case ENTRY_COLLISION:     asprintf(&str, "collision: %s", collision ? "enabled" : "disabled"                 ); break;
-               case ENTRY_TIMELAPSE:     asprintf(&str, "timelapse: %s", timelapse ? "enabled" : "disabled"                 ); break;
-               case ENTRY_FULLSCREEN:    asprintf(&str, "fullscreen: %s", window.fullscreen ? "enabled" : "disabled"        ); break;
-               case ENTRY_OPENGL:        asprintf(&str, "OpenGL %s", glGetString(GL_VERSION)                                ); break;
-               case ENTRY_GPU:           asprintf(&str, "%s", glGetString(GL_RENDERER)                                      ); break;
-               case ENTRY_ANTIALIASING:  asprintf(&str, "antialiasing: %u samples", client_config.antialiasing              ); break;
-               case ENTRY_MIPMAP:        asprintf(&str, "mipmap: %s", client_config.mipmap ? "enabled" : "disabled"         ); break;
-               case ENTRY_VIEW_DISTANCE: asprintf(&str, "view distance: %.1lf", client_config.view_distance                 ); break;
-               case ENTRY_LOAD_DISTANCE: asprintf(&str, "load distance: %u", client_terrain_get_load_distance()             ); break;
+               case ENTRY_VERSION:       asprintf(&str, "Dragonblocks Alpha %s", VERSION                                    );          break;
+               case ENTRY_FPS:           asprintf(&str, "%d FPS", game_fps                                                  );          break;
+               case ENTRY_POS:           asprintf(&str, "(%.1f %.1f %.1f)", pos.x, pos.y, pos.z                             );          break;
+               case ENTRY_YAW:           asprintf(&str, "yaw = %.1f", 360.0 - rot.y / M_PI * 180.0                          );          break;
+               case ENTRY_PITCH:         asprintf(&str, "pitch = %.1f", -rot.x / M_PI * 180.0                               );          break;
+               case ENTRY_TIME:          asprintf(&str, "%02d:%02d", hours, minutes                                         );          break;
+               case ENTRY_DAYLIGHT:      asprintf(&str, "daylight = %.2f", get_daylight()                                   );          break;
+               case ENTRY_SUN_ANGLE:     asprintf(&str, "sun angle = %.1f", fmod(get_sun_angle() / M_PI * 180.0, 360.0)     );          break;
+               case ENTRY_HUMIDITY:      asprintf(&str, "humidity = %.2f", get_humidity((v3s32) {pos.x, pos.y, pos.z})      );          break;
+               case ENTRY_TEMPERATURE:   asprintf(&str, "temperature = %.2f", get_temperature((v3s32) {pos.x, pos.y, pos.z}));          break;
+               case ENTRY_SEED:          asprintf(&str, "seed = %d", seed                                                   );          break;
+               case ENTRY_FLIGHT:        asprintf(&str, "flight: %s", flight ? "enabled" : "disabled"                       );          break;
+               case ENTRY_COLLISION:     asprintf(&str, "collision: %s", collision ? "enabled" : "disabled"                 );          break;
+               case ENTRY_TIMELAPSE:     asprintf(&str, "timelapse: %s", timelapse ? "enabled" : "disabled"                 );          break;
+               case ENTRY_FULLSCREEN:    asprintf(&str, "fullscreen: %s", window.fullscreen ? "enabled" : "disabled"        );          break;
+               case ENTRY_OPENGL:        asprintf(&str, "OpenGL %s", glGetString(GL_VERSION)                                ); GL_DEBUG break;
+               case ENTRY_GPU:           asprintf(&str, "%s", glGetString(GL_RENDERER)                                      ); GL_DEBUG break;
+               case ENTRY_ANTIALIASING:  asprintf(&str, "antialiasing: %u samples", client_config.antialiasing              );          break;
+               case ENTRY_MIPMAP:        asprintf(&str, "mipmap: %s", client_config.mipmap ? "enabled" : "disabled"         );          break;
+               case ENTRY_VIEW_DISTANCE: asprintf(&str, "view distance: %.1lf", client_config.view_distance                 );          break;
+               case ENTRY_LOAD_DISTANCE: asprintf(&str, "load distance: %u", client_terrain_get_load_distance()             );          break;
                default: break;
        }
        return str;
@@ -113,7 +115,7 @@ void debug_menu_init()
                        .scale = {1.0f, 1.0f},
                        .scale_type = SCALE_TEXT,
                        .affect_parent_scale = false,
-                       .text = strdup(""),
+                       .text = "",
                        .image = NULL,
                        .text_color = (v4f32) {1.0f, 1.0f, 1.0f, 1.0f},
                        .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
@@ -153,8 +155,11 @@ void debug_menu_update()
        pthread_mutex_unlock(&changed_elements_mtx);
 
        for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++)
-               if (changed_elements_cpy[i])
-                       gui_text(gui_elements[i], get_entry_text(i));
+               if (changed_elements_cpy[i]) {
+                       char *str = get_entry_text(i);
+                       gui_text(gui_elements[i], str);
+                       free(str);
+               }
 }
 
 void debug_menu_changed(DebugMenuEntry entry)
index 15e432a7ffe99ec925c48689ed5efe629bae64f7..2370480ee1b0d718199a2afb75413cc7a6cacf78 100644 (file)
@@ -3,6 +3,7 @@
 #include FT_FREETYPE_H
 #include "client/client.h"
 #include "client/font.h"
+#include "client/gl_debug.h"
 #include "client/texture.h"
 
 #define NUM_CHARS 128
@@ -43,7 +44,7 @@ bool font_init()
                return false;
        }
 
-       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_DEBUG
        FT_Set_Pixel_Sizes(font_face, 0, 16);
 
        for (unsigned char c = 0; c < NUM_CHARS; c++) {
@@ -138,7 +139,7 @@ void font_delete(Font *font)
 void font_render(Font *font)
 {
        for (size_t i = 0; i < font->count; i++) {
-               glBindTextureUnit(0, font->textures[i]);
+               glBindTextureUnit(0, font->textures[i]); GL_DEBUG
                mesh_render(&font->meshes[i]);
        }
 }
index 99da5785bf41cf6d6d6ab87dfe3af74479315e02..8cd2b7484f081ef755df614b313c8e5a2885ed24 100644 (file)
@@ -7,12 +7,15 @@
 #include <unistd.h>
 #include "client/camera.h"
 #include "client/client.h"
+#include "client/client_entity.h"
 #include "client/client_node.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 #include "client/debug_menu.h"
 #include "client/font.h"
 #include "client/frustum.h"
+#include "client/game.h"
+#include "client/gl_debug.h"
 #include "client/gui.h"
 #include "client/input.h"
 #include "client/sky.h"
@@ -42,21 +45,20 @@ static void crosshair_init()
 
 static void render(f64 dtime)
 {
-       glEnable(GL_DEPTH_TEST);
-       glEnable(GL_ALPHA_TEST);
-       glEnable(GL_BLEND);
-       glEnable(GL_MULTISAMPLE);
-       glEnable(GL_CULL_FACE);
+       glEnable(GL_DEPTH_TEST); GL_DEBUG
+       glEnable(GL_BLEND); GL_DEBUG
+       glEnable(GL_MULTISAMPLE); GL_DEBUG
+       glEnable(GL_CULL_FACE); GL_DEBUG
 
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glAlphaFunc(GL_GREATER, 0.1f);
-       glCullFace(GL_BACK);
-       glFrontFace(GL_CCW);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DEBUG
+       glCullFace(GL_BACK); GL_DEBUG
+       glFrontFace(GL_CCW); GL_DEBUG
 
-       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_DEBUG
 
        frustum_update();
        terrain_gfx_update();
+       client_entity_gfx_update();
 
        sky_render();
        model_scene_render(dtime);
@@ -116,6 +118,11 @@ bool game(Flag *gfx_init)
        if (!terrain_gfx_init())
                return false;
 
+       if (!client_entity_gfx_init())
+               return false;
+
+       client_player_gfx_init();
+
        client_node_init();
        client_terrain_start();
 
@@ -139,6 +146,8 @@ bool game(Flag *gfx_init)
        model_deinit();
        sky_deinit();
        terrain_gfx_deinit();
+       client_entity_gfx_deinit();
+       client_player_gfx_deinit();
 
        return true;
 }
@@ -147,48 +156,48 @@ char *game_take_screenshot()
 {
        // renderbuffer for depth & stencil buffer
        GLuint rbo;
-       glGenRenderbuffers(1, &rbo);
-       glBindRenderbuffer(GL_RENDERBUFFER, rbo);
-       glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window.width, window.height);
+       glGenRenderbuffers(1, &rbo); GL_DEBUG
+       glBindRenderbuffer(GL_RENDERBUFFER, rbo); GL_DEBUG
+       glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window.width, window.height); GL_DEBUG
 
        // 2 textures, one with AA, one without
 
        GLuint txos[2];
-       glGenTextures(2, txos);
+       glGenTextures(2, txos); GL_DEBUG
 
-       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, txos[0]);
-       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window.width, window.height, GL_TRUE);
+       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, txos[0]); GL_DEBUG
+       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window.width, window.height, GL_TRUE); GL_DEBUG
 
-       glBindTexture(GL_TEXTURE_2D, txos[1]);
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window.width, window.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+       glBindTexture(GL_TEXTURE_2D, txos[1]); GL_DEBUG
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window.width, window.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); GL_DEBUG
 
        // 2 framebuffers, one with AA, one without
 
        GLuint fbos[2];
-       glGenFramebuffers(2, fbos);
+       glGenFramebuffers(2, fbos); GL_DEBUG
 
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
-       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, txos[0], 0);
-       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, txos[0], 0); GL_DEBUG
+       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); GL_DEBUG
 
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
-       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, txos[1], 0);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, txos[1], 0); GL_DEBUG
 
        // render scene
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
        render(0.0);
-       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+       glBindFramebuffer(GL_FRAMEBUFFER, 0); GL_DEBUG
 
        // blit AA-buffer into no-AA buffer
-       glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
-       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
-       glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+       glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); GL_DEBUG
+       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_DEBUG
 
        // read data
        GLubyte data[window.width * window.height * 3];
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
-       glPixelStorei(GL_PACK_ALIGNMENT, 1);
-       glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, data);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glPixelStorei(GL_PACK_ALIGNMENT, 1); GL_DEBUG
+       glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, data); GL_DEBUG
 
        // create filename
        char filename[BUFSIZ];
@@ -200,9 +209,9 @@ char *game_take_screenshot()
        stbi_write_png(filename, window.width, window.height, 3, data, window.width * 3);
 
        // delete buffers
-       glDeleteRenderbuffers(1, &rbo);
-       glDeleteTextures(2, txos);
-       glDeleteFramebuffers(2, fbos);
+       glDeleteRenderbuffers(1, &rbo); GL_DEBUG
+       glDeleteTextures(2, txos); GL_DEBUG
+       glDeleteFramebuffers(2, fbos); GL_DEBUG
 
        return strdup(filename);
 }
diff --git a/src/client/gl_debug.c b/src/client/gl_debug.c
new file mode 100644 (file)
index 0000000..cc75d24
--- /dev/null
@@ -0,0 +1,26 @@
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <stdio.h>
+#include "client/gl_debug.h"
+
+// put this into seperate function to make it easy to trace stack using external debugger
+static void gl_error(GLenum err, const char *file, int line)
+{
+       switch (err) {
+               case GL_INVALID_ENUM:                  printf("INVALID_ENUM %s:%d\n", file, line); break;
+               case GL_INVALID_VALUE:                 printf("INVALID_VALUE %s:%d\n", file, line); break;
+               case GL_INVALID_OPERATION:             printf("INVALID_OPERATION %s:%d\n", file, line); break;
+               case GL_STACK_OVERFLOW:                printf("STACK_OVERFLOW %s:%d\n", file, line); break;
+               case GL_STACK_UNDERFLOW:               printf("STACK_UNDERFLOW %s:%d\n", file, line); break;
+               case GL_OUT_OF_MEMORY:                 printf("OUT_OF_MEMORY %s:%d\n", file, line); break;
+               case GL_INVALID_FRAMEBUFFER_OPERATION: printf("INVALID_FRAMEBUFFER_OPERATION %s:%d\n", file, line); break;
+               default: break;
+       }
+}
+void gl_debug(const char *file, int line)
+{
+       GLenum err = glGetError();
+
+       if (err != GL_NO_ERROR)
+               gl_error(err, file, line);
+}
diff --git a/src/client/gl_debug.h b/src/client/gl_debug.h
new file mode 100644 (file)
index 0000000..f65f080
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _GL_DEBUG_H_
+#define _GL_DEBUG_H_
+
+#ifdef ENABLE_GL_DEBUG
+#define GL_DEBUG gl_debug(__FILE__, __LINE__);
+#else
+#define GL_DEBUG
+#endif
+
+void gl_debug(const char *file, int line);
+
+#endif
index 29f6b916e413ff00e5fa79dd65d2ca6aaee3029b..4aecb482527e54cf2fd030a0b6de4ab6af49cfce 100644 (file)
@@ -5,6 +5,7 @@
 #include <string.h>
 #include "client/client.h"
 #include "client/cube.h"
+#include "client/gl_debug.h"
 #include "client/gui.h"
 #include "client/mesh.h"
 #include "client/shader.h"
@@ -120,23 +121,28 @@ static void render_element(GUIElement *element)
 {
        if (element->visible) {
                if (element->def.bg_color.w > 0.0f) {
-                       glUseProgram(background_prog);
-                       glUniformMatrix4fv(background_loc_model, 1, GL_FALSE, element->transform[0]);
-                       glUniform4f(background_loc_color, element->def.bg_color.x, element->def.bg_color.y, element->def.bg_color.z, element->def.bg_color.w);
+                       glUseProgram(background_prog); GL_DEBUG
+                       glUniformMatrix4fv(background_loc_model, 1, GL_FALSE, element->transform[0]); GL_DEBUG
+                       glUniform4f(background_loc_color, element->def.bg_color.x, element->def.bg_color.y, element->def.bg_color.z, element->def.bg_color.w); GL_DEBUG
                        mesh_render(&background_mesh);
                }
 
                if (element->def.image) {
-                       glUseProgram(image_prog);
-                       glUniformMatrix4fv(image_loc_model, 1, GL_FALSE, element->transform[0]);
-                       glBindTextureUnit(0, element->def.image->txo);
+                       glUseProgram(image_prog); GL_DEBUG
+                       glUniformMatrix4fv(image_loc_model, 1, GL_FALSE, element->transform[0]); GL_DEBUG
+                       glBindTextureUnit(0, element->def.image->txo); GL_DEBUG
                        mesh_render(&image_mesh);
                }
 
-               if (element->text && element->def.text_color.w > 0.0f) {
-                       glUseProgram(font_prog);
-                       glUniformMatrix4fv(font_loc_model, 1, GL_FALSE, element->text_transform[0]);
-                       glUniform4f(font_loc_color, element->def.text_color.x, element->def.text_color.y, element->def.text_color.z, element->def.text_color.w);
+               if (element->def.text && element->def.text_color.w > 0.0f) {
+                       if (!element->text) {
+                               element->text = font_create(element->def.text);
+                               gui_transform(element);
+                       }
+
+                       glUseProgram(font_prog); GL_DEBUG
+                       glUniformMatrix4fv(font_loc_model, 1, GL_FALSE, element->text_transform[0]); GL_DEBUG
+                       glUniform4f(font_loc_color, element->def.text_color.x, element->def.text_color.y, element->def.text_color.z, element->def.text_color.w); GL_DEBUG
                        font_render(element->text);
                }
 
@@ -177,6 +183,9 @@ static void scale_element(GUIElement *element)
                        break;
 
                case SCALE_TEXT:
+                       if (!element->text)
+                               break;
+
                        element->scale.x *= element->text->size.x;
                        element->scale.y *= element->text->size.y;
                        break;
@@ -231,9 +240,9 @@ bool gui_init()
                return false;
        }
 
-       background_loc_model = glGetUniformLocation(background_prog, "model");
-       background_loc_projection = glGetUniformLocation(background_prog, "projection");
-       background_loc_color = glGetUniformLocation(background_prog, "color");
+       background_loc_model = glGetUniformLocation(background_prog, "model"); GL_DEBUG
+       background_loc_projection = glGetUniformLocation(background_prog, "projection"); GL_DEBUG
+       background_loc_color = glGetUniformLocation(background_prog, "color"); GL_DEBUG
 
        // initialize image pipeline
 
@@ -242,8 +251,8 @@ bool gui_init()
                return false;
        }
 
-       image_loc_model = glGetUniformLocation(image_prog, "model");
-       image_loc_projection = glGetUniformLocation(image_prog, "projection");
+       image_loc_model = glGetUniformLocation(image_prog, "model"); GL_DEBUG
+       image_loc_projection = glGetUniformLocation(image_prog, "projection"); GL_DEBUG
 
        // initialize font pipeline
 
@@ -252,9 +261,9 @@ bool gui_init()
                return false;
        }
 
-       font_loc_model = glGetUniformLocation(font_prog, "model");
-       font_loc_projection = glGetUniformLocation(font_prog, "projection");
-       font_loc_color = glGetUniformLocation(font_prog, "color");
+       font_loc_model = glGetUniformLocation(font_prog, "model"); GL_DEBUG
+       font_loc_projection = glGetUniformLocation(font_prog, "projection"); GL_DEBUG
+       font_loc_color = glGetUniformLocation(font_prog, "color"); GL_DEBUG
 
        // initialize GUI root element
 
@@ -283,13 +292,13 @@ bool gui_init()
 
 void gui_deinit()
 {
-       glDeleteProgram(background_prog);
+       glDeleteProgram(background_prog); GL_DEBUG
        mesh_destroy(&background_mesh);
 
-       glDeleteProgram(image_prog);
+       glDeleteProgram(image_prog); GL_DEBUG
        mesh_destroy(&image_mesh);
 
-       glDeleteProgram(font_prog);
+       glDeleteProgram(font_prog); GL_DEBUG
 
        delete_elements(&root_element.children);
 }
@@ -297,9 +306,9 @@ void gui_deinit()
 void gui_update_projection()
 {
        mat4x4_ortho(projection, 0, window.width, window.height, 0, -1.0f, 1.0f);
-       glProgramUniformMatrix4fv(background_prog, background_loc_projection, 1, GL_FALSE, projection[0]);
-       glProgramUniformMatrix4fv(image_prog, image_loc_projection, 1, GL_FALSE, projection[0]);
-       glProgramUniformMatrix4fv(font_prog, font_loc_projection, 1, GL_FALSE, projection[0]);
+       glProgramUniformMatrix4fv(background_prog, background_loc_projection, 1, GL_FALSE, projection[0]); GL_DEBUG
+       glProgramUniformMatrix4fv(image_prog, image_loc_projection, 1, GL_FALSE, projection[0]); GL_DEBUG
+       glProgramUniformMatrix4fv(font_prog, font_loc_projection, 1, GL_FALSE, projection[0]); GL_DEBUG
 
        root_element.def.scale.x = window.width;
        root_element.def.scale.y = window.height;
@@ -309,13 +318,13 @@ void gui_update_projection()
 
 void gui_render()
 {
-       glDisable(GL_CULL_FACE);
-       glDisable(GL_DEPTH_TEST);
+       glDisable(GL_CULL_FACE); GL_DEBUG
+       glDisable(GL_DEPTH_TEST); GL_DEBUG
 
        render_elements(&root_element.children);
 
-       glEnable(GL_DEPTH_TEST);
-       glEnable(GL_CULL_FACE);
+       glEnable(GL_DEPTH_TEST); GL_DEBUG
+       glEnable(GL_CULL_FACE); GL_DEBUG
 }
 
 GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def)
@@ -327,15 +336,12 @@ GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def)
        element->def = def;
        element->visible = true;
        element->parent = parent;
+       element->text = NULL;
 
-       if (element->def.text) {
+       if (element->def.text)
                element->def.text = strdup(element->def.text);
-               element->text = font_create(element->def.text);
-       } else {
-               element->text = NULL;
-       }
 
-       array_ins(&parent->children, &element, (void *) &cmp_element);
+       array_ins(&parent->children, &element, &cmp_element);
        array_ini(&element->children, sizeof(GUIElement), 0);
 
        if (element->def.affect_parent_scale)
@@ -346,15 +352,16 @@ GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def)
        return element;
 }
 
-void gui_text(GUIElement *element, char *text)
+void gui_text(GUIElement *element, const char *text)
 {
        if (element->def.text)
                free(element->def.text);
 
-       element->def.text = text;
-       font_delete(element->text);
-       element->text = font_create(text);
-       gui_transform(element);
+       if (element->text)
+               font_delete(element->text);
+
+       element->def.text = strdup(text);
+       element->text = NULL;
 }
 
 void gui_transform(GUIElement *element)
index 7f4c0d2479690ef11ee3fa9e88b188caff7f2639..ea4b15e559fab2fbc35a170c595d424cbad0a440 100644 (file)
@@ -48,7 +48,7 @@ void gui_deinit();
 void gui_update_projection();
 void gui_render();
 GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def);
-void gui_text(GUIElement *element, char *text);
+void gui_text(GUIElement *element, const char *text);
 void gui_transform(GUIElement *element);
 
 #endif // _GUI_H_
index e9b154c32808fb39b10b5bd75353e82f4e4365ea..19dc81cf65b96da8b6fa3c40b3aae7978b1f98e4 100644 (file)
 #include "client/window.h"
 #include "day.h"
 
+#define SET_STATUS_MESSAGE(args...) { \
+       char *msg; asprintf(&msg, args); \
+       gui_text(status_message, msg); free(msg); \
+       status_message->def.text_color.w = 1.01f; }
+
 typedef struct {
        int key;
        bool state;
@@ -65,12 +70,6 @@ static bool key_listener(KeyListener *listener)
        return !(listener->state = (glfwGetKey(window.handle, listener->key) == GLFW_PRESS)) && was;
 }
 
-static void set_status_message(char *message)
-{
-       gui_text(status_message, message);
-       status_message->def.text_color.w = 1.01f;
-}
-
 void input_init()
 {
        pause_menu = gui_add(NULL, (GUIElementDefinition) {
@@ -97,7 +96,7 @@ void input_init()
                .scale = {1.0f, 1.0f},
                .scale_type = SCALE_TEXT,
                .affect_parent_scale = false,
-               .text = strdup(""),
+               .text = "",
                .image = NULL,
                .text_color = {1.0f, 0.91f, 0.13f, 0.0f},
                .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
@@ -137,9 +136,7 @@ void input_tick(f64 dtime)
                        pthread_rwlock_wrlock(&client_player.lock_movement);
                        client_player.movement.flight = !client_player.movement.flight;
 
-                       char *msg;
-                       asprintf(&msg, "Flight %s", client_player.movement.flight ? "Enabled" : "Disabled");
-                       set_status_message(msg);
+                       SET_STATUS_MESSAGE("Flight %s", client_player.movement.flight ? "Enabled" : "Disabled")
                        debug_menu_changed(ENTRY_FLIGHT);
 
                        pthread_rwlock_unlock(&client_player.lock_movement);
@@ -149,9 +146,7 @@ void input_tick(f64 dtime)
                        pthread_rwlock_wrlock(&client_player.lock_movement);
                        client_player.movement.collision = !client_player.movement.collision;
 
-                       char *msg;
-                       asprintf(&msg, "Collision %s", client_player.movement.collision ? "Enabled" : "Disabled");
-                       set_status_message(msg);
+                       SET_STATUS_MESSAGE("Collision %s", client_player.movement.collision ? "Enabled" : "Disabled")
                        debug_menu_changed(ENTRY_COLLISION);
 
                        pthread_rwlock_unlock(&client_player.lock_movement);
@@ -162,9 +157,7 @@ void input_tick(f64 dtime)
                        timelapse = !timelapse;
                        set_time_of_day(current_time);
 
-                       char *msg;
-                       asprintf(&msg, "Timelapse %s", timelapse ? "Enabled" : "Disabled");
-                       set_status_message(msg);
+                       SET_STATUS_MESSAGE("Timelapse %s", timelapse ? "Enabled" : "Disabled")
                        debug_menu_changed(ENTRY_TIMELAPSE);
                }
 
@@ -173,9 +166,7 @@ void input_tick(f64 dtime)
 
                if (key_listener(&listener_screenshot)) {
                        char *screenshot_filename = game_take_screenshot();
-                       char *msg;
-                       asprintf(&msg, "Screenshot saved to %s", screenshot_filename);
-                       set_status_message(msg);
+                       SET_STATUS_MESSAGE("Screenshot saved to %s", screenshot_filename)
                        free(screenshot_filename);
                }
        }
@@ -217,11 +208,11 @@ void input_cursor(double current_x, double current_y)
 
        pthread_rwlock_wrlock(&entity->lock_pos_rot);
 
-       entity->data.rot.x += (f32) delta_x * M_PI / 180.0f / 8.0f;
-       entity->data.rot.y -= (f32) delta_y * M_PI / 180.0f / 8.0f;
+       entity->data.rot.y -= (f32) delta_x * M_PI / 180.0f / 8.0f;
+       entity->data.rot.x += (f32) delta_y * M_PI / 180.0f / 8.0f;
 
-       entity->data.rot.x = fmod(entity->data.rot.x + M_PI * 2.0f, M_PI * 2.0f);
-       entity->data.rot.y = f32_clamp(entity->data.rot.y, -M_PI / 2.0f + 0.01f, M_PI / 2.0f - 0.01f);
+       entity->data.rot.y = fmod(entity->data.rot.y + M_PI * 2.0f, M_PI * 2.0f);
+       entity->data.rot.x = f32_clamp(entity->data.rot.x, -M_PI / 2.0f + 0.01f, M_PI / 2.0f - 0.01f);
 
        client_player_update_rot(entity);
        pthread_rwlock_unlock(&entity->lock_pos_rot);
diff --git a/src/client/light.c b/src/client/light.c
new file mode 100644 (file)
index 0000000..9ba99d0
--- /dev/null
@@ -0,0 +1,35 @@
+#include <linmath.h/linmath.h>
+#include "client/camera.h"
+#include "client/gl_debug.h"
+#include "client/light.h"
+#include "day.h"
+
+void light_shader_locate(LightShader *shader)
+{
+       shader->loc_daylight = glGetUniformLocation(shader->prog, "daylight"); GL_DEBUG
+       shader->loc_fogColor = glGetUniformLocation(shader->prog, "fogColor"); GL_DEBUG
+       shader->loc_ambientLight = glGetUniformLocation(shader->prog, "ambientLight"); GL_DEBUG
+       shader->loc_lightDir = glGetUniformLocation(shader->prog, "lightDir"); GL_DEBUG
+       shader->loc_cameraPos = glGetUniformLocation(shader->prog, "cameraPos"); GL_DEBUG
+}
+
+void light_shader_update(LightShader *shader)
+{
+       vec4 base_sunlight_dir = {0.0f, 0.0f, -1.0f, 1.0f};
+       vec4 sunlight_dir;
+       mat4x4 sunlight_mat;
+       mat4x4_identity(sunlight_mat);
+
+       mat4x4_rotate(sunlight_mat, sunlight_mat, 1.0f, 0.0f, 0.0f, get_sun_angle() + M_PI / 2.0f);
+       mat4x4_mul_vec4(sunlight_dir, sunlight_mat, base_sunlight_dir);
+
+       f32 daylight = get_daylight();
+       f32 ambient_light = f32_mix(0.3f, 0.7f, daylight);
+       v3f32 fog_color = v3f32_mix((v3f32) {0x03, 0x0A, 0x1A}, (v3f32) {0x87, 0xCE, 0xEB}, daylight);
+
+       glProgramUniform1f(shader->prog, shader->loc_daylight, daylight); GL_DEBUG
+       glProgramUniform3f(shader->prog, shader->loc_fogColor, fog_color.x / 0xFF * ambient_light, fog_color.y / 0xFF * ambient_light, fog_color.z / 0xFF * ambient_light); GL_DEBUG
+       glProgramUniform1f(shader->prog, shader->loc_ambientLight, ambient_light); GL_DEBUG
+       glProgramUniform3f(shader->prog, shader->loc_lightDir, sunlight_dir[0], sunlight_dir[1], sunlight_dir[2]); GL_DEBUG
+       glProgramUniform3f(shader->prog, shader->loc_cameraPos, camera.eye[0], camera.eye[1], camera.eye[2]); GL_DEBUG
+}
diff --git a/src/client/light.h b/src/client/light.h
new file mode 100644 (file)
index 0000000..10e7775
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _LIGHT_H_
+#define _LIGHT_H_
+
+#include <GL/glew.h>
+#include <GL/gl.h>
+
+typedef struct {
+       GLuint prog;
+       GLint loc_daylight;
+       GLint loc_fogColor;
+       GLint loc_ambientLight;
+       GLint loc_lightDir;
+       GLint loc_cameraPos;
+} LightShader;
+
+void light_shader_locate(LightShader *shader);
+void light_shader_update(LightShader *shader);
+
+#endif
index f2ded84a8199fa34db8c2312820738e53fbb65f9..49df5060be3eb97275a50f0264b5647eebec7198 100644 (file)
@@ -1,32 +1,33 @@
 #include <stddef.h>
 #include <stdlib.h>
+#include "client/gl_debug.h"
 #include "client/mesh.h"
 
 // upload data to GPU (only done once)
 void mesh_upload(Mesh *mesh)
 {
-       glGenVertexArrays(1, &mesh->vao);
-       glGenBuffers(1, &mesh->vbo);
+       glGenVertexArrays(1, &mesh->vao); GL_DEBUG
+       glGenBuffers(1, &mesh->vbo); GL_DEBUG
 
-       glBindVertexArray(mesh->vao);
-       glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
+       glBindVertexArray(mesh->vao); GL_DEBUG
+       glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); GL_DEBUG
 
        glBufferData(GL_ARRAY_BUFFER, mesh->count * mesh->layout->size,
-               mesh->data, GL_STATIC_DRAW);
+               mesh->data, GL_STATIC_DRAW); GL_DEBUG
 
        size_t offset = 0;
        for (GLuint i = 0; i < mesh->layout->count; i++) {
                VertexAttribute *attrib = &mesh->layout->attributes[i];
 
                glVertexAttribPointer(i, attrib->length, attrib->type, GL_FALSE,
-                       mesh->layout->size, (GLvoid *) offset);
-               glEnableVertexAttribArray(i);
+                       mesh->layout->size, (GLvoid *) offset); GL_DEBUG
+               glEnableVertexAttribArray(i); GL_DEBUG
 
                offset += attrib->size;
        }
 
-       glBindBuffer(GL_ARRAY_BUFFER, 0);
-       glBindVertexArray(0);
+       glBindBuffer(GL_ARRAY_BUFFER, 0); GL_DEBUG
+       glBindVertexArray(0); GL_DEBUG
 
        if (mesh->free_data)
                free(mesh->data);
@@ -40,8 +41,8 @@ void mesh_render(Mesh *mesh)
                mesh_upload(mesh);
 
        // render
-       glBindVertexArray(mesh->vao);
-       glDrawArrays(GL_TRIANGLES, 0, mesh->count);
+       glBindVertexArray(mesh->vao); GL_DEBUG
+       glDrawArrays(GL_TRIANGLES, 0, mesh->count); GL_DEBUG
 }
 
 void mesh_destroy(Mesh *mesh)
@@ -49,11 +50,13 @@ void mesh_destroy(Mesh *mesh)
        if (mesh->data && mesh->free_data)
                free(mesh->data);
 
-       if (mesh->vao)
-               glDeleteVertexArrays(1, &mesh->vao);
+       if (mesh->vao) {
+               glDeleteVertexArrays(1, &mesh->vao); GL_DEBUG
+       }
 
-       if (mesh->vbo)
-               glDeleteBuffers(1, &mesh->vbo);
+       if (mesh->vbo) {
+               glDeleteBuffers(1, &mesh->vbo); GL_DEBUG
+       }
 
        mesh->vao = mesh->vbo = 0;
 }
index 1d163c7b1a34c8b78a4a3bde116986626905370f..c770d1c3e15904dc04a7f6c963e57d7f71254f3c 100644 (file)
@@ -5,6 +5,7 @@
 #include "client/camera.h"
 #include "client/client_config.h"
 #include "client/frustum.h"
+#include "client/gl_debug.h"
 #include "client/model.h"
 
 typedef struct {
@@ -13,7 +14,8 @@ typedef struct {
 } ModelBatchTexture;
 
 static List scene;
-static pthread_rwlock_t lock_scene;
+static List scene_new;
+static pthread_mutex_t lock_scene_new;
 static GLint units;
 
 // fixme: blending issues still occur
@@ -57,17 +59,18 @@ static void render_node(ModelNode *node)
        for (size_t i = 0; i < node->meshes.siz; i++) {
                ModelMesh *mesh = &((ModelMesh *) node->meshes.ptr)[i];
 
-               glUseProgram(mesh->shader->prog);
-               glUniformMatrix4fv(mesh->shader->loc_transform, 1, GL_FALSE, node->abs[0]);
+               glUseProgram(mesh->shader->prog); GL_DEBUG
+               glUniformMatrix4fv(mesh->shader->loc_transform, 1, GL_FALSE, node->abs[0]); GL_DEBUG
 
                // bind textures
-               for (GLuint i = 0; i < mesh->num_textures; i++)
-                       glBindTextureUnit(i, mesh->textures[i]);
+               for (GLuint i = 0; i < mesh->num_textures; i++) {
+                       glBindTextureUnit(i, mesh->textures[i]); GL_DEBUG
+               }
 
                mesh_render(mesh->mesh);
        }
 
-       list_itr(&node->children, (void *) &render_node, NULL, NULL);
+       list_itr(&node->children, &render_node, NULL, NULL);
 }
 
 static void free_node_meshes(ModelNode *node)
@@ -79,7 +82,7 @@ static void free_node_meshes(ModelNode *node)
                free(mesh->mesh);
        }
 
-       list_clr(&node->children, (void *) &free_node_meshes, NULL, NULL);
+       list_clr(&node->children, &free_node_meshes, NULL, NULL);
 }
 
 static void delete_node(ModelNode *node)
@@ -90,7 +93,7 @@ static void delete_node(ModelNode *node)
                if (mesh->textures)
                        free(mesh->textures);
        }
-       list_clr(&node->children, (void *) &delete_node, NULL, NULL);
+       list_clr(&node->children, &delete_node, NULL, NULL);
        array_clr(&node->meshes);
 
        free(node);
@@ -121,7 +124,7 @@ static ModelNode *clone_node(ModelNode *original, ModelNode *parent)
        for (size_t i = 0; i < node->meshes.siz; i++)
                clone_mesh(&((ModelMesh *) node->meshes.ptr)[i]);
 
-       list_itr(&original->children, (void *) &clone_node, parent, NULL);
+       list_itr(&original->children, &clone_node, node, NULL);
        return node;
 }
 
@@ -132,13 +135,15 @@ static int cmp_model(const Model *model, const f32 *distance)
 
 static void render_model(Model *model)
 {
-       if (model->flags.wireframe)
-               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+       if (model->flags.wireframe) {
+               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_DEBUG
+       }
 
        render_node(model->root);
 
-       if (model->flags.wireframe)
-               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+       if (model->flags.wireframe) {
+               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GL_DEBUG
+       }
 }
 
 // step model help im stuck
@@ -172,15 +177,19 @@ static void model_step(Model *model, Tree *transparent, f64 dtime)
 void model_init()
 {
        list_ini(&scene);
-       pthread_rwlock_init(&lock_scene, NULL);
-       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units);
+       list_ini(&scene_new);
+
+       pthread_mutex_init(&lock_scene_new, NULL);
+       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); GL_DEBUG
 }
 
 // ded
 void model_deinit()
 {
        list_clr(&scene, &model_delete, NULL, NULL);
-       pthread_rwlock_destroy(&lock_scene);
+       list_clr(&scene_new, &model_delete, NULL, NULL);
+
+       pthread_mutex_destroy(&lock_scene_new);
 }
 
 // Model functions
@@ -190,6 +199,7 @@ Model *model_create()
        Model *model = malloc(sizeof *model);
        model->root = model_node_create(NULL);
        model->extra = NULL;
+       model->replace = NULL;
 
        model->callbacks.step = NULL;
        model->callbacks.delete = NULL;
@@ -272,11 +282,6 @@ Model *model_load(const char *path, const char *textures_path, Mesh *cube, Model
                                        cursor += n;
                                else
                                        fprintf(stderr, "[warning] invalid value for scale in model %s in line %d\n", path, count);
-                       } else if (strcmp(key, "angle") == 0) {
-                               if (sscanf(cursor, "%f%n", &node->angle, &n) == 1)
-                                       cursor += n;
-                               else
-                                       fprintf(stderr, "[warning] invalid value for angle in model %s in line %d\n", path, count);
                        } else if (strcmp(key, "cube") == 0) {
                                char texture[length + 1];
 
@@ -313,6 +318,7 @@ Model *model_load(const char *path, const char *textures_path, Mesh *cube, Model
        fclose(file);
        array_clr(&stack);
 
+       transform_node(model->root);
        return model;
 }
 
@@ -346,15 +352,16 @@ void model_get_bones(Model *model, ModelBoneMapping *mappings, size_t num_mappin
                name = cursor = strdup(mappings[i].name);
 
                ModelNode *node = model->root;
-               while ((tok = strtok_r(cursor, ".", &saveptr))) {
-                       node = list_get(&node->children, tok, (void *) &cmp_node, NULL);
+
+               while (node && (tok = strtok_r(cursor, ".", &saveptr))) {
+                       node = list_get(&node->children, tok, &cmp_node, NULL);
                        cursor = NULL;
                }
 
                if (node)
                        *mappings[i].node = node;
                else
-                       fprintf(stderr, "[warning] no such bone: %s\n", name);
+                       fprintf(stderr, "[warning] no such bone: %s\n", mappings[i].name);
 
                free(name);
        }
@@ -370,7 +377,6 @@ ModelNode *model_node_create(ModelNode *parent)
        node->pos = (v3f32) {0.0f, 0.0f, 0.0f};
        node->rot = (v3f32) {0.0f, 0.0f, 0.0f};
        node->scale = (v3f32) {1.0f, 1.0f, 1.0f};
-       node->angle = 0.0f;
        array_ini(&node->meshes, sizeof(ModelMesh), 0);
        init_node(node, parent);
        return node;
@@ -378,22 +384,22 @@ ModelNode *model_node_create(ModelNode *parent)
 
 void model_node_transform(ModelNode *node)
 {
+       mat4x4_identity(node->rel);
+
        mat4x4_translate(node->rel,
                node->pos.x,
                node->pos.y,
                node->pos.z);
 
-       mat4x4_rotate(node->rel, node->rel,
-               node->rot.x,
-               node->rot.y,
-               node->rot.z,
-               node->angle);
-
        mat4x4_scale_aniso(node->rel, node->rel,
                node->scale.x,
                node->scale.y,
                node->scale.z);
 
+       mat4x4_rotate_X(node->rel, node->rel, node->rot.x);
+       mat4x4_rotate_Y(node->rel, node->rel, node->rot.y);
+       mat4x4_rotate_Z(node->rel, node->rel, node->rot.z);
+
        transform_node(node);
 }
 
@@ -506,37 +512,40 @@ void model_batch_add_vertex(ModelBatch *batch, GLuint texture, const void *verte
 
 void model_scene_add(Model *model)
 {
-       pthread_rwlock_wrlock(&lock_scene);
-       list_apd(&scene, model);
-       pthread_rwlock_unlock(&lock_scene);
+       pthread_mutex_lock(&lock_scene_new);
+       list_apd(&scene_new, model);
+       pthread_mutex_unlock(&lock_scene_new);
 }
 
 void model_scene_render(f64 dtime)
 {
+       pthread_mutex_lock(&lock_scene_new);
+       if (scene_new.fst) {
+               *scene.end = scene_new.fst;
+               scene.end = scene_new.end;
+
+               list_ini(&scene_new);
+       }
+       pthread_mutex_unlock(&lock_scene_new);
+
        Tree transparent;
        tree_ini(&transparent);
 
-       pthread_rwlock_rdlock(&lock_scene);
        for (ListNode **node = &scene.fst; *node != NULL;) {
                Model *model = (*node)->dat;
 
-               pthread_rwlock_unlock(&lock_scene);
                if (model->flags.delete) {
-                       model_delete(model);
+                       if (model->replace)
+                               (*node)->dat = model->replace;
+                       else
+                               list_nrm(&scene, node);
 
-                       pthread_rwlock_wrlock(&lock_scene);
-                       list_nrm(&scene, node);
-                       pthread_rwlock_unlock(&lock_scene);
-
-                       pthread_rwlock_rdlock(&lock_scene);
+                       model_delete(model);
                } else {
-                       model_step(model, &transparent, dtime);
-
-                       pthread_rwlock_rdlock(&lock_scene);
                        node = &(*node)->nxt;
+                       model_step(model, &transparent, dtime);
                }
        }
-       pthread_rwlock_unlock(&lock_scene);
 
        tree_clr(&transparent, &render_model, NULL, NULL, TRAVERSION_INORDER);
 }
index 663df77d0a5904d1f7f743f839be6ff302678e12..977dbc6e7c2574c993a40b3eda6d1b07fc1304f8 100644 (file)
@@ -28,7 +28,6 @@ typedef struct ModelNode {
        char *name;
        bool visible;
        v3f32 pos, rot, scale;
-       f32 angle;
        mat4x4 abs, rel;
        Array meshes;
        struct ModelNode *parent;
@@ -52,6 +51,7 @@ typedef struct Model {
        void *extra;
        aabb3f32 box;
        f32 distance;
+       struct Model *replace;
        struct {
                void (*step)(struct Model *model, f64 dtime);
                void (*delete)(struct Model *model);
index f4f050f2a0ab5a684738f4435e3b708355a64502..fcf358a6b0152938323e45378f5e9648b34c8f72 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "client/gl_debug.h"
 #include "client/shader.h"
 
 static GLuint compile_shader(GLenum type, const char *path, const char *name, GLuint program, const char *definitions)
@@ -45,7 +46,7 @@ static GLuint compile_shader(GLenum type, const char *path, const char *name, GL
 
        fclose(file);
 
-       GLuint id = glCreateShader(type);
+       GLuint id = glCreateShader(type); GL_DEBUG
 
        // Minimum OpenGL version is 4.2.0 (idk some shader feature from that version is required)
        const char *version = "#version 420 core\n"; // 420 blaze it
@@ -62,28 +63,28 @@ static GLuint compile_shader(GLenum type, const char *path, const char *name, GL
                size,
        };
 
-       glShaderSource(id, 3, code_list, size_list);
+       glShaderSource(id, 3, code_list, size_list); GL_DEBUG
 
-       glCompileShader(id);
+       glCompileShader(id); GL_DEBUG
 
        GLint success;
-       glGetShaderiv(id, GL_COMPILE_STATUS, &success);
+       glGetShaderiv(id, GL_COMPILE_STATUS, &success); GL_DEBUG
        if (!success) {
                char errbuf[BUFSIZ];
-               glGetShaderInfoLog(id, BUFSIZ, NULL, errbuf);
+               glGetShaderInfoLog(id, BUFSIZ, NULL, errbuf); GL_DEBUG
                fprintf(stderr, "[error] failed to compile %s shader: %s", name, errbuf);
-               glDeleteShader(id);
+               glDeleteShader(id); GL_DEBUG
                return 0;
        }
 
-       glAttachShader(program, id);
+       glAttachShader(program, id); GL_DEBUG
 
        return id;
 }
 
 bool shader_program_create(const char *path, GLuint *idptr, const char *definitions)
 {
-       GLuint id = glCreateProgram();
+       GLuint id = glCreateProgram(); GL_DEBUG
 
        if (!definitions)
                definitions = "";
@@ -91,27 +92,27 @@ bool shader_program_create(const char *path, GLuint *idptr, const char *definiti
        GLuint vert, frag;
 
        if (!(vert = compile_shader(GL_VERTEX_SHADER, path, "vertex", id, definitions))) {
-               glDeleteProgram(id);
+               glDeleteProgram(id); GL_DEBUG
                return false;
        }
 
        if (!(frag = compile_shader(GL_FRAGMENT_SHADER, path, "fragment", id, definitions))) {
-               glDeleteShader(vert);
-               glDeleteProgram(id);
+               glDeleteShader(vert); GL_DEBUG
+               glDeleteProgram(id); GL_DEBUG
                return false;
        }
 
-       glLinkProgram(id);
-       glDeleteShader(vert);
-       glDeleteShader(frag);
+       glLinkProgram(id); GL_DEBUG
+       glDeleteShader(vert); GL_DEBUG
+       glDeleteShader(frag); GL_DEBUG
 
        GLint success;
-       glGetProgramiv(id, GL_LINK_STATUS, &success);
+       glGetProgramiv(id, GL_LINK_STATUS, &success); GL_DEBUG
        if (!success) {
                char errbuf[BUFSIZ];
-               glGetProgramInfoLog(id, BUFSIZ, NULL, errbuf);
+               glGetProgramInfoLog(id, BUFSIZ, NULL, errbuf); GL_DEBUG
                fprintf(stderr, "[error] failed to link shader program: %s\n", errbuf);
-               glDeleteProgram(id);
+               glDeleteProgram(id); GL_DEBUG
                return false;
        }
 
index 45b78365ccf20ee7de9f05a3d69b02f80d30b968..e648d8d5cea138abc828d1bc605f21a39d8889da 100644 (file)
@@ -4,6 +4,7 @@
 #include "client/camera.h"
 #include "client/client.h"
 #include "client/cube.h"
+#include "client/gl_debug.h"
 #include "client/mesh.h"
 #include "client/shader.h"
 #include "client/sky.h"
@@ -90,10 +91,10 @@ bool sky_init()
                return false;
        }
 
-       glProgramUniform1iv(skybox_prog, glGetUniformLocation(skybox_prog, "textures"), 2, (GLint[]) {0, 1});
+       glProgramUniform1iv(skybox_prog, glGetUniformLocation(skybox_prog, "textures"), 2, (GLint[]) {0, 1}); GL_DEBUG
 
-       skybox_loc_VP = glGetUniformLocation(skybox_prog, "VP");
-       skybox_loc_daylight = glGetUniformLocation(skybox_prog, "daylight");
+       skybox_loc_VP = glGetUniformLocation(skybox_prog, "VP"); GL_DEBUG
+       skybox_loc_daylight = glGetUniformLocation(skybox_prog, "daylight"); GL_DEBUG
        skybox_texture_day = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/day")->txo;
        skybox_texture_night = texture_load_cubemap(RESSOURCE_PATH "textures/skybox/night")->txo;
        skybox_mesh.data = skybox_vertices;
@@ -106,7 +107,7 @@ bool sky_init()
                return false;
        }
 
-       sun_loc_MVP = glGetUniformLocation(sun_prog, "MVP");
+       sun_loc_MVP = glGetUniformLocation(sun_prog, "MVP"); GL_DEBUG
        sun_texture = texture_load(RESSOURCE_PATH "textures/sun.png", false)->txo;
 
        // clouds
@@ -116,8 +117,8 @@ bool sky_init()
                return false;
        }
 
-       clouds_loc_VP = glGetUniformLocation(clouds_prog, "VP");
-       clouds_loc_daylight = glGetUniformLocation(clouds_prog, "daylight");
+       clouds_loc_VP = glGetUniformLocation(clouds_prog, "VP"); GL_DEBUG
+       clouds_loc_daylight = glGetUniformLocation(clouds_prog, "daylight"); GL_DEBUG
        clouds_mesh.data = clouds_vertices;
        mesh_upload(&clouds_mesh);
 
@@ -126,13 +127,13 @@ bool sky_init()
 
 void sky_deinit()
 {
-       glDeleteProgram(sun_prog);
+       glDeleteProgram(sun_prog); GL_DEBUG
        mesh_destroy(&sun_mesh);
 
-       glDeleteProgram(skybox_prog);
+       glDeleteProgram(skybox_prog); GL_DEBUG
        mesh_destroy(&skybox_mesh);
 
-       glDeleteProgram(clouds_prog);
+       glDeleteProgram(clouds_prog); GL_DEBUG
        mesh_destroy(&clouds_mesh);
 }
 
@@ -161,27 +162,27 @@ void sky_render()
        mat4x4 mvp;
        mat4x4_mul(mvp, vp, model);
 
-       glDisable(GL_CULL_FACE);
-       glDepthFunc(GL_LEQUAL);
+       glDisable(GL_CULL_FACE); GL_DEBUG
+       glDepthFunc(GL_LEQUAL); GL_DEBUG
 
-       glUseProgram(skybox_prog);
-       glUniformMatrix4fv(skybox_loc_VP, 1, GL_FALSE, vp[0]);
-       glUniform1f(skybox_loc_daylight, daylight);
-       glBindTextureUnit(0, skybox_texture_day);
-       glBindTextureUnit(1, skybox_texture_night);
+       glUseProgram(skybox_prog); GL_DEBUG
+       glUniformMatrix4fv(skybox_loc_VP, 1, GL_FALSE, vp[0]); GL_DEBUG
+       glUniform1f(skybox_loc_daylight, daylight); GL_DEBUG
+       glBindTextureUnit(0, skybox_texture_day); GL_DEBUG
+       glBindTextureUnit(1, skybox_texture_night); GL_DEBUG
        mesh_render(&skybox_mesh);
 
-       glUseProgram(sun_prog);
-       glUniformMatrix4fv(sun_loc_MVP, 1, GL_FALSE, mvp[0]);
-       glBindTextureUnit(0, sun_texture);
+       glUseProgram(sun_prog); GL_DEBUG
+       glUniformMatrix4fv(sun_loc_MVP, 1, GL_FALSE, mvp[0]); GL_DEBUG
+       glBindTextureUnit(0, sun_texture); GL_DEBUG
        mesh_render(&sun_mesh);
 
-       glUseProgram(clouds_prog);
-       glUniformMatrix4fv(clouds_loc_VP, 1, GL_FALSE, vp[0]);
-       glUniform1f(clouds_loc_daylight, daylight);
-       glBindTextureUnit(0, skybox_texture_day);
+       glUseProgram(clouds_prog); GL_DEBUG
+       glUniformMatrix4fv(clouds_loc_VP, 1, GL_FALSE, vp[0]); GL_DEBUG
+       glUniform1f(clouds_loc_daylight, daylight); GL_DEBUG
+       glBindTextureUnit(0, skybox_texture_day); GL_DEBUG
        mesh_render(&clouds_mesh);
 
-       glDepthFunc(GL_LESS);
-       glEnable(GL_CULL_FACE);
+       glDepthFunc(GL_LESS); GL_DEBUG
+       glEnable(GL_CULL_FACE); GL_DEBUG
 }
index 38c7799e2c4a1d0a495b7e2f65e0b75c32d4f8f4..a8552215640e95afdf0d467eb7e479b4d7cbeb96 100644 (file)
@@ -2,15 +2,15 @@
 #include <linmath.h/linmath.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include "client/camera.h"
 #include "client/client_config.h"
 #include "client/client_node.h"
 #include "client/client_terrain.h"
 #include "client/cube.h"
 #include "client/frustum.h"
+#include "client/gl_debug.h"
+#include "client/light.h"
 #include "client/shader.h"
 #include "client/terrain_gfx.h"
-#include "day.h"
 
 typedef struct {
        bool visible;
@@ -51,14 +51,9 @@ static v3f32 center_offset = {
 };
 
 static GLuint shader_prog;
-static GLint loc_model;
 static GLint loc_VP;
-static GLint loc_daylight;
-static GLint loc_fogColor;
-static GLint loc_ambientLight;
-static GLint loc_lightDir;
-static GLint loc_cameraPos;
 
+static LightShader light_shader;
 static ModelShader model_shader;
 
 static inline bool cull_face(NodeType self, NodeType nbr)
@@ -202,7 +197,7 @@ static Model *create_chunk_model(TerrainChunk *chunk, bool animate)
 bool terrain_gfx_init()
 {
        GLint texture_units;
-       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
+       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units); GL_DEBUG
 
        char *shader_defs;
        asprintf(&shader_defs,
@@ -212,58 +207,39 @@ bool terrain_gfx_init()
                client_config.view_distance
        );
 
-       if (!shader_program_create(RESSOURCE_PATH "shaders/terrain", &shader_prog, shader_defs)) {
+       if (!shader_program_create(RESSOURCE_PATH "shaders/3d/terrain", &shader_prog, shader_defs)) {
                fprintf(stderr, "[error] failed to create terrain shader program\n");
                return false;
        }
 
        free(shader_defs);
 
-       loc_model = glGetUniformLocation(shader_prog, "model");
-       loc_VP = glGetUniformLocation(shader_prog, "VP");
-       loc_daylight = glGetUniformLocation(shader_prog, "daylight");
-       loc_fogColor = glGetUniformLocation(shader_prog, "fogColor");
-       loc_ambientLight = glGetUniformLocation(shader_prog, "ambientLight");
-       loc_lightDir = glGetUniformLocation(shader_prog, "lightDir");
-       loc_cameraPos = glGetUniformLocation(shader_prog, "cameraPos");
+       loc_VP = glGetUniformLocation(shader_prog, "VP"); GL_DEBUG
 
        GLint texture_indices[texture_units];
        for (GLint i = 0; i < texture_units; i++)
                texture_indices[i] = i;
 
-       glProgramUniform1iv(shader_prog, glGetUniformLocation(shader_prog, "textures"), texture_units, texture_indices);
+       glProgramUniform1iv(shader_prog, glGetUniformLocation(shader_prog, "textures"), texture_units, texture_indices); GL_DEBUG
 
        model_shader.prog = shader_prog;
-       model_shader.loc_transform = loc_model;
+       model_shader.loc_transform = glGetUniformLocation(shader_prog, "model"); GL_DEBUG
+
+       light_shader.prog = shader_prog;
+       light_shader_locate(&light_shader);
 
        return true;
 }
 
 void terrain_gfx_deinit()
 {
-       glDeleteProgram(shader_prog);
+       glDeleteProgram(shader_prog); GL_DEBUG
 }
 
 void terrain_gfx_update()
 {
-       vec4 base_sunlight_dir = {0.0f, 0.0f, -1.0f, 1.0f};
-       vec4 sunlight_dir;
-       mat4x4 sunlight_mat;
-       mat4x4_identity(sunlight_mat);
-
-       mat4x4_rotate(sunlight_mat, sunlight_mat, 1.0f, 0.0f, 0.0f, get_sun_angle() + M_PI / 2.0f);
-       mat4x4_mul_vec4(sunlight_dir, sunlight_mat, base_sunlight_dir);
-
-       f32 daylight = get_daylight();
-       f32 ambient_light = f32_mix(0.3f, 0.7f, daylight);
-       v3f32 fog_color = v3f32_mix((v3f32) {0x03, 0x0A, 0x1A}, (v3f32) {0x87, 0xCE, 0xEB}, daylight);
-
-       glProgramUniformMatrix4fv(shader_prog, loc_VP, 1, GL_FALSE, frustum[0]);
-       glProgramUniform3f(shader_prog, loc_lightDir, sunlight_dir[0], sunlight_dir[1], sunlight_dir[2]);
-       glProgramUniform3f(shader_prog, loc_cameraPos, camera.eye[0], camera.eye[1], camera.eye[2]);
-       glProgramUniform1f(shader_prog, loc_daylight, daylight);
-       glProgramUniform3f(shader_prog, loc_fogColor, fog_color.x / 0xFF * ambient_light, fog_color.y / 0xFF * ambient_light, fog_color.z / 0xFF * ambient_light);
-       glProgramUniform1f(shader_prog, loc_ambientLight, ambient_light);
+       glProgramUniformMatrix4fv(shader_prog, loc_VP, 1, GL_FALSE, frustum[0]); GL_DEBUG
+       light_shader_update(&light_shader);
 }
 
 void terrain_gfx_make_chunk_model(TerrainChunk *chunk)
@@ -288,13 +264,12 @@ void terrain_gfx_make_chunk_model(TerrainChunk *chunk)
                        model_node_transform(model->root);
                }
 
+               meta->model->replace = model;
                meta->model->flags.delete = 1;
+       } else if (model) {
+               model_scene_add(model);
        }
 
        meta->model = model;
-
-       if (model)
-               model_scene_add(model);
-
        pthread_mutex_unlock(&chunk->mtx);
 }
index 9f4f7ec74c9ce4e0fdb691de4c19c3c8d738d053..a80738faeb6c87c49fee353d50cd3456c377e00d 100644 (file)
@@ -1,8 +1,11 @@
 #define STB_IMAGE_IMPLEMENTATION
+#define STB_IMAGE_RESIZE_IMPLEMENTATION
 #include <stb/stb_image.h>
+#include <stb/stb_image_resize.h>
 #include <stdbool.h>
 #include <dragonstd/tree.h>
 #include "client/client_config.h"
+#include "client/gl_debug.h"
 #include "client/texture.h"
 
 static Tree textures;
@@ -22,7 +25,7 @@ static bool lookup_texture(char *path, Texture **texture)
        TreeNode **node = tree_nfd(&textures, path, &cmp_texture);
 
        if (*node) {
-               *texture = &((TextureLookup *) &(*node)->dat)->texture;
+               *texture = &((TextureLookup *) (*node)->dat)->texture;
                return true;
        }
 
@@ -70,14 +73,31 @@ Texture *texture_load(char *path, bool mipmap)
        return texture;
 }
 
+static inline int least_common_multiple(int a, int b)
+{
+       int high, low;
+       if (a > b) {
+               high = a;
+               low = b;
+       } else {
+               high = b;
+               low = a;
+       }
+
+       int lcm = high;
+       while (lcm % low)
+               lcm += high;
+       return lcm;
+}
+
 Texture *texture_load_cubemap(char *path)
 {
        Texture *texture;
        if (lookup_texture(path, &texture))
                return texture;
 
-       glGenTextures(1, &texture->txo);
-       glBindTexture(GL_TEXTURE_CUBE_MAP, texture->txo);
+       glGenTextures(1, &texture->txo); GL_DEBUG
+       glBindTexture(GL_TEXTURE_CUBE_MAP, texture->txo); GL_DEBUG
 
        const char *directions[6] = {
                "right",
@@ -88,48 +108,77 @@ Texture *texture_load_cubemap(char *path)
                "back",
        };
 
+       typedef struct {
+               unsigned char *data;
+               int width, height, channels;
+       } CubemapFace;
+
+       CubemapFace faces[6];
+       int size = 1;
+
        for (int i = 0; i < 6; i++) {
                char filename[strlen(path) + 1 + strlen(directions[i]) + 1 + 3 + 1];
                sprintf(filename, "%s/%s.png", path, directions[i]);
 
-               unsigned char *data = stbi_load(filename,
-                       &texture->width, &texture->height, &texture->channels, 0);
-               if (!data) {
+               if (!(faces[i].data = stbi_load(filename,
+                               &faces[i].width, &faces[i].height, &faces[i].channels, 0))) {
                        fprintf(stderr, "[error] failed to load texture %s\n", filename);
                        exit(EXIT_FAILURE);
                }
 
+               size = least_common_multiple(size, faces[i].width);
+               size = least_common_multiple(size, faces[i].height);
+       }
+
+       for (int i = 0; i < 6; i++) {
+               unsigned char *data = faces[i].data;
+
+               bool resize = faces[i].width != size || faces[i].height != size;
+               if (resize) {
+                       data = malloc(size * size * faces[i].channels);
+
+                       stbir_resize_uint8_generic(
+                               faces[i].data, faces[i].width, faces[i].height, 0,
+                               data, size, size, 0,
+                               faces[i].channels, STBIR_ALPHA_CHANNEL_NONE, 0,
+                               STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR,
+                               NULL);
+               }
+
                glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,
-                       texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
-               stbi_image_free(data);
+                       size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); GL_DEBUG
+
+               stbi_image_free(faces[i].data);
+               if (resize)
+                       stbi_image_free(data);
        }
 
-       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GL_DEBUG
 
        return texture;
 }
 
 void texture_upload(Texture *texture, unsigned char *data, GLenum format, bool mipmap)
 {
-       glGenTextures(1, &texture->txo);
-       glBindTexture(GL_TEXTURE_2D, texture->txo);
+       glGenTextures(1, &texture->txo); GL_DEBUG
+       glBindTexture(GL_TEXTURE_2D, texture->txo); GL_DEBUG
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mipmap && client_config.mipmap)
-               ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+               ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); GL_DEBUG
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); GL_DEBUG
 
        glTexImage2D(GL_TEXTURE_2D, 0, format,
-               texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, data);
-       glGenerateMipmap(GL_TEXTURE_2D);
+               texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, data); GL_DEBUG
+       glGenerateMipmap(GL_TEXTURE_2D); GL_DEBUG
 }
 
 void texture_destroy(Texture *texture)
 {
-       glDeleteTextures(1, &texture->txo);
+       glDeleteTextures(1, &texture->txo); GL_DEBUG
 }
index 63dc81f01f812c8d1df1402a794bd3f96558883f..b9460eb14ac3676f4211efe19dcd89fac0fb68a6 100644 (file)
@@ -4,6 +4,7 @@
 #include "client/client_config.h"
 #include "client/debug_menu.h"
 #include "client/game.h"
+#include "client/gl_debug.h"
 #include "client/gui.h"
 #include "client/input.h"
 #include "client/window.h"
@@ -22,7 +23,7 @@ static void update_projection()
 
 static void framebuffer_size_callback(__attribute__((unused)) GLFWwindow *handle, int width, int height)
 {
-       glViewport(0, 0, width, height);
+       glViewport(0, 0, width, height); GL_DEBUG
        window.width = width;
        window.height = height;
 
index 7f80044999a6238f3b82eae2cd94e6a87e54db76..5dc2bac9be813791ab24ce609a80e28f042ce1b3 100755 (executable)
@@ -19,6 +19,7 @@ define hook-stop
         quit
     end
 end
+break gl_error
 "
 
 echo "$COMMON
index 5a754e88ff1e1c6157b009e760ec996c2de3d735..0f18ebb7876294920977353b79aad41e5512f7cc 100644 (file)
@@ -90,5 +90,5 @@ static void delete_schematic_node(SchematicNode *node)
 
 void schematic_delete(List *schematic)
 {
-       list_clr(schematic, (void *) &delete_schematic_node, NULL, NULL);
+       list_clr(schematic, &delete_schematic_node, NULL, NULL);
 }
index f4bfaa104918a73642fc179a7d8c7b59b78f0a65..aaaba088d8470ade5e5fc42646b2b27550073fe2 100644 (file)
@@ -34,15 +34,7 @@ static void on_ToServerSetnode(__attribute__((unused)) DragonnetPeer *peer, ToSe
 // update player's position
 static void on_ToServerPosRot(DragonnetPeer *peer, ToServerPosRot *pkt)
 {
-       ServerPlayer *player = peer->extra;
-
-       pthread_rwlock_wrlock(&player->lock_pos);
-       player->pos = pkt->pos;
-       player->rot = pkt->rot;
-
-       // this is recv thread, no lock_auth needed
-       database_update_player_pos_rot(player->name, player->pos, player->rot);
-       pthread_rwlock_unlock(&player->lock_pos);
+       server_player_move(peer->extra, pkt->pos, pkt->rot);
 }
 
 // tell server map manager client requested the chunk
index 1f464f93e394a374246b9171d9a122980ecf4ed1..530e9efa4c5c495eac67f210b05329b5f71d36fa 100644 (file)
 static Map players;
 static Map players_named;
 
+static void send_entity_add(ServerPlayer *player, ServerPlayer *entity)
+{
+       dragonnet_peer_send_ToClientEntityAdd(player->peer, &(ToClientEntityAdd) {
+               .type = player == entity ? ENTITY_LOCALPLAYER : ENTITY_PLAYER,
+               .data = {
+                       .id = entity->id,
+                       .pos = entity->pos,
+                       .rot = entity->rot,
+                       .nametag = entity->name,
+               },
+       });
+}
+
+static void send_entity_remove(ServerPlayer *player, ServerPlayer *entity)
+{
+       dragonnet_peer_send_ToClientEntityRemove(player->peer, &(ToClientEntityRemove) {
+               .id = entity->id,
+       });
+}
+
+static void send_entity_update_pos_rot(ServerPlayer *player, ServerPlayer *entity)
+{
+       if (player != entity)
+               dragonnet_peer_send_ToClientEntityUpdatePosRot(player->peer, &(ToClientEntityUpdatePosRot) {
+                       .id = entity->id,
+                       .pos = entity->pos,
+                       .rot = entity->rot,
+               });
+}
+
+static void send_entity_add_existing(ServerPlayer *entity, ServerPlayer *player)
+{
+       if (player != entity) {
+               pthread_rwlock_rdlock(&entity->lock_pos);
+               send_entity_add(player, entity);
+               pthread_rwlock_unlock(&entity->lock_pos);
+       }
+}
+
 // main thread
 // called on server shutdown
 static void player_drop(ServerPlayer *player)
@@ -71,17 +110,9 @@ static void player_spawn(ServerPlayer *player)
                .gravity = server_config.movement.gravity,
                .jump = server_config.movement.jump,
        });
-       dragonnet_peer_send_ToClientEntityAdd(player->peer, &(ToClientEntityAdd) {
-               .type = ENTITY_LOCALPLAYER,
-               .data = {
-                       .id = player->id,
-                       .pos = player->pos,
-                       .rot = player->rot,
-                       .box = {{-0.3f, 0.0f, -0.3f}, {0.3f, 1.75f, 0.3f}},
-                       .eye = {0.0f, 1.75f, 0.0f},
-                       .nametag = NULL,
-               },
-       });
+
+       server_player_iterate(&send_entity_add, player);
+       server_player_iterate(&send_entity_add_existing, player);
 }
 
 // any thread
@@ -169,8 +200,12 @@ void server_player_remove(DragonnetPeer *peer)
        // (we don't want disconnect messages for every player on server shutdown)
        if (map_del(&players, &player->id, &cmp_player_id, &refcount_drp, NULL, NULL))
                printf("[access] disconnected %s\n", player->name);
-       if (player->auth)
-               map_del(&players_named, player->name, &cmp_player_name, &refcount_drp, NULL, NULL);
+
+       if (player->auth && map_del(&players_named, player->name, &cmp_player_name, &refcount_drp, NULL, NULL)) {
+               pthread_rwlock_rdlock(&player->lock_pos);
+               server_player_iterate(&send_entity_remove, player);
+               pthread_rwlock_unlock(&player->lock_pos);
+       }
 
        // peer no longer has a reference to player
        refcount_drp(&player->rc);
@@ -224,6 +259,16 @@ bool server_player_auth(ServerPlayer *player, char *name)
        return success;
 }
 
+// recv thread
+void server_player_move(ServerPlayer *player, v3f64 pos, v3f32 rot)
+{
+       pthread_rwlock_wrlock(&player->lock_pos);
+       // this is recv thread, no lock_auth needed
+       database_update_player_pos_rot(player->name, player->pos = pos, player->rot = rot);
+       server_player_iterate(&send_entity_update_pos_rot, player);
+       pthread_rwlock_unlock(&player->lock_pos);
+}
+
 // any thread
 void server_player_disconnect(ServerPlayer *player)
 {
index 71d0916bebbafaa4b18856096c33ed63988efd9f..1d20a5d6fb8efc95560e36c2814e689afc47f9a4 100644 (file)
@@ -34,6 +34,7 @@ ServerPlayer *server_player_grab_named(char *name);
 
 bool server_player_auth(ServerPlayer *player, char *name);
 void server_player_disconnect(ServerPlayer *player);
+void server_player_move(ServerPlayer *player, v3f64 pos, v3f32 rot);
 void server_player_iterate(void *func, void *arg);
 
 #endif // _SERVER_PLAYER_H_
index a4aa91e0166deb6a234fa988d1e8a401f9763ee0..f6a22da591188930cd73b6743abf0aa7f21fadb4 100644 (file)
@@ -72,7 +72,7 @@ static void send_chunk_to_near(TerrainChunk *chunk)
        if (meta->state == CHUNK_CREATED)
                return;
 
-       server_player_iterate((void *) &send_chunk, chunk);
+       server_player_iterate(&send_chunk, chunk);
 }
 
 // Iterator for sending changed chunks to near clients
@@ -104,7 +104,7 @@ static void terrain_gen_step()
        meta->state = CHUNK_READY;
        pthread_mutex_unlock(&chunk->mtx);
 
-       list_clr(&changed_chunks, (void *) &iterator_send_chunk_to_near, NULL, NULL);
+       list_clr(&changed_chunks, &iterator_send_chunk_to_near, NULL, NULL);
 
        pthread_mutex_lock(&mtx_num_gen_chunks);
        num_gen_chunks--;
@@ -276,7 +276,7 @@ static void generate_spawn_hut()
        }
 
        Blob_free(&wood_color);
-       list_clr(&changed_chunks, (void *) iterator_send_chunk_to_near, NULL, NULL);
+       list_clr(&changed_chunks, &iterator_send_chunk_to_near, NULL, NULL);
 }
 
 // public functions
index bea87fd76e932ace14fda44e4ac6daeb317e617b..7148102130a319ececc0007c0050aa1f660444c9 100644 (file)
@@ -46,7 +46,7 @@ Voxelctx *voxelctx_create(List *changed_chunks, TerrainGenStage tgs, v3s32 pos)
 
 void voxelctx_delete(Voxelctx *ctx)
 {
-       list_clr(&ctx->statestack, (void *) &free, NULL, NULL);
+       list_clr(&ctx->statestack, &free, NULL, NULL);
        free(ctx);
 }
 
index 5b6d48a8f5c1d9a43ce2f79c3db0e764b9b36edb..2e8eec888072b94177a7299a6061819dd0813711 100644 (file)
@@ -15,7 +15,7 @@ static void delete_chunk(TerrainChunk *chunk, Terrain *terrain)
 
 static void delete_sector(TerrainSector *sector, Terrain *terrain)
 {
-       tree_clr(&sector->chunks, (void *) &delete_chunk, terrain, NULL, 0);
+       tree_clr(&sector->chunks, &delete_chunk, terrain, NULL, 0);
        pthread_rwlock_destroy(&sector->lock);
        free(sector);
 }
@@ -32,7 +32,7 @@ Terrain *terrain_create()
 
 void terrain_delete(Terrain *terrain)
 {
-       tree_clr(&terrain->sectors, (void *) &delete_sector, terrain, NULL, 0);
+       tree_clr(&terrain->sectors, &delete_sector, terrain, NULL, 0);
        pthread_rwlock_destroy(&terrain->lock);
        pthread_rwlock_destroy(&terrain->cache_lock);
        free(terrain);
index 9aa6aa710989b42e2df4704e4adffa6441ad0346..48c572b788499793c8361a8cfca7bfaa2a833a41 100644 (file)
@@ -23,8 +23,6 @@ EntityData
        u64 id
        v3f64 pos
        v3f32 rot
-       aabb3f32 box
-       v3f32 eye
        String nametag
 
 ; server packets
@@ -82,11 +80,6 @@ pkt ToClientEntityUpdatePosRot
        v3f64 pos
        v3f32 rot
 
-pkt ToClientEntityUpdateBoxEye
-       u64 id
-       aabb3f32 box
-       v3f32 eye
-
 pkt ToClientEntityUpdateNametag
        u64 id
        String nametag
index 25e2782fff1629b72c2e32b0a88211e6709d1506..f6e2306c9c7ae8cfe79678b03f092477c8105ccb 100644 (file)
@@ -3,7 +3,7 @@ execute_process(COMMAND git tag --points-at HEAD
        OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
-if ("${GIT_VERSION}" STREQUAL "")
+if("${GIT_VERSION}" STREQUAL "")
        execute_process(COMMAND git rev-parse --short HEAD
                OUTPUT_VARIABLE GIT_VERSION
                OUTPUT_STRIP_TRAILING_WHITESPACE
index 6b98546182867872793f9df81b72bcbc1b15d251..69ffff3be71ce28b6ef544af03f85dc5e0c0f636 100644 (file)
Binary files a/textures/models/player/arm/back.png and b/textures/models/player/arm/back.png differ
index ceaa6aaac1cec80bafbfedd93fe00a0b7d38cc65..fda334e9c6b74f5895a78d2b26011bedb0a8a95d 100644 (file)
Binary files a/textures/models/player/arm/bottom.png and b/textures/models/player/arm/bottom.png differ
index f62ee88681509fa932da82769c8d6234975682ff..ce19461a6f724f68b0476ebbba2804a5bfee1ff4 100644 (file)
Binary files a/textures/models/player/arm/front.png and b/textures/models/player/arm/front.png differ
index 558391a20a15e252aa47f2112156ba8eed2ad761..c2b232590cf461917f6cc367a53ad19b98780ac2 100644 (file)
Binary files a/textures/models/player/arm/left.png and b/textures/models/player/arm/left.png differ
index b1b7b9fc83c9ee7bdd40ed3844adbec4bc59de72..9ae2e41758835feaff48f9617002934af80e91e6 100644 (file)
Binary files a/textures/models/player/arm/right.png and b/textures/models/player/arm/right.png differ
index 45567caffdbbc6d14967e864e50943d6705ddf39..e12765d411d1b6ec14aa9fa83963e1281cb252ba 100644 (file)
Binary files a/textures/models/player/arm/top.png and b/textures/models/player/arm/top.png differ
index 0a0a8620a5a5e69e7da1fc83ad01c851d195448c..5eca9ecf87af11f699c396c291f10e635b7fe3ea 100644 (file)
Binary files a/textures/models/player/chest/back.png and b/textures/models/player/chest/back.png differ
index e51749a758c8bfd1bd028a1b212bed3e3e545206..131d33d99d0311a793666ff269bc3b0cfa9eae70 100644 (file)
Binary files a/textures/models/player/chest/bottom.png and b/textures/models/player/chest/bottom.png differ
index 6ec46e1f38a32a5a8f774c258bbffefab7644b3e..d44fd420aa38fba5e0b0a1b4faf898db50454269 100644 (file)
Binary files a/textures/models/player/chest/front.png and b/textures/models/player/chest/front.png differ
index c04fb713c7f00614e97573cd878b4b6dc33c99d1..995ad5fadc7144f310615f686323e21914a03571 100644 (file)
Binary files a/textures/models/player/chest/left.png and b/textures/models/player/chest/left.png differ
index 60329f4beecd3ce314556b634704e11fe40d1908..e48eb6695465de27bd3ee9e00c57003c561a58ea 100644 (file)
Binary files a/textures/models/player/chest/right.png and b/textures/models/player/chest/right.png differ
index 2711dd1aacc6b7040ab0d753bdc994bead1b071f..df84083be64c2b6b985b949786631a4a238379f6 100644 (file)
Binary files a/textures/models/player/chest/top.png and b/textures/models/player/chest/top.png differ
index 6b98546182867872793f9df81b72bcbc1b15d251..935a2b91032aa1d99886e9da518858fbdc669ee2 100644 (file)
Binary files a/textures/models/player/head/back.png and b/textures/models/player/head/back.png differ
index ceaa6aaac1cec80bafbfedd93fe00a0b7d38cc65..1fdae432cde4efef640a85af38f80fb04ae47764 100644 (file)
Binary files a/textures/models/player/head/bottom.png and b/textures/models/player/head/bottom.png differ
index f62ee88681509fa932da82769c8d6234975682ff..805fec0ef8d87bdac17dd7e396456811547c744f 100644 (file)
Binary files a/textures/models/player/head/front.png and b/textures/models/player/head/front.png differ
index 558391a20a15e252aa47f2112156ba8eed2ad761..7dc2a8178668ebb6c7124ada368c7abc7a5e89f8 100644 (file)
Binary files a/textures/models/player/head/left.png and b/textures/models/player/head/left.png differ
index b1b7b9fc83c9ee7bdd40ed3844adbec4bc59de72..47436ba379c29c1e36ea9983c421cc78cae9fbcd 100644 (file)
Binary files a/textures/models/player/head/right.png and b/textures/models/player/head/right.png differ
index 45567caffdbbc6d14967e864e50943d6705ddf39..916ea2b5668f000b3c45a9e15085288699b98c78 100644 (file)
Binary files a/textures/models/player/head/top.png and b/textures/models/player/head/top.png differ
index 6b98546182867872793f9df81b72bcbc1b15d251..48b93ce23de06c5c8a2d710d98b671eb3b4f2dba 100644 (file)
Binary files a/textures/models/player/leg/back.png and b/textures/models/player/leg/back.png differ
index ceaa6aaac1cec80bafbfedd93fe00a0b7d38cc65..0c942fb793139aff0409c912e50e18d36cd6afce 100644 (file)
Binary files a/textures/models/player/leg/bottom.png and b/textures/models/player/leg/bottom.png differ
index f62ee88681509fa932da82769c8d6234975682ff..13b10160f7568b4858424f4e190db48f76682032 100644 (file)
Binary files a/textures/models/player/leg/front.png and b/textures/models/player/leg/front.png differ
index 558391a20a15e252aa47f2112156ba8eed2ad761..104c6e74e0ba8d338bae30a0827a23a299125010 100644 (file)
Binary files a/textures/models/player/leg/left.png and b/textures/models/player/leg/left.png differ
index b1b7b9fc83c9ee7bdd40ed3844adbec4bc59de72..a97a13ac6c65d6cf04e182cec0e89b4b4e58108e 100644 (file)
Binary files a/textures/models/player/leg/right.png and b/textures/models/player/leg/right.png differ
index 45567caffdbbc6d14967e864e50943d6705ddf39..d575dc75f6d14440852873a2c0c37d554e3895b0 100644 (file)
Binary files a/textures/models/player/leg/top.png and b/textures/models/player/leg/top.png differ