Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[texture][rlgl] DrawTexturePro() rendering issues for rotated uneven textures (e.g. 3x3 pixels) #4360

Open
abflett opened this issue Oct 3, 2024 · 11 comments
Labels
hacktoberfest Hacktoberfest recommended issues help needed - please! I need help with this issue

Comments

@abflett
Copy link

abflett commented Oct 3, 2024

I'm experiencing graphical issues when using DrawTexturePro in Raylib for rendering uneven textures, specifically 3x3 textures. When rotating these textures at a center origin, particularly in 90-degree intervals, the output appears misaligned, leading to an incorrect rendering order (e.g., pixels are shifted, resulting in a display where pixels "abc" appear as "cab").

This issue is particularly noticeable with odd-sized textures. When the texture's origin is centered for rotation, the graphical glitches manifest as subpixel shifts that disrupt the intended visual alignment. It seems that anything other than 90-degree rotations can exacerbate these rendering issues, resulting in further misalignment.

Ensuring that all textures are evenly divisible by 2 helps avoid these graphical anomalies. However, this limitation may impact the flexibility of designing sprites and textures in the future.

I would appreciate any guidance on potential fixes or adjustments in Raylib's rendering approach to resolve these graphical inconsistencies.

(4X zoom)

(Same blue texture rotated - don't mind the positions still using the offset padding from example below)
image

   DrawTexturePro(animation_handler->animation->texture_resource->texture,
                   animation_handler->animation->frames[animation_handler->frame_index],
                   (Rectangle){
                       (float)(int)position.x,
                       (float)(int)position.y,
                       width,
                       height},
                   (Vector2){width * 0.5f, height * 0.5f},
                   animation_handler->rotation,
                   WHITE);

(Fixed as shown with code below but rotates with a 1 pixel offset, which has been adjusted with position padding)
image

    DrawTexturePro(animation_handler->animation->texture_resource->texture,
                   animation_handler->animation->frames[animation_handler->frame_index],
                   (Rectangle){
                       (float)(int)position.x,
                       (float)(int)position.y,
                       width,
                       height},
                   (Vector2){(float)(int)(width * 0.5f), (float)(int)(height * 0.5f)},
                   animation_handler->rotation,
                   WHITE);

Windows 11, Nvidia 3060, default raylib settings.

@raysan5
Copy link
Owner

raysan5 commented Oct 4, 2024

@abflett Wow! Good catch! It seems related to float rounding issues... but that's weird because float should give the most precision on results...

I'm checking the code but I can't see any point where precision can be lost so resulting numbers are directly provided to OpenGL API... so it makes me think it could be a driver/OpenGL issue...

At the moment I have no idea how it can be addressed from raylib side...

@raysan5 raysan5 added help needed - please! I need help with this issue platform: Windows Windows platform hacktoberfest Hacktoberfest recommended issues labels Oct 4, 2024
@raysan5 raysan5 changed the title Graphical Rendering Issues with DrawTexturePro for Uneven Textures (e.g., 3x3) [texture][rlgl] DrawTexturePro() rendering issues for rotated uneven textures (e.g. 3x3 pixels) Oct 4, 2024
@abflett
Copy link
Author

abflett commented Oct 5, 2024

Here is a sample of the texture atlas if it helps:

ship-thruster-atlas

@raysan5 raysan5 removed the platform: Windows Windows platform label Oct 7, 2024
@CodingMadness
Copy link

is this fixed by now?

@raysan5
Copy link
Owner

raysan5 commented Oct 29, 2024

@CodingMadness Afaik, noone has looked into it yet... feel free to be the first!

@CodingMadness
Copy link

@CodingMadness Afaik, noone has looked into it yet... feel free to be the first!

this brings me right to my question:

Is it possible to contribute to raylib by submitting PR's which are NOT coded In C but rather (Free)Pascal or delphi language?

Also I would not use any OOP styles just procedural coding.

Could that be an option for you?

@raysan5
Copy link
Owner

raysan5 commented Oct 30, 2024

@CodingMadness I'm afraid that's not an option, raylib is C and so fixes and improvements must be C. Not to mention that contributions must be tested.

@CodingMadness
Copy link

unfortunate, but okay thanks for clarification.

@notkatsuu
Copy link

Is this fixed already?

@CodingMadness Afaik, noone has looked into it yet... feel free to be the first!

I've never contributed to any project so I wanted to research and try to replicate this issue but I can't. Makes me think this is already solved ?¿

@JayLCypher
Copy link
Contributor

JayLCypher commented Nov 14, 2024

I wonder if that

(Vector2){(float)(int)(width * 0.5f), (float)(int)(height * 0.5f)},

essentially functions as a floor for width and height, resulting in something like 3 / 2 -> 1 (rather than 1.5).

@orcmid
Copy link
Contributor

orcmid commented Nov 14, 2024

I wonder if that

(Vector2){(float)(int)(width * 0.5f), (float)(int)(height * 0.5f)},

essentially functions as a floor for width and height, resulting in something like 3 / 2 -> 1 (rather than 1.5).

Yes, it appears equivalent to

(Vector2{ floorf(width*0.5f), floorf(height * 0.5f) }

assuming #include <math.h> (and understanding what it does if width or height are negative).

@dustycanteen
Copy link

dustycanteen commented Nov 20, 2024

Could this be due to numerical precision errors for trigonometric functions? The 2D rotation matrix is (cos, -sin, sin, cos) so it's possible that with rotations very close to n*PI/2 you might get a precision error.
Eg: a "90 degree rotation" or (1,0) yielding (e1,-1+e2) for some very small epsilon e1,e2.

Note that if this is the case, it would also happen for larger textures. However it would really only be noticeable for very small ones like this, and that only if AA is not used.

EDIT: OP you can test by adding a check here. If the absolute value of cos and sin rotations multiplied by the texture width and height respectively are less than half a pixel, just round the cos and sign value to the nearest integer and use that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest Hacktoberfest recommended issues help needed - please! I need help with this issue
Projects
None yet
Development

No branches or pull requests

7 participants