TorusExample(void) : make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source and compile it vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " Position;" "}" ).Compile(); // set the fragment shader source and compile it fs.Source( "#version 330\n" "in vec3 vertNormal;" "out vec4 fragColor;" "uniform vec3 LightPos;" "void main(void)" "{" " float intensity = 2.0 * max(" " dot(vertNormal, LightPos)/" " length(LightPos)," " 0.0" " );" " if(!gl_FrontFacing)" " fragColor = vec4(0.0, 0.0, 0.0, 1.0);" " else if(intensity > 0.9)" " fragColor = vec4(1.0, 0.9, 0.8, 1.0);" " else if(intensity > 0.1)" " fragColor = vec4(0.7, 0.6, 0.4, 1.0);" " else" " fragColor = vec4(0.3, 0.2, 0.1, 1.0);" "}" ).Compile(); // attach the shaders to the program prog << vs << fs; // link and use it prog.Link().Use(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices (prog|"Position").Setup(n_per_vertex, DataType::Float).Enable(); } // bind the VBO for the torus normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices (prog|"Normal").Setup(n_per_vertex, DataType::Float).Enable(); } // // set the light position (prog/"LightPos").Set(Vec3f(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.FrontFace(make_torus.FaceWinding()); gl.CullFace(Face::Back); glLineWidth(4.0f); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , transf_prog(make_transf_prog()) , face_prog(make_face_prog()) , frame_prog(make_frame_prog()) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { transf_prog.Use(); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); gl.Bind(NoProgramPipeline()); gl.Use(NoProgram()); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
TorusExample(void) : make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source and compile it 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)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ).Compile(); // set the fragment shader source and compile it 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.2 + 3.2*max(d, 0.0);" " fragColor = texture(TexUnit, vertTexCoord)*i;" "}" ).Compile(); // attach the shaders to the program prog.AttachShader(vs).AttachShader(fs); // link and use it prog.Link().Use(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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 torus normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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(); } // bind the VBO for the torus texture coordinates texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture Texture::Target tex_tgt = Texture::Target::_2D; tex.Bind(tex_tgt); { GLuint s = 256; std::vector<GLubyte> tex_data(s*s); for(GLuint v=0;v!=s;++v) for(GLuint u=0;u!=s;++u) tex_data[v*s+u] = rand() % 0x100; Texture::Image2D( tex_tgt, 0, PixelDataInternalFormat::Red, s, s, 0, PixelDataFormat::Red, PixelDataType::UnsignedByte, tex_data.data() ); Texture::MinFilter(tex_tgt, TextureMinFilter::Linear); Texture::MagFilter(tex_tgt, TextureMagFilter::Linear); Texture::WrapS(tex_tgt, TextureWrap::Repeat); Texture::WrapT(tex_tgt, TextureWrap::Repeat); Texture::SwizzleG(tex_tgt, TextureSwizzle::Red); Texture::SwizzleB(tex_tgt, TextureSwizzle::Red); } // typechecked uniform with exact data type // on compilers supporting strongly typed enums // you can use: //Typechecked<Uniform<SLtoCpp<SLDataType::Sampler2D>>>(prog, "TexUnit").Set(0); // without strongly typed enums you need to do: typedef SLtoCpp<OGLPLUS_CONST_ENUM_VALUE(SLDataType::Sampler2D)> GLSLsampler2D; Typechecked<Uniform<GLSLsampler2D>>(prog, "TexUnit").Set(0); // Uniform<Vec3f>(prog, "LightPos").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.FrontFace(make_torus.FaceWinding()); gl.CullFace(Face::Back); }
TorusExample(void) : make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source and compile it vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "void main(void)" "{" " vertNormal = mat3(CameraMatrix)*mat3(ModelMatrix)*Normal;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " Position;" "}" ).Compile(); // set the fragment shader source and compile it fs.Source( "#version 330\n" "uniform int ColorCount;" "uniform vec4 Color[8];" "in vec3 vertNormal;" "vec3 ViewDir = vec3(0.0, 0.0, 1.0);" "vec3 TopDir = vec3(0.0, 1.0, 0.0);" "out vec4 fragColor;" "void main(void)" "{" " float k = dot(vertNormal, ViewDir);" " vec3 reflDir = 2.0*k*vertNormal - ViewDir;" " float a = dot(reflDir, TopDir);" " vec3 reflColor;" " for(int i = 0; i != (ColorCount - 1); ++i)" " {" " if(a<Color[i].a && a>=Color[i+1].a)" " {" " float m = " " (a - Color[i].a)/" " (Color[i+1].a-Color[i].a);" " reflColor = mix(" " Color[i].rgb," " Color[i+1].rgb," " m" " );" " break;" " }" " }" " float i = max(dot(vertNormal, TopDir), 0.0);" " vec3 diffColor = vec3(i, i, i);" " fragColor = vec4(" " mix(reflColor, diffColor, 0.3 + i*0.7)," " 1.0" " );" "}" ).Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link().Use(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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).Enable(); } // bind the VBO for the torus normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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(n_per_vertex, DataType::Float).Enable(); } // setup the color gradient Uniform<GLint>(prog, "ColorCount").Set(8); Uniform<Vec4f> color(prog, "Color"); color[0].Set(1.0f, 1.0f, 0.9f, 1.00f); color[1].Set(1.0f, 0.9f, 0.8f, 0.97f); color[2].Set(0.9f, 0.7f, 0.5f, 0.95f); color[3].Set(0.5f, 0.5f, 1.0f, 0.95f); color[4].Set(0.2f, 0.2f, 0.7f, 0.00f); color[5].Set(0.1f, 0.1f, 0.1f, 0.00f); color[6].Set(0.2f, 0.2f, 0.2f,-0.10f); color[7].Set(0.5f, 0.5f, 0.5f,-1.00f); gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_torus.FaceWinding()); gl.CullFace(Face::Back); }
ShadowExample() : make_torus(1.0, 0.7, 72, 48) , torus_indices(make_torus.Indices()) , torus_instr(make_torus.Instructions()) , object_projection_matrix(object_prog) , object_camera_matrix(object_prog) , object_model_matrix(object_prog) , shadow_projection_matrix(shadow_prog) , shadow_camera_matrix(shadow_prog) , shadow_model_matrix(shadow_prog) , object_color(object_prog) , object_light_mult(object_prog) { vs_object.Source( "#version 140\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "out vec3 vertNormal;" "out vec3 vertLight;" "void main()" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}"); vs_object.Compile(); fs_object.Source( "#version 140\n" "in vec3 vertNormal;" "in vec3 vertLight;" "uniform vec3 Color;" "uniform float LightMult;" "out vec4 fragColor;" "void main()" "{" " float l = sqrt(length(vertLight));" " float d = l > 0.0 ?" " dot(" " vertNormal," " normalize(vertLight)" " ) / l : 0.0;" " float i = 0.3 + max(d, 0.0) * LightMult;" " fragColor = vec4(Color*i, 1.0);" "}"); fs_object.Compile(); object_prog.AttachShader(vs_object); object_prog.AttachShader(fs_object); object_prog.Link().Use(); object_projection_matrix.BindTo("ProjectionMatrix"); object_camera_matrix.BindTo("CameraMatrix"); object_model_matrix.BindTo("ModelMatrix"); object_color.BindTo("Color"); object_light_mult.BindTo("LightMult"); vs_shadow.Source( "#version 150\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "out float ld;" "void main()" "{" " gl_Position = ModelMatrix * Position;" " vec3 geomNormal = mat3(ModelMatrix)*Normal;" " vec3 lightDir = LightPos - gl_Position.xyz;" " ld = dot(geomNormal, normalize(lightDir));" "}"); vs_shadow.Compile(); gs_shadow.Source( "#version 150\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 12) out;" "in float ld[];" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "void main()" "{" " for(int v=0; v!=3; ++v)" " {" " int a = v, b = (v+1)%3, c = (v+2)%3;" " vec4 pa = gl_in[a].gl_Position;" " vec4 pb = gl_in[b].gl_Position;" " vec4 pc = gl_in[c].gl_Position;" " vec4 px, py;" " if(ld[a] == 0.0 && ld[b] == 0.0)" " {" " px = pa;" " py = pb;" " }" " else if(ld[a] > 0.0 && ld[b] < 0.0)" " {" " float x = ld[a]/(ld[a]-ld[b]);" " float y;" " px = mix(pa, pb, x);" " if(ld[c] < 0.0)" " {" " y = ld[a]/(ld[a]-ld[c]);" " py = mix(pa, pc, y);" " }" " else" " {" " y = ld[c]/(ld[c]-ld[b]);" " py = mix(pc, pb, y);" " }" " }" " else continue;" " vec3 vx = px.xyz - LightPos;" " vec3 vy = py.xyz - LightPos;" " vec4 sx = vec4(px.xyz + vx*10.0, 1.0);" " vec4 sy = vec4(py.xyz + vy*10.0, 1.0);" " vec4 cpx = CameraMatrix * px;" " vec4 cpy = CameraMatrix * py;" " vec4 csx = CameraMatrix * sx;" " vec4 csy = CameraMatrix * sy;" " gl_Position = ProjectionMatrix * cpy;" " EmitVertex();" " gl_Position = ProjectionMatrix * cpx;" " EmitVertex();" " gl_Position = ProjectionMatrix * csy;" " EmitVertex();" " gl_Position = ProjectionMatrix * csx;" " EmitVertex();" " EndPrimitive();" " break;" " }" "}"); gs_shadow.Compile(); fs_shadow.Source( "#version 150\n" "out vec4 fragColor;" "void main()" "{" " fragColor = vec4(0.0, 0.0, 0.0, 1.0);" "}"); fs_shadow.Compile(); shadow_prog.AttachShader(vs_shadow); shadow_prog.AttachShader(gs_shadow); shadow_prog.AttachShader(fs_shadow); shadow_prog.Link().Use(); shadow_projection_matrix.BindTo("ProjectionMatrix"); shadow_camera_matrix.BindTo("CameraMatrix"); shadow_model_matrix.BindTo("ModelMatrix"); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(VertexArrayAttrib::GetCommonLocation( MakeGroup(object_prog, shadow_prog), "Position")); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the torus normals torus_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); object_prog.Use(); VertexArrayAttrib attr(object_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VAO for the plane plane.Bind(); // bind the VBO for the plane vertices plane_verts.Bind(Buffer::Target::Array); { GLfloat data[4 * 3] = {-9.0f, 0.0f, -9.0f, -9.0f, 0.0f, 9.0f, 9.0f, 0.0f, -9.0f, 9.0f, 0.0f, 9.0f}; Buffer::Data(Buffer::Target::Array, 4 * 3, data); object_prog.Use(); VertexArrayAttrib attr(object_prog, "Position"); attr.Setup<GLfloat>(3); attr.Enable(); } // bind the VBO for the torus normals plane_normals.Bind(Buffer::Target::Array); { GLfloat data[4 * 3] = {-0.1f, 1.0f, 0.1f, -0.1f, 1.0f, -0.1f, 0.1f, 1.0f, 0.1f, 0.1f, 1.0f, -0.1f}; Buffer::Data(Buffer::Target::Array, 4 * 3, data); object_prog.Use(); VertexArrayAttrib attr(object_prog, "Normal"); attr.Setup<GLfloat>(3); attr.Enable(); } Vec3f lightPos(2.0f, 9.0f, 3.0f); ProgramUniform<Vec3f>(object_prog, "LightPos").Set(lightPos); ProgramUniform<Vec3f>(shadow_prog, "LightPos").Set(lightPos); gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.ClearStencil(0); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_torus.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); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , vs(ObjectDesc("Vertex")) , gs(ObjectDesc("Geometry")) , face_fs(ObjectDesc("Face fragment")) , frame_fs(ObjectDesc("Frame fragment")) , transf_prog(ObjectDesc("Transformation")) , face_prog(ObjectDesc("Face")) , frame_prog(ObjectDesc("Frame")) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 vertNormal;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;" " vertTexCoord = TexCoord;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 15) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in gl_PerVertex {" " vec4 gl_Position;" "} gl_in[];" "in vec3 vertNormal[];" "in vec2 vertTexCoord[];" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 geomNormal;" "out vec3 geomLight;" "out float geomGlow;" "flat out int geomTop;" "void main(void)" "{" " vec3 FaceNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " vec2 FaceCoord = 0.33333 * (" " vertTexCoord[0]+" " vertTexCoord[1]+" " vertTexCoord[2] " " );" " float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;" " Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;" " vec3 pos[3], norm[3];" " for(int i=0; i!=3; ++i)" " pos[i] = gl_in[i].gl_Position.xyz;" " for(int i=0; i!=3; ++i)" " norm[i] = cross(" " FaceNormal, " " normalize(pos[(i+1)%3] - pos[i])" " );" " vec3 pofs = FaceNormal * Offs;" " geomTop = 0;" " for(int i=0; i!=3; ++i)" " {" " geomNormal = norm[i];" " for(int j=0; j!=2; ++j)" " {" " vec3 tpos = pos[(i+j)%3];" " geomLight = LightPos-tpos;" " geomGlow = 1.0;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos, 1.0);" " EmitVertex();" " geomGlow = 0.7;" " geomLight = LightPos-tpos+pofs;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" " }" " geomGlow = 0.0;" " geomTop = 1;" " for(int i=0; i!=3; ++i)" " {" " geomLight = LightPos - (pos[i]+pofs);" " geomNormal = vertNormal[i];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(pos[i] + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); transf_prog.AttachShader(vs); transf_prog.AttachShader(gs); transf_prog.MakeSeparable(); transf_prog.Link(); transf_prog.Use(); ProgramUniform<Vec3f>(transf_prog, "LightPos").Set(4, 4, -8); torus.Bind(); 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(transf_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_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_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_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } face_fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLight;" "in float geomGlow;" "flat in int geomTop;" "uniform vec3 TopColor, SideColor;" "const vec3 LightColor = vec3(1.0, 1.0, 1.0);" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(" " normalize(geomLight)," " normalize(geomNormal)" " ), 0.0);" " vec3 color;" " if(geomTop != 0)" " {" " color = TopColor * d +" " LightColor * pow(d, 8.0);" " }" " else" " {" " color = SideColor * geomGlow +" " LightColor *" " pow(d, 2.0) * 0.2;" " }" " fragColor = vec4(color, 1.0);" "}" ); face_fs.Compile(); face_prog.AttachShader(face_fs); face_prog.MakeSeparable(); face_prog.Link(); ProgramUniform<Vec3f>(face_prog, "TopColor").Set(0.2f, 0.2f, 0.2f); ProgramUniform<Vec3f>(face_prog, "SideColor").Set(0.9f, 0.9f, 0.2f); face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.2, 0.1, 0.0, 1.0);" "}" ); frame_fs.Compile(); frame_prog.AttachShader(frame_fs); frame_prog.MakeSeparable(); frame_prog.Link(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); ProgramPipeline::Unbind(); Program::UseNone(); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
TorusExample(void) : make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertViewDir;" "void main(void)" "{" " vertNormal = Normal;" " vertViewDir = (" " vec4(0.0, 0.0, 1.0, 1.0)*" " CameraMatrix" " ).xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertViewDir;" "out vec4 fragColor;" "uniform vec3 LightPos[3];" "void main(void)" "{" " float amb = 0.2;" " float diff = 0.0;" " float spec = 0.0;" " for(int i=0;i!=3;++i)" " {" " diff += max(" " dot(vertNormal, LightPos[i])/" " dot(LightPos[i], LightPos[i])," " 0.0" " );" " float k = dot(vertNormal, LightPos[i]);" " vec3 r = 2.0*k*vertNormal - LightPos[i];" " spec += pow(max(" " dot(normalize(r), vertViewDir)," " 0.0" " ), 32.0 * dot(r, r));" " }" " fragColor = " " vec4(1.0, 0.1, 0.3, 1.0)*(amb+diff)+" " vec4(1.0, 1.0, 1.0, 1.0)*spec;" "}" ); // 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 torus torus.Bind(); // bind the VBO for the torus vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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 torus normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.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(n_per_vertex, DataType::Float); attr.Enable(); } // set the light positions Uniform<Vec3f> light_pos(prog, "LightPos"); light_pos[0].Set(Vec3f(2.0f,-1.0f, 0.0f)); light_pos[1].Set(Vec3f(0.0f, 3.0f, 0.0f)); light_pos[2].Set(Vec3f(0.0f,-1.0f, 4.0f)); // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_torus.FaceWinding()); gl.CullFace(Face::Back); }