Results 1 to 10 of 10

Thread: ClanLib 0.9, texelcenter and texture rotation problems

  1. #1

    Default ClanLib 0.9, texelcenter and texture rotation problems

    I'm experiencing some problems when I rotate a sprite:

    when the angle is near 90 degrees the texture appear distorted.

    I examined the sources and I found the problem in Display/sprite_impl.cpp at lines 425-426:

    PHP Code:
    float texelcenterx 0.300f * (params1.srcX[1]-params1.srcX[0])/(params1.destX[1]-params1.destX[0]);
    float texelcentery 0.300f * (params1.srcY[2]-params1.srcY[0])/(params1.destY[2]-params1.destY[0]); 
    If I set texelcenter to a constant value (like 0.375 or 0.38) the texture is displayed correctly at any angle.

    I'm not an expert about 3D so what could be the best fix for this problem?

    P.S. I noticed that in ClanLib 0.8 texelcenter is a constant value.

    Thanks to all.

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

    Default

    I would have thought, that the texture coordinates (for linear filtering) should be calculated as follows:

    Coord_X = 0.5 + ( Texture_X / Texture_Width );

    Strange!
    ... more investigation needed

  3. #3
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    ClanLib 0.8 modifies the texture matrix so that texture coordinates equal to pixels in the texture, while 0.9 does not modify the texture matrix and instead calculates the coordinate to the 0-1 range instead.

    The reason we offset the texture coordinates is because we offset the vertex coordinates in the 2D mapping modes. And the reason we offset the vertex coordinates is because we want to avoid the situation where floating points gets a value like 3.9999 when we wanted it to be 4. The 'pixel offset' value is 0.375 and is a famous value covered by the red book. Unfortunately I could not find a link for this on the net (google sucks these days). The nearest I found was this:

    What do correct texture coordinates look like?

    The answer depends on which API it is (Direct3D or OpenGL) and on what kind of texture it is. Direct3D addresses texels at their top-left corner. OpenGL addresses texel centers.

    In OpenGL, most texture coordinates are normalized to the range (0..1) in each dimension, with the exception that texture rectangles (GL_TEXTURE_RECTANGLE_ARB) use unnormalized coordinates ranging from (0..width, 0..height).

    The centers of OpenGL texels along the diagonal of a GL_TEXTURE_RECTANGLE_ARB are therefore(0.5, 0.5), (1.5, 1.5), (2.5, 2.5), etc. (To see this try writing WPOS to the output of a shader on a screen-aligned quad.)

    To get the corresponding texture coordinates for GL_TEXTURE_2D textures, you have to normalize them, meaning you divide by width and height. For a 4-by-4 GL_TEXTURE_2D, that would give us texel centers along the diagonal of (0.125,0.125), (0.375,0.375), (0.625,0.625), and (0.875,0.875).

    Direct3D texture coordinates are always normalized, so the corresponding Direct3D texel centers for a 4-by-4 texture are (0, 0), (0.25, 0.25), (0.5, 0.5), (0.75, 0.75).
    Anyway, to try to translate this into easier English, what they are talking about is the fact that a pixel has a physical size. When we draw a primitive, there is generated a fragment for each pixel and the texture coordinate for that fragment is what causes us problems.

    When we offset our pixel coordinates to stay away from pixel borders, we also need to offset the texture coordinates to get the center of the pixel to match up with the desired texel. When we do linear filtering, the texel offset becomes even more important because the GPU now takes the 4 corner values of the fragment instead of the value of the center of the fragment and then blends them together. If the texel offset is incorrect you get a blurring effect in non-zoomed situations.

    It seems that the calculations of the 4 corner values change when you rotate the primitive, and I haven't yet determined why exactly that happens. I suspect it has something to do with the fact that the right and bottom borders are exclusive and this somehow affects the texel coordinates. But that's just speculation at the moment. This rotational blur effect happens both in 0.8 and 0.9, so it is not introduced by the newer way we calculate the offset.

  4. #4
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Oh oops, I didn't look at the actual equation in the original text. The texel offset should be what equals to 0.375/texture_width in the X direction and 0.375/texture_height in the Y direction.

  5. #5
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    I changed the texelcenter to constant values. The wrong math must have been caused by porting the 0.8 sprite impl stuff to 0.9.

  6. #6

    Default

    Thank you all for your prompt reply.

    I hope ClanLib 0.9 will be ready for production soon.

    Best regards

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

    Default

    Quote Originally Posted by rombust View Post
    Coord_X = 0.5 + ( Texture_X / Texture_Width );
    My formula is way off! I must have had a bad day - I meant (Texture_X + 0.5) / Texture_Width

    For reference to the 0.375 explanation, see:

    http://glprogramming.com/red/appendixg.html#name1
    ( also found at http://msdn.microsoft.com/en-us/libr...07(VS.85).aspx )

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

    Default

    I have had a look to find out what the magic number "0.375" actually is.

    After a lot of searching, the only suggestion that i can think of is...
    That it has something to do with floating point to integer rounding errors.

    I found http://babbage.cs.qc.edu/IEEE-754/Decimal.html interesting
    With the significand being 1.5

    ... the search continues

  9. #9

    Default

    http://cs-sdl.sourceforge.net/index....ook_Appendix_H

    "An optimum compromise that allows all primitives to be specified at integer positions, while still ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of pixels, while moving line vertices close enough to the pixel centers.

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.375, 0.375, 0.0);
    /* render all primitives at integer positions */"

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

    Default

    I have finally got an explanation. See: http://www.opengl.org/discussion_boa...917#Post248917

    arekkusu: It's explained right there in the first sentence-- it's a compromise, not a correct solution.

    A correct solution is to specify points and lines on pixel centers, so you should bias by 0.5, 0.5. Filled primitives like triangles should not be biased at all. This means you need to shift your geometry or a matrix around, depending on the primitive type you're drawing. The compromise avoids that, at the cost of slightly offset rendering (which is more visible if you use any form of antialiasing.)

Similar Threads

  1. ClanLib on DevC++/mingw, among other problems
    By NiMa in forum Official ClanLib SDK Forums
    Replies: 1
    Last Post: 11-11-2008, 06:15 AM
  2. relationship between GC and Texture?
    By logixoul in forum Official ClanLib SDK Forums
    Replies: 4
    Last Post: 07-07-2008, 07:17 AM
  3. problems with clanlib template from kdevelop
    By harry666t in forum Official ClanLib SDK Forums
    Replies: 5
    Last Post: 02-19-2008, 11:31 AM
  4. Surface Rotation
    By madmark in forum Official ClanLib SDK Forums
    Replies: 1
    Last Post: 07-20-2007, 08:42 AM
  5. Rotation and brains
    By nmceri in forum Novashell Game Creation System
    Replies: 3
    Last Post: 12-31-2006, 06:08 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
  •