-
Notifications
You must be signed in to change notification settings - Fork 0
Drago3D
If you've used 3D in GameMaker in the past before migrating to GMS2, you've probably been warned against using the compatibility scripts that GameMaker provides for you when you import an older project. There are many reasons for this:
- They're slow
- They're very barebones
- They were created to use the DirectX 8 API, which at this point in time, is older than a significant number of GameMaker's actual users
- They're actually even slower than you think, since the compatibility functions don't even make an API call but instead emulate them within GML
Vertex buffers are the preferred substitute in whatever the current year is, which are orders of magnitude faster and more capable. However, there remains something to be said for having a set of immediate-mode functions for drawing 3D geometry, so here you go.
To get started, download the YYMP from the Itch page and import it into GameMaker (Tools > Import Local Package).
In all cases performance with Drago3D will be noticeably better than with using the compatibility functions.
Some shapes, particularly spheres, will get a much, much larger boost. This is due to the potentially large number of vertices that can be involved, as the compatibility functions build the geometry from scratch (and then delete it) every single time they're called.
(steps = 32)
- Drago3D can be found on Itch here
This requires a relatively modern version of GameMaker to work, probably around 2022.11 or so.
If you know what the old D3D primitive functions were like, these are exactly the same.
There's a minor difference in that you're now allowed to specify the vertex color and alpha, where in the original functions this was not possible. The color and alpha arguments are optional and will default to the current draw color.
Some functions will take a "start" and an "end" color and alpha. Those arguments are also optional. If a "start" color or alpha is given but "end" is not, the whole shape will use the same color.
d3d_draw_block(x1, y1, z1, x2, y2, z2, tex, hrepeat, vrepeat, color*, alpha*)
d3d_draw_capsule(x1, y1, z1, x2, y2, z2, tex, closed, steps, hrepeat, vrepeat, color1*, alpha1*, color2*, alpha2*)
d3d_draw_cone(x1, y1, z1, x2, y2, z2, tex, closed, steps, hrepeat, vrepeat, color*, alpha*)
d3d_draw_cylinder(x1, y1, z1, x2, y2, z2, tex, closed, steps, hrepeat, vrepeat, color1*, alpha1*, color2*, alpha2*)
d3d_draw_ellipsoid(x1, y1, z1, x2, y2, z2, tex, steps, hrepeat, vrepeat, color*, alpha*)
d3d_draw_floor(x1, y1, z1, x2, y2, z2, tex, hrepeat, vrepeat, color*, alpha*)
d3d_draw_wall(x1, y1, z1, x2, y2, z2, tex, hrepeat, vrepeat, color*, alpha*)
In addition, there's a convenience function for drawing a sphere with a radius rather than an ellipsoid. Here the hrepeat
and vrepeat
arguments default to 1, and the steps
argument defaults to 32.
d3d_draw_sphere(x, y, z, r, tex, hrepeat*, vrepeat*, steps*, color*, alpha*)
There's also a 3D "line" shape, or at least a capsule rotated on its side that generally looks like a line if you don't make it too wide. The idea of a line with a radius is rather silly but I figured if you didn't want that you'd just use a line primitive so anyway the radius defaults to 4.
d3d_draw_line(x1, y1, z1, x2, y2, z2, radius*, color1*, alpha1*, color2*, alpha2*)
And a polyline function, if you feel like getting fancy. Pass it an array of { x, y, z }
structs and have it connect them with lines. color
and alpha
properties are optional.
d3d_draw_polyline(points, radius*, default_color*, default_alpha*)
Lastly, each of these shapes has a "simple" version, which omits the arguments that are used less often in favor of even more performance:
-
hrepeat
andvrepeat
arguments default to 1 -
steps
arguments default to 32 -
color
arguments default toc_white
-
alpha
arguments default to 1 - In
d3d_draw_floor_simple
, all four corners of the tile use the samez
value
This skips out the cache lookup step and can improve performance by 10% or more.
d3d_draw_block_simple(x1, y1, z1, x2, y2, z2, tex)
d3d_draw_capsule_simple(x1, y1, z1, x2, y2, z2, tex)
d3d_draw_cone_simple(x1, y1, z1, x2, y2, z2, tex, closed)
d3d_draw_cylinder_simple(x1, y1, z1, x2, y2, z2, tex, closed)
d3d_draw_ellipsoid_simple(x1, y1, z1, x2, y2, z2, tex)
d3d_draw_floor_simple(x1, y1, x2, y2, z, tex)
d3d_draw_sphere_simple(x, y, z, r, tex)
d3d_draw_wall_simple(x1, y1, z1, x2, y2, z2, tex)
I "fixed" the texture mapping on the tops and bottoms of cylinders and cones.
Ideally you only use this thing for blocking out levels and replace everything with proper 3D meshes when you're finished, but if you really want to use this in production I can't stop you. It's better than the original d3d, at least.
These should work with the default GameMaker shader. If you want to use your own, the vertex format is position
, normal
, color
, texture
, which is what 95% of you are probably using anyway.