8 #include "shaders/gate.h"
10 typedef struct teleport_gate teleport_gate
;
14 GLuint fb
, rgb
, rb
, vao
, vbo
;
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 (*newfb
)(GLuint
*,GLuint
*,GLuint
*) )
44 newfb( &grender
.fb
, &grender
.rgb
, &grender
.rb
);
47 float quad
[] = { -ksz
,-ksz
,0.0f
, ksz
, ksz
,0.0f
, -ksz
, ksz
,0.0f
,
48 -ksz
,-ksz
,0.0f
, ksz
,-ksz
,0.0f
, ksz
, ksz
,0.0f
,
49 -ksz
,-ksz
,-0.1f
, ksz
, ksz
,-0.1f
, -ksz
, ksz
,-0.1f
,
50 -ksz
,-ksz
,-0.1f
, ksz
,-ksz
,-0.1f
, ksz
, ksz
,-0.1f
};
52 glGenVertexArrays( 1, &grender
.vao
);
53 glGenBuffers( 1, &grender
.vbo
);
54 glBindVertexArray( grender
.vao
);
55 glBindBuffer( GL_ARRAY_BUFFER
, grender
.vbo
);
56 glBufferData( GL_ARRAY_BUFFER
, sizeof(quad
), quad
, GL_STATIC_DRAW
);
57 glBindVertexArray( grender
.vao
);
58 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
,
59 sizeof(float)*3, (void*)0 );
60 glEnableVertexAttribArray( 0 );
64 model
*mgate
= vg_asset_read( "models/rs_gate.mdl" );
65 model_unpack( mgate
, &grender
.mdl
);
69 static void gate_fb_resize(void)
71 resize_renderbuffer_std( &grender
.fb
, &grender
.rgb
, &grender
.rb
);
74 static void render_gate( teleport_gate
*gate
, m4x3f camera
)
76 v3f viewpos
, viewdir
, gatedir
;
77 v3_copy( camera
[3], viewpos
);
78 m3x3_mulv( camera
, (v3f
){0.0f
,0.0f
,-1.0f
}, viewdir
);
79 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, gatedir
);
81 if( v3_dot(viewdir
, gatedir
) <= 0.0f
)
85 v3_sub( viewpos
, gate
->co
, v0
);
86 if( v3_dot(v0
, gatedir
) >= 0.0f
)
90 m4x3_mul( gate
->other
->to_world
, gate
->to_local
, transport
);
94 float sx
= gate
->dims
[0],
96 m4x3_mulv( gate
->to_world
, (v3f
){-sx
,-sy
,0.0f
}, a
);
97 m4x3_mulv( gate
->to_world
, (v3f
){ sx
,-sy
,0.0f
}, b
);
98 m4x3_mulv( gate
->to_world
, (v3f
){ sx
, sy
,0.0f
}, c
);
99 m4x3_mulv( gate
->to_world
, (v3f
){-sx
, sy
,0.0f
}, d
);
101 vg_line( a
,b
, 0xffffa000 );
102 vg_line( b
,c
, 0xffffa000 );
103 vg_line( c
,d
, 0xffffa000 );
104 vg_line( d
,a
, 0xffffa000 );
106 vg_line( gate
->co
, gate
->other
->co
, 0xffffffff );
109 m4x3_mul( transport
, camera
, cam_new
);
111 vg_line_pt3( cam_new
[3], 0.3f
, 0xff00ff00 );
113 glBindFramebuffer( GL_FRAMEBUFFER
, grender
.fb
);
114 glClearColor( 0.11f
, 0.35f
, 0.37f
, 1.0f
);
115 glClear( GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
);
118 m4x3_invert_affine( cam_new
, inverse
);
121 m4x3_expand( inverse
, view
);
124 m3x3_mulv( gate
->other
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
125 surface
[3] = v3_dot( surface
, gate
->other
->co
);
128 pipeline_projection( projection
, 0.1f
, 900.0f
);
130 #if 0 /* For debugging frustum */
133 m4x4_mul( projection
, view
, devm
);
134 m4x4_inv( devm
, devm
);
138 {-1,-1,-1, 1}, { 1,-1,-1, 1}, { 1, 1,-1, 1}, {-1, 1,-1, 1},
139 {-1,-1, 1, 1}, { 1,-1, 1, 1}, { 1, 1, 1, 1}, {-1, 1, 1, 1}
142 for( int i
=0; i
<vg_list_size(corners
); i
++ )
144 m4x4_mulv( devm
, corners
[i
], corners
[i
] );
145 v3_muls( corners
[i
], 1.0f
/corners
[i
][3], corners
[i
] );
148 vg_line( corners
[0], corners
[1], 0xffffffff );
149 vg_line( corners
[1], corners
[2], 0xffffffff );
150 vg_line( corners
[2], corners
[3], 0xffffffff );
151 vg_line( corners
[3], corners
[0], 0xffffffff );
152 vg_line( corners
[4], corners
[5], 0xffffffff );
153 vg_line( corners
[5], corners
[6], 0xffffffff );
154 vg_line( corners
[6], corners
[7], 0xffffffff );
155 vg_line( corners
[7], corners
[4], 0xffffffff );
156 vg_line( corners
[0], corners
[4], 0xffffffff );
157 vg_line( corners
[1], corners
[5], 0xffffffff );
158 vg_line( corners
[2], corners
[6], 0xffffffff );
159 vg_line( corners
[3], corners
[7], 0xffffffff );
162 for( int i
=0; i
<4; i
++ )
164 v3f v0
, c
, delta
, p0
;
165 v3_sub( corners
[4+i
],corners
[0+i
], v0
);
168 v3_muls( surface
, surface
[3], c
);
169 v3_sub( c
, corners
[0+i
], delta
);
171 float t
= v3_dot(delta
, surface
) / v3_dot(surface
, v0
);
172 v3_muladds( corners
[0+i
], v0
, t
, clipped
[i
] );
175 vg_line( clipped
[0], clipped
[1], 0xff0000ff );
176 vg_line( clipped
[1], clipped
[2], 0xff0000ff );
177 vg_line( clipped
[2], clipped
[3], 0xff0000ff );
178 vg_line( clipped
[3], clipped
[0], 0xff0000ff );
180 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
,-2.0f
,0.0f
}, a
);
181 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
,-2.0f
,0.0f
}, b
);
182 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
, 2.0f
,0.0f
}, c
);
183 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
, 2.0f
,0.0f
}, d
);
185 vg_line( clipped
[0], a
, 0xff0000ff );
186 vg_line( clipped
[1], b
, 0xff0000ff );
187 vg_line( clipped
[2], c
, 0xff0000ff );
188 vg_line( clipped
[3], d
, 0xff0000ff );
192 m4x3_mulp( inverse
, surface
, surface
);
193 surface
[3] = -fabsf(surface
[3]);
194 plane_clip_projection( projection
, surface
);
196 m4x4_mul( projection
, view
, projection
);
198 render_world( projection
, cam_new
);
199 render_water_texture( cam_new
);
200 glBindFramebuffer( GL_FRAMEBUFFER
, grender
.fb
);
201 render_water_surface( projection
);
202 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
207 m4x3_copy( gate
->to_world
, full
);
208 m4x3_scalev( full
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
210 shader_gate_uPv( vg_pv
);
211 shader_gate_uMdl( full
);
213 glActiveTexture( GL_TEXTURE0
);
214 glBindTexture( GL_TEXTURE_2D
, grender
.rgb
);
215 shader_gate_uCam( viewpos
);
216 shader_gate_uTexMain( 0 );
217 shader_gate_uTexWater( 1 );
218 shader_gate_uTime( vg_time
*0.25f
);
219 shader_gate_uInvRes( (v2f
){
220 1.0f
/ (float)vg_window_x
,
221 1.0f
/ (float)vg_window_y
});
224 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
225 glBlendEquation(GL_FUNC_ADD
);
227 mesh_bind( &grender
.mdl
);
228 mesh_draw( &grender
.mdl
);
232 glBindVertexArray( grender
.vao
);
233 glDrawArrays( GL_TRIANGLES
, 0, 12 );
236 static int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
239 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
240 surface
[3] = v3_dot( surface
, gate
->co
);
242 v3f v0
, c
, delta
, p0
;
243 v3_sub( pos
, last
, v0
);
244 float l
= v3_length( v0
);
245 v3_divs( v0
, l
, v0
);
247 v3_muls( surface
, surface
[3], c
);
248 v3_sub( c
, last
, delta
);
250 float d
= v3_dot(surface
, v0
);
252 if( fabsf(d
) > 0.00001f
)
254 float t
= v3_dot(delta
, surface
) / d
;
255 if( t
>= 0.0f
&& t
<= l
)
258 v3_muladds( last
, v0
, t
, local
);
259 v3_sub( gate
->co
, local
, rel
);
262 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
263 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
265 v2f xy
= { v3_dot( rel
, vside
), v3_dot( rel
, vup
) };
267 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )