Results 1 to 15 of 15

Thread: Possible Bug? Scaling and clipped frames.

  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

    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);

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

    Default

    Quote Originally Posted by Harry View Post
    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);
    This does not work with the Test/Display/TexelCenter test. When you select the nearest filtering, it is blocky, but sometimes you see the extra incorrect pixels.

    Maybe it's a bug in clanlib? (or the TexelCenter test)

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

    Default

    I doubt it's a bug in OpenGL. The pixel overlapping happens also when I use interpolated movement for my sprites at normal scaling. So there's something in there with floating point rounding or some such.

    I've used raw openGL for quad-sprite drawing in the past (and scaling) and I've never seen this before (though I never used texture compacting either). Unfortunately, I don't know how much has changed in the way the drawing is done from 0.8 to 2.0, but my older 0.8 projects using sprites has never done anything like this (but again, there wasn't grid clipping back then I don't think).

    So it's hard to say for sure.

    I haven't yet gone digging through the sprite or drawing code, so I can't be sure yet. It's far from my area of expertise (clan lib internal code), so it will be a learning experience

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

    Default

    Yes, it may be something to do with floating point errors in calculating "floating point coord = Pixel Offset / Texture Width".

    I guess we can check this
    Last edited by rombust; 06-03-2009 at 07:35 PM. Reason: spelling

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

    Default

    I have updated the TexelCenter test to display CL_Texture (as well as CL_Sprite and CL_Image), with the coordinates calculated as follows:

    Code:
    	CL_Rectf source_rect;
    	source_rect.left = (float) source.left / texture.get_width();
    	source_rect.top = (float) source.top / texture.get_height();
    	source_rect.right = (float) source.right / texture.get_width();
    	source_rect.bottom = (float) source.bottom / texture.get_height();
    It works with cl_filter_nearest! But cl_filter_linear looks dreadful

    Most investigation required

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

    Default

    Updated again. Now you can control the Texture sub-pixel translation.

    You can make it look smart by adjusting this value - But this value depends upon the filter used and scale used.

    Odd!

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

    Default

    Well, this is turning out to be an interesting thread... is there anything I can do to help get to the bottom of the mystery?

    Since there's really no partial pixels, would it make sense to cast to int (+0.5, or floored), or simply forgo floats entirely? At least as far as picking the grid frames?

    They are subject to rounding errors depending on the system architecture, and I'm wondering if it'll be an issue from system to system...

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

    Default

    bumpity.

    Anyone else found anything on this? I'm rather out of ideas

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

    Default

    I have some ideas to test, hopefully i'll have some time on friday.

  15. #15

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
  •