Screen rotation (No Android)

josyanf1

Member
Hello everyone!
I'm doing a vertical shump and I would like to know how to rotate the screen vertically (TATE Mode) so that it is like the Ikaruga of Nintendo Switch.
I tried with image_angle, but the GUI does not rotate and also the black bands on the sides cover what is missing from the screen. Thanks in advance!
 

Attachments

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Do you mean view_angle? If your GUI is drawn in Draw GUI event, it should behave fine. You could also draw application_surface yourself while rotating it via draw_surface_ext
 

josyanf1

Member
Do you mean view_angle? If your GUI is drawn in Draw GUI event, it should behave fine. You could also draw application_surface yourself while rotating it via draw_surface_ext
Yes, view_angle sry. But I still have the same problem. When I go from horizontal to vertical, only the sprites rotate, the screen and the GUI do not change.
 

Attachments

icuurd12b42

TMC Founder
GMC Elder
you can try to apply the view transform matrix to the gui draw.

I'm sure a few lines of code would do... build projection matrix from view matrix, apply projection matrix to the drawing, draw gui...
 

josyanf1

Member
you can try to apply the view transform matrix to the gui draw.

I'm sure a few lines of code would do... build projection matrix from view matrix, apply projection matrix to the drawing, draw gui...
I do not understand very well what you mean.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
You should be able to rotate the GUI layer by doing
Code:
d3d_set_projection_ortho(0, 0, <gui width>, <gui height>, <angle>)
prior to drawing. In GMS2, the function is replaced by a script of kind
Code:
/// @description d3d - set orthographic
/// @param x       x of tl corner
/// @param y       y of tl corner
/// @param w       w of view
/// @param h       h of view
/// @param angle   rotation angle of the projection

var xx = argument0;
var yy = argument1;
var ww = argument2;
var hh = argument3;
var angle = argument4;

var mV = matrix_build_lookat( xx+ww/2, yy+hh/2, -16000,
                             xx+ww/2, yy+hh/2, 0,
                            dsin(-angle), dcos(-angle), 0 );
var mP = matrix_build_projection_ortho( ww, hh, 1, 32000 );

//camera_set_view_mat( global.__d3dCamera, mV );
//camera_set_proj_mat( global.__d3dCamera, mP );
//camera_apply( global.__d3dCamera );
camera_set_view_mat( camera_get_active(), mV );
camera_set_proj_mat( camera_get_active(), mP );
camera_apply( camera_get_active() );
 

icuurd12b42

TMC Founder
GMC Elder
^there, I was too lazy to code that :)

perfect example of why
d3d_set_projection_ortho
should never have been taken out

all it needs is your draw gui... the drawing will be rotated on the draw without needing to change anything (hopefully)
 

josyanf1

Member
You should be able to rotate the GUI layer by doing
Code:
d3d_set_projection_ortho(0, 0, <gui width>, <gui height>, <angle>)
prior to drawing. In GMS2, the function is replaced by a script of kind
Code:
/// @description d3d - set orthographic
/// @param x       x of tl corner
/// @param y       y of tl corner
/// @param w       w of view
/// @param h       h of view
/// @param angle   rotation angle of the projection

var xx = argument0;
var yy = argument1;
var ww = argument2;
var hh = argument3;
var angle = argument4;

var mV = matrix_build_lookat( xx+ww/2, yy+hh/2, -16000,
                             xx+ww/2, yy+hh/2, 0,
                            dsin(-angle), dcos(-angle), 0 );
var mP = matrix_build_projection_ortho( ww, hh, 1, 32000 );

//camera_set_view_mat( global.__d3dCamera, mV );
//camera_set_proj_mat( global.__d3dCamera, mP );
//camera_apply( global.__d3dCamera );
camera_set_view_mat( camera_get_active(), mV );
camera_set_proj_mat( camera_get_active(), mP );
camera_apply( camera_get_active() );
It seems that that is the solution. The problem is that I think my options are interfering. (Excuse me, I'm new to the subject of the surfaces :p)

This way I have my control object configured:

Step Event:
Code:
///Shader
if shader_option = true
{
application_surface_draw_enable(false)

shader_to_use = sh_CRT_Windows

crt_surface_scale = 1;

crt_surface_width  = view_wview[0] * crt_surface_scale;
crt_surface_height = view_hview[0] * crt_surface_scale;

uni_crt_sizes = shader_get_uniform(shader_to_use, "u_crt_sizes");
distort = shader_get_uniform(shader_to_use, "distort");
distortion = shader_get_uniform(shader_to_use, "distortion");
border = shader_get_uniform(shader_to_use, "border");

var_distort = true;
var_distortion_ammount = 0.12;
var_border = true;

surface_width  = view_wview[0];
surface_height = view_hview[0];

surface_resize(application_surface, surface_width, surface_height);
}
else
{
application_surface_draw_enable(true)
surface_resize(application_surface, 704, 896)
}
Draw GUI Begin:
Code:
display_set_gui_size(176,224)

//Shader
if shader_option = true
{surface_set_target(application_surface)}
Draw GUI End:
Code:
///Shader
if shader_option = true
{
surface_reset_target();
shader_set(shader_to_use);
  shader_set_uniform_f(uni_crt_sizes, surface_width, surface_height,crt_surface_width, crt_surface_height);
  shader_set_uniform_f(distort, var_distort);
  shader_set_uniform_f(distortion, var_distortion_ammount);
  shader_set_uniform_f(border, var_border);
  draw_surface_part_ext(application_surface, 0, 0, view_wview[0], view_hview[0], 0, 0, crt_surface_scale, crt_surface_scale, c_white, 1);
shader_reset()
}
Sorry for being so heavy and thanks for the patience ":p
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
It seems that that is the solution. The problem is that I think my options are interfering. (Excuse me, I'm new to the subject of the surfaces :p)

This way I have my control object configured:

Step Event:
Code:
///Shader
if shader_option = true
{
application_surface_draw_enable(false)

shader_to_use = sh_CRT_Windows

crt_surface_scale = 1;

crt_surface_width  = view_wview[0] * crt_surface_scale;
crt_surface_height = view_hview[0] * crt_surface_scale;

uni_crt_sizes = shader_get_uniform(shader_to_use, "u_crt_sizes");
distort = shader_get_uniform(shader_to_use, "distort");
distortion = shader_get_uniform(shader_to_use, "distortion");
border = shader_get_uniform(shader_to_use, "border");

var_distort = true;
var_distortion_ammount = 0.12;
var_border = true;

surface_width  = view_wview[0];
surface_height = view_hview[0];

surface_resize(application_surface, surface_width, surface_height);
}
else
{
application_surface_draw_enable(true)
surface_resize(application_surface, 704, 896)
}
Draw GUI Begin:
Code:
display_set_gui_size(176,224)

//Shader
if shader_option = true
{surface_set_target(application_surface)}
Draw GUI End:
Code:
///Shader
if shader_option = true
{
surface_reset_target();
shader_set(shader_to_use);
  shader_set_uniform_f(uni_crt_sizes, surface_width, surface_height,crt_surface_width, crt_surface_height);
  shader_set_uniform_f(distort, var_distort);
  shader_set_uniform_f(distortion, var_distortion_ammount);
  shader_set_uniform_f(border, var_border);
  draw_surface_part_ext(application_surface, 0, 0, view_wview[0], view_hview[0], 0, 0, crt_surface_scale, crt_surface_scale, c_white, 1);
shader_reset()
}
Sorry for being so heavy and thanks for the patience ":p
With shader_option on, you'd be calling the function after surface_set_target and before drawing anything, and that should be fine.
 

icuurd12b42

TMC Founder
GMC Elder
quick note on you resizing the application surface each step

else
{
application_surface_draw_enable(true)
surface_resize(application_surface, 704, 896)
}

this is very costly... even sizing to the same size. check if the surface is not the right size first.
 

josyanf1

Member
quick note on you resizing the application surface each step

else
{
application_surface_draw_enable(true)
surface_resize(application_surface, 704, 896)
}

this is very costly... even sizing to the same size. check if the surface is not the right size first.
I resize the surface because the shader leaves it very small. I would like the shader to use the resolution I have in port on screen (x3 of the base resolution) to be able to rotate sprite without going bad etc
 

josyanf1

Member
With shader_option on, you'd be calling the function after surface_set_target and before drawing anything, and that should be fine.
Now rotate the GUI without problems, what happens now is that for some reason I do not draw outside the margin of the screen. I have to give more resolution to the sides with some function?

*If the 90º drawing is not visible because it is off the screen. I've drawn it to 200º so you can see what I mean.
 

Attachments

icuurd12b42

TMC Founder
GMC Elder
I resize the surface because the shader leaves it very small. I would like the shader to use the resolution I have in port on screen (x3 of the base resolution) to be able to rotate sprite without going bad etc
yeah but you are resizing every frame even if it's the right size... don't

if(surface_get_width (application_surface) != 704 || surface_get_height (application_surface) != 896)
{
surface_resize(application_surface, 704, 896)
}
 

josyanf1

Member
yeah but you are resizing every frame even if it's the right size... don't

if(surface_get_width (application_surface) != 704 || surface_get_height (application_surface) != 896)
{
surface_resize(application_surface, 704, 896)
}
Damn is true. Anyway, when I activate the shader it keeps changing the resolution :/
 

josyanf1

Member
With shader_option on, you'd be calling the function after surface_set_target and before drawing anything, and that should be fine.
yeah but you are resizing every frame even if it's the right size... don't

if(surface_get_width (application_surface) != 704 || surface_get_height (application_surface) != 896)
{
surface_resize(application_surface, 704, 896)
}
Hello! Sorry for the delay in responding. I have been doing tests and all the functions and the optimization that you told me work.
The only thing I need is to expand the margins of the screen and stretch it to the window for the fullscreen option. Any idea / form?
Thanks for all your help :)
 

Attachments

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Any idea / form?
If you can assemble a tiny project with just your screen setup, I could take a look at what else could be wrong. But I think you'll need to resize your application_surface to be not just that fixed size, but rather calculate the sizing while keeping aspect ratio, like so (live demo):
Code:
surf = -1;
// ...
var gameWidth = 180;
var gameHeight = 320;
if (!surface_exists(surf)) {
    surf = surface_create(gameWidth, gameHeight);
    surface_set_target(surf);
    draw_clear(c_blue);
    surface_reset_target();
}
var screenWidth = mouse_x;
var screenHeight = mouse_y;
var scale = min(screenWidth / gameWidth, screenHeight / gameHeight);
var outWidth = gameWidth * scale;
var outHeight = gameHeight * scale;
var outX = (screenWidth - outWidth) div 2;
var outY = (screenHeight - outHeight) div 2;
draw_surface_stretched(surf, outX, outY, outWidth, outHeight);
//
draw_rectangle(0, 0, screenWidth, screenHeight, 1);
 

josyanf1

Member
If you can assemble a tiny project with just your screen setup, I could take a look at what else could be wrong. But I think you'll need to resize your application_surface to be not just that fixed size, but rather calculate the sizing while keeping aspect ratio, like so (live demo):
Code:
surf = -1;
// ...
var gameWidth = 180;
var gameHeight = 320;
if (!surface_exists(surf)) {
    surf = surface_create(gameWidth, gameHeight);
    surface_set_target(surf);
    draw_clear(c_blue);
    surface_reset_target();
}
var screenWidth = mouse_x;
var screenHeight = mouse_y;
var scale = min(screenWidth / gameWidth, screenHeight / gameHeight);
var outWidth = gameWidth * scale;
var outHeight = gameHeight * scale;
var outX = (screenWidth - outWidth) div 2;
var outY = (screenHeight - outHeight) div 2;
draw_surface_stretched(surf, outX, outY, outWidth, outHeight);
//
draw_rectangle(0, 0, screenWidth, screenHeight, 1);
Surely that's it, thank you very much!
 
Top