--- deliantra/Deliantra-Client/Client.xs 2007/08/11 11:07:08 1.223 +++ deliantra/Deliantra-Client/Client.xs 2007/10/08 16:10:14 1.236 @@ -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; @@ -204,7 +205,7 @@ typedef uint16_t faceid; typedef struct { - int name; + GLuint name; int w, h; float s, t; uint8_t r, g, b, a; @@ -441,6 +442,17 @@ return n + 1; } +static unsigned int +popcount (unsigned int n) +{ + n -= (n >> 1) & 0x55555555U; + n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U); + n = ((n >> 4) + n) & 0x0f0f0f0fU; + n *= 0x01010101U; + + return n >> 24; +} + /* SDL should provide this, really. */ #define SDLK_MODIFIER_MIN 300 #define SDLK_MODIFIER_MAX 314 @@ -526,6 +538,8 @@ const_iv (SDL_APPMOUSEFOCUS), const_iv (SDL_APPACTIVE), + const_iv (SDLK_FIRST), + const_iv (SDLK_LAST), const_iv (SDLK_KP0), const_iv (SDLK_KP1), const_iv (SDLK_KP2), @@ -607,6 +621,8 @@ const_iv (KMOD_NUM), const_iv (KMOD_CAPS), const_iv (KMOD_MODE), + + const_iv (MIX_DEFAULT_FORMAT), # undef const_iv }; @@ -634,6 +650,10 @@ NV ceil (NV x) +IV minpot (UV n) + +IV popcount (UV n) + void pango_init () CODE: @@ -716,7 +736,7 @@ { av_clear (texture_av); - SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); + SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT"); #define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); #include "glfunc.h" #undef GL_FUNC @@ -812,12 +832,28 @@ } int -Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024) +Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) POSTCALL: Mix_HookMusicFinished (music_finished); Mix_ChannelFinished (channel_finished); void +Mix_QuerySpec () + PPCODE: +{ + int freq, channels; + Uint16 format; + + if (Mix_QuerySpec (&freq, &format, &channels)) + { + EXTEND (SP, 3); + PUSHs (sv_2mortal (newSViv (freq))); + PUSHs (sv_2mortal (newSViv (format))); + PUSHs (sv_2mortal (newSViv (channels))); + } +} + +void Mix_CloseAudio () int @@ -1038,6 +1074,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 +1085,7 @@ DESTROY (CFPlus::Layout self) CODE: g_object_unref (self->pl); + rc_free (self->rc); Safefree (self); void @@ -1309,20 +1347,42 @@ 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 PROTOTYPES: ENABLE -int minpot (int n) - void pad (SV *data_, int ow, int oh, int nw, int nh) CODE: @@ -1720,7 +1780,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 +1852,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) @@ -1878,11 +1936,16 @@ } } + rc_draw (rc); + rc_clear (rc); + // go through all smoothlevels, lowest to highest, then draw. // this is basically counting sort { int w, b; + glEnable (GL_TEXTURE_2D); + glBegin (GL_QUADS); for (w = 0; w < 256 / 32; ++w) { uint32_t smask = smooth_level [w]; @@ -1917,39 +1980,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); @@ -2212,7 +2278,7 @@ int x1, y1; if (*data++ != 0) - return; /* version mismatch */ + XSRETURN_EMPTY; /* version mismatch */ w = *data++ << 8; w |= *data++; h = *data++ << 8; h |= *data++; @@ -2518,6 +2584,12 @@ const_iv (GL_LUMINANCE_ALPHA), const_iv (GL_FLOAT), const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), + const_iv (GL_COMPRESSED_ALPHA_ARB), + const_iv (GL_COMPRESSED_LUMINANCE_ARB), + const_iv (GL_COMPRESSED_LUMINANCE_ALPHA_ARB), + const_iv (GL_COMPRESSED_INTENSITY_ARB), + const_iv (GL_COMPRESSED_RGB_ARB), + const_iv (GL_COMPRESSED_RGBA_ARB), const_iv (GL_COMPILE), const_iv (GL_PROXY_TEXTURE_1D), const_iv (GL_PROXY_TEXTURE_2D), @@ -2566,6 +2638,7 @@ const_iv (GL_LINE_SMOOTH_HINT), const_iv (GL_POLYGON_SMOOTH_HINT), const_iv (GL_GENERATE_MIPMAP_HINT), + const_iv (GL_TEXTURE_COMPRESSION_HINT), const_iv (GL_FASTEST), const_iv (GL_DONT_CARE), const_iv (GL_NICEST), @@ -2583,6 +2656,12 @@ AvREAL_off (texture_av); } +void +disable_GL_EXT_blend_func_separate () + CODE: + gl.BlendFuncSeparate = 0; + gl.BlendFuncSeparateEXT = 0; + char * gl_vendor () CODE: @@ -2713,6 +2792,15 @@ CODE: glRectf (x1, y1, x2, y2); +void glRect_lineloop (float x1, float y1, float x2, float y2) + CODE: + glBegin (GL_LINE_LOOP); + glVertex2f (x1, y1); + glVertex2f (x2, y1); + glVertex2f (x2, y2); + glVertex2f (x1, y2); + glEnd (); + PROTOTYPES: ENABLE void glBegin (int mode) @@ -2823,8 +2911,7 @@ SV *draw_y_sv = GvSV (draw_y_gv); SV *draw_w_sv = GvSV (draw_w_gv); SV *draw_h_sv = GvSV (draw_h_gv); - SV *hover; - double draw_x, draw_y, draw_w, draw_h; + double draw_x, draw_y; if (!SvROK (self)) croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); @@ -2862,7 +2949,7 @@ if (svp && SvTRUE (*svp)) { - glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f); + glColor4f (1.0f * 0.2f, 0.8f * 0.2f, 0.5f * 0.2f, 0.2f); glEnable (GL_BLEND); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); @@ -2875,19 +2962,17 @@ } } #if 0 - if ($ENV{CFPLUS_DEBUG} & 1) { - glPushMatrix; - glColor 1, 1, 0, 1; - glTranslate 0.375, 0.375; - glBegin GL_LINE_LOOP; - glVertex 0 , 0; - glVertex $self->{w} - 1, 0; - glVertex $self->{w} - 1, $self->{h} - 1; - glVertex 0 , $self->{h} - 1; - glEnd; - glPopMatrix; - #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw; - } + // draw borders, for debugging + glPushMatrix (); + glColor4f (1., 1., 0., 1.); + glTranslatef (.5, .5, 0.); + glBegin (GL_LINE_LOOP); + glVertex2f (0 , 0); + glVertex2f (w - 1, 0); + glVertex2f (w - 1, h - 1); + glVertex2f (0 , h - 1); + glEnd (); + glPopMatrix (); #endif PUSHMARK (SP); XPUSHs (self);