GameMaker Sprites culling when manually manipulating matrices

Hi, I'm not using cameras in my game for complicated reasons that I don't really feel like explaining. I basically have my own draw pipeline, where the main game control object handles all the drawing for my custom cameras. So my custom cameras are manipulating the matrices while setting different render targets for a kind of deferred rendering technique. Each camera basically has it's own GUI/lighting etc. I don't want to get into it lol.

It works fine for my first camera. But once I add another camera (which is rendered on the first cameras GUI), some, but usually all, of the sprites are getting culled. My debug mode, which uses draw_line's/draw_circle's, draws fine. The non-sprite draw functions don't seem to care about culling. Also, my background/terrain/lighting surfaces are drawing fine, but that may just be because they take up the whole room, so they pretty much would never be culled.

I believe this has something to do with the way GM batches draw_sprite calls. Is there a way to bypass this culling, or will I have to start drawing my sprites manually with vertex buffers? Would those get culled too?

If I disable my manual drawing, and turn all objects back to "visible", I'm seeing a full view of the whole room, which is expected. So if everything WOULD be in view if it was normally drawn... why is it suddenly culled when I set the matrices myself, even though they would still be in view?

I'm sure there will be questions to clarify what I'm doing. Feel free to ask away.

I'm really hoping nobody just says "Quit being stubborn and just use cameras/views". My game used to use cameras, but I've refactored it to not. I have my reasons. Thanks guys!
 
Last edited:

Hyomoto

Member
I've never heard of this. I use a manual draw pipeline as well, but the only reason sprites would be culled in my case is the sprite layer is drawn relative to the camera and therefore culls anything that draws outside of it. That would break a second camera for me, since anything drawn outside of the render size isn't.

By default, however, GM doesn't perform culling as far as I know except maybe when using views. If you are handling all the drawing, it shouldn't be. I don't know if any of this helps, but culling is only, if anything, a function of views and the default cameras.
 
In GMS1.4, I often run into problems where gamemaker tries to cull sprites that are "outside of the view"...

Now, I seem to have found a solution, but it'll make you mad because it makes no sense why this works, while at the same time setting a view matrix alone doesn't work:

Code:
    d3d_set_projection_ortho(x_pos,y_pos,width,height,angle);
    with (obj_test) {
        draw_self();
        draw_circle(x,y,32,1);
    }
There must be undocumented behavoir in d3d_set_projection_ortho that "tells" gamemaker somehow that it needs to change the way it checks if sprites are outside of the "view".

Since it sounds like you are using GMS2, the problem is you don't have this function! So I think the solution is to find a way to turn off culling of sprites outside of the view, or to be able to control how it works manually... for which you'll need to contact yoyogames for support. Try using the lookat function, it might have the same hidden behavoir as d3d_set_projection_ortho...
 
Thanks for the replies guys!

Try using the lookat function, it might have the same hidden behavoir as d3d_set_projection_ortho...
I'm using matrix_build_lookat and then setting the matrix with matrix_set(matrix_view, matLook);

It's just super weird how it works perfectly with one camera, but the second one has no entities. Just backgrounds/terrain/lighting.

I have views disabled, I have application surface not drawing automatically.
I am manually setting surface targets and then setting the matrices. Am I doing anything wrong?
Am I supposed to destroy the default camera? If I do destroy it, things get even weirder, BUT everything is drawing. But things are randomly stretched and totally messed up. Maybe that's a starting point. Any help would be great. I'm really struggling here...
 

Hyomoto

Member
I honestly wish I could help, @Mike knows how the engine works and might be able to offer some insight if it's being caused by something internal to GM.
 
in your second view, are the backgrounds/terrain/lighting all in the correct position?
Yes everything looks right. It's just sprites that aren't showing up.
Again, draw_rectangle/draw_circle/draw_point functions are all showing up correctly.

Sprites are only visible when I go to the top left of the room. Whatever the culling function is doing... it's as if it thinks the camera is in the top left (0,0). I've tried moving the default camera, then applying it. Nothing changes.
To reiterate, this is only happening on my second view. The code is identical for both views. First view is working flawlessly.
This must be something with the engine.

I honestly wish I could help, @Mike knows how the engine works and might be able to offer some insight if it's being caused by something internal to GM.
Thanks man I really appreciate it!

I may actually make a video of the problem, with commentary, since it seems so out-there. Hopefully I'll be able to get the attention of more advanced users and figure this out.
 
Good news. So I figured out why the first view was working fine, and the second one wasn't. And turns out the first one wasn't even working fine after all.

The first view was 2560×1440 (the resolution on my monitor). When not using views, that allows for a huge room size without anything getting culled. My room was only 2000 pixels wide, so I never saw anything get culled.
The second view was 360x640. Meaning that sprites were only showing up if their draw positions were (x < 640) and (y < 360), regardless of the view's position.

After making my room 3,000 in width and moving all the way to the right, I finally saw my character disappear and objects around him not drawing.
This clears some confusion as to why the views were showing different results. But I still have the culling to deal with.

Am I not supposed to be using matrix_set(matrix_view.... and matrix_set(matrix_projection... ?
To my understanding, this is what cameras are doing behind the scenes, when setting render targets.
Why are those functions available to us if they lead to unexpected culling? What are we supposed to use them for?
I assume I'll just have to use camera_set_view/proj_matrix and then camera_apply. That just seems tedious, but the culling algorithm only takes into account the current camera and not the matrices, so I guess I have to.
I'm happy I could figure it out, but I am quite confused on the topic. I'd really appreciate any help understanding these points.

Here's an image to show what I was dealing with:


The second view is outlined in red. White entities are shown in both views, since they are within the 640x360 camera boundary. Blue entities only show up in the main view.
 
Top