Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upThe axis from al_draw is not aligned #974
Comments
This comment has been minimized.
This comment has been minimized.
|
I did a plugin in order to start allegro. Almost everything works perfectly but the axis. But it just happens when I zoom the image. In other case it works fine. void place_draw_allegro_choice(CHAINED * user, B16U choice) {
if (place && place->machine && bit_is_on(place->machine->status, FOCUS_ON) && place->map && user && bit_is_on(USER_C(user->it)->object->status, OBJECT_VISIBLE)) {
BP32 dx = (USER_C(user->it)->object->x_route - place->map->x) + USER_C(user->it)->object->x_axis;
BP32 dy = (USER_C(user->it)->object->y_route - place->map->y) + USER_C(user->it)->object->y_axis;
switch (choice) {
case 0:
{
al_draw_rotated_bitmap(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis, dx, dy, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip);
}
break;
case 1:
{
al_draw_scaled_rotated_bitmap(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis, dx, dy, USER_C(user->it)->object->zw, USER_C(user->it)->object->zh, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip);
}
break;
case 2:
{
al_draw_tinted_rotated_bitmap(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, al_map_rgba(USER_C(user->it)->object->of->color->r, USER_C(user->it)->object->of->color->g, USER_C(user->it)->object->of->color->b, USER_C(user->it)->object->of->color->a), USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis, dx, dy, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip);
}
break;
case 3:
{
al_draw_tinted_scaled_rotated_bitmap_region(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->left, USER_C(user->it)->object->top, USER_C(user->it)->object->width, USER_C(user->it)->object->height, al_map_rgba(USER_C(user->it)->object->of->color->r, USER_C(user->it)->object->of->color->g, USER_C(user->it)->object->of->color->b, USER_C(user->it)->object->of->color->a), USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis, dx, dy, USER_C(user->it)->object->zw, USER_C(user->it)->object->zh, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip); // flag = ALLEGRO_FLIP_VERTICAL
}
break;
}
}
}
PLACE_CALL STATUS PLACE_TYPE place_user_draw(CHAINED * user) {
if (place && place->machine && bit_is_on(place->machine->status, FOCUS_ON) && place->map && user && bit_is_on(USER_C(user->it)->object->status, OBJECT_VISIBLE)) {
if (place->machine->what.b16 & SDL_SYS) {
if (place->machine->plugin && SDL_C(place->machine->plugin)->pallet) {
if (USER_C(user->it)->object->of->image && SDLIMG_C(USER_C(user->it)->object->of->image)->memory) {
SDL_Rect src = {(B32) USER_C(user->it)->object->left, (B32) USER_C(user->it)->object->top, (B32) USER_C(user->it)->object->width, (B32) USER_C(user->it)->object->height};
SDL_Rect dst = {USER_C(user->it)->object->x_route - place->map->x, USER_C(user->it)->object->y_route - place->map->y, USER_C(user->it)->object->width * USER_C(user->it)->object->zw, USER_C(user->it)->object->height * USER_C(user->it)->object->zh};
SDL_Point center = {USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis};
SDL_SetTextureAlphaMod(SDLIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->of->color->a);
SDL_RenderCopyEx(SDL_C(place->machine->plugin)->pallet, SDLIMG_C(USER_C(user->it)->object->of->image)->memory, &src, &dst, USER_C(user->it)->object->angle, ¢er, USER_C(user->it)->object->flip);
return (On);
} else {
printf("no image\n");
}
}
}
if (place->machine->what.b16 & ALLEGRO_SYS) {
if (place->machine->plugin) {
if (USER_C(user->it)->object->of->image && ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory) {
place_draw_allegro_choice(user, 3);
return (On);
}
}
}
}
return (Off);
}This is the code I am using to draw and here is main code. void user_start_up(PLACE * where, B8U * name, B64U id) {
if (where) {
where->next_front(where->set(where->object_set(id, name, 32, 112, 1, 1, 150, 50, 15, 15, where->image_select(WARRIOR_RUN_1), NULL), NULL, NULL));
}
}
void user_align_up(PLACE * where, B64U id, STATUS left) {
if (where) {
BP32 screen_w = where->machine->width, screen_h = where->machine->height;
B64U last = 0, max = 1;
CHAINED * object[max];
while (last < max) {
object[last] = where->select(id + last);
if (object[last]) {
switch (last) {
case 0: // character
{
//printf("w:%.2f h:%.2f",where->object_get(object[last])->width,where->object_get(object[last])->height);
where->image_zoom_fit(where->image_get(object[last]), screen_w * .1, screen_h * .4, &where->object_get(object[last])->zw, &where->object_get(object[last])->zh);
BP32 h_s = where->height_get(object[last]);
//where->x_set(object[last], h_s + 30);
//where->y_set(object[last], h_s);
//printf("y: %.2f",where->y_get(object[last]));
where->x_axis_set(object[last], where->width_get(object[last]) * 0.5);
where->y_axis_set(object[last], h_s);
}
break;
}
}
last++;
}
}
}When I try to zoom fit it goes out of axis. Here is the repository with the complete code https://github.com/saisilcastro/Place Thanks |
saisilcastro
changed the title
The axis from a
The axis from al_draw is not aligned
Dec 19, 2018
This comment has been minimized.
This comment has been minimized.
|
Not sure what you mean by "axis" - cx/cy specify a specific point to rotate about, it's not an axis vector like https://liballeg.org/a5docs/trunk/graphics.html#al_draw_rotated_bitmap |
This comment has been minimized.
This comment has been minimized.
|
Here is the deal. I made an engine which can alternate between allegro and sdl2. With the very same code you can do the samething in both. The only thing you have to change is the flag in the initialization. |
This comment has been minimized.
This comment has been minimized.
|
The documentation makes it very clear what these functions are meant to do:
If you expect anything other than that, I don’t know what to say other than “that’s just not how the function works”. If the behavior differs from that described in the quote above, then there is indeed a bug to fix. But I can’t figure out whether that’s the case or not just from your description of the problem... |
This comment has been minimized.
This comment has been minimized.
|
I guess it would help if you provided a description (image? gif?) of how you expect it to work. Even if Allegro's (default) way isn't what you expect, we can still give you a piece of code that'll do what you want using a few extra instructions. |
This comment has been minimized.
This comment has been minimized.
|
I am gonna do the following, I am going to record a short video showing the test with both, sdl and allegro working, so you'll can see by ourselves what I am talkin about. All right? Hold on just a short time |
This comment has been minimized.
This comment has been minimized.
|
Hey guys, I made a short video. First I've started the engine with SDL2 as you can see in command line. This is the expected behavior for the rpg. After I started with allegro5 almost everything works perfectly but the axis. I mean, when the character is falling, it does not start from the foot as in the SDL2. I don't know if it is a bug, If it is not, please, explain me how to code in my engine the right code in order to adjust that. I really like the allegro library, and wish it to work in my projects. Thanks |
This comment has been minimized.
This comment has been minimized.
|
It's not a bug. You simply have to carefully read the docs and what @fatcerberus already told you.
|
This comment has been minimized.
This comment has been minimized.
|
This is neither here nor there but personally I feel that Allegro’s behavior makes more sense - as in a rotation, (cx,cy) is the only fixed point and therefore the only one you can place reliably. I can see how it’d be unintuitive to someone used to SDL’s API (among others), but from a mathematical point of view Allegro’s behavior is very elegant. |
This comment has been minimized.
This comment has been minimized.
|
What I find less elegant is that |
This comment has been minimized.
This comment has been minimized.
|
@saisilcastro To be concrete, you want your characters to “fall backwards” by rotating on their feet. So to solve that, you would ask “where do I need to put the foot on the screen?” and specify that as the value of dx/dy and then for cx/cy you’d give the position of the foot within the bitmap. If you do that correctly, the only value you should ever have to change between frames is the angle of rotation. |
This comment has been minimized.
This comment has been minimized.
|
I have tried many ways to figure out on how to do that. I've tried to look at api, but there is no reference to al_draw_tinted_scaled_rotated_bitmap_region, and I don't know what to do anymore in order to solve that. This function is necessary in order for increase or decrease the health point, magic point and experience of the character, but even so I've tried to change for another and wasn't sucessfull. If you please can you give me a short example on how to do that I'd appreciate? |
This comment has been minimized.
This comment has been minimized.
|
cx,cy - center of rotation/zoom center (relative to bitmap dimensions, this is the fixed point) If you can’t figure out what to do from there, I don’t know what else I can say to make it clearer. |
This comment has been minimized.
This comment has been minimized.
|
If you're looking at docs on allegro.cc, then don't - they're outdated. https://liballeg.org/a5docs/trunk/graphics.html#al_draw_tinted_scaled_rotated_bitmap_region |
This comment has been minimized.
This comment has been minimized.
|
I actually played around with both APIs, I think the only difference is that when using Allegro you need to add cx and cy to dx and dy respectively. On my system, this leads to identical outputs. What confuses me on your video is that it appears as if your axis of rotation is different between Allegro and SDL, which shouldn't really happen if I understand the APIs correctly. Both should be rotation around the same axis of the destination rectangle, but differ in where the axis is placed. |
This comment has been minimized.
This comment has been minimized.
|
Oh, good point - I forgot the outdated documentation is the first thing in a Google search. I wish there was something we could do about that. |
This comment has been minimized.
This comment has been minimized.
But the code between then is exactly the same. I followed the same steps in both, and could reach a satisfied result just in one. |
This comment has been minimized.
This comment has been minimized.
|
I saw the link @dos1 docs posted, but I can't see what happens inside the function, because there's just another call of it, as if it was made in assembly and called by some object file. PLACE_CALL STATUS PLACE_TYPE place_user_draw(CHAINED * user) {
if (this && this->machine && bit_is_on(this->machine->status, FOCUS_ON) && this->map && user && bit_is_on(USER_C(user->it)->object->status, OBJECT_VISIBLE)) {
if (this->machine->what.b16 & SDL_SYS) {
if (this->machine->plugin && SDL_C(this->machine->plugin)->pallet) {
if (USER_C(user->it)->object->of->image && SDLIMG_C(USER_C(user->it)->object->of->image)->memory) {
SDL_Rect src = {(B32) USER_C(user->it)->object->left, (B32) USER_C(user->it)->object->top, (B32) USER_C(user->it)->object->width, (B32) USER_C(user->it)->object->height};
SDL_Rect dst = {USER_C(user->it)->object->x_route - this->map->x, USER_C(user->it)->object->y_route - this->map->y, USER_C(user->it)->object->width * USER_C(user->it)->object->zw, USER_C(user->it)->object->height * USER_C(user->it)->object->zh};
SDL_Point center = {USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis};
SDL_SetTextureAlphaMod(SDLIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->of->color->a);
SDL_RenderCopyEx(SDL_C(this->machine->plugin)->pallet, SDLIMG_C(USER_C(user->it)->object->of->image)->memory, &src, &dst, USER_C(user->it)->object->angle, ¢er, USER_C(user->it)->object->flip);
return (On);
} else {
printf("no image\n");
}
}
}
if (this->machine->what.b16 & ALLEGRO_SYS) {
if (this->machine->plugin) {
if (USER_C(user->it)->object->of->image && ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory) {
BP32 dx = (USER_C(user->it)->object->x_route - this->map->x); // + USER_C(user->it)->object->x_axis;
BP32 dy = (USER_C(user->it)->object->y_route - this->map->y); // + USER_C(user->it)->object->y_axis;
al_draw_tinted_scaled_rotated_bitmap_region(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->left, USER_C(user->it)->object->top, USER_C(user->it)->object->width, USER_C(user->it)->object->height, al_map_rgba(USER_C(user->it)->object->of->color->r, USER_C(user->it)->object->of->color->g, USER_C(user->it)->object->of->color->b, USER_C(user->it)->object->of->color->a), USER_C(user->it)->object->x_axis, USER_C(user->it)->object->y_axis, dx, dy, USER_C(user->it)->object->zw, USER_C(user->it)->object->zh, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip); // flag = ALLEGRO_FLIP_VERTICAL
return (On);
}
}
}
}
return (Off);
}If you see this code, there is a commentary, this is what I have made in order to align the x axis and y axis. But I wasn't sucessfull. |
This comment has been minimized.
This comment has been minimized.
|
The point is that you don’t have to align the axis at all - cx/cy specifies where in the bitmap the axis is, and dx/dy is where to place that axis on the screen. It’s only necessary for you to do that alignment manually in SDL because they do it relative to the top-left, where Allegro is relative to the center of rotation. |
This comment has been minimized.
This comment has been minimized.
|
Hmm, your comments appear to be the right solution (i.e. the |
This comment has been minimized.
This comment has been minimized.
@SiegeLord when I mark this, the character goes out of place. The dx does not stay in the same place. |
This comment has been minimized.
This comment has been minimized.
|
Are you sure you’re not swapping the cx/cy with dx/dy? |
This comment has been minimized.
This comment has been minimized.
I am pretty sure of it. I think I understand how the function works(only think), The x_route is the destiny of the object, the map->x is the scroll of the map, and x_axis is the place where it starts to rotate the object. Am I telling something wrong? |
This comment has been minimized.
This comment has been minimized.
|
Ok, I think I figured it out. Here's what Allegro does to draw the image (starting with the image drawn at top left corner):
And here's what SDL does:
So the issue is that the rotation axes are in different spots (step 1) in addition to the different shifts (step 4). So what you need to do is (for Allegro):
|
This comment has been minimized.
This comment has been minimized.
|
That SDL behavior seems kind of weird. I like Allegro’s approach as it makes sense mathematically (logically: translate -> rotate -> scale -> untranslate); I can’t even begin to see where SDL’s logic comes from. |
This comment has been minimized.
This comment has been minimized.
Thanks for that man. I am gonna give it a try. :) |
This comment has been minimized.
This comment has been minimized.
|
I think I see - in matrix terms, SDL does scale ->translate->rotate whereas Allegro does the translate first, which is IMO more intuitive but will indeed produce incorrect results if you assume the SDL behavior. |
This comment has been minimized.
This comment has been minimized.
|
@SiegeLord You're my hero man. That fixed my problem. That's what I did: if (this->machine->what.b16 & ALLEGRO_SYS) {
if (this->machine->plugin) {
if (USER_C(user->it)->object->of->image && ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory) {
BP32 dx = (USER_C(user->it)->object->x_route - this->map->x) + USER_C(user->it)->object->x_axis;
BP32 dy = (USER_C(user->it)->object->y_route - this->map->y) + USER_C(user->it)->object->y_axis;
BP32 cx = USER_C(user->it)->object->x_axis / USER_C(user->it)->object->zw;
BP32 cy = USER_C(user->it)->object->y_axis / USER_C(user->it)->object->zh;
al_draw_tinted_scaled_rotated_bitmap_region(ALLEGROIMG_C(USER_C(user->it)->object->of->image)->memory, USER_C(user->it)->object->left, USER_C(user->it)->object->top, USER_C(user->it)->object->width, USER_C(user->it)->object->height, al_map_rgba(USER_C(user->it)->object->of->color->r, USER_C(user->it)->object->of->color->g, USER_C(user->it)->object->of->color->b, USER_C(user->it)->object->of->color->a), cx, cy, dx, dy, USER_C(user->it)->object->zw, USER_C(user->it)->object->zh, USER_C(user->it)->object->angle * ((M_PI + M_PI) / 360), USER_C(user->it)->object->flip); // flag = ALLEGRO_FLIP_VERTICAL
return (On);
}
}
}You're fucking great bro. I don't know how happy I am after all this time trying and not finding the bloody problem. Thank you very much. And thanks for the guys that helped my with comments too. Now it looks like we're using the same engine no matter what we chose |
This comment has been minimized.
This comment has been minimized.
I find that sdl is more intuitive than allegro at this point, but in SDL you have to call many functions to reach the same result, which is in my opinion a waste of memory, but anyways. I think allegro manages the memory wisely than sdl. It seems more low level functions |
This comment has been minimized.
This comment has been minimized.
|
I must ask. How do you do in order to put the code into that blue boxe here in github? |
This comment has been minimized.
This comment has been minimized.
|
SDL from what I’ve seen tries to be all things to all people, so it can sometimes feel a little bloated. Allegro is a much thinner layer that merely abstracts away the low-level platform differences without layering too many extras on top. In most cases you’re simply talking directly to the graphics backend with a modified API. It doesn’t hold your hand, which is nice. |
This comment has been minimized.
This comment has been minimized.
|
For code, use a triple-backtick with an optional lowercase name of the programming language: // code here
do_stuff(); |
This comment has been minimized.
This comment has been minimized.
I think so too dude. I feel capable doing the thinks the way allegro offears me |
This comment has been minimized.
This comment has been minimized.
And thanks for the tip bro. |
saisilcastro commentedDec 19, 2018
•
edited
No description provided.