ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cf.schmorp.de/Deliantra-Client/rendercache.c
Revision: 1.4
Committed: Sun Aug 12 08:44:22 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +60 -5 lines
Log Message:
use an compressed format for glyph quad vectors. this reduces
the size of e.g. the opengl info from 200k to 20k, and typical
sizes for labels are now <<100 bytes. the cost is full immediate
mode submission of coordinates (cpu), but glInterleavedArrays is
likely not much faster and modern cpus probably prefer more decoding
over more cache misses.

File Contents

# User Rev Content
1 root 1.1 typedef struct {
2     GLenum mode;
3 root 1.3 GLenum format; // 0, GL_T2F_V3F, GL_V2F
4 root 1.1 GLint texname;
5     unsigned char r, g, b, a;
6     } rc_key_t;
7    
8     typedef struct {
9     HV *hv;
10     } rc_t;
11    
12     typedef SV rc_array_t;
13    
14     static rc_t *
15     rc_alloc ()
16     {
17     rc_t *rc = g_slice_new0 (rc_t);
18     rc->hv = newHV ();
19    
20     return rc;
21     }
22    
23     static void
24     rc_free (rc_t *rc)
25     {
26     SvREFCNT_dec (rc->hv);
27     g_slice_free (rc_t, rc);
28     }
29    
30     static void
31     rc_clear (rc_t *rc)
32     {
33     hv_clear (rc->hv);
34     }
35    
36     static rc_array_t *
37     rc_array (rc_t *rc, rc_key_t *k)
38     {
39     SV *sv = *hv_fetch (rc->hv, (char *)k, sizeof (*k), 1);
40    
41     if (SvTYPE (sv) != SVt_PV)
42     {
43     sv_upgrade (sv, SVt_PV);
44     SvPOK_only (sv);
45     }
46    
47     return sv;
48     }
49    
50     static void
51     rc_v2f (rc_array_t *arr, float x, float y)
52     {
53 root 1.2 STRLEN len = SvCUR (arr) + sizeof (float) * 2;
54 root 1.1 SvGROW (arr, len);
55    
56     ((float *)SvEND (arr))[0] = x;
57     ((float *)SvEND (arr))[1] = y;
58    
59     SvCUR_set (arr, len);
60     }
61    
62     static void
63     rc_t2f_v3f (rc_array_t *arr, float u, float v, float x, float y, float z)
64     {
65     STRLEN len = SvCUR (arr) + sizeof (float) * 5;
66     SvGROW (arr, len);
67    
68     ((float *)SvEND (arr))[0] = u;
69     ((float *)SvEND (arr))[1] = v;
70    
71     ((float *)SvEND (arr))[2] = x;
72     ((float *)SvEND (arr))[3] = y;
73     ((float *)SvEND (arr))[4] = z;
74    
75     SvCUR_set (arr, len);
76     }
77    
78     static void
79 root 1.4 rc_glyph (rc_array_t *arr, int u, int v, int w, int h, int x, int y)
80     {
81     U8 *c;
82     STRLEN len = SvCUR (arr);
83    
84     SvGROW (arr, len + 2 * 2 + 1 * 4);
85    
86     c = (U8 *)SvEND (arr);
87     *c++ = u;
88     *c++ = v;
89     *c++ = w;
90     *c++ = h;
91    
92     // use ber-encoding for up to 14 bits (16k)
93     *c = 0x80 | (x >> 7); c += (x >> 7) ? 1 : 0; *c++ = x & 0x7f;
94     *c = 0x80 | (y >> 7); c += (y >> 7) ? 1 : 0; *c++ = y & 0x7f;
95    
96     SvCUR_set (arr, c - (U8 *)SvPVX (arr));
97     }
98    
99     static void
100 root 1.1 rc_draw (rc_t *rc)
101     {
102     HE *he;
103    
104     hv_iterinit (rc->hv);
105     while ((he = hv_iternext (rc->hv)))
106     {
107     rc_key_t *key = (rc_key_t *)HeKEY (he);
108     rc_array_t *arr = HeVAL (he);
109     STRLEN len;
110     char *arr_pv = SvPV (arr, len);
111     GLsizei stride;
112    
113     if (key->texname)
114     {
115     glBindTexture (GL_TEXTURE_2D, key->texname);
116     glEnable (GL_TEXTURE_2D);
117     }
118     else
119     glDisable (GL_TEXTURE_2D);
120    
121     glColor4ub (key->r, key->g, key->b, key->a);
122 root 1.3
123 root 1.4 if (key->format)
124     {
125     stride = key->format == GL_T2F_V3F ? sizeof (float) * 5
126     : key->format == GL_V2F ? sizeof (float) * 2
127     : 65536;
128    
129     glInterleavedArrays (key->format, 0, (void *)arr_pv);
130     //glLockArraysEXT (0, len / stride);
131     glDrawArrays (key->mode, 0, len / stride);
132     //glUnlockArraysEXT ();
133     }
134     else
135     {
136     // optimised character quad storage. slower but nice on memory.
137     // reduces storage requirements from 80 bytes/char to 6-8
138     U8 *c = (U8 *)arr_pv;
139     U8 *e = c + len;
140    
141     glBegin (key->mode); // practically must be quads
142    
143     while (c < e)
144     {
145     int u, v, x, y, w, h;
146    
147     u = *c++;
148     v = *c++;
149     w = *c++;
150     h = *c++;
151    
152     x = *c++; if (x > 0x7f) x = ((x & 0x7f) << 7) | *c++;
153     y = *c++; if (y > 0x7f) y = ((y & 0x7f) << 7) | *c++;
154    
155     glTexCoord2f ( u * (1.f / TC_WIDTH), v * (1.f / TC_HEIGHT)); glVertex2i (x , y );
156     glTexCoord2f ((u + w) * (1.f / TC_WIDTH), v * (1.f / TC_HEIGHT)); glVertex2i (x + w, y );
157     glTexCoord2f ((u + w) * (1.f / TC_WIDTH), (v + h) * (1.f / TC_HEIGHT)); glVertex2i (x + w, y + h);
158     glTexCoord2f ( u * (1.f / TC_WIDTH), (v + h) * (1.f / TC_HEIGHT)); glVertex2i (x , y + h);
159     }
160 root 1.3
161 root 1.4 glEnd ();
162     }
163 root 1.1 }
164    
165     glDisable (GL_TEXTURE_2D);
166     }
167    
168    
169    
170