void AbstractImageTest::dataSize() { /* Verify that row size is properly rounded */ CORRADE_COMPARE(Image2D(ColorFormat::RGBA, ColorType::UnsignedByte).dataSize({}), 0); CORRADE_COMPARE(Image2D(ColorFormat::Red, ColorType::UnsignedByte).dataSize({4, 2}), 8); CORRADE_COMPARE(Image2D(ColorFormat::Red, ColorType::UnsignedByte).dataSize({2, 4}), 16); CORRADE_COMPARE(Image2D(ColorFormat::RGBA, ColorType::UnsignedByte).dataSize(Vector2i(1)), 4); CORRADE_COMPARE(Image2D(ColorFormat::RGBA, ColorType::UnsignedShort).dataSize({16, 8}), 4*2*16*8); }
FlowMapHolder( GLuint flow_tex_size, GLuint tex_unit, const images::Image& flow_map_image ): first_tex_unit(tex_unit) , nhm(3) , height_maps(nhm, Texture::Target::_2D, first_tex_unit) , curr(0) { std::vector<GLfloat> v(flow_tex_size*flow_tex_size, 0.0f); for(GLuint i=0; i!=nhm; ++i) { height_maps[i].Image2D( 0, PixelDataInternalFormat::Red, flow_tex_size, flow_tex_size, 0, PixelDataFormat::Red, PixelDataType::Float, v.data() ); height_maps[i].MinFilter(TextureMinFilter::Linear); height_maps[i].MagFilter(TextureMagFilter::Linear); height_maps[i].WrapS(TextureWrap::ClampToBorder); height_maps[i].WrapT(TextureWrap::ClampToBorder); } Texture::Active(BumpMapUnit()); { auto bound_tex = Bind(bump_map, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, flow_tex_size, flow_tex_size, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } Texture::Active(FlowMapUnit()); { auto bound_tex = Bind(flow_map, Texture::Target::_2D); bound_tex.Image2D(flow_map_image); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } }
FlowExample(void) : gl() , flow(images::LoadTexture("flow_map"), 1) , screen( List("Position")("TexCoord").Get(), shapes::Screen(), screen_prog ) { Texture::Active(0); { auto bound_tex = Bind(background, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("flower_glass")); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::MirroredRepeat); bound_tex.WrapT(TextureWrap::MirroredRepeat); } screen_prog.background.Set(0); screen_prog.normal_map.Set(flow.TexUnit()); gl.ClearColor(0.4f, 0.4f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
Image2D createImage(size2 size, cl_mem_flags flags = CL_MEM_READ_WRITE, typename ChannelType<T>::Type* host_ptr = NULL, size_t pitch = 0) { cl_image_format format; format.image_channel_order = O; format.image_channel_data_type = T; cl_int err; cl_mem mem = clCreateImage2D(id(), flags, &format, size.s[0], size.s[1], pitch, host_ptr, err); CLPP_CHECK_ERROR(err); return Image2D(mem); }
RippleTexHolder(GLuint ripple_tex_size, GLuint tex_unit) : first_tex_unit(tex_unit) , nhm(3) , height_maps(nhm) , curr(0) { std::vector<GLfloat> v(ripple_tex_size*ripple_tex_size, 0.0f); for(GLuint i=0; i!=nhm; ++i) { Texture::Active(first_tex_unit+i); auto bound_tex = Bind(height_maps[i], Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::Red, ripple_tex_size, ripple_tex_size, 0, PixelDataFormat::Red, PixelDataType::Float, v.data() ); bound_tex.MinFilter(TextureMinFilter::Nearest); bound_tex.MagFilter(TextureMagFilter::Nearest); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } Texture::Active(first_tex_unit+nhm); auto bound_tex = Bind(bump_map, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, ripple_tex_size, ripple_tex_size, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); }
FBTexThread(FBTexExample& example) : gl() , prog(make_prog(example)) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , shape(List("Position")("Normal")("TexCoord").Get(), shapes::TwistedTorus(), prog) , tex_side(512) , parent_ready(example.parent_ready) { example.thread_ready = &thread_ready; Uniform<Vec3f>(prog, "LightPos").Set(20.0f, 30.0f, 40.0f); Texture::Active(0); { auto bound_tex = Bind(example.tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind(fbo, Framebuffer::Target::Draw); auto bound_rbo = Bind(rbo, Renderbuffer::Target::Renderbuffer); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture(FramebufferAttachment::Color, example.tex, 0); bound_fbo.AttachRenderbuffer(FramebufferAttachment::Depth, rbo); } Use(); }
CubeExample(void) : cube( List("Position")("Normal")("TexCoord").Get(), shapes::Cube(), cube_prog ) { // setup the texture { GLuint tex_side = 512; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.2f, 0.1f, 0.4f), Vec3f(0.8f, 0.8f, 1.0f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), images::NewtonFractal::DefaultMixer() ); auto bound_tex = Bind(cube_tex, Texture::Target::_2D); bound_tex.Image2D(image); bound_tex.GenerateMipmap(); bound_tex.BorderColor(Vec4f(0.8f, 0.8f, 1.0f, 1.0f)); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } cube_prog.cube_tex = 0; cube_prog.light_position.Set(4.0f, 4.0f, -8.0f); gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.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 vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord * 6.0;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " float d = l != 0.0 ? dot(" " vertNormal, " " normalize(vertLight)" " ) / l : 0.0;" " vec3 c = vec3(0.9, 0.8, 0.2);" " vec4 t = texture(TexUnit, vertTexCoord);" " float a = 1.0 - sqrt(abs(d)), e;" " if(gl_FrontFacing)" " {" " e = d >= 0.0 ?" " d * mix(0.5, 1.0, t.a):" " (-0.9*d) * (1.0 - t.a);" " }" " else" " {" " e = d >= 0.0 ?" " (0.6*d) * (1.0 - t.a):" " (-0.7*d) * mix(0.5, 1.0, t.a);" " }" " float i = 0.1 + 9.0*e;" " fragColor = vec4(" " t.r*c.r*i, " " t.g*c.g*i, " " t.b*c.b*i, " " clamp(pow(t.a,2) + a*0.4, 0.0, 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(); // bind the VAO for the cube cube.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the texture { auto bound_tex = Bind(tex, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("honeycomb")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::MirroredRepeat); bound_tex.WrapT(TextureWrap::MirroredRepeat); } // UniformSampler(prog, "TexUnit").Set(0); Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(1.0f, 2.0f, 3.0f)); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha ); gl.Enable(Capability::CullFace); gl.FrontFace(make_cube.FaceWinding()); }
Image2D loadTexture(const std::string filename) { Image2D image; //header for testing if it is a png png_byte header[8]; //open file as binary FILE *fp = fopen(filename.c_str(), "rb"); if (!fp) { return image; } //read the header fread(header, 1, 8, fp); //test if png int is_png = !png_sig_cmp(header, 0, 8); if (!is_png) { fclose(fp); return image; } //create png struct png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); return image; } //create png info struct png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); fclose(fp); return image; } //create png info struct png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); fclose(fp); return image; } //png error stuff, not sure libpng man suggests this. if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return image; } //init png reading png_init_io(png_ptr, fp); //let libpng know you already read the first 8 bytes png_set_sig_bytes(png_ptr, 8); // read all the info up to the image data png_read_info(png_ptr, info_ptr); //variables to pass to get info int bit_depth, color_type; png_uint_32 twidth, theight; // get info about png png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, NULL, NULL, NULL); // Update the png info struct. png_read_update_info(png_ptr, info_ptr); // Row size in bytes. int rowbytes = png_get_rowbytes(png_ptr, info_ptr); image = Image2D(twidth, theight, GL_RGBA, GL_UNSIGNED_BYTE, rowbytes * theight); //row_pointers is for pointing to image_data for reading the png with libpng png_bytep *row_pointers = new png_bytep[theight]; if (!row_pointers) { //clean up memory and close stuff png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return image; } // set the individual row_pointers to point at the correct offsets of image_data for (png_uint_32 i = 0; i < theight; ++i) row_pointers[theight - 1 - i] = image.data() + i * rowbytes; //read the png into image_data through row_pointers png_read_image(png_ptr, row_pointers); //clean up memory and close stuff png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); delete[] row_pointers; fclose(fp); return image; }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { namespace se = oglplus::smart_enums; VertexShader vs; vs.Source( "#version 120\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "attribute vec4 Position;" "attribute vec3 Normal;" "attribute vec2 TexCoord;" "varying vec3 vertNormal;" "varying vec3 vertLight;" "varying vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ).Compile(); FragmentShader fs; fs.Source( "#version 120\n" "uniform sampler2D TexUnit;" "varying vec3 vertNormal;" "varying vec3 vertLight;" "varying vec2 vertTexCoord;" "void main(void)" "{" " float l = length(vertLight);" " float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.3 + 2.0*max(d, 0.0);" " vec4 t = texture2D(TexUnit, vertTexCoord);" " gl_FragColor = vec4(t.rgb*i, 1.0);" "}" ).Compile(); prog.AttachShader(vs).AttachShader(fs).Link().Use(); // bind the VAO for the cube cube.Bind(); verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); (prog|"Position").Setup(n_per_vertex, se::Float()).Enable(); } normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); (prog|"Normal").Setup(n_per_vertex, se::Float()).Enable(); } texcoords.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); (prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable(); } // setup the texture { auto bound_tex = Bind(tex, se::_2D()); auto image = images::NewtonFractal( 512, 512, Vec3f(1.0f, 1.4f, 1.3f), Vec3f(0.2f, 0.3f, 0.1f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), [](double x) -> double { return pow(SineWave(pow(x,0.5)), 4.0); } ); bound_tex.Image2D(image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // set the uniform values (prog/"TexUnit") = 0; (prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
Test01(void) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 projectionMatrix, cameraMatrix, modelMatrix;" "in vec4 vertex;" "in vec3 normal;" "in vec3 tangent;" "in vec2 texcoord;" "out vec3 fragLight;" "out vec2 fragTex;" "out mat3 normalMatrix;" "uniform vec3 lightPos;" "void main(void)" "{" " vec3 fragNormal = (" " modelMatrix *" " vec4(normal, 0.0)" " ).xyz;" " vec3 fragTangent = (" " modelMatrix *" " vec4(tangent, 0.0)" " ).xyz;" " normalMatrix[0] = fragTangent;" " normalMatrix[1] = cross(fragNormal, fragTangent);" " normalMatrix[2] = fragNormal;" " fragLight = (" " vec4(lightPos, 0.0)-" " modelMatrix*vertex" " ).xyz;" " fragTex = texcoord;" " gl_Position = " " projectionMatrix *" " cameraMatrix *" " modelMatrix *" " vertex;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D colorTex, normalTex;" "in vec3 fragLight;" "in vec2 fragTex;" "in mat3 normalMatrix;" "out vec4 fragColor;" "void main(void)" "{" " float s = 5.0;" " float l = length(fragLight);" " vec3 n = texture2D(normalTex, fragTex*s).xyz;" " vec3 finalNormal = normalMatrix * n;" " float d = (l != 0.0)?" " dot(fragLight, finalNormal)/l:" " 0.0;" " float i = 0.1 + 2.5*clamp(d, 0.0, 1.0);" " vec4 t = texture2D(colorTex, fragTex*s);" " fragColor = vec4(t.rgb*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(); // bind the VAO for the shape vao.Bind(); { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Positions(data); Bind(verts, Buffer::Target::Array).Data(data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "vertex"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Normals(data); Bind(normals, Buffer::Target::Array).Data(data); // setup the vertex attribs array for the normals VertexAttribArray attr(prog, "normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Tangents(data); Bind(tangents, Buffer::Target::Array).Data(data); VertexAttribArray attr(prog, "tangent"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the shape tex-coords { std::vector<GLfloat> data; GLuint n_per_vertex = shape.TexCoordinates(data); Bind(texcoords, Buffer::Target::Array).Data(data); // VertexAttribArray attr(prog, "texcoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the textures { Texture::Active(0); UniformSampler(prog, "colorTex").Set(0); auto bound_tex = Bind(color_tex, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("stones")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { Texture::Active(1); UniformSampler(prog, "normalTex").Set(1); auto bound_tex = Bind(normal_tex, Texture::Target::_2D); bound_tex.Image2D( images::NormalMap(images::LoadTexture("stones-hmap")) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } Uniform<Mat4f>(prog, "projectionMatrix").Set( CamMatrixf::Perspective(Degrees(24), 1.25, 1, 100) ); // VertexArray::Unbind(); gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); // gl.FrontFace(shape.FaceWinding()); gl.CullFace(Face::Back); gl.Enable(Capability::CullFace); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { namespace se = oglplus::smart_enums; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLight);" " float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.3 + 2.0*max(d, 0.0);" " vec4 t = texture(TexUnit, vertTexCoord);" " fragColor = vec4(t.rgb*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(); // bind the VAO for the cube cube.Bind(); verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); (prog|"Position").Setup(n_per_vertex, se::Float()).Enable(); } normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); (prog|"Normal").Setup(n_per_vertex, se::Float()).Enable(); } texcoords.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); (prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable(); } // setup the texture { auto bound_tex = Bind(tex, se::_2D()); bound_tex.Image2D(images::LoadTexture("concrete_block")); bound_tex.MinFilter(se::Linear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // set the uniform values (prog/"TexUnit") = 0; (prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
FBTexExample(void) : make_cube() , cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , cube_fs(ObjectDesc("Cube fragment")) , torus_fs(ObjectDesc("Torus fragment")) , torus_projection_matrix(torus_prog, "ProjectionMatrix") , torus_camera_matrix(torus_prog, "CameraMatrix") , torus_model_matrix(torus_prog, "ModelMatrix") , cube_projection_matrix(cube_prog, "ProjectionMatrix") , cube_camera_matrix(cube_prog, "CameraMatrix") , cube_model_matrix(cube_prog, "ModelMatrix") , tex_side(512) , width(tex_side) , height(tex_side) { vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos-gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); cube_fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = sqrt(length(vertLight));" " float d = l > 0? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.6 + max(d, 0.0);" " fragColor = texture(TexUnit, vertTexCoord)*i;" "}" ); cube_fs.Compile(); cube_prog.AttachShader(vs); cube_prog.AttachShader(cube_fs); cube_prog.Link(); cube_prog.Use(); cube.Bind(); cube_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } UniformSampler(cube_prog, "TexUnit").Set(0); Uniform<Vec3f>(cube_prog, "LightPos").Set(4.0f, 4.0f, -8.0f); torus_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float d = dot(" " vertNormal, " " normalize(vertLight)" " );" " float i = (" " int(vertTexCoord.x*18) % 2+" " int(vertTexCoord.y*14) % 2" " ) % 2;" " float c = (0.4 + max(d, 0.0))*(1-i/2);" " fragColor = vec4(c, c, c, 1.0);" "}" ); torus_fs.Compile(); torus_prog.AttachShader(vs); torus_prog.AttachShader(torus_fs); torus_prog.Link(); torus_prog.Use(); torus.Bind(); torus_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(torus_prog, "LightPos").Set(2.0f, 3.0f, 4.0f); { auto bound_tex = Bind(tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); auto bound_rbo = Bind( rbo, Renderbuffer::Target::Renderbuffer ); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture( FramebufferAttachment::Color, tex, 0 ); bound_fbo.AttachRenderbuffer( FramebufferAttachment::Depth, rbo ); } gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); }
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); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , light_pos(prog, "LightPos") { namespace se = oglplus::smart_enums; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec3 Tangent;" "in vec2 TexCoord;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "out mat3 NormalMatrix;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 fragNormal = mat3(ModelMatrix) * Normal;" " vec3 fragTangent = mat3(ModelMatrix) * Tangent;" " NormalMatrix[0] = fragTangent;" " NormalMatrix[1] = cross(fragNormal, fragTangent);" " NormalMatrix[2] = fragNormal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D ColorTex, NormalTex;" "in mat3 NormalMatrix;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " vec3 n = texture(NormalTex, vertTexCoord).xyz;" " vec3 finalNormal = NormalMatrix * n;" " float d = (l > 0.0) ? dot(" " normalize(vertLight), " " finalNormal" " ) / l : 0.0;" " float i = 0.2 + 4.5*max(d, 0.0);" " vec4 t = texture(ColorTex, vertTexCoord);" " fragColor = vec4(t.rgb*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(); // bind the VAO for the cube cube.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } tangents.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Tangents(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Tangent"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the textures { Texture::Active(0); UniformSampler(prog, "ColorTex").Set(0); auto bound_tex = Bind(colorTex, se::_2D()); bound_tex.Image2D(images::LoadTexture("wooden_crate")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } { Texture::Active(1); UniformSampler(prog, "NormalTex").Set(1); auto bound_tex = Bind(normalTex, se::_2D()); bound_tex.Image2D( images::NormalMap( images::LoadTexture("wooden_crate-hmap"), images::NormalMap::FromRed() ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
DOFExample(const ExampleParams& params) : face_instr(make_cube.Instructions()) , edge_instr(make_cube.EdgeInstructions()) , face_indices(make_cube.Indices()) , edge_indices(make_cube.EdgeIndices()) , cube_matrices(MakeCubeMatrices(100, 10.0)) , viewport_width(dof_prog, "ViewportWidth") , viewport_height(dof_prog, "ViewportHeight") , projection_matrix(main_prog, "ProjectionMatrix") , camera_matrix(main_prog, "CameraMatrix") , model_matrix(main_prog, "ModelMatrix") , ambient_color(main_prog, "AmbientColor") , diffuse_color(main_prog, "DiffuseColor") , focus_depth(dof_prog, "FocusDepth") , color_tex(Texture::Target::Rectangle) , depth_tex(Texture::Target::Rectangle) , width(800) , height(600) { main_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertLightDir;" "out vec3 vertNormal;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = normalize(LightPos - gl_Position.xyz);" " vertNormal = normalize(mat3(ModelMatrix)*Normal);" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it main_vs.Compile(); // set the fragment shader source main_fs.Source( "#version 330\n" "uniform vec3 AmbientColor, DiffuseColor;" "in vec3 vertLightDir;" "in vec3 vertNormal;" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(vertLightDir,vertNormal),0.0);" " float e = sin(" " 10.0*vertLightDir.x + " " 20.0*vertLightDir.y + " " 25.0*vertLightDir.z " " )*0.9;" " fragColor = vec4(" " mix(AmbientColor, DiffuseColor, d+e)," " 1.0" " );" "}" ); // compile it main_fs.Compile(); // attach the shaders to the program main_prog.AttachShader(main_vs); main_prog.AttachShader(main_fs); // link and use it main_prog.Link(); main_prog.Use(); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertices positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(main_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the cube normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(main_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(main_prog, "LightPos").Set(30.0, 50.0, 20.0); dof_vs.Source( "#version 330\n" "uniform uint ViewportWidth, ViewportHeight;" "in vec4 Position;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = Position;" " vertTexCoord = vec2(" " (Position.x*0.5 + 0.5)*ViewportWidth," " (Position.y*0.5 + 0.5)*ViewportHeight" " );" "}" ); dof_vs.Compile(); dof_fs.Source( "#version 330\n" "uniform sampler2DRect ColorTex;" "uniform sampler2DRect DepthTex;" "uniform float FocusDepth;" "uniform uint SampleMult;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "const float strength = 16.0;" "void main(void)" "{" " float fragDepth = texture(DepthTex, vertTexCoord).r;" " vec3 color = texture(ColorTex, vertTexCoord).rgb;" " float of = abs(fragDepth - FocusDepth);" " int nsam = int(of*SampleMult);" " float inv_nsam = 1.0 / (1.0 + nsam);" " float astep = (3.14151*4.0)/nsam;" " for(int i=0; i!=nsam; ++i)" " {" " float a = i*astep;" " float d = sqrt(i*inv_nsam);" " float sx = cos(a)*of*strength*d;" " float sy = sin(a)*of*strength*d;" " vec2 samTexCoord = vertTexCoord + vec2(sx, sy) + noise2(vec2(sx, sy));" " color += texture(ColorTex, samTexCoord).rgb;" " }" " fragColor = vec4(color * inv_nsam , 1.0);" "}" ); dof_fs.Compile(); dof_prog.AttachShader(dof_vs); dof_prog.AttachShader(dof_fs); dof_prog.Link(); dof_prog.Use(); GLuint sample_mult = params.HighQuality()?512:128; Uniform<GLuint>(dof_prog, "SampleMult") = sample_mult; // bind the VAO for the screen screen.Bind(); corners.Bind(Buffer::Target::Array); { GLfloat screen_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; Buffer::Data(Buffer::Target::Array, 8, screen_verts); VertexAttribArray attr(dof_prog, "Position"); attr.Setup<Vec2f>(); attr.Enable(); } Texture::Active(0); UniformSampler(dof_prog, "ColorTex").Set(0); { auto bound_tex = Bind(color_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::RGB, width, height, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); } Texture::Active(1); UniformSampler(dof_prog, "DepthTex").Set(1); { auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::DepthComponent, width, height, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Color, color_tex, 0 ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::LEqual); gl.Enable(Capability::LineSmooth); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
ImageStack::ImageStack( const Image2D& p ) { fn = p.frame_number(); planes_.push_back(p); background_.push_back(Image2D()); }
void ImageStack::push_back( const Plane& p ) { planes_.push_back( p ); background_.push_back( Image2D() ); }
SmokeExample(void) : emitters( { { { {-20.0f, -10.0f, 10.0f}, { 20.0f, 0.0f, -20.0f}, { 20.0f, 10.0f, 20.0f}, {-20.0f, 0.0f, -10.0f} }, 15.0, 200.0 }, { { { 30.0f, 0.0f, 5.0f}, {-30.0f, 0.0f, -5.0f}, {-20.0f, 20.0f, 5.0f}, { 20.0f, -10.0f, -5.0f} }, 17.0, 200.0 }, } ), vs(ShaderType::Vertex, "Vertex") , gs(ShaderType::Geometry, "Geometry") , fs(ShaderType::Fragment, "Fragment") , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , light_cam_pos(prog, "LightCamPos") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix;" "in vec4 Position;" "in float Age;" "in int Id;" "out float vertAge;" "out int vertId;" "void main(void)" "{" " gl_Position = CameraMatrix * Position;" " vertAge = Age;" " vertId = Id;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform vec3 LightCamPos;" "uniform mat4 ProjectionMatrix;" "in float vertAge[];" "in int vertId[];" "out vec2 geomTexCoord;" "out float geomAge;" "out float geomLightVal;" "out float geomLightBias;" "void main(void)" "{" " if(vertAge[0] > 1.0) return;" " vec3 pos = gl_in[0].gl_Position.xyz;" " vec3 lightDir = normalize(LightCamPos - pos);" " float s = 0.8, g = 3.0;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " float angle = vertId[0];" " float cx = cos(angle), sx = sin(angle);" " mat2 rot = mat2(cx, sx, -sx, cx);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float xoffs = xo[i]*(1.0+vertAge[0]*g)*s;" " float yoffs = yo[j]*(1.0+vertAge[0]*g)*s;" " vec2 offs = rot*vec2(xoffs, yoffs);" " gl_Position = ProjectionMatrix * vec4(" " pos.x-offs.x," " pos.y-offs.y," " pos.z," " 1.0" " );" " geomTexCoord = vec2(float(i), float(j));" " geomAge = vertAge[0];" " geomLightVal = lightDir.z;" " geomLightBias = -dot(" " normalize(vec3(offs, 0.0))," " lightDir" " );" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D SmokeTex;" "in vec2 geomTexCoord;" "in float geomAge;" "in float geomLightVal;" "in float geomLightBias;" "out vec4 fragColor;" "void main(void)" "{" " vec3 c = texture(SmokeTex, geomTexCoord).rgb;" " float depth = c.g - c.r;" " if(depth == 0.0) discard;" " float density = min(depth * c.b * 2.0, 1.0);" " float intensity = min(" " max(" " geomLightVal*0.5+" " geomLightBias," " 0.0" " )+max(" " -geomLightVal*" " (1.0 - density)*" " geomLightBias * 5.0," " 0.0" " )," " 1.0" " ) + 0.1;" " fragColor = vec4(" " intensity," " intensity," " intensity," " (1.0 - geomAge)*density" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the particles particles.Bind(); // bind the VBO for the particle positions pos_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); VertexAttribArray attr(prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages); VertexAttribArray attr(prog, "Age"); attr.Setup<GLfloat>(); attr.Enable(); } // bind the VBO for the particle identifiers id_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ids); VertexAttribArray attr(prog, "Id"); attr.Setup<GLint>(); attr.Enable(); } Texture::Active(0); UniformSampler(prog, "SmokeTex").Set(0); { auto bound_tex = Bind(smoke_tex, Texture::Target::_2D); bound_tex.Image2D( images::Cloud2D( 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); } // gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }