Add Fake 3D
MR Description
This adds Fake3D utility for PSDK.
In order to work file you need the following:
- Enable the Fake3D by setting
Fake3D::ENABLED
to true (before the window opens) - Add the shader files to
graphics/shaders
:
fake_3d.vert
#version 120
uniform mat4 camera;
uniform float z;
void main() {
vec4 vert = gl_Vertex;
vert.z = z;
gl_Position = camera * vert;
vert.z = gl_Vertex.z;
gl_TexCoord[0].xy = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
gl_FrontColor = gl_Color;
}
fake_3d.frag
#version 120
uniform sampler2D texture;
void main() {
gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * gl_Color;
}
Note: Those shaders are loaded only if Fake3D::ENABLED
is true. This way this utility won't break project missing the shaders and not actually using them!
Tests to realize
Add the following script:
class Fake3DScene < GamePlay::BaseCleanUpdate
class Sprite3D < Sprite
prepend Fake3D::Sprite3D
end
private
def create_graphics
super
@sprites = [
create_sprite(0, 20, 2, '002'),
create_sprite(20, 20, 2, '002'),
create_sprite(0, 0, 2, '002'),
create_sprite(20, 0, 2, '002'),
create_sprite(0, 0, 1),
create_sprite(20, 0, 1),
create_sprite(20, 20, 1),
create_sprite(0, 20, 1),
]
@camera = Fake3D::Camera.new(@viewport)
@camera.apply_to(@sprites)
@stack = UI::SpriteStack.new(@viewport)
@position = @stack.add_text(0, 0, 320, 16, 'Position: 0, 0, 1')
@position.z = 10_000
@rotation = @stack.add_text(0, 16, 320, 16, 'Rotation: 0, 0, 0')
@rotation.z = 10_000
@yaw = 0
@z = 1
end
def update_mouse(moved)
return if !moved && Mouse.wheel_delta == 0
if Mouse.press?(:LEFT)
@yaw += Mouse.wheel_delta / 10.0
@yaw %= 360
@camera.set_rotation(@yaw, Mouse.x - 160, Mouse.y - 120)
@camera.apply_to(@sprites)
@rotation.text = "Rotation: #{@camera.yaw.round.to_s.rjust(3)}, #{@camera.pitch.round.to_s.rjust(3)}, #{@camera.roll.round.to_s.rjust(3)}"
elsif Mouse.press?(:RIGHT)
@z += Mouse.wheel_delta / 10.0
@z = @z.clamp(0.001, 20)
@camera.set_position(Mouse.x - 160, Mouse.y - 120, @z)
@camera.apply_to(@sprites)
@position.text = "Position: #{@camera.x.to_s.rjust(4)}, #{@camera.y.to_s.rjust(4)}, #{@camera.z.to_s.rjust(4)}"
end
end
def create_sprite(x, y, z, img = '001')
sprite = Sprite3D.new(@viewport)
sprite.load(img, :icon)
sprite.set_origin(16, 16)
sprite.set_position(x, -y, z)
sprite.opacity = 180
return sprite
end
end
Call it using $scene.call_scene(Fake3DScene)
Enjoy.