3D [SOLVED]Basic 3d camera is upside down in Studio 1

I am trying to use 3d in Studio 1, but am having difficulty getting the projection (camera) right.

All that is required is a top-down camera, that when it moves across horizontally across a room see's what you'd expect from a view. However I am finding it hard to do that.

Draw event: (and yes - I do know that this code block turns off 3d at the end. I have some 2d stuff drawing afterwards that I haven't included)

GML:
d3d_start();
draw_set_color(c_white);
d3d_set_projection_perspective(x, y, room_width, room_height, 0);
d3d_draw_block(20, 100, 20, 40, 140, 60, -1, 1, 1);
d3d_end()
According to the manual
Code:
d3d_set_projection_perspective(x, y, room_width, room_height, 0);
"The above code sets up a basic 3D perspective projection."

But when I use it the image is upside down. How can I set this up correctly?

EDIT:
Is it just a case of converting every 3d objects 'y' position into 'room_height - y'?

Or is there something simpler which will make it right?
 
Last edited:

kburkhart84

Firehammer Games
I don't know the code in gms1, but what you need is to rotate the camera itself instead of your objects most likely. I don't know what the old functions for that are anymore but you may not be able to use the simple d3d one you are using there.
 

FoxyOfJungle

Kazan Games
It is upside down because you used d3d_start()... But you are using a 3D camera in the wrong place, you should use the function in Draw Event and not in the Create Event, besides, you should not use d3d_end(), otherwise you are "turning off 3D mode".
I suggest you use d3d_set_projection_perspective() in the Draw Event.
Only call d3d_end() if you are going to draw something on the screen, but then immediately enable it again while using a 3D matrix world.
Also use d3d_draw_block() in the Draw Event.
 
Last edited:
It is upside down because you used d3d_start()... But you are using a 3D camera in the wrong place, you should use the function in Draw Event and not in the Create Event, besides, you should not use d3d_end(), otherwise you are "turning off 3D mode".
I suggest you use d3d_set_projection_perspective() in the Draw Event.
Only call d3d_end() if you are going to draw something on the screen, but then immediately enable it again while using a 3D matrix world.
Also use d3d_draw_block() in the Draw Event.
This is all in the draw event, and I am drawing in 2d after the 3d part of the code. Everything is there that is meant to be there, I just didn't state that it was in the draw event.

Given that I am doing exactly your suggestion, and it isn't working, there is something still missing.
 
I don't know the code in gms1, but what you need is to rotate the camera itself instead of your objects most likely. I don't know what the old functions for that are anymore but you may not be able to use the simple d3d one you are using there.
I don't want to change the angle here
GML:
d3d_set_projection_perspective(x, y, room_width, room_height, 0);
as that only rotates the view around.

I know that there are functions with all of the aspects available to you, but this basic command is the one where I could get it be the size I want, and understand how to use it.

Code:
d3d_set_projection_ext(xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup, angle, aspect, znear, zfar)
With that one I can't figure out how to replicate the same result as the simpler command, as the xto / yto / zto confuses me.
 
"from" is the camera's origin, "to" is where the camera "will point/look".
I meant I don't understand the maths behind it, why you need it, or how you apply that to a top-down camera.

To me: from = x / y, and to = x / y. Since I don't understand how those positions can be physically changed when looked at dead centre from above. Yet I've seen several top-down camera examples, and they all have vectors and maths I don't understand, or understand why they're even needed.

Like this example: (I haven't included all of it - just showing something that has been common in the examples I've found)
Code:
x = obj_player.x  + lengthdir_x(-ztobe/4,bearing)
y = obj_player.y  + lengthdir_y(-ztobe/4,bearing)

draw_set_color(c_white)
pitch = max(min(pitch,80),-80); //this limits camera pitch -is up, + is down

ss = sin(degtorad(bearing));cc = cos(degtorad(bearing));
vector_x=cc*cos(degtorad(-pitch));
vector_y=ss*-cos(degtorad(-pitch));

vector_z=(sin(degtorad(-pitch))) + (ztobe/2500)

d3d_set_projection_ext(x,y,z,x+vector_x,y+vector_y,z+vector_z,0,0,1,45,1.3333,2,10000)
Compare all that to the simplicity of:
Code:
d3d_set_projection_perspective(x, y, room_width, room_height, 0);
The position is right, the area it covers is right. But it's upside down.
 

FoxyOfJungle

Kazan Games
To deal with 3D is to deal with advanced mathematics. But I think what you want can be done simply like this:

GML:
zoom = 100;
d3d_set_projection_ext(cam_x, cam_y, cam_z-zoom, cam_x, cam_y, cam_z, 0, 0, 1, 45, 1.3333, 2, 10000);
cam_z is the height of the camera.

1.3333 = aspect:
width / height




If you want to rotate the camera in the future, just use lengthdir_x() and lengthdir_y().
 
Last edited:

HalRiyami

Member
Even in GMS2, the 3d projection is flipped for some reason. There are a few threads about it and I haven't seen YYG explain why that's the case.
You have two options: Render to a surface then flip that surface or flip the camera projection manually. The latter is done like so in GMS2:
GML:
var _camera    = view_camera[0];
var _lookMat = matrix_build_lookat(_x, _y, -_dist, _x, _y, 0, 0, 1, 0);
var _projMat = matrix_build_projection_perspective_fov(_fov, _aspect, 3, 30000);
_projMat[5] *= -1;               
camera_set_view_mat(_camera, _lookMat);
camera_set_proj_mat(_camera, _projMat);
camera_apply(_camera);
This is taken from another thread but I don't have the link to it but the 4th line is the key. You'll want to flip the 5th element of the projection matrix.
You'll have to figure out the equivalent in GMS1.
 

Tyg

Member
Its the lookat,
i have a nice little camera function for a universal camera that i wrote
that can use ZUP, mZUP, YUP, mYUP, XUP and mXUP...."m" being minus
Ill put it on another thread because i want to show how to make a day/night skybox also and it involve shaders and stuff
 
Last edited:
I appreciate the response, and my apologies for replying a bit late. Having done a big dive into this, I'm still not able to set up 3d.

I'm not sure if it's the "camera", or if I'm not exporting my blender objects correctly, but nothing is working as I'd hoped for.

I'll mark this as solved, just so it isn't added to any further.

EDIT: I realize it isn't solved, but I'm a bit sick of going in circles, and as I don't log in often I don't want to be rude in not replying :)
 
