ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/texcache.c
(Generate patch)

Comparing deliantra/Deliantra-Client/texcache.c (file contents):
Revision 1.1 by root, Tue Jul 4 23:23:32 2006 UTC vs.
Revision 1.9 by root, Sun Nov 18 00:52:22 2018 UTC

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
6typedef struct { 7typedef 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
12extern int tc_generation;
13
11void tc_get (tc_area *area, int width, int height); 14static void tc_get (tc_area *area, int width, int height);
12void tc_put (tc_area *area); 15static void tc_put (tc_area *area);
13void tc_clear (); 16static void tc_clear (void);
17static void tc_backup (void);
18static void tc_restore (void);
14 19
15///////////////////////////////////////////////////////////////////////////// 20/////////////////////////////////////////////////////////////////////////////
16 21
22// required as bug-workaround for apple/ati/...
23static unsigned char tc_temptile [TC_WIDTH * TC_HEIGHT];
24
17#include <glib.h> 25#include <glib.h>
26
27int tc_generation;
18 28
19typedef struct tc_texture { 29typedef struct tc_texture {
20 struct tc_texture *next; 30 struct tc_texture *next;
21 GLuint name; 31 GLuint name;
22 int avail; 32 int avail;
33 char *saved; /* stores saved texture data */
23} tc_texture; 34} tc_texture;
24 35
25typedef struct tc_slice { 36typedef struct tc_slice {
26 GLuint name; 37 GLuint name;
27 int avail, y; 38 int avail, y;
29 40
30static tc_slice slices[TC_HEIGHT / TC_ROUND]; 41static tc_slice slices[TC_HEIGHT / TC_ROUND];
31static tc_texture *first_texture; 42static tc_texture *first_texture;
32 43
33void 44void
34tc_clear () 45tc_clear (void)
35{ 46{
36 int i; 47 int i;
37 48
38 for (i = TC_HEIGHT / TC_ROUND; i--; ) 49 for (i = TC_HEIGHT / TC_ROUND; i--; )
39 slices [i].name = 0; 50 slices [i].name = 0;
40 51
41 while (first_texture) 52 while (first_texture)
42 { 53 {
43 tc_texture *next = first_texture->next; 54 tc_texture *next = first_texture->next;
44 glDeleteTextures (1, &first_texture->name); 55 del_texture (first_texture->name);
45 g_slice_free (tc_texture, first_texture); 56 g_slice_free (tc_texture, first_texture);
46 first_texture = next; 57 first_texture = next;
47 } 58 }
59
60 ++tc_generation;
61}
62
63void
64tex_backup (tc_texture *tex)
65{
66 tex->saved = (char *)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
72void
73tex_restore (tc_texture *tex)
74{
75 glBindTexture (GL_TEXTURE_2D, tex->name);
76 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
77 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
78 glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved);
79
80 g_slice_free1 (TC_WIDTH * TC_HEIGHT, tex->saved);
81 tex->saved = 0;
82}
83
84void
85tc_backup (void)
86{
87 tc_texture *tex;
88
89 for (tex = first_texture; tex; tex = tex->next)
90 tex_backup (tex);
91}
92
93void
94tc_restore (void)
95{
96 tc_texture *tex;
97
98 for (tex = first_texture; tex; tex = tex->next)
99 tex_restore (tex);
48} 100}
49 101
50void 102void
51tc_get (tc_area *area, int width, int height) 103tc_get (tc_area *area, int width, int height)
52{ 104{
69 121
70 // create a new texture if necessary 122 // create a new texture if necessary
71 if (!match) 123 if (!match)
72 { 124 {
73 match = g_slice_new (tc_texture); 125 match = g_slice_new (tc_texture);
74 match->next = first_texture; 126 match->next = first_texture;
75 first_texture = match; 127 first_texture = match;
76 glGenTextures (1, &match->name); 128 match->name = gen_texture ();
77 match->avail = TC_HEIGHT; 129 match->avail = TC_HEIGHT;
130 match->saved = 0;
78 131
79 glBindTexture (GL_TEXTURE_2D, match->name); 132 glBindTexture (GL_TEXTURE_2D, match->name);
80 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 133 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 134 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); 135
136 // the last parameter should be NULL, but way too amny drivers (ATI, Mesa) crash,
137 // so we better provide some random garbage data for them.
138 glTexImage2D (GL_TEXTURE_2D,
139 0, GL_ALPHA,
140 TC_WIDTH, TC_HEIGHT,
141 0, GL_ALPHA,
142 GL_UNSIGNED_BYTE, tc_temptile);
83 } 143 }
84 144
85 match->avail -= slice_height; 145 match->avail -= slice_height;
86 146
87 slice->name = match->name; 147 slice->name = match->name;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines