3D Sprite disappears when using certain d3d transformations

A

Azurexis

Guest
Hello Game Maker Forum!


I have a small problem with the d3d transformation stuff. I try to draw a normal sprite with a certain transformation.

The sprite I want to draw is 35x34, and its origin is on 17x17.

I wrote the following code:

d3d_transform_set_identity();
d3d_transform_set_rotation_x(90);
d3d_transform_add_translation(130, 130, variable);
draw_sprite(spr_something, 0, 0, 0);
d3d_transform_set_identity();​

When the variable is 26 or lower the sprite gets displayed normally. However, if I raise the variable over 26, the sprite disappears. But if the variable is lower than -26 it disappears too.

When I change to origin of the sprite the values of where it gets displayed and where not seem to change also.

I ran out of ideas, and I really need this to work. Working with d3d_draw_wall doesn't work, because I want to work with a text/font here.


If anybody has any ideas about this I would be glad if you shared them with me!



Edit: Same thing happens when I change the second line to

d3d_transform_set_rotation_x(270);

or


d3d_transform_set_rotation_y(90);
 
A

Azurexis

Guest
Huh. Changing

draw_sprite(spr_something, 0, 0, 0);​

to

draw_sprite_ext(spr_something, 0, 0, 0, 1, 1, 0, c_white, 1);
solved the problem. The sprite is now always visible. Is there any logic behind that or should I report that as a bug?
 
Q

Quackertree

Guest
My best guess is that draw_sprite(...) obeys to the near/far clipping planes, whereas draw_sprite_ext(...) doesn't? The issue probably lies somewhere in your projection.
Alternatively, culling might not be your friend here. Have you tried d3d_set_culling(false)?

Either way, I'd still recommended d3d_draw_wall(...). This is actually possible, even though you consider it not to be - Have a look at sprite_get_texture(...), which will "convert" your sprite into a texture ID which you can then use to draw onto the wall. Something like:

Code:
d3d_draw_wall(x, y, z, x + 20, y, z + 20, sprite_get_texture(sprite_index, image_index), 1, 1 );
(From the top of my head - Don't quote me on this)

Do make sure that your sprite is marked as 3D, otherwise you'll draw the entire texture page, which includes more than just your sprite!

If that all fails, you can always draw your sprite to a surface and then use that to draw onto the wall, although this is clearly slower, since you have to maintain a surface, run checks on whether it still exists, etc.

P.S.: Setting the identity twice makes no sense. You've already set the transforms to the identity at the end of the call stack, so why do that again at the start? This is only wasting (a small bit) of CPU, which you already desperately need when working with 3D in GameMaker!
 

Yal

🐧 *penguin noises*
GMC Elder
Yeah, I've also experienced sprites disappearing if you don't use draw_sprite_ext()... but you get so many benefits from using _ext() that you might as well always do it anyway (e.g. mirroring the sprite horizontally when you move left).

Also, apart from the two identity settings being redundant, you have more than that.
Code:
d3d_transform_set_identity();
d3d_transform_set_rotation_x(90);
First you discard the old transformation matrix and set the identity matrix... then you discard the old transformation matrix and set a rotation matrix. :p


No super-huge deal so far, I'd say... better to have inefficient code than random transformation bugs that are hard to track down. But keep this in mind if you start having lag problems later.
 
A

Azurexis

Guest
First of all - thank you guys for posting your ideas!

I made some further tests and I don't think the draw_sprite(...) behaviour in the 3D stuff is intended.
The thing is the rest of the functions work all normally (draw_sprite_ext, draw_text, draw_text_ext, d3d_models, imported models etc etc).

Well the reason why I encountered this problem is that I wanted to draw a string to somewhere in the room. But instead of jumping right to draw_text I thought I should test it with draw_sprite. Turns out draw_text works perfectly, only draw_sprite is messed up. When I want to draw other sprites somewhere I use d3d walls and floors, no worries:) But would it make performance wise any differences between d3d walls / draw_sprite with transformations?

And the thing with the d3d_transform_identity: you got me there:D Now that you guys pointed it out it makes sense, I will remove the first line.



I made a quick Game Maker project with this problem, you guys can have a look at it if you want: https://ufile.io/3qmjt
I hope I didn't make any mistakes there:)
 

Yal

🐧 *penguin noises*
GMC Elder
But would it make performance wise any differences between d3d walls / draw_sprite with transformations?
No, you're still only drawing 2 textured triangles. Taking supportive fluff into account, walls probably are more efficient since you don't need to change the transformation matrix before drawing them, though, but the processing needed for the drawing functions themselves is the same.
 

Khyze

Member
Huh. Changing

draw_sprite(spr_something, 0, 0, 0);​

to

draw_sprite_ext(spr_something, 0, 0, 0, 1, 1, 0, c_white, 1);​
solved the problem. The sprite is now always visible. Is there any logic behind that or should I report that as a bug?
THANKS!!! Such a shame that it is a guest account, I'm truly thankful for that.

draw_text_colour have the same issue, I tried draw_text_ext_colour and it also have the same problem, draw_text does works as intended, I guess I should use custom fonts for that ;)
 

Yal

🐧 *penguin noises*
GMC Elder
Nice necrobump :p
Back in 2017 I guess we all thought the behavior was a bug, but it's still around so I guess it's intended at this point... all draw_set_* functions will carry over to all future drawing, unless you use the *_ext versions (or other special versions like draw_rectangle_color) which override settings on a case-by-case basis.

(Prior to Studio the drawing settings only affected vector graphics, not sprites or other textured assets)
 
Top