Jo Engine Forum

Sega Saturn Development => Jo Engine Wish List => Topic started by: null1024 on August 03, 2017, 04:15:26 am

Title: Drawing "billboard" sprites in 3D, sprite pre-scaling
Post by: null1024 on August 03, 2017, 04:15:26 am
One thing I was looking for how to do was to use two-point scaled sprites in 3D for effects that always face the screen. Eg., it's positioned and sorted in 3D, but it's just a plain 2D sprite rather than a quad (so camera rotation doesn't immediately out it as being flat as a pancake).
This sort of thing is used pretty often in Saturn and PS1 games (the example that immediately comes to mind are point items and bullets in Bulk Slash, or literally every object in After Burner 8))
This would be both faster (fewer points needed to be transformed) and convenient for things like particle effects and the lot.

also, having a function to pre-scale those sprites (billboards or 3d) before the 3D transform would be convenient as a built-in part of the library (a new user to the library might attempt to do jo_3d_set_scale before jo_3d_draw_sprite_at, which would result in the scale affecting the translation jo_3d_draw_sprite_at does and everything would be positioned wrong, and jo_3d_set_scale's name/description in the docs doesn't actually tell the user that it affects the matrix :P)

here's an implementation for that for 3D quad sprites I'd come up with (feel free to use this if you want)
Code: [Select]
void jo_3d_draw_sprite_at_scaled(int texture, int x, int y, int z, int xscale, int yscale) {
Title: Re: Drawing "billboard" sprites in 3D, sprite pre-scaling
Post by: mindslight on August 03, 2017, 09:13:11 am

Wish accepted :)
Title: Re: Drawing "billboard" sprites in 3D, sprite pre-scaling
Post by: mindslight on August 12, 2017, 03:18:06 pm
Hi Null1024,

You will find below, the prototype of the function I have added on the next release:

Code: [Select]
/** @brief Draw billboard with a specific scale
 *  @param sprite_id Sprite Id returned by jo_sprite_add(), jo_sprite_add_tga() or jo_sprite_add_image_pack()
 *  @param x X coordinate
 *  @param y Y coordinate
 *  @param z Z coordinate
 *  @param scale_x X scale
 *  @param scale_y Y scale
void      jo_3d_draw_billboard(const int sprite_id, const int x, const int y, const int z, const int scale_x, const int scale_y);
Title: Re: Drawing "billboard" sprites in 3D, sprite pre-scaling
Post by: XL2 on November 02, 2017, 03:30:53 am
I second Null1024's demand for 2 points sprites scaled support.
SGL has the slPutSprite function, which allows the usage of the current matrix to know where the position is and scale it.
It displays a 2 point sprite (I don't know if there is a better function than slPutSprite in SGL).

You only need to change one line in the current jo_sprite_draw to make it work, with maybe some small corrections to be made.
But I would suggest removing a couple of lines to speed things up might be nice since you are just using the current projection matrix and as it is you need the centered_style_coordinates always at true.
I would recommand having High Speed Shrink always ON as well (HSSon after ECdis) as it speeds up the drawing at the cost of some precision, but since we are using 2 points sprites only to display things like rings or small bullets and other things like that, it doesn't matter that much if it's very precise.

Code: [Select]
void                    jo_sprite_draw(const int sprite_id, const jo_pos3D * const pos, const bool centered_style_coordinates)
    FIXED               sgl_pos[XYZS];
    SPR_ATTR            attr = SPR_ATTRIBUTE(0, No_Palet, No_Gouraud, CL32KRGB | ECdis, sprNoflip | FUNC_Sprite);

    sgl_pos[2] = JO_MULT_BY_65536(pos->z);
    sgl_pos[3] = __jo_sprite_attributes.fixed_scale;
    if (centered_style_coordinates)
        sgl_pos[0] = JO_MULT_BY_65536(pos->x);
        sgl_pos[1] = JO_MULT_BY_65536(pos->y);
        sgl_pos[0] = JO_MULT_BY_65536(pos->x - JO_TV_WIDTH_2 + JO_DIV_BY_2(__jo_sprite_def[sprite_id].width));
        sgl_pos[1] = JO_MULT_BY_65536(pos->y - JO_TV_HEIGHT_2 + JO_DIV_BY_2(__jo_sprite_def[sprite_id].height));
    __jo_set_sprite_attributes(&attr, sprite_id);
    slPutSprite(sgl_pos, &attr, 0);   //was  slDispSprite(sgl_pos, &attr, 0);

Title: Re: Drawing "billboard" sprites in 3D, sprite pre-scaling
Post by: mindslight on November 02, 2017, 09:41:31 am
I will update the engine