summaryrefslogtreecommitdiff
path: root/src/modules/sparkler/sparkler.c
blob: b2de5ee5f291b3321979f9fe9e09b4f0ae13505f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "fb.h"
#include "rototiller.h"
#include "util.h"

#include "particles.h"

/* particle system gadget (C) Vito Caputo <vcaputo@pengaru.com> 2/15/2014 */
/* 1/10/2015 added octree bsp (though not yet leveraged) */
/* 11/25/2016 refactor and begun adapting to rototiller */

#define INIT_PARTS 100

typedef struct sparkler_context_t {
	particles_t	*particles;
	unsigned	n_cpus;
} sparkler_context_t;

extern particle_ops_t	simple_ops;


static void * sparkler_create_context(unsigned num_cpus)
{
	static int		initialized;
	sparkler_context_t	*ctxt;

	if (!initialized) {
		srand(time(NULL) + getpid());
		initialized = 1;
	}

	ctxt = calloc(1, sizeof(sparkler_context_t));
	if (!ctxt)
		return NULL;

	ctxt->particles = particles_new();
	if (!ctxt->particles) {
		free(ctxt);
		return NULL;
	}

	particles_add_particles(ctxt->particles, NULL, &simple_ops, INIT_PARTS);

	return ctxt;
}


static void sparkler_destroy_context(void *context)
{
	sparkler_context_t	*ctxt = context;

	particles_free(ctxt->particles);
	free(ctxt);
}


static int sparkler_fragmenter(void *context, const fb_fragment_t *fragment, unsigned number, fb_fragment_t *res_fragment)
{
	sparkler_context_t	*ctxt = context;

	return fb_fragment_slice_single(fragment, ctxt->n_cpus, number, res_fragment);
}

static void sparkler_prepare_frame(void *context, unsigned ncpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
	sparkler_context_t	*ctxt = context;

	*res_fragmenter = sparkler_fragmenter;
	ctxt->n_cpus = ncpus;

	particles_sim(ctxt->particles);
	particles_add_particles(ctxt->particles, NULL, &simple_ops, INIT_PARTS / 4);
	particles_age(ctxt->particles);
}


/* Render a 3D particle system */
static void sparkler_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
{
	sparkler_context_t	*ctxt = context;

	fb_fragment_zero(fragment);
	particles_draw(ctxt->particles, fragment);
}


rototiller_module_t	sparkler_module = {
	.create_context = sparkler_create_context,
	.destroy_context = sparkler_destroy_context,
	.prepare_frame = sparkler_prepare_frame,
	.render_fragment = sparkler_render_fragment,
	.name = "sparkler",
	.description = "Particle system with spatial interactions (threaded (poorly))",
	.author = "Vito Caputo <vcaputo@pengaru.com>",
	.license = "GPLv2",
};
© All Rights Reserved