Even in GMS2, the 3d projection is flipped for some reason. There are a few threads about it and I haven't seen YYG explain why that's the case.
You have two options: Render to a surface then flip that surface or flip the camera projection manually. The latter is done like so in GMS2:
GML:
var _camera    = view_camera[0];
var _lookMat = matrix_build_lookat(_x, _y, -_dist, _x, _y, 0, 0, 1, 0);
var _projMat = matrix_build_projection_perspective_fov(_fov, _aspect, 3, 30000);
_projMat[5] *= -1;              
camera_set_view_mat(_camera, _lookMat);
camera_set_proj_mat(_camera, _projMat);
camera_apply(_camera);
This is taken from another thread but I don't have the link to it but the 4th line is the key. You'll want to flip the 5th element of the projection matrix.
You'll have to figure out the equivalent in GMS1.
GML:
d3d_set_projection_perspective(view_xview, view_yview, room_width, room_height, 0)

var new_proj = matrix_get(matrix_projection);
new_proj[5] *= -1;
matrix_set(matrix_projection, new_proj);
Seems to have fixed the issue. Thanks for the help :)
 
In your lookout change the 1 to -1 to flip
To be honest: I'm unsure what this is referring to, when you talk about the "lookout".

I'm assuming this is within the extended projection version, with from and to etc.....?? To, or From, is the lookout.

I'm happy with the perspective as is :) I only really need a fixed side view, at least for the time being, and want to now get on with making sure my models have the correct UP / FORWARD definitions. Then figure out implementing lengthdir_x / y / z so I can make a kind of bone system.

Given how long it's taken just to get 3d ready, I'm going to stick with the basic camera for now, as I'd really like to get something more complete up and running.

Thanks for your help with this, anyway. It's appreciated!
 

HalRiyami

Member
I believe they mean "lookUp". The UP direction of the camera which should be (0, -1, 0) instead of (0, 1, 0) because in GM the y axis points down. This would go in the lookAt matrix.
 
I believe they mean "lookUp". The UP direction of the camera which should be (0, -1, 0) instead of (0, 1, 0) because in GM the y axis points down. This would go in the lookAt matrix.
Ah, thanks for that. Where I have now inverted the projection matrix, is presumably what they meant.
 
Top