Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/supertux/gameconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Config::Config() :
flash_intensity(50),
max_viewport(false),
fancy_gfx(true),
enable_3d_mode(false),
precise_scrolling(true),
invert_wheel_x(false),
invert_wheel_y(false),
Expand Down Expand Up @@ -330,6 +331,7 @@ Config::load()

config_video_mapping->get("magnification", magnification);
config_video_mapping->get("fancy_gfx", fancy_gfx);
config_video_mapping->get("enable_3d_mode", enable_3d_mode);
config_video_mapping->get("prefer_wayland", prefer_wayland);
config_video_mapping->get("max_viewport", max_viewport);

Expand Down Expand Up @@ -511,6 +513,7 @@ Config::save()

writer.write("magnification", magnification);
writer.write("fancy_gfx", fancy_gfx);
writer.write("enable_3d_mode", enable_3d_mode);
writer.write("prefer_wayland", prefer_wayland);
writer.write("max_viewport", max_viewport);

Expand Down
3 changes: 3 additions & 0 deletions src/supertux/gameconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class Config final
/** Toggles fancy graphical effects like displacement or blur (primarily for the GL backend) */
bool fancy_gfx;

/** Enable 3D perspective mode */
bool enable_3d_mode;

/** initial random seed. 0 ==> set from time() */
int random_seed;

Expand Down
3 changes: 3 additions & 0 deletions src/supertux/menu/options_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ OptionsMenu::refresh()
add_toggle(MNID_FANCY_GFX, _("Fancy Effects"), &g_config->fancy_gfx)
.set_help(_("Applies fancy effects such as blur, clear tile refraction, and various other effects deemed \"fancy\". May significantly degrade performance."));

add_toggle(MNID_3D_MODE, _("3D Mode"), &g_config->enable_3d_mode)
.set_help(_("Enables an isometric 3D perspective effect for the game."));

add_flash_intensity();

#if !defined(HIDE_NONMOBILE_OPTIONS) && !defined(__EMSCRIPTEN__)
Expand Down
1 change: 1 addition & 0 deletions src/supertux/menu/options_menu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class OptionsMenu final : public Menu
MNID_VSYNC,
MNID_FRAME_PREDICTION,
MNID_FANCY_GFX,
MNID_3D_MODE,
MNID_SOUND,
MNID_MUSIC,
MNID_SOUND_VOLUME,
Expand Down
16 changes: 16 additions & 0 deletions src/video/gl/gl20_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ GL20Context::ortho(float width, float height, bool vflip)

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Apply 3D isometric-like perspective transformation when enabled
if (g_config && g_config->enable_3d_mode) {
// True isometric projection with 30-degree angles for dramatic 3D effect
const GLfloat cos30 = 0.866f; // cos(30°)
const GLfloat sin30 = 0.5f; // sin(30°)

// Isometric transformation matrix combining rotation and scaling
const GLfloat iso_matrix[] = {
cos30, sin30, 0.0f, 0.0f, // X axis rotated
-sin30, cos30 * 0.5f, 0.0f, 0.0f, // Y axis compressed and rotated
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
glMultMatrixf(iso_matrix);
}

assert_gl();
}
Expand Down
37 changes: 32 additions & 5 deletions src/video/gl/gl33core_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,38 @@ GL33CoreContext::ortho(float width, float height, bool vflip)
const float tx = -1.0f;
const float ty = 1.0f * (vflip ? 1.0f : -1.0f);

const float mvp_matrix[] = {
sx, 0, tx,
0, sy, ty,
0, 0, 1
};
float mvp_matrix[9];

// Apply 3D isometric-like perspective transformation when enabled
if (g_config && g_config->enable_3d_mode) {
// True isometric projection with 30-degree angles
// This creates a dramatic 3D appearance by rotating the view
const float cos30 = 0.866f; // cos(30°)
const float sin30 = 0.5f; // sin(30°)

// Combine rotation and skew for isometric effect
// X stays the same, Y is compressed and offset by X
mvp_matrix[0] = sx * cos30; // X scale with rotation
mvp_matrix[1] = sx * sin30; // X contribution to Y
mvp_matrix[2] = tx;
mvp_matrix[3] = -sy * sin30; // Y contribution to X (creates depth)
mvp_matrix[4] = sy * cos30 * 0.5f; // Y scale (compressed for isometric)
mvp_matrix[5] = ty;
mvp_matrix[6] = 0;
mvp_matrix[7] = 0;
mvp_matrix[8] = 1;
} else {
// Standard orthographic projection
mvp_matrix[0] = sx;
mvp_matrix[1] = 0;
mvp_matrix[2] = tx;
mvp_matrix[3] = 0;
mvp_matrix[4] = sy;
mvp_matrix[5] = ty;
mvp_matrix[6] = 0;
mvp_matrix[7] = 0;
mvp_matrix[8] = 1;
}

const GLint mvp_loc = m_program->get_modelviewprojection_location();
glUniformMatrix3fv(mvp_loc, 1, false, mvp_matrix);
Expand Down
Loading