Changeset 79

Show
Ignore:
Timestamp:
07/17/08 22:24:02 (5 months ago)
Author:
JoeCoder
Message:

More font additions.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/demo2/main.d

    r75 r79  
    102102     
    103103     
    104     // Create 
     104    // Create some windows 
    105105    void onMouseDown2(Surface self, byte buttons, Vec2i coordinates){ 
    106106        self.raise(); 
     
    122122 
    123123    auto window1 = new Surface(view);    
    124     window1.style.set("top: 5%; right: 3%; width: 160; height: 120; background-position: 5px 5px; " ~  
     124    window1.style.set("top: 0; right: 0; width: 400; height: 60; background-position: 5px 5px; " ~  
    125125        "background-repeat: nineslice; background-material: url('gui/skin/clear2.png')"); 
    126126    window1.onMouseDown = &onMouseDown2; 
    127127    window1.onMouseMove = &onMouseMove2; 
    128128    window1.onMouseUp = &onMouseUp2; 
    129     window1.onMouseOver = &onMouseOver; 
    130     window1.onMouseOut = &onMouseOut; 
     129    //window1.onMouseOver = &onMouseOver; 
     130    //window1.onMouseOut = &onMouseOut; 
    131131     
    132132    auto window2 = new Surface(window1); 
    133     window2.style.set("top: 10; right: 10; width: 50; height: 30; background-position: 5px 5px; " ~  
     133    window2.style.set("top: 30; right: 0; width: 50; height: 30; background-position: 5px 5px; " ~  
    134134        "background-repeat: nineslice; background-material: url('gui/skin/clear2.png')"); 
    135135    window2.onMouseDown = &onMouseDown2; 
     
    138138    window2.onMouseOver = &onMouseOver; 
    139139    window2.onMouseOut = &onMouseOut; 
     140     
     141 
     142    window1.style.fontFamily = Resource.font("gui/font/Vera.ttf"); 
     143    window1.style.fontSize = 12; 
     144    window1.style.color = Color("black"); 
    140145 
    141146    // Music 
     
    190195        fps++; 
    191196        if (frame.get()>=0.25f) 
    192         {   char[] caption = formatString("Yage Test (%.2f fps) (%d objects, %d polygons, %d vertices rendered)\0", 
     197        {   char[] caption = formatString("(%.2f fps) (%d objects, %d polygons, %d vertices)", 
    193198                fps/frame.get(), camera.getNodeCount(), camera.getPolyCount(), camera.getVertexCount()); 
    194             SDL_WM_SetCaption(caption.ptr, null); 
    195             //delete caption; 
     199            SDL_WM_SetCaption((caption ~"\0").ptr, null); 
     200            window1.text = caption; 
    196201            frame.reset(); 
    197202            fps = 0; 
  • trunk/doc/ideas.txt

    r28 r79  
    77Add boolean set operations to the Resource manager, to load all resources from a new level and free only those that aren't part of that set. 
    88 
    9 class Layer 
     9class Surface 
    1010{ 
    11     bool passthrough;           // pass events that occur on this layer to those behind it. 
     11    bool passthrough;           // pass events that occur on this surface to those behind it. 
    1212 
    1313    setOnClick(function);       // mousebutton, mouseposition 
     
    3636 
    3737A sensor node that checks for certain events (brightness, velocity, distance, etc.) and calls callback functions when 
    38 certain events occur. 
     38certain events occur.  (any node can do this in its update function). 
    3939 
    4040Use axis sorting to tell what lights affect what nodes (instead of n*m distance check).  But most lights have large radius? 
     
    4242Use dx cross dy to calculate normals for parametric graphnodes. 
    4343 
     44Create typed exceptions. 
     45 
     46Make logging consistent and typed. 
     47 
  • trunk/doc/unresolved.txt

    r70 r79  
    2222fixed? 
    2323 
    24 Dmd has trouble compiling incrementally with -O 
    25  
    2624There is jumpiness in the rendering.  Every 10th or so frame takes almost exactly twice as long to render 
    2725than others, when rendering the same thing.  Especially noticable when rendering lots of models 
  • trunk/src/yage/core/math.d

    r67 r79  
    1010import std.math; 
    1111import std.random; 
     12import std.intrinsic; 
    1213 
    1314public const float PI_180 = 0.01745329251994;   // PI / 180 
  • trunk/yage/core/vector.d

    r76 r79  
    123123 
    124124 
    125     /// Allow for linnear additions and subtractions among Vectors of the same size and type. 
     125    /// Allow for linear additions, subtractions, multiplcations, and divisions among Vectors of the same size and type. 
    126126    VST opAdd(VST s) 
    127127    {   VST res; 
     
    130130        return res; 
    131131    } 
    132     /// Ditto 
     132    /// ditto 
    133133    void opAddAssign(VST s) 
    134134    {   for (int i=0; i<v.length; i++) 
    135135            v[i] += s.v[i]; 
    136136    }    
    137     /// Ditto 
     137    /// ditto 
    138138    VST opSub(VST s) 
    139139    {   VST res; 
     
    142142        return res; 
    143143    } 
    144     /// Ditto 
     144    /// ditto 
    145145    void opSubAssign(VST s) 
    146146    {   for (int i=0; i<v.length; i++) 
    147147            v[i] -= s.v[i]; 
     148    } 
     149     
     150    /// Allow for additions, subtractions, multiplcations, and divisions where a scalar is applied to each vector component. 
     151    void opMulAssign(float s) 
     152    {   for (int i=0; i<v.length; i++) 
     153            v[i] += s; 
     154    } 
     155    /// ditto 
     156    void opDivAssign(float s) 
     157    {   for (int i=0; i<v.length; i++) 
     158            v[i] /= s; 
    148159    } 
    149160     
  • trunk/yage/gui/style.d

    r76 r79  
    1010import yage.core.color; 
    1111import yage.core.vector; 
     12import yage.resource.font; 
    1213import yage.resource.resource; 
    1314import yage.resource.material; 
     
    154155    } 
    155156    // Font 
    156     //Font fontFamily; 
    157     //float fontSize
    158     //byte fontSizeUnit
     157    Font fontFamily; 
     158    float fontSize = 12
     159    Unit fontSizeUnit = Style.PX
    159160    //float fontWeight; 
    160     //Color color; 
     161    Color color; 
    161162         
    162163    // Padding 
     
    242243            switch (property) 
    243244            {   /// TODO: Lots more properties 
     245                case "color":               color = Color(tokens[1]); break; 
     246             
    244247                case "backgroundcolor":     backgroundColor = Color(tokens[1]); break; 
    245248                case "backgroundrepeat":    backgroundRepeat = translate[tokens[1]]; break; 
  • trunk/yage/gui/surface.d

    r76 r79  
    1313import derelict.opengl.glext; 
    1414import derelict.opengl.glu; 
     15import derelict.opengl.extension.ext.blend_color; // opengl 1.2 
    1516import yage.core.all; 
    1617import yage.system.device; 
     
    1819import yage.system.input; 
    1920import yage.resource.texture; 
     21import yage.resource.image; 
    2022import yage.gui.style; 
    2123import yage.system.rendertarget; 
     
    3335{ 
    3436    static final Style defaultStyle; 
    35     Style style;     
     37    Style style; 
     38    char[] text; 
     39    Image textImage; 
     40    Texture textTexture; 
    3641     
    3742    // internal values 
     
    4045    Vec2f offset;       // pixel distance of top left from the window's top left at 0, 0 
    4146     
    42     bool mouseIn; // is this used? 
     47    bool mouseIn; // used to track mouseover/mouseout 
    4348     
    4449    protected Style old_style; // Used for comparison to see if dirty. 
    4550    protected Surface old_parent; 
     51    protected char[] old_text; 
    4652     
    4753    protected float[72] vertices = 0; // Used for rendering 
     
    94100 
    95101    /** 
    96      * Recalculate all properties of this Surface based on its style.*/ 
     102     * Recalculate all properties of this Surface based on its style. 
     103     * TODO: Ensure vertex and tex coord assignments are 100% on the stack (see array literals).*/ 
    97104    void calculate() 
    98105    {            
     
    185192                    float h = this.height(); 
    186193                    vertices[0..8] = [0.0f, h, w, h, w, 0, 0, 0]; 
    187                     tex_coords[0..8] = [0.0f, 0, portion.x, 0, portion.x, portion.y, 0, portion.y];                         
     194                    tex_coords[0..8] = [0.0f, 0, portion.x, 0, portion.x, portion.y, 0, portion.y]; 
    188195                    break; 
    189196                case Style.NINESLICE: 
     
    201208                    // V    | 
    202209                    // 1<---2 
    203                     // TODO: Use same array for both using glScalef, once portion becomes unnecessary. 
    204210                    // TODO: Ensure this operation is 100% on the stack. 
    205211                    vertices[0..72] = [ 
     
    281287         
    282288        glEnable(GL_BLEND); 
    283       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
     289      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    284290             
    285291        //This may need to be changed for when people wish to render surfaces individually so the already rendered are not cleared. 
     
    297303    } 
    298304     
     305     
     306     
    299307    void draw() 
    300308    { 
    301         if(style.visible) 
     309        void drawQuad(int style) 
     310        {   switch(style) 
     311            {   case Style.NONE: 
     312         
     313                case Style.STRETCH: 
     314                    glDrawArrays(GL_QUADS, 0, 4); 
     315                    break; 
     316                case Style.NINESLICE: 
     317                    glDrawArrays(GL_QUADS, 0, 36); 
     318                    break; 
     319                default: 
     320                    throw new Exception("Not a valid fill type"); 
     321                    break;   
     322            } 
     323        } 
     324         
     325         
     326        if (style.visible) 
    302327        { 
    303             if (dirty) 
     328            // Update positions 
     329            if (dirty()) 
    304330                calculate(); 
    305331             
    306              
    307                  
     332            // Update Text 
     333            // Todo: check style font properties for changes also. 
     334            if (style.fontFamily && text != old_text) 
     335            {   Timer a = new Timer(); 
     336                textImage = style.fontFamily.render(text, cast(int)style.fontSize, cast(int)style.fontSize, -1, -1, true); 
     337                writefln(a, textImage.getWidth(), textImage.getHeight()); 
     338                a.reset(); 
     339                if (textTexture.texture) 
     340                    delete textTexture.texture; 
     341                 
     342                writefln(a); 
     343                a.reset(); 
     344                textTexture = Texture(new GPUTexture(textImage, false, false), true, TEXTURE_FILTER_BILINEAR); 
     345                 
     346                writefln(a); 
     347                 
     348                old_text = text; 
     349            } 
     350             
     351            // Translate to the topleft corner of this  
    308352            glPushMatrix(); 
    309353            glTranslatef(topLeft.x, topLeft.y, 0); 
    310             glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 
    311             glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr);   
    312              
    313             void draw2() 
    314             {   switch(style.backgroundRepeat) 
    315                 {   case Style.STRETCH: 
    316                         glDrawArrays(GL_QUADS, 0, 4);                        
    317                         break; 
    318                     case Style.NINESLICE: 
    319                         glDrawArrays(GL_QUADS, 0, 36); 
    320                         break; 
    321                     default: 
    322                         throw new Exception("Not a valid fill type"); 
    323                         break;   
    324                 } 
    325             } 
    326              
     354             
     355            // Draw background color 
    327356            if (style.backgroundColor.a > 0) // If backgroundColor alpha. 
    328357            {   glColor4ubv(style.backgroundColor.ub.ptr); 
    329                 draw2(); 
    330                 glColor4ubv(Color(0xFFFFFFFF).ub.ptr);               
    331             } 
    332              
     358                glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 
     359                drawQuad(Style.STRETCH); 
     360                glColor4f(1, 1, 1, 1); 
     361            } 
     362             
     363            // Draw background material 
    333364            if (style.backgroundMaterial !is null) 
    334365            {   glEnable(GL_TEXTURE_2D); 
    335                 Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR).bind(); 
    336                 draw2(); 
    337                 glDisable(GL_TEXTURE_2D); 
    338                 Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR).unbind(); 
    339             } 
    340              
     366                Texture tex = Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR); 
     367                tex.bind(); 
     368                glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 
     369                glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr); 
     370                drawQuad(style.backgroundRepeat);                
     371                tex.unbind(); 
     372            } 
     373             
     374            // Draw Text 
     375            if (textTexture.texture) 
     376            {                    
     377                float ws = textImage.getWidth(); 
     378                float hs = textImage.getHeight();                
     379                float[8] vertices = [0.0f, hs, ws, hs, ws, 0, 0, 0]; 
     380                float[8] tex_coords=[0.0f, 1, 1, 1, 1, 0, 0, 0]; 
     381                 
     382                // Apply States 
     383                glEnable(GL_TEXTURE_2D); 
     384                textTexture.bind(); 
     385                 
     386                glPushMatrix(); 
     387                glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 
     388                glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr); 
     389                 
     390                // This extension is available as of OpenGL 1.1 or 1.2 and allows drawing text in a single pass. 
     391                if (Device.getSupport(DEVICE_BLEND_COLOR)) 
     392                {    
     393                    // Apply states 
     394                    Vec4f color = style.color.vec4f;     
     395                    glBlendFunc(GL_CONSTANT_COLOR_EXT, GL_ONE_MINUS_SRC_COLOR); 
     396                    glBlendColorEXT(color.r, color.g, color.b, 1); 
     397                    glColor3f(color.a, color.a, color.a); 
     398                 
     399                    glDrawArrays(GL_QUADS, 0, 4); 
     400                     
     401                    // Revert states 
     402                    glColor4f(1, 1, 1, 1); 
     403                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // reset blend function 
     404                } else 
     405                { 
     406                    /// TODO: see http://dsource.org/projects/arclib/browser/trunk/arclib/freetype/freetype/font.d 
     407                } 
     408                 
     409                // Revert States 
     410                glPopMatrix(); 
     411                textTexture.unbind(); 
     412            }            
     413             
     414            glDisable(GL_TEXTURE_2D); 
     415                 
    341416            // Using a zbuffer might make this unecessary.  tradeoffs? 
    342417            if (!children.sorted(true, (Surface s){return s.style.zIndex;} )) 
  • trunk/yage/resource/font.d

    r76 r79  
    1010import std.stdio; 
    1111import derelict.freetype.ft; 
     12import yage.core.math; 
    1213import yage.resource.exception; 
    1314import yage.resource.resource; 
     
    2223    FT_Face face; 
    2324     
     25    /// 
    2426    this(char[] filename) 
    2527    { 
    2628        // Initialize Freetype library if not initialized 
     29        // TODO: Move this into Device? 
    2730        if (!freetype_initialized) 
    28         {   auto error = FT_Init_FreeType(&library); 
    29             if (error) 
    30                 throw new Exception("Freetype Failed"); 
     31        {   if (FT_Init_FreeType(&library)) 
     32                throw new Exception("Freetype2 Failed"); 
    3133        } 
    3234         
     
    3739            throw new ResourceLoadException("Could not open font file '" ~ source ~ "'. The format is not recognized by Freetype2."); 
    3840        else if (error) 
    39             throw new ResourceLoadException("Could not open font file '" ~ source ~ "'.");       
     41            throw new ResourceLoadException("Freetype2 could not open font file '" ~ source ~ "'.");         
     42    } 
     43     
     44    /// 
     45    ~this() 
     46    {   /// TODO: cleanup. 
    4047    } 
    4148     
    4249     
    43      
    44     Image getGlyph(dchar[] text, int width=0, int height=0) 
     50    /** 
     51     * Render an image from text. 
     52     * Params: 
     53     *     text =  
     54     *     width =  
     55     *     height =  
     56     *     line_width = Letters will wrap to the next line after this amount (breaking on spaces) 
     57     *     line_height = This much space will occur between each line, defaults to 1.5x height. 
     58     *     image_pow2 = If true, the image returned will always have its dimensions as powers of two. 
     59     * Returns: 
     60     */ 
     61    Image render(char[] text, int width, int height=0, int line_width=-1, int line_height=-1, bool image_pow2=false) 
    4562    {    
     63        // Calculate parameters 
     64        if (line_height==-1) 
     65            line_height = cast(int)(height*1.5); 
     66        if (line_width==-1) 
     67            line_width = int.max;        
    4668         
     69        // Give our font size to freetype. 
    4770        auto error = FT_Set_Pixel_Sizes(face, width, height);   // face, pixel width, pixel height 
    4871        if (error) 
    49             throw new Exception("Font Error."); 
     72            throw new Exception("Invalid font size."); 
    5073         
    51         //foreach (c; text) 
    52         //{ 
    53             error = FT_Load_Char(face, text[0], FT_LOAD_RENDER); // Load into slot  
     74        // Stores a single rendered letter. 
     75        struct Letter 
     76        {   Image image; 
     77            int advancex; 
     78            int advancey; // unnecessary? 
     79            int top; 
     80            int left; 
     81        } 
     82         
     83        Letter[] letters; // array of all rendered letters.      
     84        int total_width = 0; 
     85        int total_height = 0; 
     86        int image_height = 0; 
     87        int lines=1;    // number of lines of text. 
     88         
     89        // Create a glyph for each letter and store its parameters 
     90        foreach (c; text) 
     91        { 
     92            error = FT_Load_Char(face, c, FT_LOAD_RENDER); // Load into slot  
    5493            if (error) 
    5594                throw new Exception("Font Error."); 
    5695             
    5796            auto bitmap = face.glyph.bitmap; 
    58             writefln("glyph size=", bitmap.width, " ", bitmap.rows); 
    5997            ubyte[] data = (cast(ubyte*)bitmap.buffer)[0..(bitmap.width*bitmap.rows)]; 
    60             Image img = new Image(data, 1, bitmap.width, bitmap.rows); 
    6198             
    62             return img; 
     99            // Set the values of the 
     100            Letter letter; 
     101            letter.image = new Image(data.dup, 1, bitmap.width, bitmap.rows); 
     102            letter.top = face.glyph.bitmap_top; 
     103            letter.left = face.glyph.bitmap_left; 
     104            letter.advancex = total_width; 
     105            letter.advancey = total_height; 
     106            letters ~= letter; 
    63107             
    64         //} 
     108            total_width+= face.glyph.advance.x>>6; 
     109            total_height+= face.glyph.advance.y>>6; 
     110        } 
    65111         
    66112         
     113        // Composite all glyph images into a single image. 
     114        // We have to do this here since we need to render them before calculating sizes. 
     115        int img_width = image_pow2 ? nextPow2(total_width) : total_width; 
     116        int img_height = image_pow2 ? nextPow2(line_height*lines) : line_height*lines; 
     117        Image result = new Image(1, img_width, img_height); 
     118        for (int i=0; i<letters.length; i++) 
     119        {   result.overlay(letters[i].image, letters[i].advancex+letters[i].left, (letters[i].advancey-letters[i].top+height)); 
     120            delete letters[i].image; 
     121        } 
     122     
     123        return result; 
    67124    } 
    68      
    69     ~this() 
    70     { 
    71          
    72     } 
    73      
    74      
    75     protected void load() 
    76     { 
    77          
    78     } 
     125 
    79126} 
  • trunk/yage/resource/image.d

    r76 r79  
    1717 * Bugs: 
    1818 * An RGB image will often be returned when loading grayscale images.  Use setFormat(IMAGE_FORMAT_GRAYSCALE) to correct this. 
    19  * The load and resize functions seem to have images with widths that aren't a multiple of 4.*/ 
     19 *  
     20 * TODO: Add convolution support: http://www.php.net/manual/en/function.imageconvolution.php#77818 */ 
    2021class Image 
    2122{ 
     
    4344 
    4445    /** 
     46     * Create a new emtpy image. 
     47     * Params: 
     48     *     channels = number of color channels. 
     49     *     width = width in pixels 
     50     *     height = height in pixel */ 
     51    this(int channels, int width, int height) 
     52    {   data.length = channels*width*height; 
     53        this.channels = channels; 
     54        this.width = width; 
     55        this.height = height; 
     56    } 
     57     
     58    /** 
    4559     * Construct from image data in memory.  This does not create a copy of the data. 
    4660     * Params: 
    47      * image = array of raw image data 
    48      * width = width in pixels 
    49      * height = height in pixels, if 0 it is auto-calculated from width, channels, and data's length.*/  
     61     *     image = array of raw image data 
     62     *     channels = number of color channels. 
     63     *     width = width in pixels 
     64     *     height = height in pixels, if 0 it is auto-calculated from width, channels, and data's length.*/  
    5065    this(ubyte[] data, int channels, int width, int height=0) 
    5166    {   this.data = data; 
     
    5469        if (height) 
    5570            this.height = height; 
     71        else if (width && channels) 
     72            this.height = data.length / (width*channels); 
    5673        else 
    57             this.height = data.length / (width*channels)
     74            this.height = 0
    5875    } 
    5976     
     
    187204    body 
    188205    {   int i = (y*width+x)*channels; 
    189         //std.stdio.writefln(i, "..", i+channels); 
    190206        return data[i..(i+channels)]; 
    191207    } 
     
    193209    in { assert(x<width && y<height); } 
    194210    body 
    195     {   int i = (y*width*+x)*channels; 
     211    {   int i = (y*width+x)*channels; 
    196212        return data[i..(i+channels)] = val[0..channels]; 
    197213    } 
    198214 
     215    /** 
     216     * Paste another image on top of this one. 
     217     * This does not make a copy. */ 
     218    void overlay(Image img, int xoffset=0, int yoffset=0) 
     219    { 
     220        for (int x=0; x<img.width; x++) 
     221        {   int xoffsetx = xoffset + x; 
     222            if (xoffsetx < width && xoffsetx > 0) 
     223            {   for (int y=0; y<img.height; y++) 
     224                {   int yoffsety = yoffset+y; 
     225                    if (yoffsety < height && yoffsety > 0) 
     226                        this[xoffsetx, yoffsety][0..channels] = img[x, y][0..channels]; // TODO: convert format 
     227        }   }   } 
     228    } 
     229     
     230    void overlayAndFlip(Image img, int xoffset=0, int yoffset=0) 
     231    { 
     232        for (int x=0; x<img.width; x++) 
     233        {   int xoffsetx = xoffset + x; 
     234            if (xoffsetx < width && xoffsetx > 0) 
     235            {   for (int y=0; y<img.height; y++) 
     236                {   int yoffsety = yoffset+y; 
     237                    if (yoffsety < height && yoffsety > 0) 
     238                        this[xoffsetx, yoffsety][0..channels] = img[x, img.height-y-1][0..channels]; 
     239        }   }   } 
     240    } 
     241     
    199242    /** 
    200243     * Return a c-style pointer to the image data. 
     
    210253     *     width = The new width. 
    211254     *     height = The new height.  If 0, height will be calculated automatically with aspect ratio maintained. 
    212      * Returns: A new image of the same type.*/ 
     255     * Returns: A new image of the same type and of the new size, or an exact copy if the dimensions are the same. */ 
    213256    Image resize(int width, int height=0) 
    214257    {   Image result = new Image(); 
     
    217260            result.height = height; 
    218261        else 
    219             result.height = width*this.height/this.width; 
     262            result.height = width*this.height/this.width;       
    220263        result.channels = channels; 
     264         
     265        // Return a copy if there's nothing to resize. 
     266        if (result.width == this.width && result.height == this.height) 
     267        {   result.data = this.data.dup; 
     268            return this; 
     269        } 
     270         
    221271        result.data.length = width*height*channels; 
    222          
    223272        float width1 = 1/(width-1.0f); 
    224273        float height1= 1/(height-1.0f);      
     
    235284 
    236285    // TODO: modify this to return a new image in the given format. 
    237     void setFormat(int channels) 
     286    Image setFormat(int channels) 
    238287    {   if (channels == this.channels) 
    239             return
    240  
    241         ubyte[] result
     288            return this
     289 
     290        Image result = new Image(channels, width, height)
    242291     
    243292        switch (channels) 
     
    245294            case 1: 
    246295                // Set each pixel to the average of RGB, dropping alpha if present 
    247                 for (int i=0; i<data.length-2; i+=channels) 
    248                     data[i/channels] = cast(ubyte)((data[i] + data[i+1] + data[i+2]) / 3); 
    249                 data.length = width*height; 
     296                for (int i=0; i<data.length-this.channels-1; i+=this.channels) 
     297                {   int sum=0; 
     298                    for (int j=0; j<this.channels; j++) 
     299                        sum += data[i+j]; 
     300                    result.data[i/this.channels] = cast(ubyte)(sum / this.channels); 
     301                } 
     302                this = result; 
    250303                break; 
    251304            case 3: 
     
    277330        } 
    278331        this.channels = channels; 
     332         
     333        return this; 
    279334    } 
    280335    /** 
  • trunk/yage/resource/resource.d

    r76 r79  
    1111import yage.core.array; 
    1212import yage.core.misc; 
     13import yage.resource.font; 
    1314import yage.resource.model; 
    1415import yage.resource.material; 
     
    3233    static char[][] paths = [""];       // paths to look for resources 
    3334 
     35    private static Font[char[]]     fonts; 
    3436    private static GPUTexture[char[]][2][2]  textures; // [source][clamped][compressed][mipmapped][filter] 
    3537    private static Shader[char[]]   shaders; 
     
    119121    } 
    120122 
    121     /** Acquire and return the given Model. 
    122      *  If it has already been loaded, the in-memory copy will be returned. 
    123      *  If not, it will be loaded and uploaded to video memory. 
    124      *  All associated Materials, Textures, and Shaders will be loaded into 
    125      *  the resource pool as well. 
    126      *  Params: source = The 3D Model file that will be loaded. */ 
     123    /**  
     124     * Acquire and return the given Font. 
     125     * If it has already been loaded, the in-memory copy will be returned. 
     126     * If not, it will be loaded and then returned. 
     127     * Params: source = The Font file that will be loaded. */ 
     128    static Font font(char[] source) 
     129    {   if (source in fonts) 
     130            return fonts[source]; 
     131        Timer t = new Timer(); 
     132        fonts[source] = new Font(source); 
     133        Log.write(Log.RESOURCE, "Resource ", source ~ " loaded in ", t, " seconds."); 
     134        return fonts[source]; 
     135    } 
     136     
     137    /**  
     138     * Acquire and return the given Model. 
     139     * If it has already been loaded, the in-memory copy will be returned. 
     140     * If not, it will be loaded and uploaded to video memory. 
     141     * All associated Materials, Textures, and Shaders will be loaded into 
     142     * the resource pool as well. 
     143     * Params: source = The 3D Model file that will be loaded. */ 
    127144    static Model model(char[] source) 
    128145    {   if (source in models) 
  • trunk/yage/resource/texture.d

    r76 r79  
    172172        if (blend != BLEND_MULTIPLY) 
    173173            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
     174         
     175        glBindTexture(GL_TEXTURE_2D, 0); 
    174176    } 
    175177 
     
    205207    this() 
    206208    {   glGenTextures(1, &gl_index); 
    207         Texture(this).bind(); 
    208         Texture(this).unbind(); 
     209     
     210        // For some reason these need to be called or everything runs slowly. 
     211        glBindTexture(GL_TEXTURE_2D, gl_index); 
     212        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     213        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     214        glBindTexture(GL_TEXTURE_2D, 0); 
    209215    } 
    210216 
     
    296302 
    297303        // Upload image 
     304        // TODO: Use image's built in resizer instead of glu. 
     305        // glu has resizing issues with non power of two source textures. 
    298306        if (mipmap) 
    299307        {   //writefln(GL_TEXTURE_2D, " ", glinternalformat, " ", image.getWidth(), " ", image.getHeight(), " ", glformat, " ", GL_UNSIGNED_BYTE, " ", image.getData().length); 
     
    316324 
    317325            // Resize if necessary 
    318             image = image.resize(min(newwidth, max), min(newheight, max));           
     326            if (newwidth != width || newheight != height) 
     327                image = image.resize(min(newwidth, max), min(newheight, max));           
    319328            glTexImage2D(GL_TEXTURE_2D, 0, glinternalformat, image.getWidth(), image.getHeight(), 0, glformat, GL_UNSIGNED_BYTE, image.getData().ptr); 
    320329 
  • trunk/yage/system/constant.d

    r76 r79  
    1515    DEVICE_SHADER,              /// Hardware support for openGl vertex and fragment shaders 
    1616    DEVICE_VBO,                 /// Hardware support for caching vertex data in video memory (Vertex Buffer Object) 
     17    DEVICE_BLEND_COLOR, 
    1718 
    1819    DEVICE_MAX_LIGHTS,          /// Maximum number of lights that can be used at one time 
  • trunk/yage/system/device.d

    r76 r79  
    4141abstract class Device 
    4242{ 
     43     
    4344    // Video 
    4445    protected static SDL_Surface* sdl_surface; // Holds a reference to the main (and only) SDL surface 
     
    153154        }else 
    154155            Log.write("GL_ARB_vertex_buffer_object not supported.  This is still ok."); 
     156         
     157        // Attempt to load blend color extension 
     158        if (getSupport(DEVICE_BLEND_COLOR)) 
     159        {   if (!EXTBlendColor.load("GL_EXT_blend_color")) 
     160                throw new Exception("GL_EXT_blend_color extension detected but it could not be loaded."); 
     161            Log.write("GL_EXT_blend_color support enabled."); 
     162        }else 
     163            Log.write("GL_EXT_blend_color not supported.  This is still ok."); 
    155164 
    156165        // OpenGL options 
     
    226235    static bool checkExtension(char[] name) 
    227236    {   char[] exts = std.string.toString(cast(char*)glGetString(GL_EXTENSIONS)); 
    228         int result = find(toupper(exts), toupper(name)~" "); 
    229         delete exts; 
     237        int result = find(tolower(exts), tolower(name)~" ");  
     238        delete exts; // [above] append space to ensure we're not matching part of another extension. 
    230239        if (result>=0) 
    231240            return true; 
     
    273282    static bool getSupport(int constant) 
    274283    {   //return false; 
    275         static int shader=-1, vbo=-1, mt=-1, np2=-1;   // so support only has to be found once 
     284        static int shader=-1, vbo=-1, mt=-1, np2=-1, bc=-1;    // so lookup only has to occur once. 
    276285        switch (constant) 
    277286        {   case DEVICE_SHADER: 
     
    294303                    np2 = checkExtension("GL_ARB_texture_non_power_of_two"); 
    295304                return cast(bool)np2; 
     305            case DEVICE_BLEND_COLOR: 
     306                if (bc==-1) 
     307                    bc = checkExtension("GL_EXT_blend_color"); 
     308                return cast(bool)bc; 
    296309            default: 
    297310                throw new Exception("Unknown Device.getSupport() constant: '" ~