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

Comparing deliantra/Deliantra-Client/Client.xs (file contents):
Revision 1.222 by root, Sat Aug 11 06:34:26 2007 UTC vs.
Revision 1.225 by root, Sat Aug 11 12:07:54 2007 UTC

114 av_push (texture_av, (SV *)(size_t)name); 114 av_push (texture_av, (SV *)(size_t)name);
115 glDeleteTextures (1, &name); 115 glDeleteTextures (1, &name);
116} 116}
117 117
118#include "texcache.c" 118#include "texcache.c"
119#include "rendercache.c"
119 120
120#include "pango-font.c" 121#include "pango-font.c"
121#include "pango-fontmap.c" 122#include "pango-fontmap.c"
122#include "pango-render.c" 123#include "pango-render.c"
123 124
149typedef struct cf_layout { 150typedef struct cf_layout {
150 PangoLayout *pl; 151 PangoLayout *pl;
151 float r, g, b, a; // default color for rgba mode 152 float r, g, b, a; // default color for rgba mode
152 int base_height; 153 int base_height;
153 CFPlus__Font font; 154 CFPlus__Font font;
155 rc_t *rc;
154} *CFPlus__Layout; 156} *CFPlus__Layout;
155 157
156static CFPlus__Font default_font; 158static CFPlus__Font default_font;
157static PangoContext *opengl_context; 159static PangoContext *opengl_context;
158static PangoFontMap *opengl_fontmap; 160static PangoFontMap *opengl_fontmap;
1035 RETVAL->g = 1.; 1037 RETVAL->g = 1.;
1036 RETVAL->b = 1.; 1038 RETVAL->b = 1.;
1037 RETVAL->a = 1.; 1039 RETVAL->a = 1.;
1038 RETVAL->base_height = MIN_FONT_HEIGHT; 1040 RETVAL->base_height = MIN_FONT_HEIGHT;
1039 RETVAL->font = 0; 1041 RETVAL->font = 0;
1042 RETVAL->rc = rc_alloc ();
1040 1043
1041 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1044 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1042 layout_update_font (RETVAL); 1045 layout_update_font (RETVAL);
1043 OUTPUT: 1046 OUTPUT:
1044 RETVAL 1047 RETVAL
1045 1048
1046void 1049void
1047DESTROY (CFPlus::Layout self) 1050DESTROY (CFPlus::Layout self)
1048 CODE: 1051 CODE:
1049 g_object_unref (self->pl); 1052 g_object_unref (self->pl);
1053 rc_free (self->rc);
1050 Safefree (self); 1054 Safefree (self);
1051 1055
1052void 1056void
1053set_text (CFPlus::Layout self, SV *text_) 1057set_text (CFPlus::Layout self, SV *text_)
1054 CODE: 1058 CODE:
1306 } 1310 }
1307} 1311}
1308 1312
1309void 1313void
1310render (CFPlus::Layout self, float x, float y, int flags = 0) 1314render (CFPlus::Layout self, float x, float y, int flags = 0)
1311 PPCODE: 1315 CODE:
1316 rc_clear (self->rc);
1312 pango_opengl_render_layout_subpixel ( 1317 pango_opengl_render_layout_subpixel (
1313 self->pl, 1318 self->pl,
1319 self->rc,
1314 x * PANGO_SCALE, y * PANGO_SCALE, 1320 x * PANGO_SCALE, y * PANGO_SCALE,
1315 self->r, self->g, self->b, self->a, 1321 self->r, self->g, self->b, self->a,
1316 flags 1322 flags
1317 ); 1323 );
1324 // we assume that context_change actually clears/frees stuff
1325 // and does not do any recomputation...
1326 pango_layout_context_changed (self->pl);
1327
1328void
1329draw (CFPlus::Layout self)
1330 CODE:
1331{
1332 glEnable (GL_TEXTURE_2D);
1333 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1334 glEnable (GL_BLEND);
1335 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1336 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1337 glEnable (GL_ALPHA_TEST);
1338 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1339
1340 rc_draw (self->rc);
1341
1342 glDisable (GL_ALPHA_TEST);
1343 glDisable (GL_BLEND);
1344 glDisable (GL_TEXTURE_2D);
1345}
1318 1346
1319MODULE = CFPlus PACKAGE = CFPlus::Texture 1347MODULE = CFPlus PACKAGE = CFPlus::Texture
1320 1348
1321PROTOTYPES: ENABLE 1349PROTOTYPES: ENABLE
1322 1350
1713 1741
1714void 1742void
1715draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1743draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1716 CODE: 1744 CODE:
1717{ 1745{
1746 int x, y, z;
1747
1718 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1748 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1719 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 1749 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1720 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1750 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k)
1721 smooth_key skey; 1751 smooth_key skey;
1722 int x, y, z; 1752
1723 int last_name; 1753 rc_t *rc = rc_alloc ();
1754 rc_key_t key;
1755 rc_array_t *arr;
1724 1756
1725 // thats current max. sorry. 1757 // thats current max. sorry.
1726 if (sw > 255) sw = 255; 1758 if (sw > 255) sw = 255;
1727 if (sh > 255) sh = 255; 1759 if (sh > 255) sh = 255;
1728 1760
1729 // clear key, in case of extra padding 1761 // clear key, in case of extra padding
1730 memset (&skey, 0, sizeof (skey)); 1762 memset (&skey, 0, sizeof (skey));
1731 1763
1732 glColor4ub (255, 255, 255, 255); 1764 memset (&key, 0, sizeof (key));
1733 1765 key.r = 255;
1734 glEnable (GL_BLEND); 1766 key.g = 255;
1735 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1767 key.b = 255;
1736 glEnable (GL_TEXTURE_2D); 1768 key.a = 255;
1737 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1769 key.mode = GL_QUADS;
1738 1770 key.format = GL_T2F_V3F;
1739 glBegin (GL_QUADS);
1740
1741 last_name = -1; 1771 key.texname = -1;
1742 1772
1743 mx += self->x; 1773 mx += self->x;
1744 my += self->y; 1774 my += self->y;
1745 1775
1746 // first pass: determine smooth_max 1776 // first pass: determine smooth_max
1762 MAX (self->tex [cell->tile [0]].smoothlevel, 1792 MAX (self->tex [cell->tile [0]].smoothlevel,
1763 MAX (self->tex [cell->tile [1]].smoothlevel, 1793 MAX (self->tex [cell->tile [1]].smoothlevel,
1764 self->tex [cell->tile [2]].smoothlevel)); 1794 self->tex [cell->tile [2]].smoothlevel));
1765 } 1795 }
1766 } 1796 }
1797
1798 glEnable (GL_BLEND);
1799 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1800 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1767 1801
1768 for (z = 0; z <= 2; z++) 1802 for (z = 0; z <= 2; z++)
1769 { 1803 {
1770 memset (smooth_level, 0, sizeof (smooth_level)); 1804 memset (smooth_level, 0, sizeof (smooth_level));
1771 1805
1785 maptex tex = self->tex [tile]; 1819 maptex tex = self->tex [tile];
1786 int px, py; 1820 int px, py;
1787 1821
1788 // suppressing texture state switches here 1822 // suppressing texture state switches here
1789 // is only moderately effective, but worth the extra effort 1823 // is only moderately effective, but worth the extra effort
1790 if (last_name != tex.name) 1824 if (key.texname != tex.name)
1791 { 1825 {
1792 if (!tex.name) 1826 if (!tex.name)
1793 tex = self->tex [2]; /* missing, replace by noface */ 1827 tex = self->tex [2]; /* missing, replace by noface */
1794 1828
1795 glEnd (); 1829 key.texname = tex.name;
1796 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1830 arr = rc_array (rc, &key);
1797 glBegin (GL_QUADS);
1798 } 1831 }
1799 1832
1800 px = (x + 1) * T - tex.w; 1833 px = (x + 1) * T - tex.w;
1801 py = (y + 1) * T - tex.h; 1834 py = (y + 1) * T - tex.h;
1802 1835
1803 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1836 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1804 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1837 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1805 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1838 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1806 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1839 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1807 1840
1808 if (cell->flags && z == 2) 1841 if (cell->flags && z == 2)
1809 { 1842 {
1843 // overlays such as the speech bubble, probably more to come
1810 if (cell->flags & 1) 1844 if (cell->flags & 1)
1811 { 1845 {
1812 maptex tex = self->tex [1]; 1846 maptex tex = self->tex [1];
1813 int px = x * T + T * 2 / 32; 1847 int px = x * T + T * 2 / 32;
1814 int py = y * T - T * 6 / 32; 1848 int py = y * T - T * 6 / 32;
1815 1849
1850 if (tex.name)
1816 glEnd (); 1851 {
1817 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1852 if (key.texname != tex.name)
1853 {
1854 key.texname = tex.name;
1855 arr = rc_array (rc, &key);
1856 }
1857
1858 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1859 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1860 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1861 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1818 glBegin (GL_QUADS); 1862 }
1819
1820 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1821 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1822 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1823 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1824 } 1863 }
1825 } 1864 }
1826 1865
1827 // update smooth hash 1866 // update smooth hash
1828 if (tex.smoothtile) 1867 if (tex.smoothtile)
1863 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 1902 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1864 } 1903 }
1865 } 1904 }
1866 } 1905 }
1867 } 1906 }
1907
1908 rc_draw (rc);
1909 rc_clear (rc);
1868 1910
1869 // go through all smoothlevels, lowest to highest, then draw. 1911 // go through all smoothlevels, lowest to highest, then draw.
1870 // this is basically counting sort 1912 // this is basically counting sort
1871 { 1913 {
1872 int w, b; 1914 int w, b;
1897 int border = bits & 15; 1939 int border = bits & 15;
1898 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1940 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1899 float dx = tex.s * .0625f; // 16 images/row 1941 float dx = tex.s * .0625f; // 16 images/row
1900 float dy = tex.t * .5f ; // 2 images/column 1942 float dy = tex.t * .5f ; // 2 images/column
1901 1943
1902 // this time naively avoiding texture state changes
1903 // save gobs of state changes.
1904 if (last_name != tex.name) 1944 if (tex.name)
1905 { 1945 {
1946 // this time avoiding texture state changes
1947 // save gobs of state changes.
1906 if (!tex.name) 1948 if (key.texname != tex.name)
1907 continue; // smoothing not yet available
1908
1909 glEnd (); 1949 {
1910 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1950 key.texname = tex.name;
1911 glBegin (GL_QUADS); 1951 arr = rc_array (rc, &key);
1912 } 1952 }
1913 1953
1914 if (border) 1954 if (border)
1915 { 1955 {
1916 float ox = border * dx; 1956 float ox = border * dx;
1917 1957
1918 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1958 rc_t2f_v3f (arr, ox , 0.f , px , py , 0);
1919 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1959 rc_t2f_v3f (arr, ox , dy , px , py + T, 0);
1920 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1960 rc_t2f_v3f (arr, ox + dx, dy , px + T, py + T, 0);
1921 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1961 rc_t2f_v3f (arr, ox + dx, 0.f , px + T, py , 0);
1922 } 1962 }
1923 1963
1924 if (corner) 1964 if (corner)
1925 { 1965 {
1926 float ox = corner * dx; 1966 float ox = corner * dx;
1927 1967
1928 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1968 rc_t2f_v3f (arr, ox , dy , px , py , 0);
1929 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1969 rc_t2f_v3f (arr, ox , dy * 2.f, px , py + T, 0);
1930 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1970 rc_t2f_v3f (arr, ox + dx, dy * 2.f, px + T, py + T, 0);
1931 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1971 rc_t2f_v3f (arr, ox + dx, dy , px + T, py , 0);
1972 }
1932 } 1973 }
1933 } 1974 }
1934 } 1975 }
1935 } 1976 }
1936 } 1977 }
1937 } 1978 }
1938 1979
1939 hv_clear (smooth); 1980 hv_clear (smooth);
1981 rc_draw (rc);
1982 rc_clear (rc);
1940 } 1983 }
1941 1984
1942 glEnd ();
1943
1944 glDisable (GL_TEXTURE_2D);
1945 glDisable (GL_BLEND); 1985 glDisable (GL_BLEND);
1986 rc_free (rc);
1946 1987
1947 // top layer: overlays such as the health bar 1988 // top layer: overlays such as the health bar
1948 for (y = 0; y < sh; y++) 1989 for (y = 0; y < sh; y++)
1949 if (0 <= y + my && y + my < self->rows) 1990 if (0 <= y + my && y + my < self->rows)
1950 { 1991 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines