ParallaxExample() : prog(make_prog()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("TexCoord").Get(), shapes::Plane( Vec3f(), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -1.0f), 32, 32)) { shape.UseInProgram(prog); auto tex_image = images::LoadTexture("stones_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); gl.Bound(Texture::Target::_2D, color_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D(tex_image) .GenerateMipmap(); } catch(Error&) { } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); gl.Bound(Texture::Target::_2D, bump_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D( images::NormalMap(tex_image, images::NormalMap::FromAlpha())) .GenerateMipmap(); } catch(Error&) { } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); (Capability::DepthTest) << true; (Capability::CullFace) << false; (Functionality::ClipDistance | 0) << true; (Functionality::ClipDistance | 1) << true; (Functionality::ClipDistance | 2) << true; }
ParallaxMapExample() : prog(make()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("Normal")("Tangent")("TexCoord").Get(), shapes::Torus(1.0f, 0.5, 72, 48)) { shape.UseInProgram(prog); auto tex_image = images::LoadTexture("bricks_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); gl.Bound(Texture::Target::_2D, color_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D(tex_image) .GenerateMipmap(); } catch(Error&) { } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); gl.Bound(Texture::Target::_2D, bump_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D( images::NormalMap(tex_image, images::NormalMap::FromAlpha())) .GenerateMipmap(); } catch(Error&) { } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Disable(Capability::CullFace); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Functionality::ClipDistance, 1); gl.Enable(Functionality::ClipDistance, 2); }
TriangleExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("TexCoord").Get(), shapes::Plane( Vec3f(), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-1.0f), 32, 32 ) ) { VertexShader vs; vs.Source(StrLit( "#version 330\n" "in vec3 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = vec4(Position, 1.0);" " vertTexCoord = TexCoord;" "}" )).Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source(StrLit( "#version 330\n" "#extension GL_ARB_gpu_shader5 : enable\n" "layout(triangles, invocations = 7) in;" "layout(triangle_strip, max_vertices = 21) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "uniform vec3 CameraPosition;" "in vec2 vertTexCoord[3];" "out gl_PerVertex {" " vec4 gl_Position;" " float gl_ClipDistance[3];" "};" "flat out mat3 geomPositionFront;" "flat out mat3 geomTexCoordFront;" "flat out vec3 geomWFront;" "noperspective out vec3 geomBarycentric;" "out vec3 geomPosition;" "out vec3 geomTexCoord;" "void main(void)" "{" " vec4 world_pos[8*3];" " vec3 tex_coord[8*3];" " vec4 view_pos[8*3];" " vec3 screen_pos[8*3];" " bool front_facing[8];" " int ft = gl_InvocationID+1;" " for(int pass=0; pass!=2; ++pass)" " {" " bool first = pass == 0;" " if(((ft == 0) && first) || (((ft != 0) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " int w = 2-v;" " world_pos[0+v] = gl_in[w].gl_Position;" " tex_coord[0+v] = vec3(vertTexCoord[w], 0.0);" " }" " }" " vec4 n = vec4(-0.15 * normalize(cross(" " gl_in[1].gl_Position.xyz-gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-gl_in[0].gl_Position.xyz " " )), 0.0);" " if(((ft == 1) && first) || (((ft != 1) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " world_pos[3+v] = gl_in[v].gl_Position + n;" " tex_coord[3+v] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " int k = 2+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+0+v*6] = gl_in[v].gl_Position;" " tex_coord[6+0+v*6] = vec3(vertTexCoord[v], 0.0);" " world_pos[6+1+v*6] = gl_in[w].gl_Position;" " tex_coord[6+1+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+2+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+2+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " k = 3+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+3+v*6] = gl_in[w].gl_Position;" " tex_coord[6+3+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+4+v*6] = gl_in[w].gl_Position + n;" " tex_coord[6+4+v*6] = vec3(vertTexCoord[w], 1.0);" " world_pos[6+5+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+5+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int t=first?ft:0; t!=8; ++t)" " {" " if(!first && (t == ft)) continue;" " int o = t*3;" " for(int v=0; v!=3; ++v)" " {" " int w = o+v;" " view_pos[w] = Matrix * world_pos[w];" " screen_pos[w] = view_pos[w].xyz/view_pos[w].w;" " }" " front_facing[t] = cross(" " screen_pos[o+1]-screen_pos[o+0]," " screen_pos[o+2]-screen_pos[o+0] " " ).z < 0.0;" " if(first) break;" " }" " if(first && !front_facing[ft]) return;" " }" " int o = ft*3;" " vec4 clip_plane[3];" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " vec3 p0 = world_pos[o+v].xyz;" " vec3 p1 = world_pos[o+w].xyz;" " vec3 p2 = CameraPosition;" " vec3 pv = normalize(cross(p1-p0, p2-p0));" " clip_plane[v] = vec4(pv, -dot(pv, p0));" " }" " vec3 lo = CameraPosition;" " vec3 p0 = world_pos[o+0].xyz;" " vec3 pu = world_pos[o+1].xyz-p0;" " vec3 pv = world_pos[o+2].xyz-p0;" " vec3 lp = lo-p0;" " float w0 = view_pos[o+0].w;" " float wu = view_pos[o+1].w-w0;" " float wv = view_pos[o+2].w-w0;" " vec3 t0 = tex_coord[o+0];" " vec3 tu = tex_coord[o+1]-t0;" " vec3 tv = tex_coord[o+2]-t0;" " for(int bt=0; bt!=8; ++bt)" " {" " int k = bt*3;" " if((ft != bt) && !front_facing[bt])" " {" " for(int v=0; v!=3; ++v)" " {" " vec3 lt = world_pos[k+v].xyz;" " mat3 im = mat3(lo-lt, pu, pv);" " vec3 ic = inverse(im)*lp;" " float s = ic.y;" " float t = ic.z;" " geomPositionFront[v] = p0+pu*s+pv*t;" " geomTexCoordFront[v] = t0+tu*s+tv*t;" " geomWFront[v] = w0+wu*s+wv*t;" " }" " for(int v=0; v!=3; ++v)" " {" " int w = k+v;" " gl_Position = view_pos[w];" " for(int c=0; c!=3; ++c)" " {" " gl_ClipDistance[c] = dot(" " clip_plane[c]," " world_pos[w]" " );" " }" " geomPosition = world_pos[w].xyz;" " geomTexCoord = tex_coord[w];" " geomBarycentric = vec3(0.0);" " geomBarycentric[v] = 1.0;" " EmitVertex();" " }" " EndPrimitive();" " }" " }" "}" )).Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source(StrLit( "#version 330\n" "uniform float Time;" "uniform sampler2D ColorMap;" "uniform sampler2D BumpMap;" "uniform vec3 LightPosition;" "flat in mat3 geomPositionFront;" "flat in mat3 geomTexCoordFront;" "flat in vec3 geomWFront;" "noperspective in vec3 geomBarycentric;" "in vec3 geomPosition;" "in vec3 geomTexCoord;" "out vec3 fragColor;" "vec3 vcdiv(vec3 a, vec3 b)" "{" " return vec3(a.x/b.x, a.y/b.y, a.z/b.z);" "}" "void main(void)" "{" " const vec3 one = vec3(1.0, 1.0, 1.0);" " vec3 bzfv = vcdiv(geomBarycentric,geomWFront);" " vec3 p0 = geomPosition;" " vec3 p1 = (geomPositionFront*bzfv)/dot(one,bzfv);" " vec3 tc0 = geomTexCoord;" " vec3 tc1 = (geomTexCoordFront*bzfv)/dot(one,bzfv);" " ivec2 ts = textureSize(BumpMap, 0);" " int mts = max(ts.x, ts.y);" " vec2 dtc = tc1.xy - tc0.xy;" " float mdtc = max(abs(dtc.x), abs(dtc.y));" " int nsam = max(min(int(mdtc*mts), mts/2), 1);" " float step = 1.0 / nsam;" " for(int s=0; s<=nsam; ++s)" " {" " vec3 tc = mix(tc1, tc0, s*step);" " vec4 bm = texture(BumpMap, tc.xy);" " if(tc.z <= bm.w)" " {" " vec3 p = mix(p1, p0, s*step);" " vec3 ldir = normalize(LightPosition - p);" " float l = max(dot(ldir, bm.xzy), 0.0)*1.3;" " fragColor = texture(ColorMap, tc.xy).rgb*l;" " return;" " }" " }" " discard;" "}" )).Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); shape.UseInProgram(prog); auto tex_image = images::LoadTexture("stones_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); auto bound_tex = Bind(color_tex, Texture::Target::_2D); bound_tex.Image2D(tex_image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); auto bound_tex = Bind(bump_tex, Texture::Target::_2D); bound_tex.Image2D( images::NormalMap( tex_image, images::NormalMap::FromAlpha() ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Disable(Capability::CullFace); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Functionality::ClipDistance, 1); gl.Enable(Functionality::ClipDistance, 2); }
SkyBoxExample() : sky_box(List("Position").Get(), shapes::SkyBox()) , shape(List("Position")("Normal").Get(), shapes::WickerTorus()) , sky_box_prog() , sky_box_projection_matrix(sky_box_prog, "ProjectionMatrix") , sky_box_camera_matrix(sky_box_prog, "CameraMatrix") , shape_projection_matrix(shape_prog, "ProjectionMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , shape_model_matrix(shape_prog, "ModelMatrix") , sky_box_sun_position(sky_box_prog, "SunPosition") , shape_sun_position(shape_prog, "SunPosition") , shape_camera_position(shape_prog, "CameraPosition") { VertexShader sky_box_vs; sky_box_vs.Source( "#version 140\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix*CameraMatrix;" "in vec3 Position;" "out vec3 vertTexCoord;" "void main()" "{" " gl_Position = Matrix * vec4(Position * 100.0, 1.0);" " vertTexCoord = Position;" "}"); sky_box_vs.Compile(); sky_box_prog.AttachShader(sky_box_vs); VertexShader shape_vs; shape_vs.Source( "#version 140\n" "uniform vec3 SunPosition;" "uniform vec3 CameraPosition;" "uniform mat4 ProjectionMatrix,CameraMatrix,ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal, vertViewRefl, vertLightDir;" "void main()" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertViewRefl = reflect(" " gl_Position.xyz - CameraPosition," " vertNormal" " );" " vertLightDir = SunPosition - gl_Position.xyz;" " gl_Position = ProjectionMatrix*CameraMatrix*gl_Position;" "}"); shape_vs.Compile(); shape_prog.AttachShader(shape_vs); FragmentShader sky_box_fs; sky_box_fs.Source( "#version 140\n" "in vec3 vertTexCoord;" "out vec3 fragColor;" "vec3 sky_color(vec3 vd);" "void main()" "{" " fragColor = sky_color(normalize(vertTexCoord));" "}"); sky_box_fs.Compile(); sky_box_prog.AttachShader(sky_box_fs); FragmentShader shape_fs; shape_fs.Source( "#version 140\n" "in vec3 vertNormal, vertViewRefl, vertLightDir;" "out vec3 fragColor;" "vec3 sky_color(vec3 vd);" "void main()" "{" " float l = max(dot(normalize(vertNormal), " "normalize(vertLightDir))+0.1, 0.0);" " float a = 0.1;" " fragColor = " " 0.1*vec3(1.0, 1.0, 1.0)*(a+l)+" " 0.9*sky_color(normalize(vertViewRefl));" "}"); shape_fs.Compile(); shape_prog.AttachShader(shape_fs); FragmentShader sky_fs; sky_fs.Source( "#version 140\n" "const float WorldRadius = 6371000;" "const float AtmThickness = 50000;" "const vec3 AirColor = vec3(0.32, 0.36, 0.45);" "const vec3 LightColor = vec3(1.0, 1.0, 1.0);" "uniform vec3 SunPosition;" "uniform samplerCube EnvMap;" "float atm_intersection(vec3 v)" "{" " const vec3 c = vec3(0.0, -WorldRadius, 0.0);" " const float r = WorldRadius + AtmThickness;" " const float c_c = dot(-c, -c);" " float v_c = dot( v, -c);" " return (-v_c + sqrt(v_c*v_c - c_c + r*r))/AtmThickness;" "}" "vec3 sky_color(vec3 vd)" "{" " vec3 up = vec3(0.0, 1.0, 0.0);" " vec3 ld = normalize(SunPosition);" " vec4 cl = texture(EnvMap, vd);" " float ai = atm_intersection(vd);" " float al = max(dot(ld, up) + 0.12, 0.0);" " float vl = max(dot(vd, ld), 0.0);" " float ct = (1.0-cl.a)*cl.b;" " vec3 ac = max(LightColor-AirColor*pow(ai, 0.33), vec3(0.0, 0.0, " "0.0));" " vec3 Sun = " " ac*(vl>0.995+0.004*al ? 1.0:0.0);" " vec3 Air = " " min(AirColor*sqrt(pow(al,0.25)*ai), vec3(al, al, al)*1.5)+" " ac*pow(min(vl+0.001*ai, 1.0), 1024.0/pow(ai, 2.0))+" " ac*(vl/(1.0+pow(3.0*al, 8.0)))*pow(ai, 0.6)*0.5;" " vec3 Clouds =" " ac*pow(min(vl*(cl.g+cl.b), 1.015), 64.0)*pow(ct, 2.0)+" " ac*pow(min(vl*cl.g+cl.b, 1.020), 32.0)*ct+" " ac*pow(min(vl*cl.g*cl.b, 1.010), 16.0)*pow(ct, 0.5)+" " ac*0.7*min(cl.g + cl.b*0.5, 1.0)*al+" " ac*(cl.g*(1.0-cl.b*0.2)*5.0)*pow(1.0-al, 2.0)*(al)+" " LightColor*0.5*min(al + cl.g*0.4+cl.b*0.1, 1.0)*sqrt(al);" " return mix(Air, Clouds, cl.a*(1.0-cl.r*0.8))+Sun*(1.0-cl.a);" "}"); sky_fs.Compile(); sky_box_prog.AttachShader(sky_fs); shape_prog.AttachShader(sky_fs); sky_box_prog.Link(); sky_box.UseInProgram(sky_box_prog); shape_prog.Link(); shape.UseInProgram(shape_prog); { ProgramUniformSampler(sky_box_prog, "EnvMap").Set(0); ProgramUniformSampler(shape_prog, "EnvMap").Set(0); Texture::Active(0); gl.Bound(Texture::Target::CubeMap, env_map) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge) .WrapR(TextureWrap::ClampToEdge); Texture::ImageCM( 0, images::LoadTexture("clouds01-cm_0", false, false)); Texture::ImageCM( 1, images::LoadTexture("clouds01-cm_1", false, false)); Texture::ImageCM( 2, images::LoadTexture("clouds01-cm_2", false, false)); Texture::ImageCM( 3, images::LoadTexture("clouds01-cm_3", false, false)); Texture::ImageCM( 4, images::LoadTexture("clouds01-cm_4", false, false)); Texture::ImageCM( 5, images::LoadTexture("clouds01-cm_5", false, false)); } gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }