mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 13:29:54 +00:00
simple 3D
This commit is contained in:
parent
0a45a117e3
commit
529650b84c
8 changed files with 297 additions and 63 deletions
|
|
@ -64,15 +64,19 @@ DEF_PROP_I(Sprite, WaveAmp)
|
|||
DEF_PROP_I(Sprite, WaveLength)
|
||||
DEF_PROP_I(Sprite, WaveSpeed)
|
||||
DEF_PROP_I(Sprite, Shader)
|
||||
DEF_PROP_I(Sprite, PerspectiveZ)
|
||||
|
||||
DEF_PROP_F(Sprite, ZoomX)
|
||||
DEF_PROP_F(Sprite, ZoomY)
|
||||
DEF_PROP_F(Sprite, Angle)
|
||||
DEF_PROP_F(Sprite, WavePhase)
|
||||
DEF_PROP_F(Sprite, PerspectiveRotationX)
|
||||
DEF_PROP_F(Sprite, PerspectiveRotationY)
|
||||
|
||||
DEF_PROP_B(Sprite, MirrorX)
|
||||
DEF_PROP_B(Sprite, MirrorY)
|
||||
DEF_PROP_B(Sprite, Obscured)
|
||||
DEF_PROP_B(Sprite, PerspectiveMode)
|
||||
|
||||
RB_METHOD(spriteWidth){
|
||||
RB_UNUSED_PARAM;
|
||||
|
|
@ -125,6 +129,10 @@ void spriteBindingInit(){
|
|||
INIT_PROP_BIND( Sprite, Modulate, "modulate" );
|
||||
INIT_PROP_BIND( Sprite, Obscured, "obscured" );
|
||||
INIT_PROP_BIND( Sprite, Shader, "shader" );
|
||||
INIT_PROP_BIND( Sprite, PerspectiveMode, "pm");
|
||||
INIT_PROP_BIND( Sprite, PerspectiveZ, "pz");
|
||||
INIT_PROP_BIND( Sprite, PerspectiveRotationX, "rx");
|
||||
INIT_PROP_BIND( Sprite, PerspectiveRotationY, "ry");
|
||||
|
||||
_rb_define_method(klass, "width", spriteWidth);
|
||||
_rb_define_method(klass, "height", spriteHeight);
|
||||
|
|
|
|||
|
|
@ -90,9 +90,10 @@ class Scene_OF
|
|||
|
||||
@miss_sound = Audio.create_sound("Audio/SE/shatter")
|
||||
|
||||
@viewport_bg = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport_ui = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport_ui.ox = -Graphics.width / 2
|
||||
@viewport_ui.oy = -Graphics.height / 2
|
||||
@viewport_ui.ox = @viewport_bg.ox = -Graphics.width / 2
|
||||
@viewport_ui.oy = @viewport_bg.oy = -Graphics.height / 2
|
||||
@spritesheet = RPG::Cache.misc(".cats")
|
||||
|
||||
@cat_flying_arrows = []
|
||||
|
|
@ -165,6 +166,20 @@ class Scene_OF
|
|||
@bst_debug = Sprite.new(@viewport_ui)
|
||||
@bst_debug.bitmap = Bitmap.new(300, 40)
|
||||
|
||||
@test_bitmap = Bitmap.new(64, 64)
|
||||
@test_bitmap.stretch_blt(Rect.new(0, 0, 64, 64), @spritesheet, SPRITES[:player_target_arrow_down])
|
||||
@threeD_test1 = Sprite.new(@viewport_bg)
|
||||
@threeD_test2 = Sprite.new(@viewport_bg)
|
||||
@threeD_test1.bitmap = @test_bitmap
|
||||
@threeD_test2.bitmap = @simple_bitmap
|
||||
@threeD_test1.x = -300
|
||||
@threeD_test1.ry = 90
|
||||
@threeD_test1.pm = @threeD_test2.pm = true
|
||||
@threeD_test1.zoom_x = @threeD_test1.zoom_y = 2
|
||||
@threeD_test2.zoom_x = @threeD_test2.zoom_y = 128
|
||||
@threeD_test1.ox = @threeD_test1.oy = 32
|
||||
@threeD_test2.ox = @threeD_test2.oy = 0.5
|
||||
|
||||
@total_time = 0
|
||||
@bump_timeout = 999999
|
||||
@bump_time = 999999
|
||||
|
|
@ -218,6 +233,9 @@ class Scene_OF
|
|||
@bst_debug.bitmap.clear
|
||||
@bst_debug.bitmap.draw_text(Rect.new(0, 0, 300, 40), "#{beat} : #{step} : #{tick}")
|
||||
|
||||
@threeD_test1.pz = Math.sin(@total_time / 180.0 * Math::PI) * 400 + 400
|
||||
@threeD_test2.rx += 4
|
||||
|
||||
@bump_timeout -= 1
|
||||
@icons_bump_timeout -= 1
|
||||
if @bump_timeout <= 0
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <SDL3/SDL_rect.h>
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f;
|
||||
|
||||
struct Vec2{
|
||||
float x, y;
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,34 @@ void ShaderBase::applyViewportProj(){
|
|||
projMat.set(Vec2i(vp.w, vp.h));
|
||||
}
|
||||
|
||||
void ShaderBase::applyPerspectiveProj()
|
||||
{
|
||||
const IntRect &vp = glState.viewport.get();
|
||||
const float width = (float)vp.w;
|
||||
const float height = (float)vp.h;
|
||||
|
||||
const float cameraDistance = 1000.0f;
|
||||
|
||||
const float nearPlane = 1.0f;
|
||||
const float farPlane = 10000.0f;
|
||||
|
||||
const float sx = 2.0f * cameraDistance / width;
|
||||
const float sy = 2.0f * cameraDistance / height;
|
||||
|
||||
const float A = -(farPlane + nearPlane) / (farPlane - nearPlane);
|
||||
|
||||
const float B = -(2.0f * farPlane * nearPlane) / (farPlane - nearPlane);
|
||||
|
||||
GLfloat mat[16] = {
|
||||
sx, 0, 0, 0,
|
||||
0, sy, 0, 0,
|
||||
0, 0, A, -1,
|
||||
-cameraDistance, -cameraDistance, B, cameraDistance
|
||||
};
|
||||
|
||||
gl.UniformMatrix4fv(projMat.u_mat, 1, GL_FALSE, mat);
|
||||
}
|
||||
|
||||
void ShaderBase::setTexSize(const Vec2i &value){
|
||||
gl.Uniform2f(u_texSizeInv, 1.f / value.x, 1.f / value.y);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public:
|
|||
* calculates the corresponding ortho projection matrix
|
||||
* and loads it into the shaders uniform */
|
||||
void applyViewportProj();
|
||||
void applyPerspectiveProj();
|
||||
|
||||
void setTexSize(const Vec2i &value);
|
||||
void setTranslation(const Vec2i &value);
|
||||
|
|
|
|||
|
|
@ -318,6 +318,11 @@ DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp)
|
|||
DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length)
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed)
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase)
|
||||
// 3D shit
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, PerspectiveMode, bool, p->trans.getPerspectiveMode())
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, PerspectiveZ, int, p->trans.getPerspectiveZ())
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, PerspectiveRotationX, float, p->trans.getPerspectiveRotation().x)
|
||||
DEF_ATTR_RD_SIMPLE(Sprite, PerspectiveRotationY, float, p->trans.getPerspectiveRotation().y)
|
||||
|
||||
DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity)
|
||||
DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity)
|
||||
|
|
@ -462,6 +467,42 @@ void Sprite::setBlendType(int type){
|
|||
}
|
||||
}
|
||||
|
||||
void Sprite::setPerspectiveMode(bool value){
|
||||
guardDisposed();
|
||||
|
||||
if (p->trans.getPerspectiveMode() == value)
|
||||
return;
|
||||
|
||||
p->trans.setPerspectiveMode(value);
|
||||
}
|
||||
|
||||
void Sprite::setPerspectiveZ(int value){
|
||||
guardDisposed();
|
||||
|
||||
if (p->trans.getPerspectiveZ() == value)
|
||||
return;
|
||||
|
||||
p->trans.setPerspectiveZ(value);
|
||||
}
|
||||
|
||||
void Sprite::setPerspectiveRotationX(float value){
|
||||
guardDisposed();
|
||||
|
||||
if (p->trans.getPerspectiveRotation().x == value)
|
||||
return;
|
||||
|
||||
p->trans.setPerspectiveRotation(Vec2(value, p->trans.getPerspectiveRotation().y));
|
||||
}
|
||||
|
||||
void Sprite::setPerspectiveRotationY(float value){
|
||||
guardDisposed();
|
||||
|
||||
if (p->trans.getPerspectiveRotation().y == value)
|
||||
return;
|
||||
|
||||
p->trans.setPerspectiveRotation(Vec2(p->trans.getPerspectiveRotation().x, value));
|
||||
}
|
||||
|
||||
#define DEF_WAVE_SETTER(Name, name, type) \
|
||||
void Sprite::setWave##Name(type value) \
|
||||
{ \
|
||||
|
|
@ -517,7 +558,6 @@ void Sprite::draw(){
|
|||
if (p->obscured || p->shader == ShaderType::SHADER_obscured){
|
||||
ObscuredShader &shader = shState->shaders().obscured;
|
||||
shader.bind();
|
||||
shader.applyViewportProj();
|
||||
shader.setObscured(shState->graphics().obscuredTex());
|
||||
base = &shader;
|
||||
}
|
||||
|
|
@ -529,7 +569,6 @@ void Sprite::draw(){
|
|||
PlaneShader &shader = shState->shaders().plane;
|
||||
|
||||
shader.bind();
|
||||
shader.applyViewportProj();
|
||||
shader.setTone(p->tone->norm);
|
||||
shader.setColor(p->color->norm);
|
||||
shader.setFlash(Vec4());
|
||||
|
|
@ -586,7 +625,6 @@ void Sprite::draw(){
|
|||
|
||||
shader.setSpriteMat(p->trans.getMatrix());
|
||||
shader.setAlpha(p->opacity.norm);
|
||||
shader.applyViewportProj();
|
||||
base = &shader;
|
||||
}
|
||||
else{
|
||||
|
|
@ -594,7 +632,6 @@ void Sprite::draw(){
|
|||
shader.bind();
|
||||
|
||||
shader.setSpriteMat(p->trans.getMatrix());
|
||||
shader.applyViewportProj();
|
||||
base = &shader;
|
||||
}
|
||||
|
||||
|
|
@ -606,6 +643,10 @@ void Sprite::draw(){
|
|||
boost::chrono::duration<float> elapsed = currentTime - startTime;
|
||||
base->setTime(elapsed.count());
|
||||
|
||||
base->applyViewportProj();
|
||||
if(p->trans.getPerspectiveMode())
|
||||
base->applyPerspectiveProj();
|
||||
|
||||
glState.blendMode.pushSet(p->blendType);
|
||||
|
||||
p->bitmap->bindTex(*base);
|
||||
|
|
@ -644,7 +685,6 @@ void Sprite::releaseResources(){
|
|||
|
||||
void Sprite::defaultSpriteShaderInit(SpriteShaderBase &shader){
|
||||
shader.bind();
|
||||
shader.applyViewportProj();
|
||||
shader.setSpriteMat(p->trans.getMatrix());
|
||||
|
||||
shader.setTone(p->tone->norm);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,11 @@ public:
|
|||
DECL_ATTR( WavePhase, float )
|
||||
DECL_ATTR( Obscured, bool )
|
||||
DECL_ATTR( Shader, int )
|
||||
// 3D test shit
|
||||
DECL_ATTR( PerspectiveMode, bool )
|
||||
DECL_ATTR( PerspectiveZ, int )
|
||||
DECL_ATTR( PerspectiveRotationX, float )
|
||||
DECL_ATTR( PerspectiveRotationY, float )
|
||||
|
||||
void initDynAttribs();
|
||||
|
||||
|
|
|
|||
136
src/transform.h
136
src/transform.h
|
|
@ -52,13 +52,13 @@
|
|||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f;
|
||||
|
||||
class Transform{
|
||||
public:
|
||||
Transform()
|
||||
: scale(1, 1),
|
||||
rotation(0),
|
||||
perspectiveZ(0),
|
||||
perspectiveRotation(0, 0),
|
||||
dirty(true)
|
||||
{
|
||||
SDL_memset(matrix, 0, sizeof(matrix));
|
||||
|
|
@ -71,8 +71,11 @@ public:
|
|||
Vec2 &getOrigin() { return origin; }
|
||||
Vec2 &getScale() { return scale; }
|
||||
Vec2 &getGlobalScale() { return globalScale; }
|
||||
Vec2 &getPerspectiveRotation() { return perspectiveRotation; }
|
||||
float getRotation() { return rotation; }
|
||||
float getGlobalRotation() { return globalRotation; }
|
||||
float getPerspectiveZ() { return perspectiveZ; }
|
||||
bool getPerspectiveMode() { return perspectiveMode; }
|
||||
|
||||
Vec2i getPositionI() const{
|
||||
return Vec2i(position.x, position.y);
|
||||
|
|
@ -82,11 +85,21 @@ public:
|
|||
return Vec2i(origin.x, origin.y);
|
||||
}
|
||||
|
||||
void setPerspectiveMode(bool mode) {
|
||||
perspectiveMode = mode;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void setPosition(const Vec2 &value){
|
||||
position = value;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void setPerspectiveZ(float value) {
|
||||
perspectiveZ = value;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void setOrigin(const Vec2 &value){
|
||||
origin = value;
|
||||
dirty = true;
|
||||
|
|
@ -102,6 +115,11 @@ public:
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
void setPerspectiveRotation(const Vec2 &value){
|
||||
perspectiveRotation = value;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void setGlobalRotation(float value){
|
||||
globalRotation = value;
|
||||
dirty = true;
|
||||
|
|
@ -133,6 +151,7 @@ private:
|
|||
|
||||
if (globalRotation >= 360 || globalRotation < -360)
|
||||
globalRotation = (float)SDL_fmod(globalRotation, 360);
|
||||
if (!perspectiveMode) {
|
||||
|
||||
// object rotation cos and sin
|
||||
float angle = rotation * PI / 180.0f;
|
||||
|
|
@ -176,10 +195,117 @@ private:
|
|||
|
||||
matrix[0] = na;
|
||||
matrix[1] = nb;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 0;
|
||||
matrix[4] = nc;
|
||||
matrix[5] = nd;
|
||||
matrix[6] = 0;
|
||||
matrix[7] = 0;
|
||||
matrix[8] = 0;
|
||||
matrix[9] = 0;
|
||||
matrix[10] = 1;
|
||||
matrix[11] = 0;
|
||||
matrix[12] = tx;
|
||||
matrix[13] = ty;
|
||||
matrix[14] = -1;
|
||||
matrix[15] = 1;
|
||||
}
|
||||
else {
|
||||
if (perspectiveRotation.x >= 360 || perspectiveRotation.x < -360)
|
||||
perspectiveRotation.x = (float)SDL_fmod(perspectiveRotation.x, 360);
|
||||
|
||||
if (perspectiveRotation.y >= 360 || perspectiveRotation.y < -360)
|
||||
perspectiveRotation.y = (float)SDL_fmod(perspectiveRotation.y, 360);
|
||||
|
||||
float rx = perspectiveRotation.x * PI / 180.0f;
|
||||
float ry = perspectiveRotation.y * PI / 180.0f;
|
||||
float rz = rotation * PI / 180.0f;
|
||||
|
||||
float cx = SDL_cos(rx);
|
||||
float sx = SDL_sin(rx);
|
||||
|
||||
float cy = SDL_cos(ry);
|
||||
float sy = SDL_sin(ry);
|
||||
|
||||
float cz = SDL_cos(rz);
|
||||
float sz = SDL_sin(rz);
|
||||
|
||||
float m00 = cy * cz;
|
||||
float m01 = cz * sx * sy - cx * sz;
|
||||
float m02 = sx * sz + cx * cz * sy;
|
||||
|
||||
float m10 = cy * sz;
|
||||
float m11 = cx * cz + sx * sy * sz;
|
||||
float m12 = cx * sy * sz - cz * sx;
|
||||
|
||||
float m20 = -sy;
|
||||
float m21 = cy * sx;
|
||||
float m22 = cx * cy;
|
||||
|
||||
m00 *= scale.x;
|
||||
m10 *= scale.x;
|
||||
m20 *= scale.x;
|
||||
|
||||
m01 *= scale.y;
|
||||
m11 *= scale.y;
|
||||
m21 *= scale.y;
|
||||
|
||||
float globalAngle = globalRotation * PI / 180.0f;
|
||||
float gc = SDL_cos(globalAngle);
|
||||
float gs = SDL_sin(globalAngle);
|
||||
|
||||
// Rotate X/Y basis around Z
|
||||
|
||||
float r00 = m00 * gc - m01 * gs;
|
||||
float r01 = m00 * gs + m01 * gc;
|
||||
|
||||
float r10 = m10 * gc - m11 * gs;
|
||||
float r11 = m10 * gs + m11 * gc;
|
||||
|
||||
float r20 = m20 * gc - m21 * gs;
|
||||
float r21 = m20 * gs + m21 * gc;
|
||||
|
||||
m00 = r00;
|
||||
m01 = r01;
|
||||
|
||||
m10 = r10;
|
||||
m11 = r11;
|
||||
|
||||
m20 = r20;
|
||||
m21 = r21;
|
||||
|
||||
m00 *= globalScale.x;
|
||||
m10 *= globalScale.x;
|
||||
m20 *= globalScale.x;
|
||||
|
||||
m01 *= globalScale.y;
|
||||
m11 *= globalScale.y;
|
||||
m21 *= globalScale.y;
|
||||
|
||||
float tx = position.x - (m00 * origin.x + m01 * origin.y) + offset.x;
|
||||
float ty = position.y - (m10 * origin.x + m11 * origin.y) + offset.y;
|
||||
float tz = -perspectiveZ - (m20 * origin.x + m21 * origin.y);
|
||||
|
||||
matrix[0] = m00;
|
||||
matrix[1] = m10;
|
||||
matrix[2] = m20;
|
||||
matrix[3] = 0;
|
||||
|
||||
matrix[4] = m01;
|
||||
matrix[5] = m11;
|
||||
matrix[6] = m21;
|
||||
matrix[7] = 0;
|
||||
|
||||
matrix[8] = m02;
|
||||
matrix[9] = m12;
|
||||
matrix[10] = m22;
|
||||
matrix[11] = 0;
|
||||
|
||||
matrix[12] = tx;
|
||||
matrix[13] = ty;
|
||||
matrix[14] = tz;
|
||||
matrix[15] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Vec2 position;
|
||||
|
|
@ -188,6 +314,12 @@ private:
|
|||
float rotation;
|
||||
float globalRotation;
|
||||
|
||||
// 3D moments lol
|
||||
float perspectiveZ;
|
||||
// X and Y, Z is just rotation
|
||||
Vec2 perspectiveRotation;
|
||||
bool perspectiveMode = false;
|
||||
|
||||
/* Silently added to position */
|
||||
Vec2i offset;
|
||||
/* Silently added to scale */
|
||||
|
|
|
|||
Loading…
Reference in a new issue