ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cf.schmorp.de/Deliantra-Client/texcache.c
Revision: 1.6
Committed: Tue Dec 25 19:08:31 2007 UTC (16 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_03, rel-2_02, rel-0_9965, rel-0_9964, rel-0_9963, rel-2_05, rel-2_04, rel-0_9968, rel-2_0, rel-0_9972, rel-0_9973, rel-0_9974, rel-0_9975, rel-0_9976, rel-0_9977, rel-0_9978, rel-0_9971, rel-0_9967, rel-1_21, rel-0_9966
Changes since 1.5: +5 -3 lines
Log Message:
staticify

File Contents

# Content
1 // all these must be powers of two
2 // width and height better be <=256 as we use bytes in the rendercache
3 #define TC_WIDTH 256
4 #define TC_HEIGHT 256
5 #define TC_ROUND 4
6
7 typedef struct {
8 GLuint name;
9 int x, y, w, h;
10 } tc_area;
11
12 extern int tc_generation;
13
14 static void tc_get (tc_area *area, int width, int height);
15 static void tc_put (tc_area *area);
16 static void tc_clear (void);
17 static void tc_backup (void);
18 static void tc_restore (void);
19
20 /////////////////////////////////////////////////////////////////////////////
21
22 #include <glib.h>
23
24 int tc_generation;
25
26 typedef struct tc_texture {
27 struct tc_texture *next;
28 GLuint name;
29 int avail;
30 char *saved; /* stores saved texture data */
31 } tc_texture;
32
33 typedef struct tc_slice {
34 GLuint name;
35 int avail, y;
36 } tc_slice;
37
38 static tc_slice slices[TC_HEIGHT / TC_ROUND];
39 static tc_texture *first_texture;
40
41 void
42 tc_clear (void)
43 {
44 int i;
45
46 for (i = TC_HEIGHT / TC_ROUND; i--; )
47 slices [i].name = 0;
48
49 while (first_texture)
50 {
51 tc_texture *next = first_texture->next;
52 del_texture (first_texture->name);
53 g_slice_free (tc_texture, first_texture);
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;
91 }
92 }
93
94 void
95 tc_get (tc_area *area, int width, int height)
96 {
97 int slice_height = MIN (height + TC_ROUND - 1, TC_HEIGHT) & ~(TC_ROUND - 1);
98 tc_slice *slice = slices + slice_height / TC_ROUND;
99
100 area->w = width;
101 area->h = height;
102
103 width = MIN (width, TC_WIDTH);
104
105 if (!slice->name || slice->avail < width)
106 {
107 // try to find a texture with enough space
108 tc_texture *tex, *match = 0;
109
110 for (tex = first_texture; tex; tex = tex->next)
111 if (tex->avail >= slice_height && (!match || match->avail > tex->avail))
112 match = tex;
113
114 // create a new texture if necessary
115 if (!match)
116 {
117 match = g_slice_new (tc_texture);
118 match->next = first_texture;
119 first_texture = match;
120 match->name = gen_texture ();
121 match->avail = TC_HEIGHT;
122 match->saved = 0;
123
124 glBindTexture (GL_TEXTURE_2D, match->name);
125 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
126 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
127 glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
128 }
129
130 match->avail -= slice_height;
131
132 slice->name = match->name;
133 slice->avail = TC_WIDTH;
134 slice->y = match->avail;
135 }
136
137 slice->avail -= width;
138
139 area->name = slice->name;
140 area->x = slice->avail;
141 area->y = slice->y;
142 }
143
144 void
145 tc_put (tc_area *area)
146 {
147 // our management is too primitive to support this operation yet
148 }