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

# Content
1 typedef struct {
2 GLenum mode;
3 GLenum format; // 0, GL_T2F_V3F, GL_V2F
4 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 STRLEN len = SvCUR (arr) + sizeof (float) * 2;
54 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 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 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
123 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
161 glEnd ();
162 }
163 }
164
165 glDisable (GL_TEXTURE_2D);
166 }
167
168
169
170