• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker How to draw vertex buffers transformed?

Erik Leppen

Member
I'm used to draw a vertex buffer in old versions of GM like so:

Code:
d3d_transform_set_identity();
d3d_transform_add_scaling(xscale, yscale, 1);
d3d_transform_add_translation(xorigin, yorigin, 0);
  
  vertex_submit(vbuff, pr_trianglelist, -1);

d3d_transform_set_identity();
Apparently, in GM Studio 2, the d3d functions have been deprecated. What's the correct way to draw a vertex buffer transformed (scaled and translated)?

I read something about matrices and cameras, but I couldn't find any usable code sample in the manual. The page "obsolete functions", which is the only place the d3d functions are still mentioned, also brings me nowhere. So... what's the GMS2 way to achieve the above?
 

GMWolf

aka fel666
Setting the camera is one way (look for GMS2 camera you should find a bunch of tutorials, including one by pixelated pope).

I would do it with matrices and setting them directly.
Matrix_build will let you build a transformation matrix.
You can combine matrices using matrix_multiply.
You can set the current transformation matrix to use for subsequent draw calls using Matrix_set with the world matrix.

To make sure you don't mess up your other draws, you can use the matrix stack and matrix_get to restore the state of the world matrix.
 

Bart

WiseBart
In 3D you have the model (or world), view and projection matrices.

In GMS2 the view and projection matrices are no longer set indirectly each step (e.g. using d3d_set_projection_ext) but they are stored in a camera instance that you assign to a view and are built using the matrix functions.
For the projection matrix you can use matrix_build_projection_ortho, matrix_build_projection_perspective or matrix_build_projection_perspective_fov and for the view matrix there's matrix_build_lookat.
Assigning a camera to a view means that you use that camera's view and projection matrix when drawing that view.
The difference with before is that you don't have to call d3d_set_projection anymore each step inside a draw event.

The world matrix can be built using matrix_build and there's matrix_build_identity that returns an identity matrix.
As an example, your code with the d3d functions translates to this using the matrix functions:
Code:
var _mat = matrix_build(xorigin, yorigin, 0, 0, 0, 0, xscale, yscale, 1);
matrix_set(matrix_world, _mat);

    vertex_submit(vbuff, pr_trianglelist, -1);

matrix_set(matrix_world, matrix_build_identity());

What you can always do is import a GM1.4 project in GMS2. It generates compatibility scripts that show exactly how the d3d functions are mapped to the matrix, view and camera functions.
 

Erik Leppen

Member
@GMWolf and @Bart: you just made my game twice as fast :D
I could get things to work with the following code:
Code:
var ma = matrix_build(xorigin, yorigin, 0, 0, 0, 0, xscale, yscale, 0);
matrix_set(matrix_world, ma);
 vertex_submit(vbuff, pr_trianglelist, -1);
matrix_set(matrix_world, matrix_build_identity());
It's good to see it's 99,9% identical to the code sample from @Bart, so thanks to you as well! :)

Also I searched for a camera tutorial, and found one by @MaddeMichael that seems very useful (https://forum.yoyogames.com/index.php?threads/guide-meet-the-new-camera-system.12269/). It seems my current solution using a separate "ijgrid" object and transforming world coordinates (i, j) to pixels (x, y) back-and-forth myself is not really needed anymore! (So this will mean another speed boost.) At least, I hope mouse_x and mouse_y cooperate as well when using camera stuff. Anyhow, this seems a really useful subject to take my time to study one day. Thanks! :)

Edit: I like the "import form 1.4" idea. Thanks for that suggestion :)
 
Top