#include "model.h"
#include "render.h"
#include "shaders/water.h"
+#include "scene.h"
vg_tex2d tex_water_surf = { .path = "textures/water_surf.qoi" };
GLuint fb, rgb, rb;
glmesh mdl;
+ GLuint depthmap;
+ boxf depthbounds;
+ int depth_computed;
+
float height;
}
wrender;
create_renderbuffer_std( &wrender.fb, &wrender.rgb, &wrender.rb );
}
+static int ray_world( v3f pos, v3f dir, ray_hit *hit );
+
+#ifndef VG_RELEASE
+__attribute__((minsize))
+#endif
+static void water_compute_depth( boxf bounds )
+{
+#ifdef VG_RELEASE
+ int const kres = 512;
+#else
+ int const kres = 64;
+#endif
+
+ vg_info( "Computing depth map\n" );
+ u8 *img = malloc( kres*kres );
+
+ v3f volume;
+ v3_sub( bounds[1], bounds[0], volume );
+ box_copy( bounds, wrender.depthbounds );
+
+ for( int y=0; y<kres; y++ )
+ {
+ for( int x=0; x<kres; x++ )
+ {
+ v3f pos = { x, 0, y };
+ v3_divs( pos, kres, pos );
+ v3_muladd( bounds[0], pos, volume, pos );
+ pos[1] = wrender.height;
+
+ ray_hit hit;
+ hit.dist = INFINITY;
+ u8 *dst = &img[ y*kres+x ];
+
+ if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
+ {
+ float h = wrender.height - hit.pos[1];
+ h *= 1.0f/15.0f;
+ h = vg_clampf( h, 0.0f, 1.0f );
+ *dst = (u8)(h*255.0f);
+ }
+ else
+ *dst = 0;
+ }
+ }
+
+ if( wrender.depth_computed )
+ glDeleteTextures( 1, &wrender.depthmap );
+
+ glGenTextures( 1, &wrender.depthmap );
+ glBindTexture( GL_TEXTURE_2D, wrender.depthmap );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, kres, kres, 0,
+ GL_RED, GL_UNSIGNED_BYTE, img );
+
+ vg_tex2d_mipmap();
+ vg_tex2d_linear_mipmap();
+ vg_tex2d_clamp();
+
+ wrender.depth_computed = 1;
+ free( img );
+ vg_success( "Done.\n" );
+}
+
static void water_set_surface( glmesh *surf, float height )
{
wrender.mdl = *surf;
1.0f / (float)vg_window_x,
1.0f / (float)vg_window_y });
+ glActiveTexture( GL_TEXTURE2 );
+ glBindTexture( GL_TEXTURE_2D, wrender.depthmap );
+ shader_water_uTexDepth( 2 );
+ shader_water_uDepthBounds( (v4f){
+ wrender.depthbounds[0][0],
+ wrender.depthbounds[0][2],
+ 1.0f/ (wrender.depthbounds[1][0]-wrender.depthbounds[0][0]),
+ 1.0f/ (wrender.depthbounds[1][2]-wrender.depthbounds[0][2])} );
+
shader_water_uTime( vg_time );
shader_water_uPv( pv );
shader_water_uMdl( full );
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
mesh_bind( &wrender.mdl );
mesh_draw( &wrender.mdl );
+
+ glDisable(GL_BLEND);
}
#endif /* WATER_H */