Results 1 to 15 of 15

Thread: Possible Bug? Scaling and clipped frames.

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default Possible Bug? Scaling and clipped frames.

    I've noticed when I use the add_clipped_frames portion of a sprite description, then scale that sprite up, the frames go a little awry.

    In particular it looks like the texture might be wrapping at some points, and it seems the final frame of each row is slightly offset by a pixel.

    I've verified my numbers several times and even tried different clipped frames. The graphics are used in a production game so I know they aren't off (and I've double checked the spacings, sizes, etc).

    It only seems to happen when scaling the sprite up. Sprite is created by first making a sprite description, using CL_Texture to add_clipped_frames, then constructing a sprite out of that.

    Let me know if you need more details or are unable to reproduce.

    This is the latest release version of CL 2 (2.0.2 I believe it is).

  2. #2
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Bergen, Norway
    Posts
    588

    Default

    If you want to raise the chance of a dev looking at a bug, its wise to send along a working example using the smallest amount of code needed to reproduce an error. But it is still not guaranteed a dev will have the time or energy to look into it.

    The best is to try to figure out the bug yourself. If you get stuck, ask a specific question about that area you got stuck in.
    Last edited by sphair; 05-31-2009 at 09:17 PM.

  3. #3
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    Naturally... and I did check myself, at least I checked the clipping code and I can't see an error there, but also, when not scaled, there is no glitch. So I do not think it's the clipping itself, but rather the way CL binds/draws textures when they are scaled (there may be some blending trouble here too, well at least my graphics dither oddly and take on artifact-silhouette).

    Finding the actual drawing/scaling code for sprites is a little trickier, I spent some time looking, but ultimately felt writing a bug report would be more useful to a dev than me trying to find it and learn it (I know it's open source, but I didn't write the engine nor design it, I really don't have time to learn it's innards; if I did, I wouldn't need to use ClanLib).

    So you can take my effort to at least report a bug as a contribution, I hope. And I will supply my source that seems to create the issue.

    Code:
    // Some class constructor that takes a CL_StringRef dir, and makes a sprite out of it.
    // Create a description / Sprite
    tex = new CL_Texture(gc,dir);
    CL_SpriteDescription desc;
    desc.add_gridclipped_frames(*tex,0,0,28,28,16,3);
    sprite = new CL_Sprite(gc,desc);
    sprite->set_scale(4.0,4.0); // any value over 1.0 seems to cause the problem?
    
    // Draw.
    // some class member that draws the sprite itself.
    if(sprite != NULL)
        sprite->draw(gc, position.x, position.y);
    Not very complex, but nor is my program. Again, I could be doing something wrong, so if you notice something, please correct me. I am still learning.

  4. #4
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    I think I understand what you are talking about.

    It is a known problem, that needs to be resolved.

    The problem is caused by how OpenGL performs filtering to scaled images. (Both Linear and Nearest).

    Lets say a CL_Texture (Open GL texture) is using a section of the texture e.g. (0.2, 0.2) to (0.8, 0.8), the image boundary is still (0.0, 0.0) to (1.0, 1.0)

    Now, lets say the texture will be drawn is a scale factor of 2.0

    OpenGL performs filtering, to fill in the missing pixels.
    So, for the right edge, it uses the average of 0.8 + (0.8 plus a pixel)

    Since CL_Sprite's are multiple images, within the same CL_Texture. When OpenGL draws the image, the sprite right edge plus a pixel is not a part of the sprite image - This causes distortion (During scaling)

    See the first attached screen grab from the Test/Display/TexelCenter test, showing this distortion.

    The Examples/GUI3D example also has this problem.

    There are 2 solution's to this problem:

    1) Give each sprite within the texture a pixel outline with the same colors as the sprite boundary

    The Test/Display/TexelCenter test does this with the "Outline Source Image" checkbox set - See the second attached screen grab.

    The Utilities/TexturePacker also does this in TexturePacker::add_border() for packing the GUI textures

    I do not know that if you scale the texture with say, a scale of 4.0 - if you require a 2 pixel outline etc.

    2) The OpenGL shader clips the source texture coordinates.
    This would be ideal, but I am not sure if there will be a performance penalty.
    Attached Images Attached Images   

  5. #5
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    So if I understand you correctly, this is an OpenGL issue when it comes to using multiple sprite images on one texture?

    I don't plan to do much scaling in my application, but for testing I was blowing them up just to see how they look and I noticed this. So my immediate work around is just not to use scaling right now.

    If I ever do plan on scaling, I can probably implement one of the solutions you offered.

    Thanks for the replies!

  6. #6
    Squire
    Join Date
    Jun 2007
    Posts
    27

    Default

    OpenGL has a few filtering modes for textures - all with their good and bad sides. CL_Sprite uses Linear filtering by default, and that causes scaled and rotated graphics to be smoothed out. In fact it blurs all graphics a bit. That blurring is what causes problems at edges, when using an array of sprites from the same texture, as the final pixel is averaged from surrounding pixels.

    To completely disable the smoothing you can use Nearest filtering. This retains the pixels as you scale up (making things blocky) while scaling down makes some pixels disappear. Also rotations don't look quite as good using nearest filtering. It does solve the edge problem though. You can try if nearest filtering is good enough for you simply by doing:
    Code:
     sprite.set_linear_filter(false);

Similar Threads

  1. cl_sprite with multiple frames
    By dwune in forum Official ClanLib SDK Forums
    Replies: 7
    Last Post: 08-29-2008, 08:49 AM
  2. Scaling when some tile of parallaxed background selected.
    By Rrrichi in forum Novashell Game Creation System
    Replies: 4
    Last Post: 06-13-2007, 03:11 AM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •