8 #include "shaders/gate.h"
10 typedef struct teleport_gate teleport_gate
;
25 m4x3f to_world
, to_local
;
29 static void gate_transform_update( teleport_gate
*gate
)
31 q_m3x3( gate
->q
, gate
->to_world
);
32 v3_copy( gate
->co
, gate
->to_world
[3] );
34 m4x3_invert_affine( gate
->to_world
, gate
->to_local
);
37 static void gate_register(void)
39 shader_gate_register();
42 static void gate_init(void)
44 create_renderbuffer_std( &grender
.fb
, &grender
.rgb
, &grender
.rb
);
46 model
*mgate
= vg_asset_read( "models/rs_gate.mdl" );
47 model_unpack( mgate
, &grender
.mdl
);
51 static void gate_fb_resize(void)
53 resize_renderbuffer_std( &grender
.fb
, &grender
.rgb
, &grender
.rb
);
56 static void render_gate( teleport_gate
*gate
, m4x3f camera
)
58 v3f viewpos
, viewdir
, gatedir
;
59 v3_copy( camera
[3], viewpos
);
60 m3x3_mulv( camera
, (v3f
){0.0f
,0.0f
,-1.0f
}, viewdir
);
61 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, gatedir
);
63 if( v3_dot(viewdir
, gatedir
) <= 0.0f
)
67 v3_sub( viewpos
, gate
->co
, v0
);
68 if( v3_dot(v0
, gatedir
) >= 0.0f
)
72 m4x3_mul( gate
->other
->to_world
, gate
->to_local
, transport
);
76 float sx
= gate
->dims
[0],
78 m4x3_mulv( gate
->to_world
, (v3f
){-sx
,-sy
,0.0f
}, a
);
79 m4x3_mulv( gate
->to_world
, (v3f
){ sx
,-sy
,0.0f
}, b
);
80 m4x3_mulv( gate
->to_world
, (v3f
){ sx
, sy
,0.0f
}, c
);
81 m4x3_mulv( gate
->to_world
, (v3f
){-sx
, sy
,0.0f
}, d
);
83 vg_line( a
,b
, 0xffffa000 );
84 vg_line( b
,c
, 0xffffa000 );
85 vg_line( c
,d
, 0xffffa000 );
86 vg_line( d
,a
, 0xffffa000 );
88 vg_line( gate
->co
, gate
->other
->co
, 0xffffffff );
91 m4x3_mul( transport
, camera
, cam_new
);
93 vg_line_pt3( cam_new
[3], 0.3f
, 0xff00ff00 );
95 glBindFramebuffer( GL_FRAMEBUFFER
, grender
.fb
);
96 glClearColor( 0.11f
, 0.35f
, 0.37f
, 1.0f
);
97 glClear( GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
);
100 m4x3_invert_affine( cam_new
, inverse
);
103 m4x3_expand( inverse
, view
);
106 m3x3_mulv( gate
->other
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
107 surface
[3] = v3_dot( surface
, gate
->other
->co
);
110 pipeline_projection( projection
, 0.1f
, 900.0f
);
112 #if 0 /* For debugging frustum */
115 m4x4_mul( projection
, view
, devm
);
116 m4x4_inv( devm
, devm
);
120 {-1,-1,-1, 1}, { 1,-1,-1, 1}, { 1, 1,-1, 1}, {-1, 1,-1, 1},
121 {-1,-1, 1, 1}, { 1,-1, 1, 1}, { 1, 1, 1, 1}, {-1, 1, 1, 1}
124 for( int i
=0; i
<vg_list_size(corners
); i
++ )
126 m4x4_mulv( devm
, corners
[i
], corners
[i
] );
127 v3_muls( corners
[i
], 1.0f
/corners
[i
][3], corners
[i
] );
130 vg_line( corners
[0], corners
[1], 0xffffffff );
131 vg_line( corners
[1], corners
[2], 0xffffffff );
132 vg_line( corners
[2], corners
[3], 0xffffffff );
133 vg_line( corners
[3], corners
[0], 0xffffffff );
134 vg_line( corners
[4], corners
[5], 0xffffffff );
135 vg_line( corners
[5], corners
[6], 0xffffffff );
136 vg_line( corners
[6], corners
[7], 0xffffffff );
137 vg_line( corners
[7], corners
[4], 0xffffffff );
138 vg_line( corners
[0], corners
[4], 0xffffffff );
139 vg_line( corners
[1], corners
[5], 0xffffffff );
140 vg_line( corners
[2], corners
[6], 0xffffffff );
141 vg_line( corners
[3], corners
[7], 0xffffffff );
144 for( int i
=0; i
<4; i
++ )
146 v3f v0
, c
, delta
, p0
;
147 v3_sub( corners
[4+i
],corners
[0+i
], v0
);
150 v3_muls( surface
, surface
[3], c
);
151 v3_sub( c
, corners
[0+i
], delta
);
153 float t
= v3_dot(delta
, surface
) / v3_dot(surface
, v0
);
154 v3_muladds( corners
[0+i
], v0
, t
, clipped
[i
] );
157 vg_line( clipped
[0], clipped
[1], 0xff0000ff );
158 vg_line( clipped
[1], clipped
[2], 0xff0000ff );
159 vg_line( clipped
[2], clipped
[3], 0xff0000ff );
160 vg_line( clipped
[3], clipped
[0], 0xff0000ff );
162 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
,-2.0f
,0.0f
}, a
);
163 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
,-2.0f
,0.0f
}, b
);
164 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
, 2.0f
,0.0f
}, c
);
165 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
, 2.0f
,0.0f
}, d
);
167 vg_line( clipped
[0], a
, 0xff0000ff );
168 vg_line( clipped
[1], b
, 0xff0000ff );
169 vg_line( clipped
[2], c
, 0xff0000ff );
170 vg_line( clipped
[3], d
, 0xff0000ff );
174 m4x3_mulp( inverse
, surface
, surface
);
175 surface
[3] = -fabsf(surface
[3]);
176 plane_clip_projection( projection
, surface
);
178 m4x4_mul( projection
, view
, projection
);
180 render_world( projection
, cam_new
);
181 render_water_texture( cam_new
);
182 glBindFramebuffer( GL_FRAMEBUFFER
, grender
.fb
);
183 render_water_surface( projection
);
184 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
189 m4x3_copy( gate
->to_world
, full
);
190 m4x3_scalev( full
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
192 shader_gate_uPv( vg_pv
);
193 shader_gate_uMdl( full
);
195 glActiveTexture( GL_TEXTURE0
);
196 glBindTexture( GL_TEXTURE_2D
, grender
.rgb
);
197 shader_gate_uCam( viewpos
);
198 shader_gate_uTexMain( 0 );
199 shader_gate_uTexWater( 1 );
200 shader_gate_uTime( vg_time
*0.25f
);
201 shader_gate_uInvRes( (v2f
){
202 1.0f
/ (float)vg_window_x
,
203 1.0f
/ (float)vg_window_y
});
206 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
207 glBlendEquation(GL_FUNC_ADD
);
209 mesh_bind( &grender
.mdl
);
210 mesh_draw( &grender
.mdl
);
215 static int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
218 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
219 surface
[3] = v3_dot( surface
, gate
->co
);
221 v3f v0
, c
, delta
, p0
;
222 v3_sub( pos
, last
, v0
);
223 float l
= v3_length( v0
);
224 v3_divs( v0
, l
, v0
);
226 v3_muls( surface
, surface
[3], c
);
227 v3_sub( c
, last
, delta
);
229 float d
= v3_dot(surface
, v0
);
231 if( fabsf(d
) > 0.00001f
)
233 float t
= v3_dot(delta
, surface
) / d
;
234 if( t
>= 0.0f
&& t
<= l
)
237 v3_muladds( last
, v0
, t
, local
);
238 v3_sub( gate
->co
, local
, rel
);
241 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
242 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
244 v2f xy
= { v3_dot( rel
, vside
), v3_dot( rel
, vup
) };
246 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )