#ifndef CHARACTER_H
#define CHARACTER_H
+/* TODO: -> Common.h */
+#define VG_3D
#include "vg/vg.h"
+
#include "model.h"
#include "scene.h"
#include "ik.h"
#include "rigidbody.h"
-
-SHADER_DEFINE( shader_player,
-
- /*Include*/ VERTEX_STANDARD_ATTRIBUTES
-
- "uniform mat4 uPv;"
- "uniform mat4x3 uMdl;"
- "uniform float uOpacity;"
- ""
- "out vec4 aColour;"
- "out vec2 aUv;"
- "out vec3 aNorm;"
- "out vec3 aCo;"
- "out float aOpacity;"
- ""
- "void main()"
- "{"
- "vec3 world_pos = uMdl * vec4(a_co,1.0);"
- "gl_Position = uPv * vec4(world_pos,1.0);"
-
- "aColour = a_colour;"
- "aUv = a_uv;"
- "aNorm = mat3(uMdl) * a_norm;"
- "aCo = a_co;"
- "aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;"
- "}",
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- "uniform vec4 uColour;"
- ""
- "in vec4 aColour;"
- "in vec2 aUv;"
- "in vec3 aNorm;"
- "in vec3 aCo;"
- "in float aOpacity;"
- ""
- "void main()"
- "{"
- "vec3 diffuse = texture( uTexMain, aUv ).rgb;"
- "FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);"
- "}"
- ,
- UNIFORMS({ "uTexMain", "uPv", "uMdl", "uOpacity" })
-)
+#include "shaders/character.h"
#define FOREACH_PART(FN) \
FN( foot_l ) \
static void character_draw( struct character *ch, float temp )
{
- SHADER_USE(shader_player);
- glUniformMatrix4fv( SHADER_UNIFORM( shader_player, "uPv" ),
- 1, GL_FALSE, (float *)vg_pv );
-
- glUniform1i( SHADER_UNIFORM( shader_player, "uTexMain" ), 0 );
- glUniform1f( SHADER_UNIFORM( shader_player, "uOpacity" ), temp );
+ shader_character_use();
- GLint kuMdl = SHADER_UNIFORM( shader_player, "uMdl" );
+ shader_character_uPv( vg_pv );
+ shader_character_uTexMain( 0 );
+ shader_character_uOpacity( temp );
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
for( int i=4; i<PART_COUNT; i++ )
{
- glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i] );
+ shader_character_uMdl( ch->matrices[i] );
submodel_draw( &ch->parts[i] );
}
{
if( ch->shoes[i] )
{
- glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i] );
+ shader_character_uMdl( ch->matrices[i] );
submodel_draw( &ch->parts[i] );
}
else
{
- glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i+2] );
+ shader_character_uMdl( ch->matrices[i+2] );
submodel_draw( &ch->parts[i] );
- glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i] );
+ shader_character_uMdl( ch->matrices[i] );
submodel_draw( &ch->parts[i+2] );
}
}
}
-static void character_shader_register(void)
+static void character_register(void)
{
- SHADER_INIT(shader_player);
+ shader_character_register();
}
#ifndef GATE_H
#define GATE_H
+#define VG_3D
#include "vg/vg.h"
-
-static const float k_gatesize = 4.0f;
-
-SHADER_DEFINE( shader_gate,
- "layout (location=0) in vec3 a_co;"
- "uniform mat4 uPv;"
- "uniform mat4x3 uMdl;"
- ""
- "void main()"
- "{"
- "gl_Position = uPv * vec4(uMdl * vec4( a_co, 1.0 ),1.0);"
- "}",
-
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- "uniform vec2 uInvRes;"
- ""
- "void main()"
- "{"
- "vec2 uv = gl_FragCoord.xy*uInvRes;"
- "FragColor = texture( uTexMain, uv );"
- "}"
- ,
- UNIFORMS({ "uPv", "uMdl", "uTexMain", "uInvRes" })
-)
+#include "model.h"
+#include "render.h"
+#include "shaders/gate.h"
typedef struct teleport_gate teleport_gate;
static struct
{
GLuint fb, rgb, rb, vao, vbo;
+ glmesh mdl;
}
grender;
{
v3f co;
v4f q;
+ v2f dims;
m4x3f to_world, to_local;
teleport_gate *other;
static void gate_register(void)
{
- SHADER_INIT( shader_gate );
+ shader_gate_register();
}
-static void gate_init(void)
+static void gate_init( void (*newfb)(GLuint*,GLuint*,GLuint*) )
{
- glGenFramebuffers( 1, &grender.fb );
- glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
-
- glGenTextures( 1, &grender.rgb );
- glBindTexture( GL_TEXTURE_2D, grender.rgb );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y,
- 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, grender.rgb, 0);
-
- /* TODO: Check for DEPTH32f availiblity and use if possible */
-
- glGenRenderbuffers( 1, &grender.rb );
- glBindRenderbuffer( GL_RENDERBUFFER, grender.rb );
- glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
- vg_window_x, vg_window_y );
-
- glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, grender.rb );
-
+ newfb( &grender.fb, &grender.rgb, &grender.rb );
{
- float ksz = k_gatesize;
+ float ksz = 1.0f;
float quad[] = { -ksz,-ksz,0.0f, ksz, ksz,0.0f, -ksz, ksz,0.0f,
-ksz,-ksz,0.0f, ksz,-ksz,0.0f, ksz, ksz,0.0f,
- -ksz,-ksz,0.0f, -ksz, ksz,0.0f, ksz, ksz,0.0f,
- -ksz,-ksz,0.0f, ksz, ksz,0.0f, ksz,-ksz,0.0f };
+ -ksz,-ksz,-0.1f, ksz, ksz,-0.1f, -ksz, ksz,-0.1f,
+ -ksz,-ksz,-0.1f, ksz,-ksz,-0.1f, ksz, ksz,-0.1f };
glGenVertexArrays( 1, &grender.vao );
glGenBuffers( 1, &grender.vbo );
glEnableVertexAttribArray( 0 );
VG_CHECK_GL();
}
-}
-static void render_world(m4x4f pv);
+ model *mgate = vg_asset_read( "models/rs_gate.mdl" );
+ model_unpack( mgate, &grender.mdl );
+ free( mgate );
+}
-/*
- * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
- */
-static void plane_clip_projection( m4x4f mat, v4f plane )
+static void gate_fb_resize( void (*resize)(GLuint*,GLuint*,GLuint*) )
{
- v4f c =
- {
- (vg_signf(plane[0]) + mat[2][0]) / mat[0][0],
- (vg_signf(plane[1]) + mat[2][1]) / mat[1][1],
- -1.0f,
- (1.0f + mat[2][2]) / mat[3][2]
- };
-
- v4_muls( plane, 2.0f / v4_dot(plane,c), c );
-
- mat[0][2] = c[0];
- mat[1][2] = c[1];
- mat[2][2] = c[2] + 1.0f;
- mat[3][2] = c[3];
+ resize( &grender.fb, &grender.rgb, &grender.rb );
}
-static void render_gate( teleport_gate *gate, m4x3f camera, float fov )
+static void render_gate( teleport_gate *gate, m4x3f camera )
{
- m4x3f transport;
+ v3f viewpos, viewdir, gatedir;
+ v3_copy( camera[3], viewpos );
+ m3x3_mulv( camera, (v3f){0.0f,0.0f,-1.0f}, viewdir );
+ m3x3_mulv( gate->to_world, (v3f){0.0f,0.0f,-1.0f}, gatedir );
+
+ if( v3_dot(viewdir, gatedir) <= 0.0f )
+ return;
+
+ v3f v0;
+ v3_sub( viewpos, gate->co, v0 );
+ if( v3_dot(v0, gatedir) >= 0.0f )
+ return;
+ m4x3f transport;
m4x3_mul( gate->other->to_world, gate->to_local, transport );
v3f a,b,c,d;
-
- float ksz = k_gatesize;
- m4x3_mulv( gate->to_world, (v3f){-ksz,-ksz,0.0f}, a );
- m4x3_mulv( gate->to_world, (v3f){ ksz,-ksz,0.0f}, b );
- m4x3_mulv( gate->to_world, (v3f){ ksz, ksz,0.0f}, c );
- m4x3_mulv( gate->to_world, (v3f){-ksz, ksz,0.0f}, d );
+
+ float sx = gate->dims[0],
+ sy = gate->dims[1];
+ m4x3_mulv( gate->to_world, (v3f){-sx,-sy,0.0f}, a );
+ m4x3_mulv( gate->to_world, (v3f){ sx,-sy,0.0f}, b );
+ m4x3_mulv( gate->to_world, (v3f){ sx, sy,0.0f}, c );
+ m4x3_mulv( gate->to_world, (v3f){-sx, sy,0.0f}, d );
vg_line( a,b, 0xffffa000 );
vg_line( b,c, 0xffffa000 );
vg_line_pt3( cam_new[3], 0.3f, 0xff00ff00 );
glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
- glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
+ glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-
m4x3f inverse;
m4x3_invert_affine( cam_new, inverse );
m4x4f projection;
m4x4_projection( projection,
- fov,
+ gpipeline.fov,
(float)vg_window_x / (float)vg_window_y,
- 0.01f, 900.0f );
+ 0.1f, 900.0f );
#if 0 /* For debugging frustum */
{
m4x4_mul( projection, view, projection );
render_world( projection );
+ render_water_texture( cam_new );
+ glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
+ render_water_surface( projection );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- SHADER_USE( shader_gate );
+ shader_gate_use();
+
+ m4x3f full;
+ m4x3_copy( gate->to_world, full );
+ m4x3_scalev( full, (v3f){ gate->dims[0], gate->dims[1], 1.0f } );
- glUniformMatrix4fv( SHADER_UNIFORM( shader_gate, "uPv" ),
- 1, GL_FALSE, (float *)vg_pv );
- glUniformMatrix4x3fv( SHADER_UNIFORM( shader_gate, "uMdl" ),
- 1, GL_FALSE, (float *)gate->to_world );
+ shader_gate_uPv( vg_pv );
+ shader_gate_uMdl( full );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, grender.rgb );
- glUniform1i( SHADER_UNIFORM( shader_gate, "uTexMain"), 0 );
- glUniform2f( SHADER_UNIFORM( shader_gate, "uInvRes"),
+ shader_gate_uCam( viewpos );
+ shader_gate_uTexMain( 0 );
+ shader_gate_uTexWater( 1 );
+ shader_gate_uTime( vg_time*0.25f );
+ shader_gate_uInvRes( (v2f){
1.0f / (float)vg_window_x,
- 1.0f / (float)vg_window_y );
+ 1.0f / (float)vg_window_y });
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
+ mesh_bind( &grender.mdl );
+ mesh_draw( &grender.mdl );
+ glDisable(GL_BLEND);
+ return;
glBindVertexArray( grender.vao );
glDrawArrays( GL_TRIANGLES, 0, 12 );
}
v2f xy = { v3_dot( rel, vside ), v3_dot( rel, vup ) };
- if( fabsf(xy[0]) <= k_gatesize && fabsf(xy[1]) <= k_gatesize )
+ if( fabsf(xy[0]) <= gate->dims[0] && fabsf(xy[1]) <= gate->dims[1] )
{
return 1;
}
.flags = VG_TEXTURE_CLAMP };
vg_tex2d tex_cement = { .path = "textures/cement512.qoi" };
vg_tex2d tex_pallet = { .path = "textures/ch_gradient.qoi" };
-
-vg_tex2d *texture_list[] =
-{
- &tex_norwey,
- &tex_gradients,
- &tex_grid,
- &tex_sky,
- &tex_cement,
- &tex_pallet
-};
-
-SHADER_DEFINE( shader_blit,
- "layout (location=0) in vec2 a_co;"
- "out vec2 aUv;"
- ""
- "void main()"
- "{"
- "gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);"
- "aUv = a_co;"
- "}",
-
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- ""
- "in vec2 aUv;"
- ""
- "void main()"
- "{"
- "FragColor = texture( uTexMain, aUv );"
- "}"
- ,
- UNIFORMS({ "uTexMain" })
-)
+vg_tex2d tex_water = { .path = "textures/water.qoi" };
/* Convars */
static int freecam = 0;
#include "terrain.h"
#include "ragdoll.h"
#include "rigidbody.h"
+#include "render.h"
#include "gate.h"
+#include "water.h"
+
+#include "shaders/blit.h"
+#include "shaders/standard.h"
+#include "shaders/unlit.h"
+
+void vg_register(void)
+{
+ shader_blit_register();
+ shader_standard_register();
+ shader_unlit_register();
+
+ terrain_register();
+ character_register();
+ water_register();
+ gate_register();
+}
+
+vg_tex2d *texture_list[] =
+{
+ &tex_norwey,
+ &tex_gradients,
+ &tex_grid,
+ &tex_sky,
+ &tex_cement,
+ &tex_pallet,
+ &tex_water,
+ &tex_water_surf
+};
int main( int argc, char *argv[] )
{
static struct gplayer
{
/* Physics */
- v3f co, v, a, v_last;
+ v3f co, v, a, v_last, m, bob;
v4f rot;
float vswitch, slip, slip_last,
reverse;
{
scene geo;
submodel sm_road, sm_terrain;
+ glmesh skybox;
v3f tutorial;
}
return 1;
}
-void vg_register(void)
+static void create_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
{
- scene_register();
- gate_register();
- character_shader_register();
- SHADER_INIT( shader_blit );
+ glGenFramebuffers( 1, fb );
+ glBindFramebuffer( GL_FRAMEBUFFER, *fb );
+
+ glGenTextures( 1, rgb );
+ glBindTexture( GL_TEXTURE_2D, *rgb );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, *rgb, 0);
+
+ /* TODO: Check for DEPTH32f availiblity and use if possible */
+
+ glGenRenderbuffers( 1, rb );
+ glBindRenderbuffer( GL_RENDERBUFFER, *rb );
+ glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
+ vg_window_x, vg_window_y );
+
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, *rb );
+}
+
+static void resize_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
+{
+ glBindTexture( GL_TEXTURE_2D, *rgb );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, NULL );
+
+ glBindRenderbuffer( GL_RENDERBUFFER, *rb );
+ glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
+ vg_window_x, vg_window_y );
}
void vg_start(void)
v3_copy( gb->co, gate_b.co );
v4_copy( ga->q, gate_a.q );
v4_copy( gb->q, gate_b.q );
+ v2_copy( ga->s, gate_a.dims );
+ v2_copy( gb->s, gate_b.dims );
+
gate_a.other = &gate_b;
gate_b.other = &gate_a;
gate_transform_update( &gate_b );
}
+ /* WATER DEV */
+ {
+ glmesh surf;
+ submodel *sm = submodel_get(mworld,"mp_dev_water");
+ model_unpack_submodel( mworld, &surf, sm );
+
+ water_init( create_renderbuffer_std );
+ water_set_surface( &surf, sm->pivot[1] );
+ }
+ {
+ model *msky = vg_asset_read("models/rs_skydome.mdl");
+ model_unpack( msky, &world.skybox );
+ free(msky);
+ }
+
free( mworld );
scene_upload( &world.geo );
bvh_create( &world.geo );
- reset_player( 0, NULL );
+ reset_player( 1, (const char *[]){ "tutorial" } );
player_transform_update();
/* Create framebuffers */
GL_TEXTURE_2D,
render.rgb_background, 0);
- gate_init();
+ gate_init( create_renderbuffer_std );
{
float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
m3x3_mulv( player.to_local, player.v, vel );
/* Calculate local forces */
+
+ if( fabsf(vel[2]) > 0.01f )
+ slip = fabsf(-vel[0] / vel[2]) * vg_signf(vel[0]);
- slip = fabsf(-vel[0] / vel[2]) * vg_signf(vel[0]);
if( fabsf( slip ) > 1.2f )
slip = vg_signf( slip ) * 1.2f;
player.slip = slip;
q_axis_angle( rotate, vup, siY );
q_mul( rotate, player.rot, player.rot );
- player.look_dir[0] = atan2f( player.v[0], -player.v[2] );
- player.look_dir[1] = atan2f( -player.v[1], sqrtf(player.v[0]*player.v[0]+
- player.v[2]*player.v[2]) ) * 0.3f;
-
player.iY = 0.0f; /* temp */
/* GATE COLLISION */
m4x3_mulv( transport, player.co, player.co );
m3x3_mulv( transport, player.v, player.v );
m3x3_mulv( transport, player.v_last, player.v_last );
+ m3x3_mulv( transport, player.m, player.m );
+ m3x3_mulv( transport, player.bob, player.bob );
v4f transport_rotation;
m3x3_q( transport, transport_rotation );
/* Camera and character */
player_transform_update();
- q_normalize(player.rot);
player_animate();
+
+ player.look_dir[0] = atan2f( player.v[0], -player.v[2] );
+ player.look_dir[1] = atan2f( -player.v[1], sqrtf(player.v[0]*player.v[0]+
+ player.v[2]*player.v[2]) ) * 0.3f;
}
void vg_update(void)
static void player_animate(void)
{
/* Camera position */
- static v3f momentum, bob;
-
v3_sub( player.v, player.v_last, player.a );
v3_copy( player.v, player.v_last );
- v3_add( momentum, player.a, momentum );
- v3_lerp( momentum, (v3f){0.0f,0.0f,0.0f}, 0.1f, momentum );
+ v3_add( player.m, player.a, player.m );
+ v3_lerp( player.m, (v3f){0.0f,0.0f,0.0f}, 0.1f, player.m );
v3f target;
- momentum[0] = vg_clampf( momentum[0], -2.0f, 2.0f );
- momentum[1] = vg_clampf( momentum[1], -0.2f, 5.0f );
- momentum[2] = vg_clampf( momentum[2], -2.0f, 2.0f );
- v3_copy( momentum, target );
- v3_lerp( bob, target, 0.2f, bob );
+ player.m[0] = vg_clampf( player.m[0], -2.0f, 2.0f );
+ player.m[1] = vg_clampf( player.m[1], -0.2f, 5.0f );
+ player.m[2] = vg_clampf( player.m[2], -2.0f, 2.0f );
+ v3_copy( player.m, target );
+ v3_lerp( player.bob, target, 0.2f, player.bob );
/* Head */
float lslip = fabsf(player.slip); //vg_minf( 0.4f, slip );
head[2] = 0.0f;
v3f offset;
- m3x3_mulv( player.to_local, bob, offset );
+ m3x3_mulv( player.to_local, player.bob, offset );
offset[0] *= 0.3333f;
offset[1] *= -0.25f;
glBindTexture( GL_TEXTURE_2D, render.rgb_background );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL );
+
+ gate_fb_resize( resize_renderbuffer_std );
+ water_fb_resize( resize_renderbuffer_std );
}
static void render_world( m4x4f projection )
{
- SHADER_USE(shader_standard_lit);
-
m4x3f identity_matrix;
m4x3_identity( identity_matrix );
- glUniformMatrix4fv( SHADER_UNIFORM( shader_standard_lit, "uPv" ),
- 1, GL_FALSE, (float *)projection );
- glUniformMatrix4x3fv( SHADER_UNIFORM( shader_standard_lit, "uMdl" ),
- 1, GL_FALSE, (float *)identity_matrix );
+ shader_unlit_use();
+ shader_unlit_uPv( projection );
+ shader_unlit_uTexMain( 0 );
+ vg_tex2d_bind( &tex_sky, 0 );
+
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+
+ mesh_bind( &world.skybox );
+ mesh_draw( &world.skybox );
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+
+
+ shader_standard_use();
+ shader_standard_uPv( projection );
+ shader_standard_uMdl( identity_matrix );
vg_tex2d_bind( &tex_grid, 0 );
- glUniform1i( SHADER_UNIFORM( shader_standard_lit, "uTexMain" ), 0 );
- glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"),
- 0.4f,0.4f,0.4f,1.0f );
+ shader_standard_uTexMain( 0 );
+ shader_standard_uColour( (v4f){0.4f,0.4f,0.4f,1.0f} );
scene_bind( &world.geo );
scene_draw( &world.geo );
glViewport( 0,0, vg_window_x, vg_window_y );
glDisable( GL_DEPTH_TEST );
- glClearColor( 0.1f, 0.0f, 0.2f, 1.0f );
- glClearColor(111.0f/255.0f, 46.0f/255.0f, 45.0f/255.0f,1.0f);
-
- glClearColor( powf(0.066f,1.0f/2.2f),
- powf(0.050f,1.0f/2.2f),
- powf(0.046f,1.0f/2.2f), 1.0f );
+ glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
v3f pos_inv;
m4x4f world_4x4;
m4x3_expand( world_matrix, world_4x4 );
- float fov = freecam? 60.0f: 120.0f;
- m4x4_projection( vg_pv, fov, (float)vg_window_x / (float)vg_window_y,
- 0.01f, 1000.0f );
+ gpipeline.fov = freecam? 60.0f: 120.0f;
+ m4x4_projection( vg_pv, gpipeline.fov,
+ (float)vg_window_x / (float)vg_window_y,
+ 0.1f, 1000.0f );
m4x4_mul( vg_pv, world_4x4, vg_pv );
/*
* Draw world
*/
- SHADER_USE(shader_standard_lit);
-
- m4x3f identity_matrix;
- m4x3_identity( identity_matrix );
-
- glUniformMatrix4fv( SHADER_UNIFORM( shader_standard_lit, "uPv" ),
- 1, GL_FALSE, (float *)vg_pv );
- glUniformMatrix4x3fv( SHADER_UNIFORM( shader_standard_lit, "uMdl" ),
- 1, GL_FALSE, (float *)identity_matrix );
-
- vg_tex2d_bind( &tex_grid, 0 );
- glUniform1i( SHADER_UNIFORM( shader_standard_lit, "uTexMain" ), 0 );
-
- glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"),
- 0.4f,0.4f,0.4f,1.0f );
-
- scene_bind( &world.geo );
- scene_draw( &world.geo );
-
-#if 0
- if( !replay_record )
- {
- m4x3f *base = &replay_buffer[(PART_COUNT)*replay_buffer_frame];
-
- for( int i=0; i<PART_COUNT; i++ )
- m4x3_copy( base[i], player.mdl.matrices[i] );
-
- replay_buffer_frame ++;
-
- if( replay_buffer_frame == REPLAY_LENGTH )
- replay_buffer_frame = 0;
-
- vg_tex2d_bind( &tex_pallet, 0 );
- character_draw( &player.mdl, 0.0f );
- player_animate();
- }
-#endif
m4x3f cam_transform;
m4x3_invert_affine( world_matrix, cam_transform );
- render_gate( &gate_a, cam_transform, fov );
+ render_world( vg_pv );
+ render_water_texture( cam_transform );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ render_water_surface( vg_pv );
+
+ vg_tex2d_bind( &tex_water, 1 );
+ render_gate( &gate_a, cam_transform );
/* Copy the RGB of what we have into the background buffer */
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
glBlendEquation(GL_FUNC_ADD);
- SHADER_USE( shader_blit );
-
- glUniform1i( SHADER_UNIFORM(shader_blit,"uTexMain"), 0 );
+ shader_blit_use();
+ shader_blit_uTexMain( 0 );
glActiveTexture(GL_TEXTURE0);
glBindTexture( GL_TEXTURE_2D, render.rgb_background );
m4x4_projection( vg_pv,
100.0f,
(float)128.0f / (float)128.0f,
- 0.01f, 1000.0f );
+ 0.1f, 1000.0f );
m4x4_mul( vg_pv, world_4x4, vg_pv );
if(sv_debugcam)
u32 indice_count;
};
-#define VERTEX_STANDARD_ATTRIBUTES \
- "layout (location=0) in vec3 a_co;" \
- "layout (location=1) in vec3 a_norm;" \
- "layout (location=2) in vec4 a_colour;" \
- "layout (location=3) in vec2 a_uv;"
-
static void mesh_upload( glmesh *mesh,
model_vert *verts, u32 vert_count,
u32 *indices, u32 indice_count )
mesh_drawn( sm->indice_start, sm->indice_count );
}
+static void model_unpack_submodel( model *model, glmesh *mesh, submodel *sm )
+{
+ mesh_upload( mesh,
+ model_vertex_base( model ) + sm->vertex_start, sm->vertex_count,
+ model_indice_base( model ) + sm->indice_start, sm->indice_count );
+}
+
static void model_unpack( model *model, glmesh *mesh )
{
u32 offset = model_get_submodel( model, 0 )->vertex_count;
--- /dev/null
+#ifndef RENDER_H
+#define RENDER_H
+#define VG_3D
+#include "vg/vg.h"
+
+static struct pipeline
+{
+ float fov;
+}
+gpipeline;
+
+static void render_water_texture( m4x3f camera );
+static void render_water_surface( m4x4f pv );
+static void render_world( m4x4f pv );
+
+/*
+ * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
+ */
+static void plane_clip_projection( m4x4f mat, v4f plane )
+{
+ v4f c =
+ {
+ (vg_signf(plane[0]) + mat[2][0]) / mat[0][0],
+ (vg_signf(plane[1]) + mat[2][1]) / mat[1][1],
+ -1.0f,
+ (1.0f + mat[2][2]) / mat[3][2]
+ };
+
+ v4_muls( plane, 2.0f / v4_dot(plane,c), c );
+
+ mat[0][2] = c[0];
+ mat[1][2] = c[1];
+ mat[2][2] = c[2] + 1.0f;
+ mat[3][2] = c[3];
+}
+
+#endif /* RENDER_H */
}
}
-/* https://www.shadertoy.com/view/4sfGzS */
-#define SHADER_VALUE_NOISE_3D \
-"uniform sampler2D uTexNoise;" \
-"" \
-"float noise( vec3 x )" \
-"{" \
- "vec3 i = floor(x);" \
- "vec3 f = fract(x);" \
- "f = f*f*(3.0-2.0*f);" \
- "vec2 uv = (i.xy+vec2(37.0,17.0)*i.z) + f.xy;" \
- "vec2 rg = texture( uTexNoise, (uv+0.5)/256.0).yx;"\
- "return mix( rg.x, rg.y, f.z );" \
-"}" \
-"" \
-"const mat3 m = mat3( 0.00, 0.80, 0.60," \
- "-0.80, 0.36, -0.48," \
- "-0.60, -0.48, 0.64 );" \
-"" \
-"float fractalNoise( vec3 x )" \
-"{" \
- "vec3 q = 8.0*x;" \
- "float f;" \
- "f = 0.5000*noise( q ); q = m*q*2.01;" \
- "f += 0.2500*noise( q ); q = m*q*2.02;" \
- "f += 0.1250*noise( q ); q = m*q*2.03;" \
- "f += 0.0625*noise( q ); q = m*q*2.01;" \
- "return f;" \
-"}"
-
-SHADER_DEFINE( shader_debug_vcol,
-
- /*Include*/ VERTEX_STANDARD_ATTRIBUTES
-
- "uniform mat4 uPv;"
- "uniform mat4x3 uMdl;"
- "uniform float uTime;"
- "uniform float uSwayAmt;"
- ""
- "out vec4 aColour;"
- "out vec2 aUv;"
- "out vec3 aNorm;"
- "out vec3 aCo;"
- ""
- "vec3 compute_sway( vec3 pos )"
- "{"
- "vec4 sines = vec4( sin(uTime + pos.x)*1.0,"
- "sin(uTime*1.2 + pos.z*2.0)*1.1,"
- "sin(uTime*2.33)*0.5,"
- "sin(uTime*0.6 + pos.x*0.3)*1.3 );"
-
- "vec3 offset = vec3( sines.x+sines.y*sines.w, 0.0, sines.x+sines.z );"
- "return pos + offset*a_colour.r*uSwayAmt;"
- "}"
- ""
- "void main()"
- "{"
- "vec3 swaypos = compute_sway( a_co );"
- "gl_Position = uPv * vec4(uMdl * vec4(swaypos,1.0), 1.0 );"
- "aColour = a_colour;"
- "aUv = a_uv;"
- "aNorm = normalize(mat3(uMdl) * a_norm);"
- "aCo = a_co;"
- "}",
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform int uMode;"
- "uniform sampler2D uTexMain;"
- "uniform sampler2D uTexGradients;"
- ""
- /*Include*/ SHADER_VALUE_NOISE_3D
- ""
- "in vec4 aColour;"
- "in vec2 aUv;"
- "in vec3 aNorm;"
- "in vec3 aCo;"
- ""
- "void main()"
- "{"
- "vec4 colour = vec4(1.0,0.0,0.5,1.0);"
- "vec4 diffuse = texture( uTexMain, aUv );"
-
- "if( uMode == 1 )"
- "{"
- "colour = vec4(aNorm * 0.5 + 0.5, 1.0);"
- "}"
- "if( uMode == 2 )"
- "{"
- "colour = aColour;"
- "}"
- "if( uMode == 3 )"
- "{"
- "float light = dot(aNorm, vec3(0.2,0.8,0.1));"
- "vec3 grid3 = fract(aCo);"
-
- "colour = vec4(vec3(light)*(1.0-grid3*0.3),1.0);"
- "}"
- "if( uMode == 4 )"
- "{"
- "colour = vec4( aUv, 0.0, 1.0 );"
- "}"
- "if( uMode == 5 )"
- "{"
- "if( diffuse.a < 0.45 ) discard;"
- "colour = diffuse;"
- "}"
- "if( uMode == 6 )"
- "{"
- "float r1 = fractalNoise(aCo);"
- "colour = vec4( vec3(r1), 1.0 );"
- "}"
- "if( uMode == 7 )"
- "{"
- "if( diffuse.a < 0.2 ) discard;"
- "float lighting = 1.0 - aColour.g*0.8;"
-
- "float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));"
- "float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));"
- "vec3 lt = vec3(0.2,0.2,0.2 ) + "
- "vec3(1.0,1.0,0.9)*light1 + "
- "vec3(0.1,0.3,0.4 )*light2;"
-
-
- "colour = vec4(vec3(pow(lighting,1.6)*(diffuse.r*0.7+0.5)),1.0);"
- "colour = vec4(colour.rgb*lt,1.0);"
-
- "vec2 gradUV = vec2(lighting*1.9,aColour.b*0.8);"
- "vec4 gradient_sample = texture( uTexGradients, gradUV );"
- "colour = colour*gradient_sample;"
- "}"
- "if( uMode == 8 )"
- "{"
- "if( diffuse.a < 0.45 ) discard;"
- "float light = 1.0 - aColour.g;"
- "light = pow(light,1.6)*(diffuse.r*0.7+0.5);"
- "float r1 = fractalNoise(aCo*0.01);"
-
- "vec2 gradUV = vec2(light*1.9,r1+aColour.b);"
- "vec4 gradient_sample = texture( uTexGradients, gradUV );"
- "colour = gradient_sample*light;"
- "}"
-
- "FragColor = colour;"
- "}"
- ,
- UNIFORMS({ "uPv", "uMode", "uTexMain", "uTexGradients", "uTexNoise", \
- "uTime", "uSwayAmt", "uMdl" })
-)
-
-SHADER_DEFINE( shader_standard_lit,
-
- /*Include*/ VERTEX_STANDARD_ATTRIBUTES
-
- "uniform mat4 uPv;"
- "uniform mat4x3 uMdl;"
- ""
- "out vec4 aColour;"
- "out vec2 aUv;"
- "out vec3 aNorm;"
- "out vec3 aCo;"
- ""
- "void main()"
- "{"
- "gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );"
- "aColour = a_colour;"
- "aUv = a_uv;"
- "aNorm = mat3(uMdl) * a_norm;"
- "aCo = a_co;"
- "}",
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- "uniform vec4 uColour;"
- ""
- "in vec4 aColour;"
- "in vec2 aUv;"
- "in vec3 aNorm;"
- "in vec3 aCo;"
- ""
- "void main()"
- "{"
- "vec3 diffuse = texture( uTexMain, aUv ).rgb;"
-
- "float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));"
- "float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));"
- "diffuse += vec3(0.2,0.2,0.2) + "
- "vec3(1.0,1.0,0.9)*light1 + "
- "vec3(0.1,0.3,0.4)*light2;"
-
- "FragColor = vec4(diffuse*uColour.rgb, aColour.a*uColour.a);"
- "}"
- ,
- UNIFORMS({ "uColour","uTexMain","uPv","uMdl" })
-)
-
-SHADER_DEFINE( shader_unlit,
-
- /*Include*/ VERTEX_STANDARD_ATTRIBUTES
-
- "uniform mat4 uPv;"
- "uniform mat4x3 uMdl;"
- ""
- "out vec4 aColour;"
- "out vec2 aUv;"
- "out vec3 aNorm;"
- "out vec3 aCo;"
- ""
- "void main()"
- "{"
- "gl_Position = uPv * vec4(uMdl * vec4(a_co,1.0), 1.0);"
- "aColour = a_colour;"
- "aUv = a_uv;"
- "aNorm = mat3(uMdl) * a_norm;"
- "aCo = a_co;"
- "}",
- /* Fragment */
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- "uniform vec4 uColour;"
- ""
- "in vec4 aColour;"
- "in vec2 aUv;"
- "in vec3 aNorm;"
- "in vec3 aCo;"
- ""
- "void main()"
- "{"
- "vec3 diffuse = texture( uTexMain, aUv ).rgb;"
- "FragColor = vec4(pow(diffuse,vec3(1.0)),1.0);"
- "}"
- ,
- UNIFORMS({ "uTexMain", "uPv", "uMdl" })
-)
-
static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount,
size_t emsize )
{
static void scene_register(void)
{
- SHADER_INIT( shader_debug_vcol );
- SHADER_INIT( shader_standard_lit );
- SHADER_INIT( shader_unlit );
}
--- /dev/null
+out vec4 FragColor;
+uniform sampler2D uTexMain;
+
+in vec2 aUv;
+
+void main()
+{
+ FragColor = texture( uTexMain, aUv );
+}
--- /dev/null
+#ifndef SHADER_blit_H
+#define SHADER_blit_H
+static void shader_blit_link(void);
+static void shader_blit_register(void);
+static struct vg_shader _shader_blit = {
+ .name = "blit",
+ .link = shader_blit_link,
+ .vs =
+{
+.orig_file = "../shaders/blit.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+" aUv = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/blit.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"uniform sampler2D uTexMain;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+" FragColor = texture( uTexMain, aUv );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_blit_uTexMain;
+static void shader_blit_uTexMain(int i){
+ glUniform1i( _uniform_blit_uTexMain, i );
+}
+static void shader_blit_register(void){
+ vg_shader_register( &_shader_blit );
+}
+static void shader_blit_use(void){ glUseProgram(_shader_blit.id); }
+static void shader_blit_link(void){
+ _uniform_blit_uTexMain = glGetUniformLocation( _shader_blit.id, "uTexMain" );
+}
+#endif /* SHADER_blit_H */
--- /dev/null
+layout (location=0) in vec2 a_co;
+out vec2 aUv;
+
+void main()
+{
+ gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);
+ aUv = a_co;
+}
--- /dev/null
+out vec4 FragColor;
+
+uniform sampler2D uTexMain;
+uniform vec4 uColour;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+in vec3 aCo;
+in float aOpacity;
+
+void main()
+{
+ vec3 diffuse = texture( uTexMain, aUv ).rgb;
+ FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);
+}
--- /dev/null
+#ifndef SHADER_character_H
+#define SHADER_character_H
+static void shader_character_link(void);
+static void shader_character_register(void);
+static struct vg_shader _shader_character = {
+ .name = "character",
+ .link = shader_character_link,
+ .vs =
+{
+.orig_file = "../shaders/character.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"uniform float uOpacity;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out float aOpacity;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
+" gl_Position = uPv * vec4(world_pos,1.0);\n"
+"\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = mat3(uMdl) * a_norm;\n"
+" aCo = a_co;\n"
+" aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/character.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in float aOpacity;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_character_uPv;
+static GLuint _uniform_character_uMdl;
+static GLuint _uniform_character_uOpacity;
+static GLuint _uniform_character_uTexMain;
+static GLuint _uniform_character_uColour;
+static void shader_character_uPv(m4x4f m){
+ glUniformMatrix4fv( _uniform_character_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_character_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_character_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_character_uOpacity(float f){
+ glUniform1f( _uniform_character_uOpacity, f );
+}
+static void shader_character_uTexMain(int i){
+ glUniform1i( _uniform_character_uTexMain, i );
+}
+static void shader_character_uColour(v4f v){
+ glUniform4fv( _uniform_character_uColour, 1, v );
+}
+static void shader_character_register(void){
+ vg_shader_register( &_shader_character );
+}
+static void shader_character_use(void){ glUseProgram(_shader_character.id); }
+static void shader_character_link(void){
+ _uniform_character_uPv = glGetUniformLocation( _shader_character.id, "uPv" );
+ _uniform_character_uMdl = glGetUniformLocation( _shader_character.id, "uMdl" );
+ _uniform_character_uOpacity = glGetUniformLocation( _shader_character.id, "uOpacity" );
+ _uniform_character_uTexMain = glGetUniformLocation( _shader_character.id, "uTexMain" );
+ _uniform_character_uColour = glGetUniformLocation( _shader_character.id, "uColour" );
+}
+#endif /* SHADER_character_H */
--- /dev/null
+#include "vertex_standard.glsl"
+
+uniform mat4 uPv;
+uniform mat4x3 uMdl;
+uniform float uOpacity;
+
+out vec4 aColour;
+out vec2 aUv;
+out vec3 aNorm;
+out vec3 aCo;
+out float aOpacity;
+
+void main()
+{
+ vec3 world_pos = uMdl * vec4(a_co,1.0);
+ gl_Position = uPv * vec4(world_pos,1.0);
+
+ aColour = a_colour;
+ aUv = a_uv;
+ aNorm = mat3(uMdl) * a_norm;
+ aCo = a_co;
+ aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;
+}
--- /dev/null
+out vec4 FragColor;
+
+uniform sampler2D uTexMain;
+uniform sampler2D uTexWater;
+uniform vec2 uInvRes;
+uniform float uTime;
+uniform vec3 uCam;
+
+in vec3 aNorm;
+in vec2 aUv;
+in vec3 aCo;
+
+void main()
+{
+ vec2 ssuv = gl_FragCoord.xy*uInvRes;
+ vec4 mapwater = texture( uTexWater, vec2(aUv.x,aUv.y-uTime));
+
+ float undistort = smoothstep(0.1,0.6,distance( uCam, aCo )*0.1);
+ vec2 trimedge = smoothstep(0.0,0.2,1.0-abs(ssuv-0.5)*2.0);
+ undistort *= trimedge.x * trimedge.y;
+
+ vec2 warpamt = (mapwater.rg-0.5)*0.05*aUv.y*undistort;
+ vec4 mapbackbuffer = texture( uTexMain, ssuv + warpamt );
+
+ float opacity = 1.0-smoothstep(0.4,1.0,aUv.y);
+ FragColor = vec4( mapbackbuffer.rgb, opacity );
+}
--- /dev/null
+#ifndef SHADER_gate_H
+#define SHADER_gate_H
+static void shader_gate_link(void);
+static void shader_gate_register(void);
+static struct vg_shader _shader_gate = {
+ .name = "gate",
+ .link = shader_gate_link,
+ .vs =
+{
+.orig_file = "../shaders/gate.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line 2 0 \n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec3 aNorm;\n"
+"out vec2 aUv;\n"
+"out vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos = uMdl * vec4( a_co, 1.0 );\n"
+" gl_Position = uPv * vec4(world_pos,1.0);\n"
+"\n"
+" aNorm = a_norm;\n"
+" aCo = world_pos;\n"
+" aUv = a_uv;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/gate.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexWater;\n"
+"uniform vec2 uInvRes;\n"
+"uniform float uTime;\n"
+"uniform vec3 uCam;\n"
+"\n"
+"in vec3 aNorm;\n"
+"in vec2 aUv;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
+" vec4 mapwater = texture( uTexWater, vec2(aUv.x,aUv.y-uTime));\n"
+"\n"
+" float undistort = smoothstep(0.1,0.6,distance( uCam, aCo )*0.1);\n"
+" vec2 trimedge = smoothstep(0.0,0.2,1.0-abs(ssuv-0.5)*2.0);\n"
+" undistort *= trimedge.x * trimedge.y;\n"
+"\n"
+" vec2 warpamt = (mapwater.rg-0.5)*0.05*aUv.y*undistort;\n"
+" vec4 mapbackbuffer = texture( uTexMain, ssuv + warpamt );\n"
+"\n"
+" float opacity = 1.0-smoothstep(0.4,1.0,aUv.y);\n"
+" FragColor = vec4( mapbackbuffer.rgb, opacity );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_gate_uPv;
+static GLuint _uniform_gate_uMdl;
+static GLuint _uniform_gate_uTexMain;
+static GLuint _uniform_gate_uTexWater;
+static GLuint _uniform_gate_uInvRes;
+static GLuint _uniform_gate_uTime;
+static GLuint _uniform_gate_uCam;
+static void shader_gate_uPv(m4x4f m){
+ glUniformMatrix4fv( _uniform_gate_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_gate_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_gate_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_gate_uTexMain(int i){
+ glUniform1i( _uniform_gate_uTexMain, i );
+}
+static void shader_gate_uTexWater(int i){
+ glUniform1i( _uniform_gate_uTexWater, i );
+}
+static void shader_gate_uInvRes(v2f v){
+ glUniform2fv( _uniform_gate_uInvRes, 1, v );
+}
+static void shader_gate_uTime(float f){
+ glUniform1f( _uniform_gate_uTime, f );
+}
+static void shader_gate_uCam(v3f v){
+ glUniform3fv( _uniform_gate_uCam, 1, v );
+}
+static void shader_gate_register(void){
+ vg_shader_register( &_shader_gate );
+}
+static void shader_gate_use(void){ glUseProgram(_shader_gate.id); }
+static void shader_gate_link(void){
+ _uniform_gate_uPv = glGetUniformLocation( _shader_gate.id, "uPv" );
+ _uniform_gate_uMdl = glGetUniformLocation( _shader_gate.id, "uMdl" );
+ _uniform_gate_uTexMain = glGetUniformLocation( _shader_gate.id, "uTexMain" );
+ _uniform_gate_uTexWater = glGetUniformLocation( _shader_gate.id, "uTexWater" );
+ _uniform_gate_uInvRes = glGetUniformLocation( _shader_gate.id, "uInvRes" );
+ _uniform_gate_uTime = glGetUniformLocation( _shader_gate.id, "uTime" );
+ _uniform_gate_uCam = glGetUniformLocation( _shader_gate.id, "uCam" );
+}
+#endif /* SHADER_gate_H */
--- /dev/null
+#include "vertex_standard.glsl"
+uniform mat4 uPv;
+uniform mat4x3 uMdl;
+
+out vec3 aNorm;
+out vec2 aUv;
+out vec3 aCo;
+
+void main()
+{
+ vec3 world_pos = uMdl * vec4( a_co, 1.0 );
+ gl_Position = uPv * vec4(world_pos,1.0);
+
+ aNorm = a_norm;
+ aCo = world_pos;
+ aUv = a_uv;
+}
--- /dev/null
+out vec4 FragColor;
+
+uniform sampler2D uTexMain;
+uniform vec4 uColour;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+in vec3 aCo;
+
+void main()
+{
+ vec3 diffuse = texture( uTexMain, aUv ).rgb;
+ float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));
+ float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));
+ diffuse += vec3(0.2,0.2,0.2) +
+ vec3(1.0,1.0,0.9)*light1 +
+ vec3(0.1,0.3,0.4)*light2;
+ FragColor = vec4(diffuse*uColour.rgb, aColour.a*uColour.a);
+}
--- /dev/null
+#ifndef SHADER_standard_H
+#define SHADER_standard_H
+static void shader_standard_link(void);
+static void shader_standard_register(void);
+static struct vg_shader _shader_standard = {
+ .name = "standard",
+ .link = shader_standard_link,
+ .vs =
+{
+.orig_file = "../shaders/standard.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = mat3(uMdl) * a_norm;\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/standard.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));\n"
+" float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));\n"
+" diffuse += vec3(0.2,0.2,0.2) +\n"
+" vec3(1.0,1.0,0.9)*light1 + \n"
+" vec3(0.1,0.3,0.4)*light2;\n"
+" FragColor = vec4(diffuse*uColour.rgb, aColour.a*uColour.a);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_standard_uPv;
+static GLuint _uniform_standard_uMdl;
+static GLuint _uniform_standard_uTexMain;
+static GLuint _uniform_standard_uColour;
+static void shader_standard_uPv(m4x4f m){
+ glUniformMatrix4fv( _uniform_standard_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_standard_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_standard_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_standard_uTexMain(int i){
+ glUniform1i( _uniform_standard_uTexMain, i );
+}
+static void shader_standard_uColour(v4f v){
+ glUniform4fv( _uniform_standard_uColour, 1, v );
+}
+static void shader_standard_register(void){
+ vg_shader_register( &_shader_standard );
+}
+static void shader_standard_use(void){ glUseProgram(_shader_standard.id); }
+static void shader_standard_link(void){
+ _uniform_standard_uPv = glGetUniformLocation( _shader_standard.id, "uPv" );
+ _uniform_standard_uMdl = glGetUniformLocation( _shader_standard.id, "uMdl" );
+ _uniform_standard_uTexMain = glGetUniformLocation( _shader_standard.id, "uTexMain" );
+ _uniform_standard_uColour = glGetUniformLocation( _shader_standard.id, "uColour" );
+}
+#endif /* SHADER_standard_H */
--- /dev/null
+#include "vertex_standard.glsl"
+
+uniform mat4 uPv;
+uniform mat4x3 uMdl;
+
+out vec4 aColour;
+out vec2 aUv;
+out vec3 aNorm;
+out vec3 aCo;
+
+void main()
+{
+ gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );
+ aColour = a_colour;
+ aUv = a_uv;
+ aNorm = mat3(uMdl) * a_norm;
+ aCo = a_co;
+}
--- /dev/null
+#include "common.glsl"
+
+void main()
+{
+
+}
--- /dev/null
+#ifndef SHADER_terrain_H
+#define SHADER_terrain_H
+static void shader_terrain_link(void);
+static void shader_terrain_register(void);
+static struct vg_shader _shader_terrain = {
+ .name = "terrain",
+ .link = shader_terrain_link,
+ .vs =
+{
+.orig_file = "../shaders/terrain.vs",
+.static_src =
+"uniform mat4x3 uMdl;\n"
+"\n"
+"void main()\n"
+"{\n"
+"\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/terrain.fs",
+.static_src =
+"// Nothing\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+"\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_terrain_uMdl;
+static void shader_terrain_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_terrain_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_terrain_register(void){
+ vg_shader_register( &_shader_terrain );
+}
+static void shader_terrain_use(void){ glUseProgram(_shader_terrain.id); }
+static void shader_terrain_link(void){
+ _uniform_terrain_uMdl = glGetUniformLocation( _shader_terrain.id, "uMdl" );
+}
+#endif /* SHADER_terrain_H */
--- /dev/null
+uniform mat4x3 uMdl;
+
+void main()
+{
+
+}
--- /dev/null
+out vec4 FragColor;
+
+uniform sampler2D uTexMain;
+uniform vec4 uColour;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+in vec3 aCo;
+
+void main()
+{
+ vec3 diffuse = texture( uTexMain, aUv ).rgb;
+ FragColor = vec4(pow(diffuse,vec3(1.0)),1.0);
+}
--- /dev/null
+#ifndef SHADER_unlit_H
+#define SHADER_unlit_H
+static void shader_unlit_link(void);
+static void shader_unlit_register(void);
+static struct vg_shader _shader_unlit = {
+ .name = "unlit",
+ .link = shader_unlit_link,
+ .vs =
+{
+.orig_file = "../shaders/standard.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = mat3(uMdl) * a_norm;\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/unlit.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" FragColor = vec4(pow(diffuse,vec3(1.0)),1.0);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_unlit_uPv;
+static GLuint _uniform_unlit_uMdl;
+static GLuint _uniform_unlit_uTexMain;
+static GLuint _uniform_unlit_uColour;
+static void shader_unlit_uPv(m4x4f m){
+ glUniformMatrix4fv( _uniform_unlit_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_unlit_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_unlit_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_unlit_uTexMain(int i){
+ glUniform1i( _uniform_unlit_uTexMain, i );
+}
+static void shader_unlit_uColour(v4f v){
+ glUniform4fv( _uniform_unlit_uColour, 1, v );
+}
+static void shader_unlit_register(void){
+ vg_shader_register( &_shader_unlit );
+}
+static void shader_unlit_use(void){ glUseProgram(_shader_unlit.id); }
+static void shader_unlit_link(void){
+ _uniform_unlit_uPv = glGetUniformLocation( _shader_unlit.id, "uPv" );
+ _uniform_unlit_uMdl = glGetUniformLocation( _shader_unlit.id, "uMdl" );
+ _uniform_unlit_uTexMain = glGetUniformLocation( _shader_unlit.id, "uTexMain" );
+ _uniform_unlit_uColour = glGetUniformLocation( _shader_unlit.id, "uColour" );
+}
+#endif /* SHADER_unlit_H */
--- /dev/null
+out vec4 FragColor;
+
+uniform sampler2D uTexMain;
+uniform sampler2D uTexDudv;
+uniform vec2 uInvRes;
+uniform float uTime;
+
+in vec2 aUv;
+
+void main()
+{
+ vec2 ssuv = gl_FragCoord.xy*uInvRes;
+ vec4 dudva = texture( uTexDudv, aUv + vec2(uTime*0.04f,uTime*0.03f) );
+ vec4 dudvb = texture( uTexDudv, aUv - vec2(uTime*0.1,uTime*0.054) );
+
+ vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;
+
+ vec4 reflected = texture( uTexMain, ssuv+distortamt );
+ FragColor = vec4(reflected.rgb*0.9,reflected.a);
+}
--- /dev/null
+#ifndef SHADER_water_H
+#define SHADER_water_H
+static void shader_water_link(void);
+static void shader_water_register(void);
+static struct vg_shader _shader_water = {
+ .name = "water",
+ .link = shader_water_link,
+ .vs =
+{
+.orig_file = "../shaders/water.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos = uMdl * vec4( a_co, 1.0 );\n"
+" gl_Position = uPv * vec4(world_pos,1.0);\n"
+" aUv = vec2(world_pos[0],world_pos[2])*0.15;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "../shaders/water.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexDudv;\n"
+"uniform vec2 uInvRes;\n"
+"uniform float uTime;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
+" vec4 dudva = texture( uTexDudv, aUv + vec2(uTime*0.04f,uTime*0.03f) );\n"
+" vec4 dudvb = texture( uTexDudv, aUv - vec2(uTime*0.1,uTime*0.054) );\n"
+"\n"
+" vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;\n"
+"\n"
+" vec4 reflected = texture( uTexMain, ssuv+distortamt );\n"
+" FragColor = vec4(reflected.rgb*0.1,reflected.a);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_water_uPv;
+static GLuint _uniform_water_uMdl;
+static GLuint _uniform_water_uTexMain;
+static GLuint _uniform_water_uTexDudv;
+static GLuint _uniform_water_uInvRes;
+static GLuint _uniform_water_uTime;
+static void shader_water_uPv(m4x4f m){
+ glUniformMatrix4fv( _uniform_water_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_water_uMdl(m4x3f m){
+ glUniformMatrix4x3fv( _uniform_water_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_water_uTexMain(int i){
+ glUniform1i( _uniform_water_uTexMain, i );
+}
+static void shader_water_uTexDudv(int i){
+ glUniform1i( _uniform_water_uTexDudv, i );
+}
+static void shader_water_uInvRes(v2f v){
+ glUniform2fv( _uniform_water_uInvRes, 1, v );
+}
+static void shader_water_uTime(float f){
+ glUniform1f( _uniform_water_uTime, f );
+}
+static void shader_water_register(void){
+ vg_shader_register( &_shader_water );
+}
+static void shader_water_use(void){ glUseProgram(_shader_water.id); }
+static void shader_water_link(void){
+ _uniform_water_uPv = glGetUniformLocation( _shader_water.id, "uPv" );
+ _uniform_water_uMdl = glGetUniformLocation( _shader_water.id, "uMdl" );
+ _uniform_water_uTexMain = glGetUniformLocation( _shader_water.id, "uTexMain" );
+ _uniform_water_uTexDudv = glGetUniformLocation( _shader_water.id, "uTexDudv" );
+ _uniform_water_uInvRes = glGetUniformLocation( _shader_water.id, "uInvRes" );
+ _uniform_water_uTime = glGetUniformLocation( _shader_water.id, "uTime" );
+}
+#endif /* SHADER_water_H */
--- /dev/null
+#include "vertex_standard.glsl"
+
+uniform mat4 uPv;
+uniform mat4x3 uMdl;
+
+out vec2 aUv;
+
+void main()
+{
+ vec3 world_pos = uMdl * vec4( a_co, 1.0 );
+ gl_Position = uPv * vec4(world_pos,1.0);
+ aUv = vec2(world_pos[0],world_pos[2])*0.15;
+}
+#ifndef TERRAIN_H
+#define TERRAIN_H
+
+#define VG_3D
#include "vg/vg.h"
-#include "scene.h"
+#include "model.h"
+#include "render.h"
+
+#include "shaders/terrain.h"
+static void terrain_register(void)
+{
+ shader_terrain_register();
+}
+void test(void)
+{
+
+}
+#endif
vg_src="main.c"
vg_target="game"
+
+shader blit blit.vs blit.fs
+shader terrain terrain.vs terrain.fs
+shader standard standard.vs standard.fs
+shader unlit standard.vs unlit.fs
+shader character character.vs character.fs
+shader gate gate.vs gate.fs
+shader water water.vs water.fs
--- /dev/null
+#ifndef WATER_H
+#define WATER_H
+
+#define VG_3D
+#include "vg/vg.h"
+
+#include "model.h"
+#include "render.h"
+#include "shaders/water.h"
+
+vg_tex2d tex_water_surf = { .path = "textures/water_surf.qoi" };
+
+static struct
+{
+ GLuint fb, rgb, rb;
+ glmesh mdl;
+
+ float height;
+}
+wrender;
+
+static void water_register(void)
+{
+ shader_water_register();
+}
+
+static void water_init( void (*newfb)(GLuint*,GLuint*,GLuint*))
+{
+ newfb( &wrender.fb, &wrender.rgb, &wrender.rb );
+}
+
+static void water_set_surface( glmesh *surf, float height )
+{
+ wrender.mdl = *surf;
+ wrender.height = height;
+}
+
+static void water_fb_resize( void (*resize)(GLuint*,GLuint*,GLuint*) )
+{
+ resize( &wrender.fb, &wrender.rgb, &wrender.fb );
+}
+
+static void render_water_texture( m4x3f camera )
+{
+ /* Draw reflection buffa */
+ glBindFramebuffer( GL_FRAMEBUFFER, wrender.fb );
+ glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+
+ m4x3f new_cam, inverse;
+ v3_copy( camera[3], new_cam[3] );
+ new_cam[3][1] -= 2.0f * (camera[3][1] - wrender.height);
+
+ m3x3f flip;
+ m3x3_identity( flip );
+ flip[1][1] = -1.0f;
+ m3x3_mul( flip, camera, new_cam );
+
+
+ v3f p0;
+ m3x3_mulv( new_cam, (v3f){0.0f,0.0f,-1.0f}, p0 );
+ v3_add( new_cam[3], p0, p0 );
+ vg_line( new_cam[3], p0, 0xffffffff );
+
+ m4x4f view;
+ vg_line_pt3( new_cam[3], 0.3f, 0xff00ffff );
+
+ m4x3_invert_affine( new_cam, inverse );
+ m4x3_expand( inverse, view );
+
+ v4f clippa = { 0.0f, 1.0f, 0.0f, wrender.height-0.1f };
+ m4x3_mulp( inverse, clippa, clippa );
+ clippa[3] *= -1.0f;
+
+ m4x4f projection;
+ m4x4_projection( projection,
+ gpipeline.fov,
+ (float)vg_window_x / (float)vg_window_y,
+ 0.1f, 900.0f );
+ plane_clip_projection( projection, clippa );
+ m4x4_mul( projection, view, projection );
+
+ glCullFace( GL_FRONT );
+ render_world( projection );
+ glCullFace( GL_BACK );
+}
+
+static void render_water_surface( m4x4f pv )
+{
+ /* Draw surface */
+ shader_water_use();
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, wrender.rgb );
+ shader_water_uTexMain( 0 );
+
+ vg_tex2d_bind( &tex_water_surf, 1 );
+ shader_water_uTexDudv( 1 );
+ shader_water_uInvRes( (v2f){
+ 1.0f / (float)vg_window_x,
+ 1.0f / (float)vg_window_y });
+
+ shader_water_uTime( vg_time );
+ shader_water_uPv( pv );
+
+ m4x3f full;
+ m4x3_identity( full );
+ full[3][1] = wrender.height;
+
+ shader_water_uMdl( full );
+
+ mesh_bind( &wrender.mdl );
+ mesh_draw( &wrender.mdl );
+}
+
+#endif /* WATER_H */