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 (*resize
)(GLuint
*,GLuint
*,GLuint
*) )
71 resize( &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 m4x4_projection( projection
,
130 (float)vg_window_x
/ (float)vg_window_y
,
133 #if 0 /* For debugging frustum */
136 m4x4_mul( projection
, view
, devm
);
137 m4x4_inv( devm
, devm
);
141 {-1,-1,-1, 1}, { 1,-1,-1, 1}, { 1, 1,-1, 1}, {-1, 1,-1, 1},
142 {-1,-1, 1, 1}, { 1,-1, 1, 1}, { 1, 1, 1, 1}, {-1, 1, 1, 1}
145 for( int i
=0; i
<vg_list_size(corners
); i
++ )
147 m4x4_mulv( devm
, corners
[i
], corners
[i
] );
148 v3_muls( corners
[i
], 1.0f
/corners
[i
][3], corners
[i
] );
151 vg_line( corners
[0], corners
[1], 0xffffffff );
152 vg_line( corners
[1], corners
[2], 0xffffffff );
153 vg_line( corners
[2], corners
[3], 0xffffffff );
154 vg_line( corners
[3], corners
[0], 0xffffffff );
155 vg_line( corners
[4], corners
[5], 0xffffffff );
156 vg_line( corners
[5], corners
[6], 0xffffffff );
157 vg_line( corners
[6], corners
[7], 0xffffffff );
158 vg_line( corners
[7], corners
[4], 0xffffffff );
159 vg_line( corners
[0], corners
[4], 0xffffffff );
160 vg_line( corners
[1], corners
[5], 0xffffffff );
161 vg_line( corners
[2], corners
[6], 0xffffffff );
162 vg_line( corners
[3], corners
[7], 0xffffffff );
165 for( int i
=0; i
<4; i
++ )
167 v3f v0
, c
, delta
, p0
;
168 v3_sub( corners
[4+i
],corners
[0+i
], v0
);
171 v3_muls( surface
, surface
[3], c
);
172 v3_sub( c
, corners
[0+i
], delta
);
174 float t
= v3_dot(delta
, surface
) / v3_dot(surface
, v0
);
175 v3_muladds( corners
[0+i
], v0
, t
, clipped
[i
] );
178 vg_line( clipped
[0], clipped
[1], 0xff0000ff );
179 vg_line( clipped
[1], clipped
[2], 0xff0000ff );
180 vg_line( clipped
[2], clipped
[3], 0xff0000ff );
181 vg_line( clipped
[3], clipped
[0], 0xff0000ff );
183 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
,-2.0f
,0.0f
}, a
);
184 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
,-2.0f
,0.0f
}, b
);
185 m4x3_mulv( gate
->other
->to_world
, (v3f
){ 2.0f
, 2.0f
,0.0f
}, c
);
186 m4x3_mulv( gate
->other
->to_world
, (v3f
){-2.0f
, 2.0f
,0.0f
}, d
);
188 vg_line( clipped
[0], a
, 0xff0000ff );
189 vg_line( clipped
[1], b
, 0xff0000ff );
190 vg_line( clipped
[2], c
, 0xff0000ff );
191 vg_line( clipped
[3], d
, 0xff0000ff );
195 m4x3_mulp( inverse
, surface
, surface
);
196 surface
[3] = -fabsf(surface
[3]);
197 plane_clip_projection( projection
, surface
);
199 m4x4_mul( projection
, view
, projection
);
201 render_world( projection
);
202 render_water_texture( cam_new
);
203 glBindFramebuffer( GL_FRAMEBUFFER
, grender
.fb
);
204 render_water_surface( projection
);
205 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
210 m4x3_copy( gate
->to_world
, full
);
211 m4x3_scalev( full
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
213 shader_gate_uPv( vg_pv
);
214 shader_gate_uMdl( full
);
216 glActiveTexture( GL_TEXTURE0
);
217 glBindTexture( GL_TEXTURE_2D
, grender
.rgb
);
218 shader_gate_uCam( viewpos
);
219 shader_gate_uTexMain( 0 );
220 shader_gate_uTexWater( 1 );
221 shader_gate_uTime( vg_time
*0.25f
);
222 shader_gate_uInvRes( (v2f
){
223 1.0f
/ (float)vg_window_x
,
224 1.0f
/ (float)vg_window_y
});
227 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
228 glBlendEquation(GL_FUNC_ADD
);
230 mesh_bind( &grender
.mdl
);
231 mesh_draw( &grender
.mdl
);
235 glBindVertexArray( grender
.vao
);
236 glDrawArrays( GL_TRIANGLES
, 0, 12 );
239 static int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
242 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
243 surface
[3] = v3_dot( surface
, gate
->co
);
245 v3f v0
, c
, delta
, p0
;
246 v3_sub( pos
, last
, v0
);
247 float l
= v3_length( v0
);
248 v3_divs( v0
, l
, v0
);
250 v3_muls( surface
, surface
[3], c
);
251 v3_sub( c
, last
, delta
);
253 float d
= v3_dot(surface
, v0
);
255 if( fabsf(d
) > 0.00001f
)
257 float t
= v3_dot(delta
, surface
) / d
;
258 if( t
>= 0.0f
&& t
<= l
)
261 v3_muladds( last
, v0
, t
, local
);
262 v3_sub( gate
->co
, local
, rel
);
265 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
266 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
268 v2f xy
= { v3_dot( rel
, vside
), v3_dot( rel
, vup
) };
270 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )