3D in GameMaker Studio 2: Beginners Guide.

Roa

Member
(Reserved)
NOTE: I will be adding concepts and how-to methods for 3d in the new GameMaker Studio 2 environment here shortly as soon as I full-proof concepts and organize it into digestible bits. If you find something to add, PM me.

Textures
Textures in GMS:2 may no longer be loaded from backgrounds as they are a removed functionality. In order to add textures to a 3d mesh, you most import the texture in a varaible using the old script sprite_get_texture(sprite_index,image_index).

Important things to note:

  • The 3d tickbox for preparing images to be textures has been removed. You must now click the "seperate texture page" box if you intended to use repeating textures.
  • texture_repeat() has been replaced with the new function gpu_set_texrepeat()
  • texture_set_interpolation() has been replaced with gpu_set_texfilter()

Projection And Cameras
The view and projection system has been replaces with the new camera and view matrix functions. The way you set this up is fundamentally different compared to its d3d counter parts.

step 1: You must declare a new camera that will be applied to the view. Creating a camera is done with a single new function.


Code:
//create event

view_camera[0] = camera_create();
view_camera stores an array 0-7 of possible camera IDs, while camera_create returns a view port id for that camera.

Legacy Conversion: d3d_set_projection_ext(x1,y1,z1,x2,y2,z2,xup,yup,zup,fov, aspect ratio, near clip, far clip, camera id)
dropping this script into your project will give you the convenience of the old method. Only one argument was added and that's for the camera ID that this projection needs applied to.
https://www.dropbox.com/sh/iyz4kbl0pfup2mu/AACVvAx_LQZpyE_aVZpfqaZna?dl=0

step 2: Now that you have a camera defined, you need to declare some matrices to apply to the 3d perspective.

Vertex Buffers and Geometry.
.



Game Ready Assets
.
 
Last edited:

Roa

Member
Just wanted to let everyone know, I am working on a library of quick functions, mainly replacing the d3d functions with extended options like alternate floor slope and full UVcords. Im also converting my vertex buffer_from_model scripts to save to bins, then reload. Its not very usefull if people cant even include files so I have to make a way to load models into bins which you can just place in code, then convert those to vertex buffers. Feeling a little lazy right now. Its coming though. Not hard work, just a lot of it.
 
P

Pixelrobin

Guest
I am confused as to how to actually draw models or geometry. I saw @xygthop3 managed to draw a floor... how do you do that without the d3d functions?
 

xygthop3

Member
I am confused as to how to actually draw models or geometry. I saw @xygthop3 managed to draw a floor... how do you do that without the d3d functions?
Vertex Buffers are the replacement to all primitive/model functions.

This is a script I use in GMS1 to replace the d3d_model_load() and to use vertex buffers instead, it should just work the same in GMS2 however it can't be tested yet due to the lack of loading external resources in the trial.

Code:
#define vertex_d3d_model
///vertex_d3d_model(vertex_index,file_name);
/*
NOTE
 This will only load models that use primitive type 4 (pr_trianglelist)
 and use all x,y,z,normal_x,normal_y,normal_z,texture_u,texture_v,color,alpha
*/

ind = argument0; //Get vertex buffer input from user
file_name=file_text_open_read(argument1); //Get GM model file name from user

//Start reading from file

//Read first line of header, version number
version = file_text_read_real(file_name);
if file_text_eoln(file_name){file_text_readln(file_name);}

//Read second line of header, number of lines in file
num_lines = file_text_read_real(file_name);
if file_text_eoln(file_name){file_text_readln(file_name);}

//while (!file_text_eof(file_name)){

for (i=0; i<num_lines; i++)
    {
        text_real = file_text_read_real(file_name);

       
         if (text_real == 0)
         {
            //Do nothing, this is d3d_model_primitive_begin()
         }
       
         if (text_real == 1)
         {
            //Do nothing, this is d3d_model_primitive_end()
         }
       
         //x, y, z,  d3d_model_vertex()
         if (text_real == 2)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = 0;
            _ny  = 0;
            _nz  = 0;
            _tu  = 0;
            _tv  = 0;
            _col = c_white;
            _alp = 1;

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
         //x, y, z, color, alpha = d3d_model_vertex_color()
         if (text_real == 3)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = 0;
            _ny  = 0;
            _nz  = 0;
            _tu  = 0;
            _tv  = 0;
            _col = file_text_read_real(file_name);
            _alp = file_text_read_real(file_name);

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }

         //x, y, z, U, V = d3d_model_vertex_texture()
         if (text_real == 4)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = 0;
            _ny  = 0;
            _nz  = 0;
            _tu  = file_text_read_real(file_name);
            _tv  = file_text_read_real(file_name);
            _col = c_white;
            _alp = 1;

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }

         //x, y, z, U, V, color, alpha = d3d_model_vertex_texture_color()
         if (text_real == 5)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = 0;
            _ny  = 0;
            _nz  = 0;
            _tu  = file_text_read_real(file_name);
            _tv  = file_text_read_real(file_name);
            _col = file_text_read_real(file_name);
            _alp = 1;

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
         //x, y, z, nx, ny, nz = d3d_model_vertex_normal()
         if (text_real == 6)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = file_text_read_real(file_name);
            _ny  = file_text_read_real(file_name);
            _nz  = file_text_read_real(file_name);
            _tu  = 0;
            _tv  = 0;
            _col = 0;
            _alp = 1;

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
         //x, y, z, nx, ny, nz, color, alpha = d3d_model_vertex_normal_color()
         if (text_real == 7)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = file_text_read_real(file_name);
            _ny  = file_text_read_real(file_name);
            _nz  = file_text_read_real(file_name);
            _tu  = 0;
            _tv  = 0;
            _col = file_text_read_real(file_name);
            _alp = file_text_read_real(file_name);

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
         //x, y, z, nx, ny, nz, U, V = d3d_model_vertex_normal_texture()
         if (text_real == 8)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = file_text_read_real(file_name);
            _ny  = file_text_read_real(file_name);
            _nz  = file_text_read_real(file_name);
            _tu  = file_text_read_real(file_name);
            _tv  = file_text_read_real(file_name);
            _col = c_white;
            _alp = 1;

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
         //x, y, z, norm x, norm y, U, V, color, alpha
         if (text_real == 9)
         {
            _x   = file_text_read_real(file_name);
            _y   = file_text_read_real(file_name);
            _z   = file_text_read_real(file_name);
            _nx  = file_text_read_real(file_name);
            _ny  = file_text_read_real(file_name);
            _nz  = file_text_read_real(file_name);
            _tu  = file_text_read_real(file_name);
            _tv  = file_text_read_real(file_name);
            _col = file_text_read_real(file_name);
            _alp = file_text_read_real(file_name);

            vertex_position_3d(ind, _x, _y, _z);
            vertex_texcoord(ind, _tu, _tv);
            vertex_normal(ind, _nx, _ny, _nz);          
            vertex_colour(ind, _col, _alp);
         }
       
       
 
    file_text_readln(file_name);
}
file_text_close(file_name);
 
H

Huder

Guest
This is my first try:

I have 3 objects: "oInit" this is where i load textures, create blank camera and globalvars:\

Code:
/// Init

globalvar gCamera;
gCamera = camera_create();

gpu_set_texrepeat(true);
gpu_set_texfilter(false);
gpu_set_cullmode(cull_noculling);


// models

// textures
globalvar gTex;
gTex[0] = sprite_get_texture(texCarpet, 0);

room_goto_next();

"oCamera" where all projection things goes:
Code:
cam = gCamera;
view_camera[0] = cam;

camWidth = 1024;
camHeight = 720;

z = 0;
yaw = 0;
pitch = 0;
Code:
/// camera
xTo = lengthdir_x(1, yaw);
yTo = lengthdir_y(1, yaw);
zTo = 0;

yaw++;
matrixView = matrix_build_lookat(x, y, z, xTo, yTo, zTo, 0, 0, 1);
matrixProj = matrix_build_projection_perspective(camWidth, camHeight, 5, 10000);

camera_set_view_mat(cam, matrixView);
camera_set_proj_mat(cam, matrixProj);

And "oFloor" To draw simple flat texture
Code:
/// draw floor
draw_sprite(texCarpet, 0, 100, 0);

Layers was organised like this:



It looks like FOV is very very huge? Any ideas what i could do wrong?
 

xygthop3

Member
Use matrix_build_projection_perspective_fov() instead
(Set a new variable for the camWidth/camHeight in the Create event called aspectRatio so you're not dividing them every step for no benefit)
eg: matrix_build_projection_perspective_fov(60, aspectRatio, 5, 10000);

Just as an FYI you don't need to rebuild this matrix every step (in the Draw event) you can move it in to the Create event and only call it if you actually need to change it.

I suggest you don't use sprites to draw in a 3D space, you should build a billboard with a vertex buffer and use matrix functions for translation/transformations.
 
H

Huder

Guest
Ok that was helpful. But when i move camera position i don't need rebuild matrix?
Edit: No its not rotating then. Ok i see that i need to rebuild only matrixView :)
 
Last edited by a moderator:

KurtBlissZ

Member
@Huder :p
But when i move camera position i don't need rebuild matrix?
Just as an FYI you don't need to rebuild this matrix every step (in the Draw event) you can move it in to the Create event and only call it if you actually need to change it.
Thanks for the script d3d_projection_ext script Roa. Helped me to get a first person camera to work finally.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Cool work so far! I'll keep an eye on this thread to follow the investigation.
 
L

Lemth

Guest
Subscribing to this topic. Interested to see if anyone creates any video-tutorials on this subject.
 

Roa

Member
Personally, I dont have GMS2, so it wont be going anywhere by my hands anytime soon. Others are probably willing to contribute though.
 
M

Misu

Guest
Im willing to contribute knowing that have been using with GM's 3D for more than 6 years. I manage to prepare decent scripts but I still cant get my head around setting a position or assigning a matrix to a vertex buffer. We will see how this go.
 

Yal

šŸ§ *penguin noises*
GMC Elder
For the basic cases, are there any reason not to just use the compability scripts?
 

Yal

šŸ§ *penguin noises*
GMC Elder
...it's that simple now? Holy o__O

I can't say the stuff I've read in the manual so far has given me that impression since there's a huge section about matrix transforms and stuff, but this looks a lot less hassleful than the old approach.
 

slojanko

Member
GMS2 creates compatibility scripts for obsolete d3d functions, getting a block without those is a bit harder.

Here's a script I wrote for adding a block with 7 parameters:
- vertex buffer the block will be added to (buffer format needs position, colour & texture coordinates)
- x1 and y1 have to be smaller than x2, y2.
- z2 has to be smaller than z1 because z values decrease when you move the camera UP.
- colour

It works with counterclockwise orientation culling.

Code:
var buffer_model = argument[0];
var x1 = argument[1];
var y1 = argument[2];
var z1 = argument[3];

var x2 = argument[4];
var y2 = argument[5];
var z2 = argument[6];

var c = argument[7];


// BOTTOM
//The first triangle
vertex_position_3d(buffer_model, x2, y1, z1);
//vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x1, y1, z1);
//vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y2, z1);
//vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);

//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x1, y1, z1);
//vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y2, z1);
//vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x2, y2, z1);
////vertex_normal(buffer_model, 0, 0, 1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


// TOP
//The first triangle
vertex_position_3d(buffer_model, x1, y1, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x2, y1, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y2, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);

//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x2, y1, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y2, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x1, y2, z2);
//vertex_normal(buffer_model, 0, 0, -1);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


// LEFT
//The first triangle
vertex_position_3d(buffer_model, x1, y1, z2);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x1, y2, z2);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y1, z1);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);

//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x1, y2, z2);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y2, z1);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x1, y1, z1);
//vertex_normal(buffer_model, -1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


//RIGHT
//The first triangle
vertex_position_3d(buffer_model, x2, y2, z2);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x2, y1, z2);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y2, z1);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);

//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x2, y1, z2);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y1, z1);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x2, y2, z1);
//vertex_normal(buffer_model, 1, 0, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


// BACK
//The first triangle
vertex_position_3d(buffer_model, x2, y1, z2);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x1, y1, z2);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y1, z1);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x1, y1, z2);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y1, z1);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x2, y1, z1);
//vertex_normal(buffer_model, 0, -1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


//FRONT
//The first triangle
vertex_position_3d(buffer_model, x1, y2, z2);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 0);

vertex_position_3d(buffer_model, x2, y2, z2);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x1, y2, z1);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);


//The second triangle. The winding order has been maintained so drawing is consistent if culling is enabled.
vertex_position_3d(buffer_model, x2, y2, z2);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 0);

vertex_position_3d(buffer_model, x2, y2, z1);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 1, 1);

vertex_position_3d(buffer_model, x1, y2, z1);
//vertex_normal(buffer_model, 0, 1, 0);
vertex_colour(buffer_model, c, 1.0);
vertex_texcoord(buffer_model, 0, 1);
 
Last edited:
M

Misu

Guest
I made the scripts entirely myself. I am still new to GMS2 and did not knew about the compatibility scripts nor how to do that.
Anyway I prefer to make them on my own.
 

Roa

Member
Yeah, sorry to everyone that I abandoned this. I was telling Misu this, that if anyone has anything to contribute, then do so. I did not have time with school going to actively work with GMS2's 3d very much and by the time I had the window, the trials were over. I might buy it one day if it ever proves worth it, but until then, I'm not going to be making much progress on this thread.
 

slojanko

Member
Can someone help me achieve downscaling then stretching? I would like each pixel to be 8 times bigger but the settings I tried changing within cameras and views were not successful.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Can someone help me achieve downscaling then stretching? I would like each pixel to be 8 times bigger but the settings I tried changing within cameras and views were not successful.
Have you tried making the viewport 8 times bigger than the actual view region (with an orthographic view camera)?
 
L

Lemth

Guest
Yeah, sorry to everyone that I abandoned this. I was telling Misu this, that if anyone has anything to contribute, then do so. I did not have time with school going to actively work with GMS2's 3d very much and by the time I had the window, the trials were over. I might buy it one day if it ever proves worth it, but until then, I'm not going to be making much progress on this thread.
I made the scripts entirely myself. I am still new to GMS2 and did not knew about the compatibility scripts nor how to do that.
Anyway I prefer to make them on my own.
Hey Misu, could you perhaps expand on how you created to cube? (exact script and why?)
 

Yal

šŸ§ *penguin noises*
GMC Elder
Cameras basically feels like they moved projections up one level on the abstraction scale, it's now a first-order citizen instead of a second-order... if that makes sense. Feels a lot less hard to wrap your head around once you know that.

 
I

icuurd12b42

Guest
Cameras basically feels like they moved projections up one level on the abstraction scale, it's now a first-order citizen instead of a second-order... if that makes sense. Feels a lot less hard to wrap your head around once you know that.

Except they messed up the up's y vector...
 
L

Lemth

Guest
Cameras basically feels like they moved projections up one level on the abstraction scale, it's now a first-order citizen instead of a second-order... if that makes sense. Feels a lot less hard to wrap your head around once you know that.

Except they messed up the up's y vector...
I've watched the video and tried my hand at moving the camera in a spherical way around point (0,0,0), but it's not working so far.
I've mentioned my steps in THIS TOPIC

Here's a quote of the content:
Thank you, that was it! I actually need a "cull_noculling" later on and will only draw 54 triangles at maximum so I should be fine.

One more question;

I tried to modify your "third person camera" by using arrow keys to make it move around (0,0,0) in a spherical way like, but it only makes very weird movements. Any ideas?

I'm trying to implement THIS
By using the following formulas:


This is what it looks like:
@icuurd12b42 : Does the Y vector you mentioned have anything to do with the camera not moving in a sphere perhaps?
 

chance

predictably random
Forum Staff
Moderator
Except they messed up the up's y vector...
I've adopted a new coordinate system for all my 3D apps in Studio 2. I set the up vector as <0,0,1> in the view matrix. Counter-intuitively, the z axis is now positive into the screen. So I place a camera (for example) at:

x = room_width/2;
y = room_height;
z = -400;

And the perspective view is looking slant-down (in the -y direction) on the usual 2D room surface, with the (x,y) origin in the upper left as usual. So the advantage is that I can draw 2D images on the "floor" without having to flip them in y, as with previous GM versions.

Of course, you can define any coordinate system you want. But I like a right-handed version with z into the screen.
 
I

icuurd12b42

Guest
>Does the Y vector you mentioned have anything to do with the camera not moving in a sphere perhaps?
Don't know. it has to do that y of 1 making the camera upright (when facing down like in the video) on a system where positive y is actually down... so the y vector is reversed what the world system is, if you set up vector's y to 1 the camera should be upside down... not sure how they could mess that up. they are obviously aware of this in the audio listener documentation image used to describe the up vector...




@chance
>the z axis is now positive into the screen
It has always been so since gm7 (depth is z that is why lower objects draw first) but less obvious since gms1, where it still is, but the drawing seems to draw lesser depth first while depth is still z)


I would have hoped all these oopsies would have been taken care of by now

Oh and in gms:1 you need the set the camera aspect ratio to a negative angle if you want the x axis to remain intact (-x on the left, +x on the right). which then breaks every model since they are now turned inside out
 
Last edited by a moderator:

chance

predictably random
Forum Staff
Moderator
@chance
>the z axis is now positive into the screen
It has always been so since gm7 (depth is z that is why lower objects draw first) but less obvious since gms1, where it still is, but the drawing seems to draw lesser depth first while depth is still z)
I understand. I didn't mean to imply the +/- convention for z had changed. Just that with the <up> vector I mentioned, and a camera looking down from -z above the floor, the y-axis isn't flipped as (I believe...) it was in previous versions. So 3D is a more natural extension of 2D.

I haven't noticed the issue you mentioned about drawing order versus depth in z. But I generally put most of my 3D objects in the same DRAW and submit them in order of decreasing z. So I'll have a look at the issue you mentioned. Sounds like a bug.
 
I

icuurd12b42

Guest
Sounds like a bug.
Not sure it is. They may have done this on purpose to make the rendering faster, that is if hidden was on it would skip pixels drawn behind stuff already drawn, though I fail to see exactly. the whole system is confusing the heck out of me because you can still see through stuff...

this is my setup for gms1. pretty much like you discovered

d3d_start();
d3d_set_culling(1);
draw_set_alpha_test(1);
draw_set_alpha_test_ref_value(128);
d3d_set_hidden(true);
aspect = room_width/room_height
d3d_set_projection_ext(room_width/2,room_height/2,-800,room_width/2,room_height/2,0,0,-1,0,59,-aspect,1,32000);

the difference between gm8 and studio:
draw_set_alpha_test(1);
draw_set_alpha_test_ref_value(128);
and -aspect

and the drawing of shapes in studio require
d3d_transform_set_scaling(1,1,-1); //the first transform in the set

and having to flip the model scaling with gmmodelfix on z to turn the model inside out so that it turns it back outsize in with the set scaling line above... tedious.

But all this only if you want to mix 2d and 3d. I mean most people deal with axis reversals and have their + z being up for some reason and code their game around that in most tutorials on 3d
 
L

Lemth

Guest
@icuurd12b42 @chance : you guys seem to have some knowledge of 3D camera's.

I'm still trying to implement the camera I mentioned earlier, I've found a better example of the exact effect that I want:


Is this doable while rotating the camera or is it better to just move the object? (Also, any GMS examples on this?) Cheers!
 
I

icuurd12b42

Guest
I'm not sure how to do this with matrices unfortunately. I can't do 4d thinking

traditionally, assuming you would draw your planet at 0,0,0, to simplify things
//looking at 0,0,0
topos[0] = 0;
topos[1] = 0;
topos[2] = 0;

//Rotate on z and on x
rotz += keyboard_check(vk_right)-keyboard_check(vk_left); //set rotz to 0 on create
rotx += keyboard_check(vk_down)-keyboard_check(vk_upt); //set rotx to 0 on create

let's use the d3d transforms with d3d_transform_vertex to make things easier
d3d_transform_set_identity(); //start using the transforms to rotate our data
d3d_transform_add_rotation_z(rotz); //rotate on z
d3d_transform_add_rotation_x(rotx); //rotate on x
frompos = d3d_transform_vertex(0,1000,0); // from the initial cam position 0,1000,0 on x,y,z for initial from position, eg at a radius of 1000, rotate vertex
upvector = d3d_transform_vertex(0,0,-1); // from the initial up of the top of the head of the cam facing to the sky on z (-1), rotate vector
d3d_transform_set_identity(); //done using the transforms as helper
//apply the position, lookat and up vector
d3d_set_projection(frompos[0],frompos[1],frompos[2],topos[0],topos[1],topos[2],upvector[0],upvector[1],upvector[2]);

the image below shows the initial position of the camera and the final position after having applied the transforms on the position vertex and the up vector
upload_2017-5-10_3-31-29.png
 
L

Lemth

Guest
I'm not sure how to do this with matrices unfortunately. I can't do 4d thinking

