Particle(const VertexShader& vs, FragmentShader&& frag) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , fs(std::forward<FragmentShader>(frag)) { // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); projection_matrix = (prog/"ProjectionMatrix"); camera_matrix = (prog/"CameraMatrix"); model_matrix = (prog/"ModelMatrix"); light_pos = (prog/"LightPos"); // bind the VAO for the sphere sphere.Bind(); const GLuint n_attr = 2; // pointers to the vertex attribute data build functions typedef GLuint (shapes::Sphere::*Func)(std::vector<GLfloat>&) const; Func func[n_attr] = { &shapes::Sphere::Positions, &shapes::Sphere::Normals, }; // managed references to the VBOs Reference<Buffer> vbo[n_attr] = {verts, normals}; // vertex attribute identifiers from the shaders const GLchar* ident[n_attr] = {"Position", "Normal"}; for(GLuint i=0; i!=n_attr; ++i) { // bind the VBO vbo[i].Bind(Buffer::Target::Array); // make the data std::vector<GLfloat> data; GLuint n_per_vertex = (make_sphere.*func[i])(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attrib VertexArrayAttrib attr(prog, ident[i]); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } }
SphereExample(void) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , hole_count(50) , hole_diameter(0.30f) { // This shader will be used in transform fedback mode // to transform the vertices used to "cut out the holes" // the same way the sphere is transformed vs_tfb.Source( "#version 330\n" "uniform mat4 CameraMatrix, ModelMatrix;" "uniform float Diameter;" "in vec3 Hole;" "out vec3 vertTransfHole;" "void main(void)" "{" " vertTransfHole = (" " CameraMatrix *" " ModelMatrix *" " vec4(Hole * (1.0 + 0.5 * Diameter), 0.0)" " ).xyz;" "}" ); // compile, setup transform feedback output variables // link and use the program vs_tfb.Compile(); prog_tfb.AttachShader(vs_tfb); const GLchar* var_name = "vertTransfHole"; prog_tfb.TransformFeedbackVaryings( 1, &var_name, TransformFeedbackMode::InterleavedAttribs ); prog_tfb.Link(); prog_tfb.Use(); Uniform<GLfloat> diameter(prog_tfb, "Diameter"); diameter.Set(hole_diameter); // bind the VAO for the holes holes.Bind(); // bind the VBO for the hole vertices hole_verts.Bind(Buffer::Target::Array); // and the VBO for the transformed hole vertices captured by tfb transf_hole_verts.Bind(Buffer::Target::TransformFeedback); { std::vector<GLfloat> data; make_hole_data(data, hole_count); Buffer::Data(Buffer::Target::TransformFeedback, data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog_tfb, "Hole"); attr.Setup<Vec3f>(); attr.Enable(); } transf_hole_verts.BindBase( Buffer::IndexedTarget::TransformFeedback, 0 ); // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLight;" "const vec3 LightPos = vec3(2.0, 3.0, 3.0);" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos-gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "const int HoleCount = 50;" "uniform vec3 TransfHole[50];" "uniform float Diameter;" "void main(void)" "{" " int imax = 0;" " float dmax = -1.0;" " for(int i=0; i!=HoleCount; ++i)" " {" " float d = dot(vertNormal, TransfHole[i]);" " if(dmax < d)" " {" " dmax = d;" " imax = i;" " }" " }" " float l = length(vertLight);" " vec3 FragDiff = TransfHole[imax] - vertNormal;" " vec3 FinalNormal = " " length(FragDiff) > Diameter?" " vertNormal:" " normalize(FragDiff+vertNormal*Diameter);" " float i = (l > 0.0) ? dot(" " FinalNormal, " " normalize(vertLight)" " ) / l : 0.0;" " i = 0.2+max(i*2.5, 0.0);" " fragColor = vec4(i, i, i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); diameter.Set(hole_diameter); // bind the VAO for the sphere sphere.Bind(); // bind the VBO for the sphere vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the sphere normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Normals(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
SphereExample(void) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { // Vertex shader VertexShader vs; // Set the vertex shader source and compile it vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "layout(location = 0) in vec4 Position;" "layout(location = 1) in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" "}" ).Compile(); // Fragment shader FragmentShader fs; // set the fragment shader source and compile it fs.Source( "#version 330\n" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float i = (" " int(vertTexCoord.x*18) % 2+" " int(vertTexCoord.y*14) % 2" " ) % 2;" " fragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);" "}" ).Compile(); // attach the shaders to the program prog.AttachShader(vs).AttachShader(fs); // link and use it prog.Link().Use(); // bind the VAO for the sphere sphere.Bind(); // bind the VBO for the sphere vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices // (prog|0) is equivalent to VertexAttribArray(prog, VertexAtribSlot(0)) (prog|0).Setup<GLfloat>(n_per_vertex).Enable(); } // bind the VBO for the sphere UV-coordinates texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.TexCoordinates(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices // (prog|1) is equivalent to VertexAttribArray(prog, VertexAtribSlot(1)) (prog|1).Setup<GLfloat>(n_per_vertex).Enable(); } // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); Capability::DepthTest << true; }
CloudExample(const ExampleParams& params) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , samples(25 + params.quality*params.quality*100) , positions(make_positions()) , sizes(make_sizes()) , cloud_tex(positions.size()) , light_path(make_light_path_cps()) { assert(positions.size() == sizes.size()); std::srand(123456); light_vs.Source( "#version 330\n" "in vec3 Position;" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "void main(void)" "{" " float s = 0.1;" " gl_Position = " " ProjectionMatrix*" " CameraMatrix*" " vec4(Position*s + LightPos, 1.0);" "}" ).Compile(); light_fs.Source( "#version 330\n" "out vec4 fragLight;" "void main(void)" "{" " fragLight = vec4(1.0, 1.0, 1.0, 1.0);" "}" ).Compile(); light_prog << light_vs << light_fs; light_prog.Link().Use(); light.Bind(); buffer.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); Buffer::Data(Buffer::Target::Array, data); (light_prog|"Position").Setup(n_per_vertex, DataType::Float).Enable(); } cloud_vs.Source( "#version 330\n" "in vec4 Position;" "in float Size;" "uniform int SampleCount;" "uniform mat4 CameraMatrix;" "uniform vec4 ViewZ;" "out float vertZOffs;" "out float vertSize;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " vertSize = Size;" " gl_Position = vec4(" " Position.xyz +" " ViewZ.xyz*vertZOffs*Size*0.5," " 1.0" " );" "}" ).Compile(); cloud_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "in float vertSize[];" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec4 ViewX, ViewY, ViewZ;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "void main(void)" "{" " float zo = vertZOffs[0];" " float s = vertSize[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " vec4 v = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX.xyz * xo[i] * s * 0.5+" " ViewY.xyz * yo[j] * s * 0.5," " 1.0" " );" " gl_Position = ProjectionMatrix * CameraMatrix * v;" " geomLightDir = LightPos - v.xyz;" " geomTexCoord = " " vec3(0.5, 0.5, 0.5)+" " ViewX.xyz*(xo[i])*0.707+" " ViewY.xyz*(yo[j])*0.707+" " ViewZ.xyz*(zo )*0.707;" " EmitVertex();" " }" " EndPrimitive();" "}" ).Compile(); cloud_fs.Source( "#version 330\n" "uniform sampler3D CloudTex;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "out vec4 fragColor;" "void main(void)" "{" " float d = texture(CloudTex, geomTexCoord).r;" " float o = 1.0;" " float s = 2.0/128.0;" " float r = s * 8.0;" " vec3 sampleOffs = normalize(geomLightDir) * s;" " vec3 samplePos = geomTexCoord;" " if(d > 0.01) while(o > 0.0)" " {" " if(samplePos.x<0.0 || samplePos.x>1.0)" " break;" " if(samplePos.y<0.0 || samplePos.y>1.0)" " break;" " if(samplePos.z<0.0 || samplePos.z>1.0)" " break;" " o -= texture(CloudTex, samplePos).r*r;" " samplePos += sampleOffs;" " }" " float a = 0.4 * d;" " float i = mix(0.2, 1.0, o);" " fragColor = vec4(i, i, i, a);" "}" ).Compile(); cloud_prog << cloud_vs << cloud_gs << cloud_fs; cloud_prog.Link().Use(); // bind the VAO for the clouds clouds.Bind(); // bind the VBO for the cloud positions pos_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); (cloud_prog|"Position").Setup(3, DataType::Float).Enable(); } // bind the VBO for the cloud sizes size_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, sizes); (cloud_prog|"Size").Setup(1, DataType::Float).Enable(); } // set the number of samples cloud_prog/"SampleCount" = GLint(samples); Texture::Active(0); cloud_prog/"CloudTex" = 0; for(std::size_t i=0, n=positions.size(); i!=n; ++i) { auto bound_tex = Bind(cloud_tex[i], Texture::Target::_3D); bound_tex.Image3D( images::Cloud( 128, 128, 128, Vec3f(0.1f, -0.5f, 0.3f), 0.5f ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); bound_tex.WrapR(TextureWrap::ClampToBorder); } gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Disable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
SphereExample(void) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float i = int((" " vertTexCoord.x+" " vertTexCoord.y " " )*16) % 2;" " fragColor = mix(" " vec4(0.9, 0.9, 0.9, 1.0)," " vec4(1.0, 0.3, 0.4, 1.0)," " i" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the sphere sphere.Bind(); // bind the VBO for the sphere vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the sphere UV-coordinates texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.TexCoordinates(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }