• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Question - Code Help with drawing to layers rather than depths...

H

heyimdandan

Guest
So this morning I bought and paid for GameMaker Studio 2. I expect my project will be finished at the end of 2017 / early 2018. If some of the export modules aren't going to be available for GM1.4 at that time then I figured it would be best to upgrade and see what's going on. So I imported my 1.4 project - and a whole lot of flickering is what's going on, and at first guess it all seems to be related to drawing events.

The FPS of my game has taken a critical hit running at half the speed it did, but I get the feeling that's largely down to the compatibility scripts. If I update my code to remove the need for the compatibility scripts then I'm sure this will be over come if I put a few weeks work into making the changes. I'm really pleased to see that he game actually runs much more smoothly on screen which is great. It's certainly not as jerky at points as GM1.4 was.

However, a lot of my objects do clever things that give this pseudo 3D depth effect, and in a lot of my Draw Events I'm setting the depth at multiple levels to draw a sprite, then setting the depth again to draw something else, then setting the depth further forward to draw a health bar over the player or the enemy. Am I right in assuming that constantly adjusting the depth in a Draw Event doesn't conform to the format of drawing layers in the new style much akin to Photoshop? And would I be right in assuming this is likely the cause of so much on screen flickering where I know my objects are making significant use of adjusting the depth?


I guess my question is, how can I draw multiple sprites in a Draw Event and how do I assign each sprite or a health bar to a different layer? I haven't found much useful information in the manual about this, possibly because I don't know where to look. Is there a command I can use to assign different elements of a draw event to a particular layer?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
You don't draw on a layer... the layer is a purely organisational tool that sets the render depth for whatever is assigned to it. So if you want something to render on a specific layer it needs to be assigned to that layer (you can set the "layer" build in variable, but I suspect that it should be done outside the draw event). Also note that if you have previously been changing depths in the draw event, then you have been doing something very wrong, as that will have NO effect on what is drawn for that step. For example if I have this code:

Code:
depth = -100;
draw_self();
depth = 100;
draw_self();
What ACTUALLY happens is that the depth is set to -100, BUT since this is the draw event and rendering has already started it will be ignored until the end of the draw event when it will be set, but it will be set to 100 since that is the last setting it was given, which in turn means that the next render step will render to the last set depth, which is 100, regardless of the -100 setting you have there. So both times the draw_self() function will draw at the same depth....
 
H

heyimdandan

Guest
Very much on the contrary... I've been drawing at various depths in a single Draw Event with huge success in GM1.4 for quite some time. Give it a go, and not using draw_self. Using different sprites with draw_sprite.
 

rwkay

GameMaker Staff
GameMaker Dev.
Errr.. you are not doing what you think you are doing I am afraid....

In GMS anything that you execute in a Draw Event is added to the drawing pipeline at that point - any depth changing would be down to GPU (ie Z testing if the Z buffer is active and other GPU operations) - not down the depth, as any depth changes are not acted on until the Draw Event code has finished.

Not disputing that your code is organised that way, just that what you are actually doing is different to what you think you are doing.

Russell
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I don't know what you're doing, but if it works in 1.4 then great! But you are wrong in your ideas... Get this project: https://www.dropbox.com/s/hzp3fkb0dlfir61/DepthTest.gmz?dl=0

Now, run the project with the debugger and place a breakpoint on the line where the depth is set to -100.
Click the mouse and you'll see that the code stops right on that depth setting, which means the next draw_self should draw the instance OVER the green square, no?
Only it doesn't. If you keep stepping through the code it won't actually draw over the green square until the NEXT step, which is what I would expect.
 
H

heyimdandan

Guest
Check this video and take a look at the effect created by the object on the left. The draw event has 7 sprites all being drawn at different depths, and all the lines are drawn at various depths too.


Now, regardless of whether my GPU is doing it or not - this effect works successfully on every PC I've tried it on. As long as the positive depth is drawn first, and then successively higher depths are drawn afterwards.

But this doesn't really answer my question. I believe the depth changes are the issue causing the flickering in GM2.0, and if anyone has any suggestions on how I can work around this I'd be very grateful.
 
H

heyimdandan

Guest
I don't know what you're doing, but if it works in 1.4 then great! But you are wrong in your ideas... Get this project: https://www.dropbox.com/s/hzp3fkb0dlfir61/DepthTest.gmz?dl=0

Now, run the project with the debugger and place a breakpoint on the line where the depth is set to -100.
Click the mouse and you'll see that the code stops right on that depth setting, which means the next draw_self should draw the instance OVER the green square, no?
Only it doesn't. If you keep stepping through the code it won't actually draw over the green square until the NEXT step, which is what I would expect.
The red box comes to the foreground when I click! :)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
You need to assign the things to be drawn at different depths to an instance or an asset on different layers. How you are trying to do it just won't work, and if you say it's working in GMS 1.4 then you are relying on undocumented behaviour that goes against the recommended use of the variable. The manual does clearly state that you cannot change depth in the draw event. http://docs.yoyogames.com/source/da...nces/instances/instance properties/depth.html

So, you'll need to separate off the things you want to draw into different instances and assign those to specific layers, OR you can create the layers in the create event of the object and then assign the sprites that need to be drawn as assets to those layers, manipulating them as required in the Step event rather than the draw. See: http://docs2.yoyogames.com/index.ht...pting/4_gml_reference/rooms/layers/index.html and http://docs2.yoyogames.com/index.ht...ting/4_gml_reference/rooms/sprites/index.html

The red box comes to the foreground when I click! :)
It will for one frame. But it's the frame AFTER the one you want it o come to the foreground in. Did you run it in the debugger? If you do and step through the code you can clearly see that it's the NEXT frame that is drawn at -100.
 
H

heyimdandan

Guest
Take a gander at this depth example I've pulled together: http://www.eataudio.com/uploads/depthexample.gmz

This demonstrates that variable depth in a draw object works, and my game is full of it. It may be unexpected behaviour, and yes, the manual may even state that it isn't mean to work this way - but it does, and I assumed this was intentional.

I'll have to spend a considerable amount of time working out how to implement this technique in GM2.0, either that or try and get hold of the XB1 and PS4 modules for GM1.4 sooner rather than later.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
lol! Remove the depth calls in that example and it'll still work. :) You don't NEED depth ordering there as you are drawing things in a specific order based on the "if" checks. So maybe remove these calls from the draw event in GMS2 and see what happens?
 
A

atmobeat

Guest
Also note that if you have previously been changing depths in the draw event, then you have been doing something very wrong, as that will have NO effect on what is drawn for that step. For example if I have this code:

Code:
depth = -100;
draw_self();
depth = 100;
draw_self();
What ACTUALLY happens is that the depth is set to -100, BUT since this is the draw event and rendering has already started it will be ignored until the end of the draw event when it will be set, but it will be set to 100 since that is the last setting it was given, which in turn means that the next render step will render to the last set depth, which is 100, regardless of the -100 setting you have there. So both times the draw_self() function will draw at the same depth....
In GMS anything that you execute in a Draw Event is added to the drawing pipeline at that point - any depth changing would be down to GPU (ie Z testing if the Z buffer is active and other GPU operations) - not down the depth, as any depth changes are not acted on until the Draw Event code has finished.
Russell
I assume this also applies to changing layers in the draw event as well? If I wanted to use the function draw_tile in a similar way as the OP was trying how would I do that? If I wanted a tiling object to draw tiles on different layers for depth-sorting, would I just have to call draw_tile in the step event instead of the draw event of the tiling object?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I assume this also applies to changing layers in the draw event as well? If I wanted to use the function draw_tile in a similar way as the OP was trying how would I do that? If I wanted a tiling object to draw tiles on different layers for depth-sorting, would I just have to call draw_tile in the step event instead of the draw event of the tiling object?
Drawing in the step event won't achieve anything I'm afraid. All draw code needs to go in the draw event. If you want tiles on different depths you need to make your own depth system and draw them that way (along with everything else) in the draw event of a controller object or assign each depth a layer (which is simpler unless you have thousands of depths).

PS: It's better to make a new topic than necro-bump and old one (you can still quote the old one). ;)
 
Top