1 | // all these must be powers of two |
1 | // all these must be powers of two |
|
|
2 | // width and height better be <=256 as we use bytes in the rendercache |
2 | #define TC_WIDTH 256 |
3 | #define TC_WIDTH 256 |
3 | #define TC_HEIGHT 256 |
4 | #define TC_HEIGHT 256 |
4 | #define TC_ROUND 4 |
5 | #define TC_ROUND 4 |
5 | |
6 | |
6 | typedef struct { |
7 | typedef struct { |
7 | GLuint name; |
8 | GLuint name; |
8 | int x, y, w, h; |
9 | int x, y, w, h; |
9 | } tc_area; |
10 | } tc_area; |
10 | |
11 | |
|
|
12 | extern int tc_generation; |
|
|
13 | |
11 | void tc_get (tc_area *area, int width, int height); |
14 | static void tc_get (tc_area *area, int width, int height); |
12 | void tc_put (tc_area *area); |
15 | static void tc_put (tc_area *area); |
13 | void tc_clear (); |
16 | static void tc_clear (void); |
|
|
17 | static void tc_backup (void); |
|
|
18 | static void tc_restore (void); |
14 | |
19 | |
15 | ///////////////////////////////////////////////////////////////////////////// |
20 | ///////////////////////////////////////////////////////////////////////////// |
16 | |
21 | |
17 | #include <glib.h> |
22 | #include <glib.h> |
18 | |
23 | |
|
|
24 | int tc_generation; |
|
|
25 | |
19 | typedef struct tc_texture { |
26 | typedef struct tc_texture { |
20 | struct tc_texture *next; |
27 | struct tc_texture *next; |
21 | GLuint name; |
28 | GLuint name; |
22 | int avail; |
29 | int avail; |
|
|
30 | char *saved; /* stores saved texture data */ |
23 | } tc_texture; |
31 | } tc_texture; |
24 | |
32 | |
25 | typedef struct tc_slice { |
33 | typedef struct tc_slice { |
26 | GLuint name; |
34 | GLuint name; |
27 | int avail, y; |
35 | int avail, y; |
… | |
… | |
29 | |
37 | |
30 | static tc_slice slices[TC_HEIGHT / TC_ROUND]; |
38 | static tc_slice slices[TC_HEIGHT / TC_ROUND]; |
31 | static tc_texture *first_texture; |
39 | static tc_texture *first_texture; |
32 | |
40 | |
33 | void |
41 | void |
34 | tc_clear () |
42 | tc_clear (void) |
35 | { |
43 | { |
36 | int i; |
44 | int i; |
37 | |
45 | |
38 | for (i = TC_HEIGHT / TC_ROUND; i--; ) |
46 | for (i = TC_HEIGHT / TC_ROUND; i--; ) |
39 | slices [i].name = 0; |
47 | slices [i].name = 0; |
40 | |
48 | |
41 | while (first_texture) |
49 | while (first_texture) |
42 | { |
50 | { |
43 | tc_texture *next = first_texture->next; |
51 | tc_texture *next = first_texture->next; |
44 | glDeleteTextures (1, &first_texture->name); |
52 | del_texture (first_texture->name); |
45 | g_slice_free (tc_texture, first_texture); |
53 | g_slice_free (tc_texture, first_texture); |
46 | first_texture = next; |
54 | first_texture = next; |
|
|
55 | } |
|
|
56 | |
|
|
57 | ++tc_generation; |
|
|
58 | } |
|
|
59 | |
|
|
60 | void |
|
|
61 | tc_backup (void) |
|
|
62 | { |
|
|
63 | tc_texture *tex = first_texture; |
|
|
64 | while (tex) |
|
|
65 | { |
|
|
66 | tex->saved = g_slice_alloc (TC_WIDTH * TC_HEIGHT); |
|
|
67 | |
|
|
68 | glBindTexture (GL_TEXTURE_2D, tex->name); |
|
|
69 | glGetTexImage (GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved); |
|
|
70 | |
|
|
71 | tex = tex->next; |
|
|
72 | } |
|
|
73 | } |
|
|
74 | |
|
|
75 | void |
|
|
76 | tc_restore (void) |
|
|
77 | { |
|
|
78 | tc_texture *tex = first_texture; |
|
|
79 | |
|
|
80 | while (tex) |
|
|
81 | { |
|
|
82 | glBindTexture (GL_TEXTURE_2D, tex->name); |
|
|
83 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
84 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
85 | glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved); |
|
|
86 | |
|
|
87 | g_slice_free1 (TC_WIDTH * TC_HEIGHT, tex->saved); |
|
|
88 | tex->saved = 0; |
|
|
89 | |
|
|
90 | tex = tex->next; |
47 | } |
91 | } |
48 | } |
92 | } |
49 | |
93 | |
50 | void |
94 | void |
51 | tc_get (tc_area *area, int width, int height) |
95 | tc_get (tc_area *area, int width, int height) |
… | |
… | |
69 | |
113 | |
70 | // create a new texture if necessary |
114 | // create a new texture if necessary |
71 | if (!match) |
115 | if (!match) |
72 | { |
116 | { |
73 | match = g_slice_new (tc_texture); |
117 | match = g_slice_new (tc_texture); |
74 | match->next = first_texture; |
118 | match->next = first_texture; |
75 | first_texture = match; |
119 | first_texture = match; |
76 | glGenTextures (1, &match->name); |
120 | match->name = gen_texture (); |
77 | match->avail = TC_HEIGHT; |
121 | match->avail = TC_HEIGHT; |
|
|
122 | match->saved = 0; |
78 | |
123 | |
79 | glBindTexture (GL_TEXTURE_2D, match->name); |
124 | glBindTexture (GL_TEXTURE_2D, match->name); |
80 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
125 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
81 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
126 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
82 | glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); |
127 | glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); |