traditionally, assuming you would draw your planet at 0,0,0, to simplify things
//looking at 0,0,0
topos[0] = 0;
topos[1] = 0;
topos[2] = 0;

//Rotate on z and on x
rotz += keyboard_check(vk_right)-keyboard_check(vk_left); //set rotz to 0 on create
rotx += keyboard_check(vk_down)-keyboard_check(vk_upt); //set rotx to 0 on create

let's use the d3d transforms with d3d_transform_vertex to make things easier
d3d_transform_set_identity(); //start using the transforms to rotate our data
d3d_transform_add_rotation_z(rotz); //rotate on z
d3d_transform_add_rotation_x(rotx); //rotate on x
frompos = d3d_transform_vertex(0,1000,0); // from the initial cam position 0,1000,0 on x,y,z for initial from position, eg at a radius of 1000, rotate vertex
upvector = d3d_transform_vertex(0,0,-1); // from the initial up of the top of the head of the cam facing to the sky on z (-1), rotate vector
d3d_transform_set_identity(); //done using the transforms as helper
//apply the position, lookat and up vector
d3d_set_projection(frompos[0],frompos[1],frompos[2],topos[0],topos[1],topos[2],upvector[0],upvector[1],upvector[2]);

the image below shows the initial position of the camera and the final position after having applied the transforms on the position vertex and the up vector
View attachment 9527
Tried this out on GMLIVE: https://tinyurl.com/lxehf8k

Didn't get it to work though.. what am I missing?

(updated link to add gui)


GOT IT WORKING: https://tinyurl.com/kh4rgya

But it's not what I was looking for. The rotations should be done using the 'CURRENT" x and y axis instead of the "original" x and y axis. Such that pressing up will always move rotate the block upwards despite it's orientation.

(Left and right work as intended, but up and down makes the cube spin on it's OWN axis and not the 'view's' axis.)
 
Last edited by a moderator:
I

icuurd12b42

Guest
Tried this out on GMLIVE: https://tinyurl.com/lxehf8k

Didn't get it to work though.. what am I missing?

(updated link to add gui)


GOT IT WORKING: https://tinyurl.com/kh4rgya

But it's not what I was looking for. The rotations should be done using the 'CURRENT" x and y axis instead of the "original" x and y axis. Such that pressing up will always move rotate the block upwards despite it's orientation.
You want to use quaternions for rotation then. can, worms, opened, mess
 
L

Lemth

Guest
@icuurd12b42 @chance : you guys seem to have some knowledge of 3D camera's.

I'm still trying to implement the camera I mentioned earlier, I've found a better example of the exact effect that I want:


Is this doable while rotating the camera or is it better to just move the object? (Also, any GMS examples on this?) Cheers!
In case anyone would require this in the future; got it the way I wanted it (in GMS 1.4, but should be easy translation to GMS 2.x)
Check it out here:

http://tinyurl.com/l2cfgzb (set to GL mode and press RUN)
 
Last edited by a moderator:
P

Pinqu

Guest
Hi! Could someone point me in the right direction to add some 2d hud elements?

I got a working hud in gms1.4 and got the code below through the compatibility scripts in gms2.

I have this code in the draw_event of a hud object:
var matrix_look = matrix_build_lookat(160, 90, -16000, 160, 90, 0, 0, 1, 0);
var matrix_ortho = matrix_build_projection_ortho(320, 180, 1, 32000);

camera_set_view_mat(camera_get_active(), matrix_look);
camera_set_proj_mat(camera_get_active(), matrix_ortho);
camera_apply(camera_get_active());

draw_set_color(c_black);
draw_text(16, 16, "TESTING!");
draw_sprite(spr_test, -1, 64, 64);

//reset to default projection
matrix = matrix_build_projection_perspective_fov(60, view_get_wport(0)/view_get_hport(0), 1, 32000);
camera_set_proj_mat(camera_get_active(), matrix);

Now this does display the text and the sprite, but it's all blue like the background color set in the backgrounds layer..
 

Genetix

Member
Just as a side thought: Anyone else think that GMS3 will have much fuller 3d support and possibly be title Game Maker Studio 3D? (Just me?)
 

Genetix

Member
I'm not for it much either - and they are becoming known as one of the places to go for devoted high quality 2d game dev, despite that - the title would still be clever marketing. (I don't think it will happen either.)
 
Top