PoolTilesExample(void) : make_plane( Vec3f(), Vec3f(7.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-7.0f), 48, 48 ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , make_shape() , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , plane_vs(ObjectDesc("Plane vertex")) , shape_vs(ObjectDesc("Shape vertex")) , plane_fs(ObjectDesc("Plane fragment")) , shape_fs(ObjectDesc("Shape fragment")) , plane_camera_matrix(plane_prog, "CameraMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , plane_camera_position(plane_prog, "CameraPosition") , width(800) , height(600) , refl_tex_side(width > height ? height : width) , tile_tex_side(64) { gl.RequireAtLeast(LimitQuery::MaxCombinedTextureImageUnits, 5); plane_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform vec3 CameraPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec2 TexCoord;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "out vec4 vertReflTexCoord;" "out vec2 vertTileTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix* Position;" " vertLightDir = normalize(LightPosition - gl_Position.xyz);" " vertViewDir = normalize(CameraPosition - gl_Position.xyz);" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertReflTexCoord = gl_Position;" " vertTileTexCoord = TexCoord;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 140\n" "uniform sampler2D RandTex, PictTex, TileTex, NormTex;" "uniform sampler2D ReflectTex;" "uniform uint TileCount;" "uniform float Aspect;" "in vec3 vertLightDir;" "in vec3 vertViewDir;" "in vec4 vertReflTexCoord;" "in vec2 vertTileTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Normal = texture(" " NormTex, " " vertTileTexCoord * TileCount" " ).rgb;" " vec3 LightRefl = reflect(" " -normalize(vertLightDir)," " normalize(Normal)" " );" " float Diffuse = max(dot(" " Normal, " " vertLightDir" " ), 0.0);" " float Specular = max(dot(" " LightRefl," " vertViewDir" " ), 0.0);" " float PlasterLight = 0.3 + max(Diffuse, 0.0);" " float TileLight = 0.3 + pow(Diffuse, 2.0)*0.9 + pow(Specular, 4.0)*2.5;" " vec2 ReflCoord = vertReflTexCoord.xy;" " ReflCoord /= vertReflTexCoord.w;" " ReflCoord *= 0.5;" " ReflCoord += vec2(Aspect*0.5, 0.5);" " ReflCoord += vec2(Normal.x, Normal.z)*0.5;" " vec3 ReflColor = texture(" " ReflectTex, " " ReflCoord" " ).rgb;" " vec3 TileProps = texture(" " TileTex, " " vertTileTexCoord * TileCount" " ).rgb;" " float Pict = texture(PictTex, vertTileTexCoord).r;" " float Rand = texture(RandTex, vertTileTexCoord).r;" " float LightVsDark = " " mix( 0.1, 0.9, Pict)+" " mix(-0.1, 0.1, Rand);" " vec3 TileColor = mix(" " vec3(0.1, 0.1, 0.5)," " vec3(0.4, 0.4, 0.9)," " LightVsDark " " );" " vec3 PlasterColor = vec3(0.9, 0.9, 0.9);" " fragColor = vec4(" " mix(" " PlasterColor * PlasterLight," " TileColor * TileLight, " " TileProps.b" " ) +" " ReflColor * TileProps.g * 0.6," " 1.0" " );" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Vec3f lightPos(3.0f, 2.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<GLuint>(plane_prog, "TileCount").Set(tile_tex_side); Uniform<Mat4f>(plane_prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, -0.5f, 0.0f) ); std::vector<GLfloat> data; GLuint n_per_vertex; n_per_vertex = make_plane.Positions(data); plane_verts.Data(data); DSAVertexArrayAttribEXT(plane, plane_prog, "Position") .Setup<GLfloat>(plane_verts, n_per_vertex) .Enable(); n_per_vertex = make_plane.TexCoordinates(data); plane_texcoords.Data(data); DSAVertexArrayAttribEXT(plane, plane_prog, "TexCoord") .Setup<GLfloat>(plane_texcoords, n_per_vertex) .Enable(); // rand_tex.target = Texture::Target::_2D; rand_tex.Image2D( images::RandomRedUByte( tile_tex_side, tile_tex_side ) ); rand_tex.Filter(TextureFilter::Nearest); rand_tex.Wrap(TextureWrap::Repeat); Texture::Active(0); UniformSampler(plane_prog, "RandTex").Set(0); rand_tex.Bind(); // pict_tex.target = Texture::Target::_2D; pict_tex.Image2D(images::LoadTexture("pool_pictogram")); pict_tex.Filter(TextureFilter::Linear); pict_tex.Wrap(TextureWrap::Repeat); Texture::Active(1); UniformSampler(plane_prog, "PictTex").Set(1); pict_tex.Bind(); // auto tile_image = images::LoadTexture("small_tile"); // tile_tex.target = Texture::Target::_2D; tile_tex.Image2D(tile_image); tile_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); tile_tex.MagFilter(TextureMagFilter::Linear); tile_tex.Wrap(TextureWrap::Repeat); tile_tex.GenerateMipmap(); Texture::Active(2); UniformSampler(plane_prog, "TileTex").Set(2); tile_tex.Bind(); // norm_tex.target = Texture::Target::_2D; norm_tex.Image2D( images::TransformComponents<GLfloat, 3>( images::NormalMap(tile_image), Mat4d( Vec4d(1.0, 0.0, 0.0, 0.0), Vec4d(0.0, 0.0, 1.0, 0.0), Vec4d(0.0,-1.0, 0.0, 0.0), Vec4d(0.0, 0.0, 0.0, 1.0) ) ) ); norm_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); norm_tex.MagFilter(TextureMagFilter::Linear); norm_tex.Wrap(TextureWrap::Repeat); norm_tex.GenerateMipmap(); Texture::Active(3); UniformSampler(plane_prog, "NormTex").Set(3); norm_tex.Bind(); // reflect_tex.target = Texture::Target::_2D; reflect_tex.Image2D( 0, PixelDataInternalFormat::RGB, refl_tex_side, refl_tex_side, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); reflect_tex.Filter(TextureFilter::Linear); reflect_tex.Wrap(TextureWrap::ClampToEdge); Texture::Active(4); UniformSampler(plane_prog, "ReflectTex").Set(4); reflect_tex.Bind(); rbo.Storage( PixelDataInternalFormat::DepthComponent, refl_tex_side, refl_tex_side ); fbo.target = Framebuffer::Target::Draw; fbo.AttachTexture( FramebufferAttachment::Color, reflect_tex, 0 ); fbo.AttachRenderbuffer( FramebufferAttachment::Depth, rbo ); shape_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = " " ModelMatrix *" " Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (" " vec4(0.0, 0.0, 1.0, 1.0)*" " CameraMatrix" " ).xyz;" " vertViewRefl = reflect(" " -normalize(vertViewDir)," " normalize(vertNormal)" " );" " vertColor = vec3(0.3, 0.3, 0.7);" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 140\n" "uniform sampler2D PictTex, TileTex;" "uniform uint TileCount;" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " float LtDist = length(vertLightDir);" " float Diffuse = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / LtDist;" " float Specular = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 LightColor = vec3(1.0, 1.0, 1.0);" " vec2 ReflTexCoord = -vec2(" " vertViewRefl.x," " vertViewRefl.z " " );" " ReflTexCoord *= 0.25;" " ReflTexCoord += vec2(0.5, 0.5);" " float Pict = texture(PictTex, ReflTexCoord).r;" " float LightVsDark = mix( 0.1, 0.9, Pict);" " vec3 TileColor = mix(" " vec3(0.2, 0.2, 0.6)," " vec3(0.5, 0.5, 0.9)," " LightVsDark" " );" " vec3 PlasterColor = vec3(0.7, 0.7, 0.7);" " vec3 FloorColor = mix(" " PlasterColor, " " TileColor, " " texture(TileTex, ReflTexCoord*TileCount).b" " );" " vec3 ReflColor = mix(" " vec3(0.5, 0.5, 0.4), " " FloorColor, " " pow(max((-vertViewRefl.y-0.5)*2.0, 0.0), 2.0)" " );" " fragColor = vec4(" " vertColor * 0.4 + " " ReflColor * 0.3 + " " (LightColor + vertColor)*pow(max(2.5*Diffuse, 0.0), 3) + " " LightColor * pow(max(Specular, 0.0), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); Uniform<Mat4f>(shape_prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, 0.6f, 0.0f) ); UniformSampler(shape_prog, "PictTex").Set(0); UniformSampler(shape_prog, "TileTex").Set(1); Uniform<GLuint>(shape_prog, "TileCount").Set(tile_tex_side); n_per_vertex = make_shape.Positions(data); shape_verts.Data(data); DSAVertexArrayAttribEXT(shape, shape_prog, "Position") .Setup<GLfloat>(shape_verts, n_per_vertex) .Enable(); n_per_vertex = make_shape.Normals(data); shape_normals.Data(data); DSAVertexArrayAttribEXT(shape, shape_prog, "Normal") .Setup<GLfloat>(shape_normals, n_per_vertex) .Enable(); // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
Field(const images::Image& map, const Program& prog) : gl() { const GLuint w = map.Width(); const GLuint h = map.Height(); const GLuint d = map.Depth(); const GLuint c = 3; radius = std::sqrt(GLfloat(w*w+h*h+d*d))*0.5f; vert_count = w*h*d; std::vector<GLfloat> pos_data(w*h*d*c); std::vector<GLuint> tec_data(w*h*d*c); GLfloat xo = w * 0.5f; GLfloat yo = h * 0.5f; GLfloat zo = d * 0.5f; for(GLuint z=0; z!=d; ++z) { for(GLuint y=0; y!=h; ++y) { for(GLuint x=0; x!=w; ++x) { GLuint k = z*w*h*c+y*w*c+x*c; pos_data[k+0] = x-xo; pos_data[k+1] = y-yo; pos_data[k+2] = z-zo; tec_data[k+0] = x; tec_data[k+1] = y; tec_data[k+2] = z; } } } positions.Data(pos_data); texcoords.Data(tec_data); DSAVertexArrayAttribEXT(vao, prog, "Position") .Setup<Vector<GLfloat, 3>>(positions) .Enable(); DSAVertexArrayAttribEXT(vao, prog, "TexCoord") .Setup<Vector<GLuint, 3>>(texcoords) .Enable(); ProgramUniformSampler(prog, "Pattern").Set(1); pattern.BindMulti(1, Texture::Target::_3D); pattern.Image3D(map); pattern.MinFilter(TextureMinFilter::Nearest); pattern.MagFilter(TextureMagFilter::Nearest); pattern.WrapS(TextureWrap::ClampToBorder); pattern.WrapT(TextureWrap::ClampToBorder); pattern.WrapR(TextureWrap::ClampToBorder); pattern.BorderColor(Vec4f(0,0,0,1)); ProgramUniformSampler(prog, "FadeMap").Set(2); fademap.BindMulti(2, Texture::Target::_3D); fademap.Image3D(images::RandomRedUByte( map.Width(), map.Height(), map.Depth() )); fademap.MinFilter(TextureMinFilter::Nearest); fademap.MagFilter(TextureMagFilter::Nearest); fademap.WrapS(TextureWrap::ClampToBorder); fademap.WrapT(TextureWrap::ClampToBorder); fademap.WrapR(TextureWrap::ClampToBorder); fademap.BorderColor(Vec4f(0,0,0,1)); }