]> git.lizzy.rs Git - dragonblocks_alpha.git/blobdiff - src/client/model.c
Fix memory leak in model.c
[dragonblocks_alpha.git] / src / client / model.c
index c770d1c3e15904dc04a7f6c963e57d7f71254f3c..7c1c1e2b6170e7a5da819538e7011fcbf373a19d 100644 (file)
@@ -1,11 +1,12 @@
 #include <dragonstd/tree.h>
+#include <getline.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include "client/camera.h"
 #include "client/client_config.h"
 #include "client/frustum.h"
-#include "client/gl_debug.h"
+#include "client/opengl.h"
 #include "client/model.h"
 
 typedef struct {
@@ -18,7 +19,6 @@ static List scene_new;
 static pthread_mutex_t lock_scene_new;
 static GLint units;
 
-// fixme: blending issues still occur
 static int cmp_batch_texture(const ModelBatchTexture *ta, const ModelBatchTexture *tb)
 {
        return
@@ -56,9 +56,16 @@ static void render_node(ModelNode *node)
        if (!node->visible)
                return;
 
+       if (node->clockwise) {
+               glFrontFace(GL_CW); GL_DEBUG
+       }
+
        for (size_t i = 0; i < node->meshes.siz; i++) {
                ModelMesh *mesh = &((ModelMesh *) node->meshes.ptr)[i];
 
+               if (!mesh->mesh)
+                       continue;
+
                glUseProgram(mesh->shader->prog); GL_DEBUG
                glUniformMatrix4fv(mesh->shader->loc_transform, 1, GL_FALSE, node->abs[0]); GL_DEBUG
 
@@ -71,6 +78,10 @@ static void render_node(ModelNode *node)
        }
 
        list_itr(&node->children, &render_node, NULL, NULL);
+
+       if (node->clockwise) {
+               glFrontFace(GL_CCW); GL_DEBUG
+       }
 }
 
 static void free_node_meshes(ModelNode *node)
@@ -96,6 +107,8 @@ static void delete_node(ModelNode *node)
        list_clr(&node->children, &delete_node, NULL, NULL);
        array_clr(&node->meshes);
 
+       if (node->name)
+               free(node->name);
        free(node);
 }
 
@@ -118,6 +131,8 @@ static ModelNode *clone_node(ModelNode *original, ModelNode *parent)
 {
        ModelNode *node = malloc(sizeof *node);
        *node = *original;
+       if (original->name)
+               node->name = strdup(original->name);
        init_node(node, parent);
 
        array_cln(&node->meshes, &original->meshes);
@@ -130,34 +145,32 @@ static ModelNode *clone_node(ModelNode *original, ModelNode *parent)
 
 static int cmp_model(const Model *model, const f32 *distance)
 {
-       return f32_cmp(&model->distance, distance);
+       return -f32_cmp(&model->distance, distance);
 }
 
 static void render_model(Model *model)
 {
-       if (model->flags.wireframe) {
-               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_DEBUG
-       }
+       if (model->callbacks.before_render)
+               model->callbacks.before_render(model);
 
        render_node(model->root);
 
-       if (model->flags.wireframe) {
-               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GL_DEBUG
-       }
+       if (model->callbacks.after_render)
+               model->callbacks.after_render(model);
 }
 
 // step model help im stuck
 static void model_step(Model *model, Tree *transparent, f64 dtime)
 {
+       if (model->callbacks.step)
+               model->callbacks.step(model, dtime);
+
        if (client_config.view_distance < (model->distance = sqrt(
                        pow(model->root->pos.x - camera.eye[0], 2) +
                        pow(model->root->pos.y - camera.eye[1], 2) +
                        pow(model->root->pos.z - camera.eye[2], 2))))
                return;
 
-       if (model->callbacks.step)
-               model->callbacks.step(model, dtime);
-
        if (!model->root->visible)
                return;
 
@@ -180,7 +193,7 @@ void model_init()
        list_ini(&scene_new);
 
        pthread_mutex_init(&lock_scene_new, NULL);
-       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); GL_DEBUG
+       units = opengl_texture_batch_units();
 }
 
 // ded
@@ -202,10 +215,11 @@ Model *model_create()
        model->replace = NULL;
 
        model->callbacks.step = NULL;
+       model->callbacks.before_render = NULL;
+       model->callbacks.after_render = NULL;
        model->callbacks.delete = NULL;
 
        model->flags.delete =
-               model->flags.wireframe =
                model->flags.frustum_culling =
                model->flags.transparent = 0;
 
@@ -277,11 +291,15 @@ Model *model_load(const char *path, const char *textures_path, Mesh *cube, Model
                                        cursor += n;
                                else
                                        fprintf(stderr, "[warning] invalid value for rot in model %s in line %d\n", path, count);
+
+                               node->rot = v3f32_scale(node->rot, M_PI / 180.0);
                        } else if (strcmp(key, "scale") == 0) {
                                if (sscanf(cursor, "%f %f %f %n", &node->scale.x, &node->scale.y, &node->scale.z, &n) == 3)
                                        cursor += n;
                                else
                                        fprintf(stderr, "[warning] invalid value for scale in model %s in line %d\n", path, count);
+                       } else if (strcmp(key, "clockwise") == 0) {
+                               node->clockwise = 1;
                        } else if (strcmp(key, "cube") == 0) {
                                char texture[length + 1];
 
@@ -290,7 +308,7 @@ Model *model_load(const char *path, const char *textures_path, Mesh *cube, Model
 
                                        char filepath[strlen(textures_path) + 1 + strlen(texture) + 1];
                                        sprintf(filepath, "%s/%s", textures_path, texture);
-                                       Texture *texture = texture_load_cubemap(filepath);
+                                       Texture *texture = texture_load_cubemap(filepath, false);
 
                                        model_node_add_mesh(node, &(ModelMesh) {
                                                .mesh = cube,
@@ -373,7 +391,8 @@ ModelNode *model_node_create(ModelNode *parent)
 {
        ModelNode *node = malloc(sizeof *node);
        node->name = NULL;
-       node->visible = true;
+       node->visible = 1;
+       node->clockwise = 0;
        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};
@@ -421,7 +440,7 @@ void model_node_add_batch(ModelNode *node, ModelBatch *batch)
 
        size_t num_meshes = ceil((double) batch->textures.siz / (double) units);
        array_grw(&node->meshes, num_meshes);
-       ModelMesh *meshes = node->meshes.ptr + node->meshes.siz - num_meshes;
+       ModelMesh *meshes = &((ModelMesh *) node->meshes.ptr)[node->meshes.siz - num_meshes];
 
        for (size_t m = 0; m < num_meshes; m++) {
                ModelMesh *mesh = &meshes[m];