--- deliantra/Deliantra-Client/Client.xs 2007/08/11 11:21:46 1.224 +++ deliantra/Deliantra-Client/Client.xs 2007/08/13 14:15:09 1.227 @@ -152,6 +152,7 @@ float r, g, b, a; // default color for rgba mode int base_height; CFPlus__Font font; + rc_t *rc; } *CFPlus__Layout; static CFPlus__Font default_font; @@ -1038,6 +1039,7 @@ RETVAL->a = 1.; RETVAL->base_height = MIN_FONT_HEIGHT; RETVAL->font = 0; + RETVAL->rc = rc_alloc (); pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); layout_update_font (RETVAL); @@ -1048,6 +1050,7 @@ DESTROY (CFPlus::Layout self) CODE: g_object_unref (self->pl); + rc_free (self->rc); Safefree (self); void @@ -1309,13 +1312,37 @@ void render (CFPlus::Layout self, float x, float y, int flags = 0) - PPCODE: + CODE: + rc_clear (self->rc); pango_opengl_render_layout_subpixel ( self->pl, + self->rc, x * PANGO_SCALE, y * PANGO_SCALE, self->r, self->g, self->b, self->a, flags ); + // we assume that context_change actually clears/frees stuff + // and does not do any recomputation... + pango_layout_context_changed (self->pl); + +void +draw (CFPlus::Layout self) + CODE: +{ + glEnable (GL_TEXTURE_2D); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable (GL_BLEND); + gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, + GL_ONE , GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_ALPHA_TEST); + glAlphaFunc (GL_GREATER, 7.f / 255.f); + + rc_draw (self->rc); + + glDisable (GL_ALPHA_TEST); + glDisable (GL_BLEND); + glDisable (GL_TEXTURE_2D); +} MODULE = CFPlus PACKAGE = CFPlus::Texture @@ -1720,7 +1747,7 @@ HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level - static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) + static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) smooth_key skey; rc_t *rc = rc_alloc (); @@ -1792,8 +1819,6 @@ maptex tex = self->tex [tile]; int px, py; - // suppressing texture state switches here - // is only moderately effective, but worth the extra effort if (key.texname != tex.name) { if (!tex.name) @@ -1886,6 +1911,8 @@ { int w, b; + glEnable (GL_TEXTURE_2D); + glBegin (GL_QUADS); for (w = 0; w < 256 / 32; ++w) { uint32_t smask = smooth_level [w]; @@ -1920,39 +1947,42 @@ // save gobs of state changes. if (key.texname != tex.name) { - key.texname = tex.name; - arr = rc_array (rc, &key); + glEnd (); + glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); + glBegin (GL_QUADS); } if (border) { float ox = border * dx; - rc_t2f_v3f (arr, ox , 0.f , px , py , 0); - rc_t2f_v3f (arr, ox , dy , px , py + T, 0); - rc_t2f_v3f (arr, ox + dx, dy , px + T, py + T, 0); - rc_t2f_v3f (arr, ox + dx, 0.f , px + T, py , 0); + glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); + glTexCoord2f (ox , dy ); glVertex2i (px , py + T); + glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); + glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); } if (corner) { float ox = corner * dx; - rc_t2f_v3f (arr, ox , dy , px , py , 0); - rc_t2f_v3f (arr, ox , dy * 2.f, px , py + T, 0); - rc_t2f_v3f (arr, ox + dx, dy * 2.f, px + T, py + T, 0); - rc_t2f_v3f (arr, ox + dx, dy , px + T, py , 0); + glTexCoord2f (ox , dy ); glVertex2i (px , py ); + glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); + glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); + glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); } } } } } } + + glEnd (); + glDisable (GL_TEXTURE_2D); + key.texname = -1; } hv_clear (smooth); - rc_draw (rc); - rc_clear (rc); } glDisable (GL_BLEND); @@ -2215,7 +2245,7 @@ int x1, y1; if (*data++ != 0) - return; /* version mismatch */ + XSRETURN_EMPTY; /* version mismatch */ w = *data++ << 8; w |= *data++; h = *data++ << 8; h |= *data++;