Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(+1)

Those user events are being called by another draw event of the light engine, so they are called in draw event.

It sounds like they straight up do not use any vertex color with draw_sprite_pos then.  So, it is not possible to use as is.

Instead a primitive or vertex buffer would need to be used which supplies the correct vertex color as the same as image_blend for vertex color.

I can add the feature in the future.

It would be a great feature! Using draw_sprite_pos can create a parallax effect by modifying sprites based on camera position. It really creates an additional sense of depth for the top down perspective.

(+1)

Gotcha.  I'm currently in Hawaii and have no access to my dev computer, but I'll look into it when I get back in a few weeks.  

You could try using a vertex buffer or primitive in the meantime.  If you look at the shadow caster objects and the one that is like "textured" or something.  It is setup to use a path to define its polygon.  It won't do a stretch or skew, but it should use a vertex buffer which would use the format you need and there should be enough info there to make a version like draw_sprite_pos.

Also, it is worth confirming that there is no vertex color used in draw_sprite_pos.  Just make a blank project and draw with it while setting the global draw color or something.  See if you can get it to actually do different image blends or something.  If it actually does blend, then it is possible I just need to add something to get it working with the normal and material sprites.  

I checked, there is no draw_sprite_pos_ext or anything... that seems like it should exist though.  The extended version of most draw calls have image_blend, rotation, and alpha.  When I add the feature I'll basically just be adding that exact function since I'd say its simply a missing feature of GM itself.

(1 edit)

I used the __le_game object as a parent, then overrode the create/normal/material events with additional vertex buffer drawing, AND IT WORKED!

I'm very new to writing my own vertex buffers, but I understand that if you have dynamic shapes, you can't just store the data once since you are recalculating the coordinates. Is this correct for the normals draw event or do I have too much that could be moved to the create event (obviously I would make some of the vars into local variables)? (I just want to make sure I'm doing this efficiently, because it dips below 45 fps if I have like 8 objects drawing this on screen)

CREATE

////

event_inherited()

vertex_format_begin();

vertex_format_add_position_3d();

vertex_format_add_colour();

vertex_format_add_texcoord();

format = vertex_format_end();


USER EVENT 15

////


var _uv_data = sprite_get_uvs(normal_map, 0);

var _umin = _uv_data[0], _vmin = _uv_data[1], _umax = _uv_data[2], _vmax = _uv_data[3];

var vb = vertex_create_buffer();

vertex_begin(vb, format);

vertex_position_3d(vb,  bbox_left,  bbox_top, 0); vertex_color(vb, normal, LE_NORMAL_ANGLE); vertex_texcoord(vb, _umin, _vmin);

vertex_position_3d(vb, bbox_right,bbox_top, 0); vertex_color(vb, normal, LE_NORMAL_ANGLE); vertex_texcoord(vb, _umax, _vmin);

vertex_position_3d(vb,  mouse_x, mouse_y, 0); vertex_color(vb, normal, LE_NORMAL_ANGLE); vertex_texcoord(vb, _umin, _vmax);

vertex_position_3d(vb, mouse_x+100, mouse_y, 0); vertex_color(vb, normal, LE_NORMAL_ANGLE); vertex_texcoord(vb, _umax, _vmax);

vertex_end(vb);

var _tex = sprite_get_texture(normal_map, 0);

vertex_submit(vb, pr_trianglestrip, _tex);

That's good to hear.

So, this does mean that the default draw_sprite_pos does not include vertex color information.

There are things you can do to optimize a bit and I'll write a better function at some point as well. 

One thing that is important to check first though, is that you do not seem to be destroying the vertex buffer which will lead to a memory leak for sure.  You can destroy it and create a new one, or if the object is not moving or anything you can create the vertex buffer on create only once and then submit it in the user event like you have.  Then add some code to destroy the vertex buffer on the clean-up event.

Another thing is the macro LE_NORMAL_ANGLE performs some calculations, so instead of calling it for each vertex you should declare a local variable like "var _angle = LE_NORMAL_ANGLE;" and then use that local for the argument.

I can make the whole thing into a new object or function in the future with other optimizations.

Are you also having this cast shadow too?  Given the shape I would assume you need to use something like the shadow path object to get the correct polygon shape.  This might be a new object I should add that also is a shadow caster.  The shadow path object type is for more complex polygon shapes, and I never considered just a skewed/stretched rectangle which is more simple.

I was destroying the buffer in the clean-up, but then I switched to creating the buffer as a temporary var which I assumed wouldn't work in a separate event. I switched to a local variable for the buffer, so I don't have to keep creating and destroying it every draw event (which I assume is not efficient). I also used the var _angle suggestion for normal events. Still seeing a frame drop even with these modifications, but it seems better. There is a frame dip from 60 to 50 if I make the scale of the object bigger or place 6 of them on screen at once.

Yes! I plan on utilizing shadows if possible. A shadow path object that has the functionality of draw_sprite_pos would be incredibly helpful.

Creating a buffer with "var" does not matter, it is still a memory leak if you do not destroy it.  Having it created every single frame in the draw event is going to be much slower.  If it does not move then create it once and freeze the buffer.  If it moves you can create it, use and then destroy it.  Or use primitive drawing if it provides the right format for the vertex...I'd have to check.  

When you create any type of dynamic memory such as buffers, ds_lists, other ds structures, or surfaces, they are in memory until you destroy them manually.  Declaring a local variable with "var" only holds a reference to the memory, it still exists and still needs to be managed or you'll have a memory leak.  Even vertex formats can be destroyed, but those usually are very tiny and you make a couple that never need deleted until the game closes.

Note, that if something uses memory that will always persist until the game closes then you really do not have to destroy it.  When the game closes the entire heap will be freed by the OS.

Thanks for the clarification! I moved the vertex_position() code into the step event from the draw event, and it all runs smoothly at 60 fps now.