// makes a fragment shader from the prologe, custom part and epilogue static FragmentShader make_fs(StrCRef color_fs) { FragmentShader shader; StrCRef source[3] = {fs_prologue(), color_fs, fs_epilogue()}; shader.Source(source); shader.Compile(); return shader; }
static Program make_prog(void) { VertexShader vs; vs.Source( "#version 130\n" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "uniform vec4 ClipPlane;" "attribute vec4 Position;" "attribute vec2 TexCoord;" "varying vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ModelMatrix *" " Position;" " gl_ClipDistance[0] = dot(ClipPlane, gl_Position);" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" ); vs.Compile(); FragmentShader fs; fs.Source( "#version 130\n" "varying vec2 vertTexCoord;" "void main(void)" "{" " float i = (" " int(vertTexCoord.x*36) % 2+" " int(vertTexCoord.y*24) % 2" " ) % 2;" " if(gl_FrontFacing)" " {" " gl_FragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);" " }" " else" " {" " gl_FragColor = vec4(0+i/2, 0+i/2, 0+i/2, 1.0);" " }" "}" ); fs.Compile(); Program prog; prog.AttachShader(vs); prog.AttachShader(fs); prog.Link(); prog.Use(); return prog; }
static Program make_prog(void) { VertexShader vs; vs.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertColor;" "out vec3 vertNormal;" "out vec3 vertLight;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertColor = abs(normalize(Normal+vec3(1, 1, 1)));" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); FragmentShader fs; fs.Source( "#version 330\n" "in vec3 vertColor;" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " float d = l > 0.0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.2 + max(d*3.2, 0.0);" " fragColor = vec4(vertColor*i, 1.0);" "}" ); fs.Compile(); Program prog; prog.AttachShader(vs); prog.AttachShader(fs); prog.Link(); return prog; }
static Program make_face_prog(void) { FragmentShader fs; 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);" "}" ); fs.Compile(); Program prog; prog.AttachShader(fs); prog.MakeSeparable(); prog.Link(); ProgramUniform<Vec3f>(prog, "TopColor").Set(0.2f, 0.2f, 0.2f); ProgramUniform<Vec3f>(prog, "SideColor").Set(0.9f, 0.9f, 0.2f); return prog; }
//----------------------------------------------------------------------------------------------------------------------------------------------------- Ptr<GPUProgram> Context::CreateGPUProgram( LPCTSTR VertexShaderSource, LPCTSTR FragmentShaderSource ) { VertexShader* pVertexShader = 0; FragmentShader* pFragmentShader = 0; if (VertexShaderSource) { pVertexShader = new VertexShader(this); pVertexShader->Compile(VertexShaderSource); } if (FragmentShaderSource) { pFragmentShader = new FragmentShader(this); pFragmentShader->Compile(FragmentShaderSource); } return CreateGPUProgram( pVertexShader, pFragmentShader ); }
static Program make_frame_prog(void) { FragmentShader fs; fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.2, 0.1, 0.0, 1.0);" "}" ); fs.Compile(); Program prog; prog.AttachShader(fs); prog.MakeSeparable(); prog.Link(); return prog; }
bool ShaderLoader::Load(ShaderResource** resource, Handle handle, const std::string& filename1, const std::string& filename2) { *resource = new ShaderResource(handle, filename1); Program* shader = new Program(); (*resource)->mRaw = shader; VertexShader vs; vs.Source(readFile(filename1)); vs.Compile(); FragmentShader fs; fs.Source(readFile(filename2)); fs.Compile(); shader->AttachShader(vs).AttachShader(fs); shader->BindAttribute(VertexAttributes::POSITION, "in_Position"); shader->BindAttribute(VertexAttributes::NORMAL, "in_Normal"); shader->BindAttribute(VertexAttributes::TANGENT, "in_Tangent"); shader->BindAttribute(VertexAttributes::TEXCOORD, "in_TexCoords"); shader->Link(); return true; }
Program * ProgramFromShaderMap(const map<string, string> &mapShdString, const string &root) { VertexShader vs; FragmentShader fs; Program *prog = new Program(); string defS("#version 420\n"); defS.append("#define MAX_BONES "); defS.append(ConvertIntString(G_MAX_BONES_UNIFORM)); defS.append("\n"); defS.append("#define MAX_BONES_INFL "); defS.append(ConvertIntString(G_MAX_BONES_INFLUENCING)); defS.append("\n"); string vsSrc(defS); vsSrc.append(mapShdString.at(string("vs").append(root))); string fsSrc(defS); fsSrc.append(mapShdString.at(string("fs").append(root))); vs.Source(vsSrc); fs.Source(fsSrc); vs.Compile(); fs.Compile(); prog->AttachShader(vs); prog->AttachShader(fs); prog->Link(); return prog; }
TessellationExample(void) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , tess_level(prog, "TessLevel") , viewport_dimensions(prog, "ViewportDimensions") , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { vs.Source( "#version 330\n" "in vec4 Position;" "void main(void)" "{" " gl_Position = Position;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 48) out;" "const vec3 LightPosition = vec3(12.0, 10.0, 7.0);" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec2 ViewportDimensions;" "uniform int TessLevel;" "noperspective out vec3 geomDist;" "flat out vec3 geomNormal;" "out vec3 geomColor;" "out vec3 geomLightDir;" "void make_triangle(vec4 p0, vec4 p1, vec4 p2)" "{" " vec3 n0 = (ModelMatrix*vec4(p0.xyz, 0)).xyz;" " vec3 n1 = (ModelMatrix*vec4(p1.xyz, 0)).xyz;" " vec3 n2 = (ModelMatrix*vec4(p2.xyz, 0)).xyz;" " vec4 m0 = ModelMatrix*p0;" " vec4 m1 = ModelMatrix*p1;" " vec4 m2 = ModelMatrix*p2;" " vec4 c0 = ProjectionMatrix*CameraMatrix*m0;" " vec4 c1 = ProjectionMatrix*CameraMatrix*m1;" " vec4 c2 = ProjectionMatrix*CameraMatrix*m2;" " vec2 s0 = ViewportDimensions * c0.xy/c0.w;" " vec2 s1 = ViewportDimensions * c1.xy/c1.w;" " vec2 s2 = ViewportDimensions * c2.xy/c2.w;" " vec2 v0 = s2 - s1;" " vec2 v1 = s0 - s2;" " vec2 v2 = s1 - s0;" " float d0 = abs(v1.x*v2.y-v1.y*v2.x)/length(v0);" " float d1 = abs(v2.x*v0.y-v2.y*v0.x)/length(v1);" " float d2 = abs(v0.x*v1.y-v0.y*v1.x)/length(v2);" " geomNormal = normalize(n0+n1+n2);" " gl_Position = c0;" " geomColor = normalize(abs(vec3(1, 1, 1) - n0));" " geomLightDir = LightPosition - m0.xyz;" " geomDist = vec3(d0, 0.0, 0.0);" " EmitVertex();" " gl_Position = c1;" " geomColor = normalize(abs(vec3(1, 1, 1) - n1));" " geomLightDir = LightPosition - m1.xyz;" " geomDist = vec3(0.0, d1, 0.0);" " EmitVertex();" " gl_Position = c2;" " geomColor = normalize(abs(vec3(1, 1, 1) - n2));" " geomLightDir = LightPosition - m2.xyz;" " geomDist = vec3(0.0, 0.0, d2);" " EmitVertex();" " EndPrimitive();" "}" "void do_tess_1(vec4 p_0, vec4 p_1, vec4 p_2, int l)" "{" " if(l == 1) make_triangle(p_0, p_1, p_2);" " else" " {" " vec4 p01 = vec4(normalize(p_0.xyz+p_1.xyz), 1.0);" " vec4 p12 = vec4(normalize(p_1.xyz+p_2.xyz), 1.0);" " vec4 p20 = vec4(normalize(p_2.xyz+p_0.xyz), 1.0);" " make_triangle(p_0, p01, p20);" " make_triangle(p01, p_1, p12);" " make_triangle(p20, p12, p_2);" " make_triangle(p01, p12, p20);" " }" "}" "void do_tess_0(vec4 p_0, vec4 p_1, vec4 p_2, int l)" "{" " if(l == 0) make_triangle(p_0, p_1, p_2);" " else" " {" " vec4 p01 = vec4(normalize(p_0.xyz+p_1.xyz), 1.0);" " vec4 p12 = vec4(normalize(p_1.xyz+p_2.xyz), 1.0);" " vec4 p20 = vec4(normalize(p_2.xyz+p_0.xyz), 1.0);" " do_tess_1(p_0, p01, p20, l);" " do_tess_1(p01, p_1, p12, l);" " do_tess_1(p20, p12, p_2, l);" " do_tess_1(p01, p12, p20, l);" " }" "}" "void main(void)" "{" " do_tess_0(" " gl_in[0].gl_Position," " gl_in[1].gl_Position," " gl_in[2].gl_Position," " TessLevel" " );" "}" ); gs.Compile(); fs.Source( "#version 330\n" "noperspective in vec3 geomDist;" "flat in vec3 geomNormal;" "in vec3 geomColor;" "in vec3 geomLightDir;" "out vec3 fragColor;" "void main(void)" "{" " float MinDist = min(min(geomDist.x,geomDist.y),geomDist.z);" " float EdgeAlpha = exp2(-pow(MinDist, 2.0));" " const float Ambient = 0.7;" " float Diffuse = max(dot(" " normalize(geomNormal)," " normalize(geomLightDir)" " )+0.1, 0.0)*1.4;" " vec3 FaceColor = geomColor * (Diffuse + Ambient);" " const vec3 EdgeColor = vec3(0.0, 0.0, 0.0);" " fragColor = mix(FaceColor, EdgeColor, EdgeAlpha);" "}" ); fs.Compile(); prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); prog.Link(); prog.Use(); shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); indices.Bind(Buffer::Target::ElementArray); Buffer::Data(Buffer::Target::ElementArray, shape_indices); shape_indices.clear(); } // gl.ClearColor(0.7f, 0.7f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); prog.Use(); }
MetaballExample(void) { for(GLuint i=0; i!=64; ++i) { GLuint j = 0, n = 3+std::rand()%3; std::vector<Vec4f> points(n); while(j != n) { points[j] = Vec4f( 1.4*std::rand()/GLdouble(RAND_MAX) - 0.7, 1.4*std::rand()/GLdouble(RAND_MAX) - 0.7, 0.0, 0.1*std::rand()/GLdouble(RAND_MAX) + 0.1 ); ++j; } ball_paths.push_back(CubicBezierLoop<Vec4f, double>(points)); ++i; } // Set the vertex shader source vs.Source(StrLit( "#version 330\n" "in vec2 Position;" "out vec3 vertPosition;" "void main(void)" "{" " vertPosition = vec3(Position, 0.0);" " gl_Position = vec4(vertPosition, 1.0);" "}" )); // compile it vs.Compile(); // set the fragment shader source fs.Source(StrLit( "#version 330\n" "uniform sampler1D Metaballs;" "in vec3 vertPosition;" "out vec3 fragColor;" "const vec3 AmbientColor = vec3(0.3, 0.4, 0.9);" "const vec3 DiffuseColor = vec3(0.5, 0.6, 1.0);" "const vec3 LightDir = normalize(vec3(1.0, 1.0, 1.0));" "void main(void)" "{" " int i = 0, n = textureSize(Metaballs, 0);" " float InvN = 1.0/n;" " float Value = 0.0;" " vec3 Normal = vec3(0.0, 0.0, 0.0);" " while(i != n)" " {" " vec4 Metaball = texelFetch(Metaballs, i, 0);" " float Radius = Metaball.w;" " vec3 Vect = vertPosition - Metaball.xyz;" " float Tmp = pow(Radius,2.0)/dot(Vect, Vect)-0.25;" " Value += Tmp;" " float Mul = max(Tmp, 0.0);" " Normal += Mul*vec3(Vect.xy, Mul*InvN/Radius);" " ++i;" " }" " if(Value > 0.0)" " {" " float Diffuse = 1.4*max(dot(" " LightDir," " normalize(Normal)" " ), 0.0);" " float Ambient = 0.3;" " fragColor = " " Ambient*AmbientColor+" " Diffuse*DiffuseColor;" " }" " else fragColor = vec3(0.4, 0.4, 0.4);" "}" )); // compile it fs.Compile(); // attach the shaders to the program prog << vs << fs; // link and use it prog.Link().Use(); // bind the VAO for the rectangle rectangle.Bind(); GLfloat rectangle_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // bind the VBO for the rectangle vertices verts.Bind(Buffer::Target::Array); // upload the data Buffer::Data(Buffer::Target::Array, rectangle_verts); // setup the vertex attribs array for the vertices VertexAttribArray vert_attr(prog, "Position"); vert_attr.Setup(2, DataType::Float).Enable(); // Texture::Active(0); UniformSampler(prog, "Metaballs").Set(0); { auto bound_tex = Bind(metaballs_tex, Texture::Target::_1D); bound_tex.Image1D( 0, PixelDataInternalFormat::RGBA32F, ball_paths.size(), 0, PixelDataFormat::RGBA, PixelDataType::Float, nullptr ); bound_tex.MinFilter(TextureMinFilter::Nearest); bound_tex.MagFilter(TextureMagFilter::Nearest); bound_tex.WrapS(TextureWrap::MirroredRepeat); } gl.ClearDepth(1.0f); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , front_facing(prog, "FrontFacing") , inst_count(32) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "uniform int InstCount;" "uniform int FrontFacing;" "in vec4 Position;" "in vec3 Normal;" "out float vertMult;" "out vec3 vertColor;" "out vec3 vertWrapNormal;" "out vec3 vertNormal;" "out vec3 vertLight;" "void main(void)" "{" " int inst = (FrontFacing != 0) ? " " (InstCount - gl_InstanceID - 1):" " gl_InstanceID;" " vertMult = float(inst) / float(InstCount-1);" " float sca = 1.0 - 0.3 * pow(vertMult, 2);" " mat4 ScaleMatrix = mat4(" " sca, 0.0, 0.0, 0.0," " 0.0, sca, 0.0, 0.0," " 0.0, 0.0, sca, 0.0," " 0.0, 0.0, 0.0, 1.0 " " );" " gl_Position = ModelMatrix * Position;" " vertColor = Normal;" " vec3 wrap = Position.xyz - Normal;" " vertWrapNormal = " " mat3(ModelMatrix)*" " normalize(mix(" " Normal," " wrap," " mix(0.5, 1.0, vertMult)" " ));" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos-gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ScaleMatrix *" " gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in float vertMult;" "in vec3 vertColor;" "in vec3 vertWrapNormal;" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "uniform int InstCount;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " float d = l > 0.0 ? dot(" " vertNormal, " " normalize(vertLight)" " ) / l : 0.0;" " float s = max(" " dot(vertWrapNormal, vertLight)/l," " 0.0" " );" " float intensity = clamp(" " 0.2 + d * 3.0 + s * 5.5," " 0.0," " 1.0" " );" " fragColor = vec4(" " abs(vertColor) * intensity," " (2.5 + 1.5*d + 1.5*s) / InstCount" " );" "}" ); // 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(); // bind the VBO for the cube vertices verts.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 VertexArrayAttrib attr(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); // upload the data Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // the light position Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(-3.0f, -2.0f, -3.0f)); // and the instance count Uniform<GLint>(prog, "InstCount").Set(inst_count); // gl.ClearColor(0.5f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_cube.FaceWinding()); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
MultiViewportExample(void) : make_shape(1.0, 0.1, 8, 4, 48) , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , camera_position_3(prog, "CameraPosition[3]") , camera_matrix_0(prog, "CameraMatrix[0]") , camera_matrix_1(prog, "CameraMatrix[1]") , camera_matrix_2(prog, "CameraMatrix[2]") , camera_matrix_3(prog, "CameraMatrix[3]") , model_matrix(prog, "ModelMatrix") { VertexShader vs; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertTexCoord;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " vertTexCoord = Normal;" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPos-gl_Position.xyz;" " vertLightRefl = reflect(-vertLightDir, vertNormal);" "}" ); vs.Compile(); GeometryShader gs; // Set the geometry shader source gs.Source( "#version 330\n" "#extension GL_ARB_viewport_array : enable\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 12) out;" "uniform mat4 CameraMatrix[4];" "uniform vec3 CameraPosition[4];" "in vec3 vertNormal[];" "in vec3 vertTexCoord[];" "in vec3 vertLightDir[];" "in vec3 vertLightRefl[];" "out vec3 geomNormal;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "out vec3 geomLightRefl;" "out vec3 geomViewDir;" "out vec3 geomViewRefl;" "void main(void)" "{" " for(int vp=0; vp!=4; ++vp)" " {" " gl_ViewportIndex = vp;" " for(int v=0; v!=3; ++v)" " {" " geomNormal = vertNormal[v];" " geomTexCoord = vertTexCoord[v];" " geomLightDir = vertLightDir[v];" " geomLightRefl = vertLightRefl[v];" " geomViewDir = " " CameraPosition[vp] - " " gl_in[v].gl_Position.xyz;" " geomViewRefl = reflect(" " -geomViewDir," " geomNormal" " );" " gl_Position = " " CameraMatrix[vp] *" " gl_in[v].gl_Position;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); gs.Compile(); FragmentShader fs; // set the fragment shader source fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 geomNormal;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "in vec3 geomLightRefl;" "in vec3 geomViewDir;" "in vec3 geomViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLightDir);" " float d = dot(" " normalize(geomNormal), " " normalize(geomLightDir)" " ) / l;" " float s = dot(" " normalize(geomLightRefl)," " normalize(geomViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 tex = texture(TexUnit, geomTexCoord).rgb;" " fragColor = vec4(" " tex * 0.4 + " " (lt + tex) * 1.5 * max(d, 0.0) + " " lt * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); // 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 shape shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::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_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture { GLuint tex_side = 512; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.8f, 0.8f, 1.0f), Vec3f(0.1f, 0.0f, 0.2f), Vec2f(-0.707f, -0.707f), Vec2f( 0.707f, 0.707f), images::NewtonFractal::X4Minus1(), [](double x) -> double { return pow(SineWave(pow(x,0.5)), 4.0); } ); auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); for(int i=0; i!=6; ++i) Texture::Image2D(Texture::CubeMapFace(i), image); } // UniformSampler(prog, "TexUnit").Set(0); Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.1f, 0.05f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); Uniform<Vec3f> camera_position(prog, "CameraPosition"); camera_position[0].Set(Vec3f(2, 0, 0)); camera_position[1].Set(Vec3f(0, 2, 0)); camera_position[2].Set(Vec3f(0, 0, 2)); }
GlassExample(void) : make_plane(Vec3f(2.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -2.0f)) , 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_proj_matrix(plane_prog) , plane_camera_matrix(plane_prog) , plane_model_matrix(plane_prog) , shape_proj_matrix(shape_prog) , shape_camera_matrix(shape_prog) , shape_model_matrix(shape_prog) , shape_clip_plane(shape_prog) , shape_clip_direction(shape_prog) , width(512) , height(512) , tex_side(512) { plane_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec2 TexCoord;" "out vec3 vertLightDir;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = " " ModelMatrix* " " Position;" " vertLightDir = normalize(" " LightPosition - gl_Position.xyz" " );" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" " vertTexCoord = TexCoord;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 140\n" "uniform vec3 Normal;" "in vec3 vertLightDir;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float checker = (" " int(vertTexCoord.x*18) % 2+" " int(vertTexCoord.y*18) % 2" " ) % 2;" " vec3 color = mix(" " vec3(0.2, 0.4, 0.9)," " vec3(0.2, 0.2, 0.7)," " checker" " );" " float d = dot(" " Normal, " " vertLightDir" " );" " float intensity = 0.5 + pow(1.4*d, 2.0);" " fragColor = vec4(color*intensity, 1.0);" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); plane_proj_matrix.BindTo("ProjectionMatrix"); plane_camera_matrix.BindTo("CameraMatrix"); plane_model_matrix.BindTo("ModelMatrix"); Vec3f lightPos(3.0f, 3.0f, 3.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal()); gl.Bind(plane); gl.Bind(Buffer::Target::Array, plane_verts); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } gl.Bind(Buffer::Target::Array, plane_texcoords); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(plane_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } shape_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "uniform vec4 ClipPlane;" "uniform float ClipDirection;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = " " ModelMatrix *" " Position;" " gl_ClipDistance[0] = " " ClipDirection* " " dot(ClipPlane, gl_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;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vec3 TexOffs = mat3(CameraMatrix)*vertNormal*0.05;" " vertTexCoord = " " vec2(0.5, 0.5) +" " (gl_Position.xy/gl_Position.w)*0.5 +" " (TexOffs.z<0.0 ? TexOffs.xy : -TexOffs.xy);" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 140\n" "uniform sampler2D RefractTex;" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "float adj_lt(float i)" "{" " return i > 0.0 ? i : -0.7*i;" "}" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 tex = texture(RefractTex, vertTexCoord).rgb;" " fragColor = vec4(" " tex * 0.5 + " " (lt + tex) * 1.5 * adj_lt(d) + " " lt * pow(adj_lt(s), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); shape_proj_matrix.BindTo("ProjectionMatrix"); shape_camera_matrix.BindTo("CameraMatrix"); shape_model_matrix.BindTo("ModelMatrix"); shape_clip_plane.BindTo("ClipPlane"); shape_clip_direction.BindTo("ClipDirection"); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); gl.Bind(shape); gl.Bind(Buffer::Target::Array, shape_verts); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(shape_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } gl.Bind(Buffer::Target::Array, shape_normals); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(shape_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // Texture::Active(0); UniformSampler(shape_prog, "RefractTex").Set(0); { gl.Bound(Texture::Target::_2D, refract_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::MirroredRepeat) .WrapT(TextureWrap::MirroredRepeat) .Image2D( 0, PixelDataInternalFormat::RGB, tex_side, tex_side, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); } // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
LandscapeExample(void) : grid_side(8) , make_plane( Vec3f(0.0f, 0.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-1.0f), grid_side, grid_side ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , vc_int(prog, "vc_int") , gc_int(prog, "gc_int") , fc_int(prog, "fc_int") { VertexShader vs; vs.Source(StrLit( "#version 420\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "layout(binding = 0, offset = 0) uniform atomic_uint vc;" "const float mult = 1.0/128.0;" "uniform float vc_int;" "in vec4 Position;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" " vertColor = vec3(" " fract(atomicCounterIncrement(vc)*mult)," " 0.0," " 0.0 " " )*max(vc_int, 0.0);" "}" )); vs.Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source(StrLit( "#version 420\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 3) out;" "layout(binding = 0, offset = 4) uniform atomic_uint gc;" "const float mult = 1.0/128.0;" "uniform float gc_int;" "in vec3 vertColor[3];" "out vec3 geomColor;" "void main(void)" "{" " vec3 Color = vec3(" " 0.0," " fract(atomicCounterIncrement(gc)*mult)," " 0.0 " " )*max(gc_int, 0.0);" " for(int v=0; v!=3; ++v)" " {" " gl_Position = gl_in[v].gl_Position;" " geomColor = vertColor[v] + Color;" " EmitVertex();" " }" " EndPrimitive();" "}" )); gs.Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source(StrLit( "#version 420\n" "layout(binding = 0, offset = 8) uniform atomic_uint fc;" "const float mult = 1.0/4096.0;" "uniform float fc_int;" "in vec3 geomColor;" "out vec3 fragColor;" "void main(void)" "{" " vec3 Color = vec3(" " 0.0," " 0.0," " sqrt(fract(atomicCounterIncrement(fc)*mult))" " )*max(fc_int, 0.0);" " fragColor = geomColor + Color;" "}" )); fs.Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); // bind the VAO for the plane plane.Bind(); // bind the VBO for the plane vertices positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.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(); } counters.Bind(Buffer::Target::AtomicCounter); { const GLuint tmp[3] = {0u, 0u, 0u}; Buffer::Data( Buffer::Target::AtomicCounter, 3, tmp, BufferUsage::DynamicDraw ); } counters.BindBase(Buffer::IndexedTarget::AtomicCounter, 0); gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); plane.Bind(); }
ReflectionExample(void) : torus_indices(make_torus.Indices()) , torus_instr(make_torus.Instructions()) , vs_norm(ObjectDesc("Vertex-Normal")) , vs_refl(ObjectDesc("Vertex-Reflection")) , gs_refl(ObjectDesc("Geometry-Reflection")) { namespace se = oglplus::smart_enums; // Set the normal object vertex shader source vs_norm.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "out vec3 geomColor;" "out vec3 geomNormal;" "out vec3 geomLight;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " geomColor = Normal;" " geomNormal = mat3(ModelMatrix)*Normal;" " geomLight = LightPos-gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs_norm.Compile(); // Set the reflected object vertex shader source // which just passes data to the geometry shader vs_refl.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "void main(void)" "{" " gl_Position = Position;" " vertNormal = Normal;" "}" ); // compile it vs_refl.Compile(); // Set the reflected object geometry shader source // This shader creates a reflection matrix that // relies on the fact that the reflection is going // to be done by the y-plane gs_refl.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 6) out;" "in vec3 vertNormal[];" "uniform mat4 ProjectionMatrix;" "uniform mat4 CameraMatrix;" "uniform mat4 ModelMatrix;" "out vec3 geomColor;" "out vec3 geomNormal;" "out vec3 geomLight;" "uniform vec3 LightPos;" "mat4 ReflectionMatrix = mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0,-1.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " ");" "void main(void)" "{" " for(int v=0; v!=gl_in.length(); ++v)" " {" " vec4 Position = gl_in[v].gl_Position;" " gl_Position = ModelMatrix * Position;" " geomColor = vertNormal[v];" " geomNormal = mat3(ModelMatrix)*vertNormal[v];" " geomLight = LightPos - gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ReflectionMatrix *" " gl_Position;" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs_refl.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec3 geomColor;" "in vec3 geomNormal;" "in vec3 geomLight;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLight);" " float d = l > 0.0 ? dot(" " geomNormal, " " normalize(geomLight)" " ) / l : 0.0;" " float i = 0.2 + max(d, 0.0) * 2.0;" " fragColor = vec4(abs(geomNormal)*i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the normal rendering program prog_norm.AttachShader(vs_norm); prog_norm.AttachShader(fs); // link it prog_norm.Link(); // attach the shaders to the reflection rendering program prog_refl.AttachShader(vs_refl); prog_refl.AttachShader(gs_refl); prog_refl.AttachShader(fs); // link it prog_refl.Link(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); // upload the data Buffer::Data(se::Array(), data); // setup the vertex attribs array for the vertices typedef VertexAttribArray VAA; VertexAttribSlot loc_norm = VAA::GetLocation(prog_norm, "Position"), loc_refl = VAA::GetLocation(prog_refl, "Position"); assert(loc_norm == loc_refl); VertexAttribArray attr(loc_norm); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the torus normals torus_normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); // upload the data Buffer::Data(se::Array(), data); // setup the vertex attribs array for the normals typedef VertexAttribArray VAA; VertexAttribSlot loc_norm = VAA::GetLocation(prog_norm, "Normal"), loc_refl = VAA::GetLocation(prog_refl, "Normal"); assert(loc_norm == loc_refl); VertexAttribArray attr(loc_norm); 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(se::Array()); { GLfloat data[4*3] = { -2.0f, 0.0f, 2.0f, -2.0f, 0.0f, -2.0f, 2.0f, 0.0f, 2.0f, 2.0f, 0.0f, -2.0f }; // upload the data Buffer::Data(se::Array(), 4*3, data); // setup the vertex attribs array for the vertices prog_norm.Use(); VertexAttribArray attr(prog_norm, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the torus normals plane_normals.Bind(se::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 }; // upload the data Buffer::Data(se::Array(), 4*3, data); // setup the vertex attribs array for the normals prog_norm.Use(); VertexAttribArray attr(prog_norm, "Normal"); attr.Setup<Vec3f>(); attr.Enable(); } VertexArray::Unbind(); Vec3f lightPos(2.0f, 2.0f, 3.0f); prog_norm.Use(); SetUniform(prog_norm, "LightPos", lightPos); prog_refl.Use(); SetUniform(prog_refl, "LightPos", lightPos); // gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.ClearStencil(0); }
ReflectionExample() : make_plane( Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15) , 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_projection_matrix(plane_prog) , plane_camera_matrix(plane_prog) , plane_model_matrix(plane_prog) , shape_projection_matrix(shape_prog) , shape_camera_matrix(shape_prog) , shape_model_matrix(shape_prog) , width(800) , height(600) , tex_size_div(2) { plane_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertLightDir;" "out vec4 vertTexCoord;" "void main()" "{" " gl_Position = ModelMatrix*Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertTexCoord = gl_Position;" "}"); plane_vs.Compile(); plane_fs.Source( "#version 140\n" "uniform sampler2DRect ReflectTex;" "uniform vec3 Normal;" "in vec3 vertLightDir;" "in vec4 vertTexCoord;" "out vec3 fragColor;" "const int n = 5;" "const int ns = (n*n);" "const float blur = 0.15/n;" "void main()" "{" " float d = dot(Normal, normalize(vertLightDir));" " float intensity = 0.5 + pow(1.4*d, 2.0);" " vec3 color = vec3(0.0, 0.0, 0.0);" " int n = 2;" " float pct = 0.5/vertTexCoord.w;" " for(int y=-n; y!=(n+1); ++y)" " for(int x=-n; x!=(n+1); ++x)" " {" " vec2 coord = vertTexCoord.xy;" " coord += vec2(blur*x, blur*y);" " coord *= pct;" " coord += vec2(0.5, 0.5);" " coord *= textureSize(ReflectTex);" " color += texture(ReflectTex, coord).rgb/ns;" " }" " fragColor = color*intensity;" "}"); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); plane_projection_matrix.BindTo("ProjectionMatrix"); plane_camera_matrix.BindTo("CameraMatrix"); plane_model_matrix.BindTo("ModelMatrix"); Vec3f lightPos(3.0f, 0.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal()); plane.Bind(); plane_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // Texture::Active(1); gl.Bound(Texture::Target::Rectangle, depth_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge); Texture::Active(0); ProgramUniformSampler(plane_prog, "ReflectTex").Set(0); gl.Bound(Texture::Target::Rectangle, reflect_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge); gl.Bound(Framebuffer::Target::Draw, fbo) .AttachTexture(FramebufferAttachment::Color, reflect_tex, 0) .AttachTexture(FramebufferAttachment::Depth, depth_tex, 0); 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 vertColor;" "void main()" "{" " 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;" " vertColor = vec3(1, 1, 1) - vertNormal;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}"); shape_vs.Compile(); shape_fs.Source( "#version 140\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertColor;" "out vec3 fragColor;" "void main()" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " fragColor = " " vertColor * 0.4 + " " (lt + vertColor)*pow(max(2.5*d, 0.0), 3) + " " lt * pow(max(s, 0.0), 64);" "}"); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); shape_projection_matrix.BindTo("ProjectionMatrix"); shape_camera_matrix.BindTo("CameraMatrix"); shape_model_matrix.BindTo("ModelMatrix"); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); shape.Bind(); shape_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(shape_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(shape_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); }
TessellationExample(void) : shape_instr(make_shape.Instructions(PrimitiveType::Patches)) , shape_indices(make_shape.Indices()) , vs(ObjectDesc("Vertex")) , cs(ObjectDesc("Tessellation Control")) , es(ObjectDesc("Tessellation Evaluation")) , gs(ObjectDesc("Geometry")) , fs(ObjectDesc("Fragment")) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , offset(prog, "Offset") , view_position(prog, "ViewPosition") , viewport_dimensions(prog, "ViewportDimensions") { vs.Source( "#version 330\n" "uniform vec3 ViewPosition;" "in vec3 Position;" "out vec3 vertPosition;" "out float vertDistance;" "void main(void)" "{" " vertPosition = Position;" " vertDistance = length(ViewPosition - vertPosition);" "}" ); vs.Compile(); cs.Source( "#version 330\n" "#extension ARB_tessellation_shader : enable\n" "layout(vertices = 3) out;" "in vec3 vertPosition[];" "in float vertDistance[];" "out vec3 tecoPosition[];" "int tessLevel(float dist)" "{" " return int(9.0 / sqrt(dist+0.1));" "}" "void main(void)" "{" " tecoPosition[gl_InvocationID] =" " vertPosition[gl_InvocationID];" " if(gl_InvocationID == 0)" " {" " gl_TessLevelInner[0] = tessLevel((" " vertDistance[0]+" " vertDistance[1]+" " vertDistance[2] " " )*0.333);" " gl_TessLevelOuter[0] = tessLevel((" " vertDistance[1]+" " vertDistance[2] " " )*0.5);" " gl_TessLevelOuter[1] = tessLevel((" " vertDistance[2]+" " vertDistance[0] " " )*0.5);" " gl_TessLevelOuter[2] = tessLevel((" " vertDistance[0]+" " vertDistance[1] " " )*0.5);" " }" "}" ); cs.Compile(); es.Source( "#version 330\n" "#extension ARB_tessellation_shader : enable\n" "layout(triangles, equal_spacing, ccw) in;" "const vec3 LightPosition = vec3(12.0, 10.0, 7.0);" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec3 tecoPosition[];" "out vec3 teevNormal;" "out vec3 teevLightDir;" "void main(void)" "{" " vec3 p0 = gl_TessCoord.x * tecoPosition[0];" " vec3 p1 = gl_TessCoord.y * tecoPosition[1];" " vec3 p2 = gl_TessCoord.z * tecoPosition[2];" " vec4 tempPosition = vec4(normalize(p0+p1+p2), 0.0);" " teevNormal = (ModelMatrix * tempPosition).xyz;" " tempPosition.w = 1.0;" " tempPosition = ModelMatrix * tempPosition;" " teevLightDir = LightPosition - tempPosition.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " tempPosition;" "}" ); es.Compile(); gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 3) out;" "uniform vec3 Offset;" "uniform vec2 ViewportDimensions;" "in vec3 teevNormal[], teevLightDir[];" "noperspective out vec3 geomDist;" "flat out vec3 geomNormal;" "out vec3 geomColor;" "out vec3 geomLightDir;" "void main(void)" "{" " geomNormal = normalize(" " teevNormal[0]+" " teevNormal[1]+" " teevNormal[2]" " );" " vec2 ScreenPos[3];" " for(int i=0; i!=3; ++i)" " {" " ScreenPos[i] = " " ViewportDimensions*" " gl_in[i].gl_Position.xy/" " gl_in[i].gl_Position.w;" " }" " vec2 TmpVect[3];" " for(int i=0; i!=3; ++i)" " {" " TmpVect[i] = " " ScreenPos[(i+2)%3]-" " ScreenPos[(i+1)%3];" " }" " const vec3 EdgeMask[3] = vec3[3](" " vec3(1.0, 0.0, 0.0)," " vec3(0.0, 1.0, 0.0)," " vec3(0.0, 0.0, 1.0) " " );" " for(int i=0; i!=3; ++i)" " {" " float Dist = abs(" " TmpVect[(i+1)%3].x*TmpVect[(i+2)%3].y-" " TmpVect[(i+1)%3].y*TmpVect[(i+2)%3].x " " ) / length(TmpVect[i]);" " vec3 DistVect = vec3(Dist, Dist, Dist);" " gl_Position = gl_in[i].gl_Position;" " geomColor = normalize(abs(" " vec3(2.0, 2.0, 2.0)-" " teevNormal[i]-" " Offset" " ));" " geomLightDir = teevLightDir[i];" " geomDist = EdgeMask[i] * DistVect;" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); fs.Source( "#version 330\n" "noperspective in vec3 geomDist;" "flat in vec3 geomNormal;" "in vec3 geomColor;" "in vec3 geomLightDir;" "out vec3 fragColor;" "void main(void)" "{" " float MinDist = min(min(geomDist.x,geomDist.y),geomDist.z);" " float EdgeAlpha = exp2(-pow(MinDist, 2.0));" " const float Ambient = 0.8;" " float Diffuse = max(dot(" " normalize(geomNormal)," " normalize(geomLightDir)" " ), 0.0);" " vec3 FaceColor = geomColor * (Diffuse + Ambient);" " const vec3 EdgeColor = vec3(0.0, 0.0, 0.0);" " fragColor = mix(FaceColor, EdgeColor, EdgeAlpha);" "}" ); fs.Compile(); prog.AttachShader(vs); prog.AttachShader(cs); prog.AttachShader(es); prog.AttachShader(gs); prog.AttachShader(fs); prog.Link(); prog.Use(); shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); indices.Bind(Buffer::Target::ElementArray); Buffer::Data(Buffer::Target::ElementArray, shape_indices); shape_indices.clear(); } // gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); prog.Use(); }
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()); }
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); }
CubeMapExample(void) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.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 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (" " vec4(0.0, 0.0, 1.0, 1.0)*" " CameraMatrix" " ).xyz;" " vertViewRefl = reflect(" " normalize(vertViewDir)," " normalize(vertNormal)" " );" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 env = texture(TexUnit, vertViewRefl).rgb;" " fragColor = vec4(" " env * 0.4 + " " (lt + env) * 1.5 * max(d, 0.0) + " " lt * pow(max(s, 0.0), 64), " " 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 shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.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_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the texture { GLuint tex_side = 256; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.3f, 0.1f, 0.2f), Vec3f(1.0f, 0.8f, 0.9f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), images::NewtonFractal::DefaultMixer() ); auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); for(int i=0; i!=6; ++i) Texture::Image2D(Texture::CubeMapFace(i), image); } // typechecked uniform with the exact sampler type // on compilers supporting strongly typed enums // you can use: //Typechecked<Uniform<SLtoCpp<SLDataType::SamplerCube>>>(prog, "TexUnit").Set(0); // without strongly typed enums you need to do: typedef SLtoCpp<OGLPLUS_CONST_ENUM_VALUE(SLDataType::SamplerCube)> GLSLsamplerCube; Typechecked<Uniform<GLSLsamplerCube>>(prog, "TexUnit").Set(0); // Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.2f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); }
BlenderMeshExample(int argc, const char* argv[]) : prog() , camera_matrix(prog, "CameraMatrix") , light_position(prog, "LightPosition") , camera_position(prog, "CameraPosition") , face_normals(prog, "FaceNormals") , element_count(0) { using namespace oglplus; VertexShader vs; vs.Source( "#version 330\n" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPosition, CameraPosition;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "in vec3 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "void main(void)" "{" " vertNormal = Normal;" " vertLightDir = LightPosition - Position;" " vertViewDir = CameraPosition - Position;" " gl_Position = Matrix * vec4(Position, 1.0);" "}" ); vs.Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices=3) out;" "uniform bool FaceNormals;" "in vec3 vertNormal[3];" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec3 geomNormal;" "out vec3 geomLightDir;" "out vec3 geomViewDir;" "void main(void)" "{" " vec3 fn;" " if(FaceNormals)" " {" " vec3 p0 = gl_in[0].gl_Position.xyz;" " vec3 p1 = gl_in[1].gl_Position.xyz;" " vec3 p2 = gl_in[2].gl_Position.xyz;" " fn = normalize(cross(p1-p0, p2-p0));" " }" " for(int v=0; v!=3; ++v)" " {" " gl_Position = gl_in[v].gl_Position;" " if(FaceNormals) geomNormal = fn;" " else geomNormal = vertNormal[v];" " geomLightDir = vertLightDir[v];" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLightDir;" "in vec3 geomViewDir;" "out vec3 fragColor;" "void main(void)" "{" " vec3 LightColor = vec3(1.0, 1.0, 1.0);" " vec3 MatColor = vec3(0.5, 0.5, 0.5);" " vec3 LightRefl = reflect(-geomLightDir, geomNormal);" " float Ambient = 0.3;" " float Diffuse = max(dot(" " normalize(geomNormal)," " normalize(geomLightDir)" " ), 0.0);" " float Contour = pow((1.0 - max(dot(" " normalize(geomNormal)," " normalize(geomViewDir)" " )-0.1, 0.0))*1.05, 4.0);" " float Specular = pow(clamp(dot(" " normalize(geomViewDir)," " normalize(LightRefl)" " )+0.005, 0.0, 0.98), 64.0);" " fragColor = MatColor * LightColor * (Contour + Diffuse + Ambient)+" " LightColor * Specular;" "}" ); fs.Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); gl.PrimitiveRestartIndex(0); // vectors with vertex position and normals // the values at index 0 is unused // 0 is used as primitive restart index std::vector<GLfloat> pos_data(3, 0.0); std::vector<GLfloat> nml_data(3, 0.0); // index offset starting at 1 GLuint index_offset = 1; // vectors with vertex indices std::vector<GLuint> idx_data(1, 0); // open an input stream std::ifstream input(argc>1? argv[1]: "./test.blend"); // check if we succeeded if(!input.good()) throw std::runtime_error("Error opening file for reading"); // parse the input stream imports::BlendFile blend_file(input); // get the file's global block auto glob_block = blend_file.StructuredGlobalBlock(); // get the default scene auto scene_data = blend_file[glob_block.curscene]; // // get the pointer to the first object in the scene auto object_link_ptr = scene_data.Field<void*>("base.first").Get(); // and go through the whole list of objects while(object_link_ptr) { // for each list element open the linked list block auto object_link_data = blend_file[object_link_ptr]; // get the pointer to its object auto object_ptr = object_link_data.Field<void*>("object").Get(); // open the object block (if any) if(object_ptr) try { auto object_data = blend_file[object_ptr]; // get the data pointer auto object_data_ptr = object_data.Field<void*>("data").Get(); // open the data block (if any) if(object_data_ptr) { auto object_data_data = blend_file[object_data_ptr]; // if it is a mesh if(object_data_data.StructureName() == "Mesh") { // get the object matrix field auto object_obmat_field = object_data.Field<float>("obmat"); // make a transformation matrix Mat4f obmat( object_obmat_field.Get(0, 0), object_obmat_field.Get(0, 4), object_obmat_field.Get(0, 8), object_obmat_field.Get(0,12), object_obmat_field.Get(0, 1), object_obmat_field.Get(0, 5), object_obmat_field.Get(0, 9), object_obmat_field.Get(0,13), object_obmat_field.Get(0, 2), object_obmat_field.Get(0, 6), object_obmat_field.Get(0,10), object_obmat_field.Get(0,14), object_obmat_field.Get(0, 3), object_obmat_field.Get(0, 7), object_obmat_field.Get(0,11), object_obmat_field.Get(0,15) ); // the number of vertices std::size_t n_verts = 0; // get the vertex block pointer auto vertex_ptr = object_data_data.Field<void*>("mvert").Get(); // open the vertex block (if any) if(vertex_ptr) { auto vertex_data = blend_file[vertex_ptr]; // get the number of vertices in the block n_verts = vertex_data.BlockElementCount(); // get the vertex coordinate and normal fields auto vertex_co_field = vertex_data.Field<float>("co"); auto vertex_no_field = vertex_data.Field<short>("no"); // make two vectors of position and normal data std::vector<GLfloat> ps(3 * n_verts); std::vector<GLfloat> ns(3 * n_verts); for(std::size_t v=0; v!=n_verts; ++v) { // (transpose y and z axes) // get the positional coordinates Vec4f position( vertex_co_field.Get(v, 0), vertex_co_field.Get(v, 1), vertex_co_field.Get(v, 2), 1.0f ); Vec4f newpos = obmat * position; ps[3*v+0] = newpos.x(); ps[3*v+1] = newpos.z(); ps[3*v+2] =-newpos.y(); // get the normals Vec4f normal( vertex_no_field.Get(v, 0), vertex_no_field.Get(v, 1), vertex_no_field.Get(v, 2), 0.0f ); Vec4f newnorm = obmat * normal; ns[3*v+0] = newnorm.x(); ns[3*v+1] = newnorm.z(); ns[3*v+2] =-newnorm.y(); } // append the values pos_data.insert(pos_data.end(), ps.begin(), ps.end()); nml_data.insert(nml_data.end(), ns.begin(), ns.end()); } // get the face block pointer auto face_ptr = object_data_data.Field<void*>("mface").Get(); // open the face block (if any) if(face_ptr) { auto face_data = blend_file[face_ptr]; // get the number of faces in the block std::size_t n_faces = face_data.BlockElementCount(); // get the vertex index fields of the face auto face_v1_field = face_data.Field<int>("v1"); auto face_v2_field = face_data.Field<int>("v2"); auto face_v3_field = face_data.Field<int>("v3"); auto face_v4_field = face_data.Field<int>("v4"); // make a vector of index data std::vector<GLuint> is(5 * n_faces); for(std::size_t f=0; f!=n_faces; ++f) { // get face vertex indices int v1 = face_v1_field.Get(f); int v2 = face_v2_field.Get(f); int v3 = face_v3_field.Get(f); int v4 = face_v4_field.Get(f); is[5*f+0] = v1+index_offset; is[5*f+1] = v2+index_offset; is[5*f+2] = v3+index_offset; is[5*f+3] = v4?v4+index_offset:0; is[5*f+4] = 0; // primitive restart index } // append the values idx_data.insert(idx_data.end(), is.begin(), is.end()); } // get the poly block pointer auto poly_ptr = object_data_data.TryGet<void*>("mpoly", nullptr); // and the loop block pointer auto loop_ptr = object_data_data.TryGet<void*>("mloop", nullptr); // open the poly and loop blocks (if we have both) if(poly_ptr && loop_ptr) { auto poly_data = blend_file[poly_ptr]; auto loop_data = blend_file[loop_ptr]; // get the number of polys in the block std::size_t n_polys = poly_data.BlockElementCount(); // get the fields of poly and loop auto poly_loopstart_field = poly_data.Field<int>("loopstart"); auto poly_totloop_field = poly_data.Field<int>("totloop"); auto loop_v_field = loop_data.Field<int>("v"); // make a vector of index data std::vector<GLuint> is; for(std::size_t f=0; f!=n_polys; ++f) { int ls = poly_loopstart_field.Get(f); int tl = poly_totloop_field.Get(f); for(int l=0; l!=tl; ++l) { int v = loop_v_field.Get(ls+l); is.push_back(v+index_offset); } is.push_back(0); // primitive restart index } // append the values idx_data.insert(idx_data.end(), is.begin(), is.end()); } index_offset += n_verts; } } } catch(...) { } // and get the pointer to the nex block object_link_ptr = object_link_data.Field<void*>("next").Get(); } meshes.Bind(); positions.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, pos_data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(3); attr.Enable(); } normals.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, nml_data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(3); attr.Enable(); } indices.Bind(Buffer::Target::ElementArray); Buffer::Data(Buffer::Target::ElementArray, idx_data); element_count = idx_data.size(); // find the extremes of the mesh(es) GLfloat min_x = pos_data[3], max_x = pos_data[3]; GLfloat min_y = pos_data[4], max_y = pos_data[4]; GLfloat min_z = pos_data[5], max_z = pos_data[5]; for(std::size_t v=1, vn=pos_data.size()/3; v!=vn; ++v) { GLfloat x = pos_data[v*3+0]; GLfloat y = pos_data[v*3+1]; GLfloat z = pos_data[v*3+2]; if(min_x > x) min_x = x; if(min_y > y) min_y = y; if(min_z > z) min_z = z; if(max_x < x) max_x = x; if(max_y < y) max_y = y; if(max_z < z) max_z = z; } // position the camera target camera_target = Vec3f( (min_x + max_x) * 0.5, (min_y + max_y) * 0.5, (min_z + max_z) * 0.5 ); // and calculate a good value for camera distance camera_distance = 1.1*Distance(camera_target, Vec3f(min_x, min_y, min_z))+1.0; gl.ClearColor(0.17f, 0.22f, 0.17f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::PrimitiveRestart); }
CubeMapExample(void) : make_shape(4) , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertNormal;" "out vec3 vertTexCoord;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 Normal = Position.xyz;" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertTexCoord = Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 3) out;" "in vec3 vertNormal[3];" "in vec3 vertTexCoord[3];" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec3 geomNormal;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "out vec3 geomLightRefl;" "out vec3 geomViewDir;" "void main(void)" "{" " vec3 FaceNormal = 0.333333*(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " for(int v=0; v!=3; ++v)" " {" " gl_Position = gl_in[v].gl_Position;" " geomNormal = 0.5*(vertNormal[v]+FaceNormal);" " geomTexCoord = vertTexCoord[v];" " geomLightDir = vertLightDir[v];" " geomLightRefl = reflect(" " -normalize(geomLightDir)," " normalize(FaceNormal)" " );" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 geomNormal;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "in vec3 geomLightRefl;" "in vec3 geomViewDir;" "out vec3 fragColor;" "void main(void)" "{" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 tex = texture(TexUnit, geomTexCoord).rgb;" " float d = dot(" " normalize(geomNormal), " " normalize(geomLightDir)" " );" " float s = dot(" " normalize(geomLightRefl)," " normalize(geomViewDir)" " );" " float b = 1.0-sqrt(max(dot(" " normalize(geomNormal)," " normalize(geomViewDir)" " ), 0.0));" " float ea = clamp(tex.b*(-d+0.2), 0.0, 1.0);" " float sr = 1.0-tex.b*0.8;" " fragColor = " " tex * (0.3*ea + 0.6*b + 0.8*max(d, 0.0)) + " " (tex+lt) * 0.8*sr*pow(clamp(s+0.05, 0.0, 1.0), 32);" "}" ); 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 shape shape.Bind(); positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture { auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); const char* tex_name[6] = { "cube_0_right", "cube_1_left", "cube_2_top", "cube_3_bottom", "cube_4_front", "cube_5_back" }; for(GLuint i=0; i!=6; ++i) { Texture::Image2D( Texture::CubeMapFace(i), images::LoadTexture(tex_name[i], false, true) ); } } UniformSampler(prog, "TexUnit").Set(0); // Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.05f, 0.2f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); }
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); }
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); }
SmokeExample(void) : emitters() , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f(-20.0f, -10.0f, 10.0f)) (Vec3f( 20.0f, 0.0f, -20.0f)) (Vec3f( 20.0f, 10.0f, 20.0f)) (Vec3f(-20.0f, 0.0f, -10.0f)) .As<std::vector<Vec3f>>(), 5.0, 200.0 ) ); emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f( 30.0f, 0.0f, 0.0f)) (Vec3f(-30.0f, 0.0f, 0.0f)) (Vec3f(-20.0f, 20.0f, 0.0f)) (Vec3f( 20.0f, -10.0f, 0.0f)) .As<std::vector<Vec3f>>(), 3.0, 200.0 ) ); emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f( 5.0f, 20.0f, 20.0f)) (Vec3f( -5.0f, 20.0f, -20.0f)) (Vec3f( 5.0f, -20.0f, -20.0f)) (Vec3f( -5.0f, -20.0f, 20.0f)) .As<std::vector<Vec3f>>(), 20.0, 100.0 ) ); // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix;" "in vec4 Position;" "in float Age;" "out float vertAge;" "void main(void)" "{" " gl_Position = CameraMatrix * Position;" " vertAge = Age;" "}" ); // 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 mat4 ProjectionMatrix;" "in float vertAge[];" "out float geomAge;" "void main(void)" "{" " if(vertAge[0] > 1.0) return;" " float s = 0.5;" " 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)" " {" " float xoffs = xo[i]*(1.0+vertAge[0])*s;" " float yoffs = yo[j]*(1.0+vertAge[0])*s;" " gl_Position = ProjectionMatrix * vec4(" " gl_in[0].gl_Position.x-xoffs," " gl_in[0].gl_Position.y-yoffs," " gl_in[0].gl_Position.z," " 1.0" " );" " geomAge = vertAge[0];" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in float geomAge;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Color1 = vec3(1.0, 0.5, 0.5);" " vec3 Color2 = vec3(0.3, 0.1, 0.1);" " fragColor = vec4(" " mix(Color1, Color2, geomAge)," " 1.0 - geomAge" " );" "}" ); // 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, BufferUsage::DynamicDraw); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages, BufferUsage::DynamicDraw); VertexAttribArray attr(prog, "Age"); attr.Setup(1, DataType::Float); attr.Enable(); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "in vec4 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " 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 = (" " 1 +" " int(vertTexCoord.x*8) % 2+" " int(vertTexCoord.y*8) % 2" " ) % 2;" " 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(); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertices verts.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(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the cube texture-coordinates texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.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); }
CloudExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { // Set the vertex shader source vs.Source( "#version 330\n" "in vec4 Position;" "uniform mat4 CameraMatrix;" "void main(void)" "{" " gl_Position = " " CameraMatrix *" " Position;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 100) out;" "const int p = 25;" "const float hp = (p-1)*0.5;" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "void main(void)" "{" " float s = 0.6;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " vec3 cx = vec3(" " CameraMatrix[0][0]," " CameraMatrix[1][0]," " CameraMatrix[2][0] " " );" " vec3 cy = vec3(" " CameraMatrix[0][1]," " CameraMatrix[1][1]," " CameraMatrix[2][1] " " );" " vec3 cz = vec3(" " CameraMatrix[0][2]," " CameraMatrix[1][2]," " CameraMatrix[2][2] " " );" " for(int k=0;k!=p;++k)" " {" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float zo = ((k - hp) / hp);" " float xoffs = xo[i]*s;" " float yoffs = yo[j]*s;" " float zoffs = zo *s;" " vec4 v = vec4(" " gl_in[0].gl_Position.x+xoffs," " gl_in[0].gl_Position.y+yoffs," " gl_in[0].gl_Position.z+zoffs," " 1.0" " );" " gl_Position = ProjectionMatrix * v;" " geomLightDir = LightPos - v.xyz;" " geomTexCoord = " " vec3(0.5, 0.5, 0.5)+" " cx*(xo[i])*0.707+" " cy*(yo[j])*0.707+" " cz*(zo )*0.707;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); // compile it gs.Compile(); // set the fragment shader source 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.2 * d;" " float i = mix(0.4, 1.0, o);" " fragColor = vec4(i, i, i, a);" "}" ); // 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 clouds clouds.Bind(); // bind the VBO for the cloud positions buffer.Bind(Buffer::Target::Array); { GLfloat positions[3] = {0.5f, 0.1f, 0.2f}; Buffer::Data(Buffer::Target::Array, 3, positions); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } { Texture::Active(0); UniformSampler(prog, "cloudTex").Set(0); auto bound_tex = Bind(cloud_tex, Texture::Target::_3D); bound_tex.Image3D(images::Cloud(128, 128, 128)); 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); } Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(10.0f, 1.0f, 5.0f)); gl.ClearColor(0.2f, 0.3f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
HaloExample(void) : make_shape() , shape_indices(make_shape.Indices()) , shape_instr(make_shape.Instructions()) , vs_shape(ObjectDesc("Shape VS")) , vs_plane(ObjectDesc("Plane VS")) , fs_shape(ObjectDesc("Shape FS")) , fs_plane(ObjectDesc("Plane FS")) , vs_halo(ObjectDesc("Halo VS")) , gs_halo(ObjectDesc("Halo GS")) , fs_halo(ObjectDesc("Halo FS")) , shape_projection_matrix(shape_prog, "ProjectionMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , shape_model_matrix(shape_prog, "ModelMatrix") , plane_projection_matrix(plane_prog, "ProjectionMatrix") , plane_camera_matrix(plane_prog, "CameraMatrix") , halo_projection_matrix(halo_prog, "ProjectionMatrix") , halo_camera_matrix(halo_prog, "CameraMatrix") , halo_model_matrix(halo_prog, "ModelMatrix") { vs_shape.Source( "#version 140\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "out vec3 vertNormal;" "out vec3 vertViewNormal;" "out vec3 vertLight;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertViewNormal = mat3(CameraMatrix)*vertNormal;" " vertLight = LightPos - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs_shape.Compile(); fs_shape.Source( "#version 140\n" "in vec3 vertNormal;" "in vec3 vertViewNormal;" "in vec3 vertLight;" "uniform mat4 CameraMatrix;" "out vec4 fragColor;" "void main(void)" "{" " float ltlen = sqrt(length(vertLight));" " float ltexp = dot(" " normalize(vertNormal)," " normalize(vertLight)" " );" " float lview = dot(" " normalize(vertLight)," " normalize(vec3(" " CameraMatrix[0][2]," " CameraMatrix[1][2]," " CameraMatrix[2][2] " " ))" " );" " float depth = normalize(vertViewNormal).z;" " vec3 ftrefl = vec3(0.9, 0.8, 0.7);" " vec3 scatter = vec3(0.9, 0.6, 0.1);" " vec3 bklt = vec3(0.8, 0.6, 0.4);" " vec3 ambient = vec3(0.5, 0.4, 0.3);" " fragColor = vec4(" " pow(max(ltexp, 0.0), 8.0)*ftrefl+" " ( ltexp+1.0)/ltlen*pow(depth,2.0)*scatter+" " (-ltexp+1.0)/ltlen*(1.0-depth)*scatter+" " (-lview+1.0)*0.6*(1.0-abs(depth))*bklt+" " 0.2*ambient," " 1.0" " );" "}" ); fs_shape.Compile(); shape_prog.AttachShader(vs_shape); shape_prog.AttachShader(fs_shape); shape_prog.Link(); vs_plane.Source( "#version 140\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "uniform vec3 LightPos;" "out vec3 vertNormal;" "out vec3 vertLight;" "void main(void)" "{" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" " vertNormal = Normal;" " vertLight = LightPos-Position.xyz;" "}" ); vs_plane.Compile(); fs_plane.Source( "#version 140\n" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "void main(void)" "{" " float l = sqrt(length(vertLight));" " float e = dot(" " vertNormal," " normalize(vertLight)" " );" " float d = l > 0.0 ? e / l : 0.0;" " float i = 0.2 + 2.5 * d;" " fragColor = vec4(0.8*i, 0.7*i, 0.4*i, 1.0);" "}" ); fs_plane.Compile(); plane_prog.AttachShader(vs_plane); plane_prog.AttachShader(fs_plane); plane_prog.Link(); vs_halo.Source( "#version 150\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ModelMatrix, CameraMatrix;" "out vec3 vertNormal;" "out float vd;" "void main(void)" "{" " gl_Position = " " CameraMatrix *" " ModelMatrix *" " Position;" " vertNormal = (" " CameraMatrix *" " ModelMatrix *" " vec4(Normal, 0.0)" " ).xyz;" " vd = vertNormal.z;" "}" ); vs_halo.Compile(); gs_halo.Source( "#version 150\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 12) out;" "in vec3 vertNormal[];" "in float vd[];" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "out float geomAlpha;" "void main(void)" "{" " 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;" " vec3 na = vertNormal[a];" " vec3 nb = vertNormal[b];" " vec3 nc = vertNormal[c];" " vec3 nx, ny;" " if(vd[a] == 0.0 && vd[b] == 0.0)" " {" " px = pa;" " nx = na;" " py = pb;" " ny = nb;" " }" " else if(vd[a] > 0.0 && vd[b] < 0.0)" " {" " float x = vd[a]/(vd[a]-vd[b]);" " float y;" " px = mix(pa, pb, x);" " nx = mix(na, nb, x);" " if(vd[c] < 0.0)" " {" " y = vd[a]/(vd[a]-vd[c]);" " py = mix(pa, pc, y);" " ny = mix(na, nc, y);" " }" " else" " {" " y = vd[c]/(vd[c]-vd[b]);" " py = mix(pc, pb, y);" " ny = mix(nc, nb, y);" " }" " }" " else continue;" " vec4 gx1 = vec4(px.xyz, 1.0);" " vec4 gy1 = vec4(py.xyz, 1.0);" " vec4 gx2 = vec4(px.xyz + nx*0.3, 1.0);" " vec4 gy2 = vec4(py.xyz + ny*0.3, 1.0);" " gl_Position = ProjectionMatrix * gy1;" " geomAlpha = 1.0;" " EmitVertex();" " gl_Position = ProjectionMatrix * gx1;" " geomAlpha = 1.0;" " EmitVertex();" " gl_Position = ProjectionMatrix * gy2;" " geomAlpha = 0.0;" " EmitVertex();" " gl_Position = ProjectionMatrix * gx2;" " geomAlpha = 0.0;" " EmitVertex();" " EndPrimitive();" " break;" " }" "}" ); gs_halo.Compile(); fs_halo.Source( "#version 150\n" "in float geomAlpha;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(" " 0.5, 0.4, 0.3," " pow(geomAlpha, 2.0)" " );" "}" ); fs_halo.Compile(); halo_prog.AttachShader(vs_halo); halo_prog.AttachShader(gs_halo); halo_prog.AttachShader(fs_halo); halo_prog.Link(); // bind the VAO for the shape shape.Bind(); // bind the VBO for the shape vertices shape_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribSlot location; if(VertexArrayAttrib::QueryCommonLocation( MakeGroup(shape_prog, halo_prog), "Position", location )) { VertexArrayAttrib attr(location); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } else OGLPLUS_ABORT("Inconsistent 'Position' location"); } // bind the VBO for the shape normals shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); shape_prog.Use(); VertexArrayAttrib attr(shape_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); plane_prog.Use(); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the plane 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); plane_prog.Use(); VertexArrayAttrib attr(plane_prog, "Normal"); attr.Setup<Vec3f>(); attr.Enable(); } Vec3f lightPos(2.0f, 2.5f, 9.0f); ProgramUniform<Vec3f>(shape_prog, "LightPos").Set(lightPos); ProgramUniform<Vec3f>(plane_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.BlendFunc(BlendFn::SrcAlpha, BlendFn::One); }
LandscapeExample(void) : grid_side(128) , make_plane( Vec3f(0.0f, 0.0f, 0.0f), Vec3f(9.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-9.0f), grid_side*3, grid_side*3 ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , light_pos(prog, "LightPos") , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , light_path( ListOf<Vec3f> (Vec3f(-3.0f, 2.0f, -3.5f)) (Vec3f( 0.0f, 5.0f, 0.5f)) (Vec3f( 3.0f, 3.0f, 3.0f)) (Vec3f( 3.0f, 3.0f, -3.0f)) (Vec3f( 0.0f, 5.0f, 0.5f)) (Vec3f(-3.2f, 2.0f, 3.0f)) .Get() ) { VertexShader vs; vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "uniform sampler2D TexUnit;" "in vec4 Position;" "in vec2 TexCoord;" "out vec3 vertLight;" "out vec3 vertNormal;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = Position;" " float o = 0.0;" " float s[9];" " int k=0;" " for(int y=-1; y!=2; ++y)" " for(int x=-1; x!=2; ++x)" " {" " s[k] = sqrt(texture(" " TexUnit, " " TexCoord*3.0+" " vec2(x, y)/128.0" " ).r);" " o += s[k++];" " }" " gl_Position.y += o*0.5;" " vec3 c = vec3( 0.0, s[4], 0.0);" " float d = 1.0/32.0;" " vertNormal = normalize(" " cross(" " vec3( 0.0, s[1], -d) - c," " vec3( -d, s[3], 0.0) - c" " )+" " cross(" " vec3( d, s[5], 0.0) - c," " vec3( 0.0, s[1], -d) - c" " )+" " cross(" " vec3( 0.0, s[7], d) - c," " vec3( d, s[5], 0.0) - c" " )+" " cross(" " vec3( -d, s[3], 0.0) - c," " vec3( 0.0, s[7], d) - c" " )" " );" " vertLight = LightPos - gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" ); vs.Compile(); FragmentShader fs; fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLight);" " float d = l > 0? dot(" " normalize(vertNormal), " " normalize(vertLight)" " ) / l : 0.0;" " float i = 0.1 + 1.2*max(d, 0.0) + 4.2*pow(d, 2.0);" " fragColor = vec4(i*0.7, i*0.7, i*0.3, 1.0);" "}" ); 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 plane plane.Bind(); // bind the VBO for the plane vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.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 plane texture coordinates texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.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); { auto image = images::NewtonFractal( grid_side, grid_side, Vec3f(0.0f, 0.1f, 0.2f), Vec3f(1.0f, 0.8f, 0.9f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X3Minus1(), images::NewtonFractal::DefaultMixer() ); Texture::Image2D(tex_tgt, image); Texture::MinFilter(tex_tgt, TextureMinFilter::Linear); Texture::MagFilter(tex_tgt, TextureMagFilter::Linear); Texture::WrapS(tex_tgt, TextureWrap::MirroredRepeat); Texture::WrapT(tex_tgt, TextureWrap::MirroredRepeat); } // UniformSampler(prog, "TexUnit").Set(0); 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_plane.FaceWinding()); gl.CullFace(Face::Back); }