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()); }
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(); }
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); }
static Program make(void) { VertexShader vs; vs.Source( "#version 330\n" "uniform mat4 LightMatrix, ModelMatrix;" "uniform vec3 LightPosition;" "uniform vec3 CameraPosition;" "in vec4 Position;" "out vec4 vertDepthCoord;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertDepthCoord = LightMatrix * gl_Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertViewDir = CameraPosition - gl_Position.xyz;" "}" ).Compile(); GeometryShader gs; gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices=3) out;" "uniform mat4 CameraMatrix;" "in vec4 vertDepthCoord[3];" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec4 geomDepthCoord;" "out vec3 geomLightDir;" "out vec3 geomViewDir;" "out vec3 geomNormal;" "void main(void)" "{" " geomNormal = normalize(" " cross(" " gl_in[1].gl_Position.xyz-" " gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-" " gl_in[0].gl_Position.xyz " " )" " );" " for(int v=0; v!=3; ++v)" " {" " gl_Position = CameraMatrix * gl_in[v].gl_Position;" " geomDepthCoord = vertDepthCoord[v];" " geomLightDir = vertLightDir[v];" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ).Compile(); FragmentShader fs; fs.Source( "#version 330\n" "uniform sampler2D DepthMap;" "uniform vec2 DepthOffs[32];" "const int DepthSamples = 32;" "const float InvDepthSamples = 1.0 / DepthSamples;" "in vec4 gl_FragCoord;" "in vec4 geomDepthCoord;" "in vec3 geomLightDir;" "in vec3 geomViewDir;" "in vec3 geomNormal;" "out vec3 fragColor;" "void main(void)" "{" " float LightDist = geomDepthCoord.z/geomDepthCoord.w;" " vec3 Normal = normalize(geomNormal);" " vec3 LightDir = normalize(geomLightDir);" " vec3 LightRefl = reflect(-LightDir, Normal);" " vec3 ViewDir = normalize(geomViewDir);" " float inv_w = 1.0/geomDepthCoord.w;" " float Depth = 0.0;" " for(int s=0; s!=DepthSamples; ++s)" " {" " vec2 SampleCoord = DepthOffs[s]+geomDepthCoord.xy;" " SampleCoord *= inv_w;" " SampleCoord *= 0.5;" " SampleCoord += 0.5;" " float Sample = texture(DepthMap, SampleCoord).r;" " if(Sample < 0.95)" " Depth += Sample;" " else Depth += 0.5;" " }" " Depth *= InvDepthSamples;" " float Ambi = 0.15;" " float BkLt = (dot(-LightDir, ViewDir)+3.0)*0.25;" " float SuSS = pow(abs(Depth-LightDist), 2.0)*BkLt*1.2;" " float Shdw = min(pow(abs(Depth-LightDist)*2.0, 8.0), 1.0);" " float Diff = sqrt(max(dot(LightDir, Normal)+0.1, 0.0))*0.4;" " float Spec = pow(max(dot(LightRefl, ViewDir), 0.0), 64.0);" " vec3 Color = vec3(0.2, 0.9, 0.7);" " fragColor = (Ambi + Shdw*Diff + SuSS) * Color;" " fragColor += Shdw*Spec * vec3(1.0, 1.0, 1.0);" "}" ).Compile(); Program prog; prog << vs << gs << fs; prog.Link().Use(); ProgramUniform<Vec2f> depth_offs(prog, "DepthOffs"); for(GLuint i=0; i!=32; ++i) { float u = std::rand() / float(RAND_MAX); float v = std::rand() / float(RAND_MAX); float x = std::sqrt(v) * std::cos(2*3.1415*u); float y = std::sqrt(v) * std::sin(2*3.1415*u); depth_offs[i].Set(x, y); } return std::move(prog); }
static Program make_prog(void) { Program prog; VertexShader vs; vs.Source(StrCRef( "#version 330\n" "in vec3 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = vec4(Position, 1.0);" " vertTexCoord = TexCoord;" "}" )).Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source(StrCRef( "#version 330\n" "#extension GL_ARB_gpu_shader5 : enable\n" "layout(triangles, invocations = 7) in;" "layout(triangle_strip, max_vertices = 21) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "uniform vec3 CameraPosition;" "in vec2 vertTexCoord[3];" "out gl_PerVertex {" " vec4 gl_Position;" " float gl_ClipDistance[3];" "};" "flat out mat3 geomPositionFront;" "flat out mat3 geomTexCoordFront;" "flat out vec3 geomWFront;" "noperspective out vec3 geomBarycentric;" "out vec3 geomPosition;" "out vec3 geomTexCoord;" "void main(void)" "{" " vec4 world_pos[8*3];" " vec3 tex_coord[8*3];" " vec4 view_pos[8*3];" " vec3 screen_pos[8*3];" " bool front_facing[8];" " int ft = gl_InvocationID+1;" " for(int pass=0; pass!=2; ++pass)" " {" " bool first = pass == 0;" " if(((ft == 0) && first) || (((ft != 0) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " int w = 2-v;" " world_pos[0+v] = gl_in[w].gl_Position;" " tex_coord[0+v] = vec3(vertTexCoord[w], 0.0);" " }" " }" " vec4 n = vec4(-0.15 * normalize(cross(" " gl_in[1].gl_Position.xyz-gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-gl_in[0].gl_Position.xyz " " )), 0.0);" " if(((ft == 1) && first) || (((ft != 1) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " world_pos[3+v] = gl_in[v].gl_Position + n;" " tex_coord[3+v] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " int k = 2+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+0+v*6] = gl_in[v].gl_Position;" " tex_coord[6+0+v*6] = vec3(vertTexCoord[v], 0.0);" " world_pos[6+1+v*6] = gl_in[w].gl_Position;" " tex_coord[6+1+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+2+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+2+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " k = 3+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+3+v*6] = gl_in[w].gl_Position;" " tex_coord[6+3+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+4+v*6] = gl_in[w].gl_Position + n;" " tex_coord[6+4+v*6] = vec3(vertTexCoord[w], 1.0);" " world_pos[6+5+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+5+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int t=first?ft:0; t!=8; ++t)" " {" " if(!first && (t == ft)) continue;" " int o = t*3;" " for(int v=0; v!=3; ++v)" " {" " int w = o+v;" " view_pos[w] = Matrix * world_pos[w];" " screen_pos[w] = view_pos[w].xyz/view_pos[w].w;" " }" " front_facing[t] = cross(" " screen_pos[o+1]-screen_pos[o+0]," " screen_pos[o+2]-screen_pos[o+0] " " ).z < 0.0;" " if(first) break;" " }" " if(first && !front_facing[ft]) return;" " }" " int o = ft*3;" " vec4 clip_plane[3];" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " vec3 p0 = world_pos[o+v].xyz;" " vec3 p1 = world_pos[o+w].xyz;" " vec3 p2 = CameraPosition;" " vec3 pv = normalize(cross(p1-p0, p2-p0));" " clip_plane[v] = vec4(pv, -dot(pv, p0));" " }" " vec3 lo = CameraPosition;" " vec3 p0 = world_pos[o+0].xyz;" " vec3 pu = world_pos[o+1].xyz-p0;" " vec3 pv = world_pos[o+2].xyz-p0;" " vec3 lp = lo-p0;" " float w0 = view_pos[o+0].w;" " float wu = view_pos[o+1].w-w0;" " float wv = view_pos[o+2].w-w0;" " vec3 t0 = tex_coord[o+0];" " vec3 tu = tex_coord[o+1]-t0;" " vec3 tv = tex_coord[o+2]-t0;" " for(int bt=0; bt!=8; ++bt)" " {" " int k = bt*3;" " if((ft != bt) && !front_facing[bt])" " {" " for(int v=0; v!=3; ++v)" " {" " vec3 lt = world_pos[k+v].xyz;" " mat3 im = mat3(lo-lt, pu, pv);" " vec3 ic = inverse(im)*lp;" " float s = ic.y;" " float t = ic.z;" " geomPositionFront[v] = p0+pu*s+pv*t;" " geomTexCoordFront[v] = t0+tu*s+tv*t;" " geomWFront[v] = w0+wu*s+wv*t;" " }" " for(int v=0; v!=3; ++v)" " {" " int w = k+v;" " gl_Position = view_pos[w];" " for(int c=0; c!=3; ++c)" " {" " gl_ClipDistance[c] = dot(" " clip_plane[c]," " world_pos[w]" " );" " }" " geomPosition = world_pos[w].xyz;" " geomTexCoord = tex_coord[w];" " geomBarycentric = vec3(0.0);" " geomBarycentric[v] = 1.0;" " EmitVertex();" " }" " EndPrimitive();" " }" " }" "}" )).Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source(StrCRef( "#version 330\n" "uniform float Time;" "uniform sampler2D ColorMap;" "uniform sampler2D BumpMap;" "uniform vec3 LightPosition;" "flat in mat3 geomPositionFront;" "flat in mat3 geomTexCoordFront;" "flat in vec3 geomWFront;" "noperspective in vec3 geomBarycentric;" "in vec3 geomPosition;" "in vec3 geomTexCoord;" "out vec3 fragColor;" "vec3 vcdiv(vec3 a, vec3 b)" "{" " return vec3(a.x/b.x, a.y/b.y, a.z/b.z);" "}" "void main(void)" "{" " const vec3 one = vec3(1.0, 1.0, 1.0);" " vec3 bzfv = vcdiv(geomBarycentric,geomWFront);" " vec3 p0 = geomPosition;" " vec3 p1 = (geomPositionFront*bzfv)/dot(one,bzfv);" " vec3 tc0 = geomTexCoord;" " vec3 tc1 = (geomTexCoordFront*bzfv)/dot(one,bzfv);" " ivec2 ts = textureSize(BumpMap, 0);" " int mts = max(ts.x, ts.y);" " vec2 dtc = tc1.xy - tc0.xy;" " float mdtc = max(abs(dtc.x), abs(dtc.y));" " int nsam = max(min(int(mdtc*mts), mts/2), 1);" " float step = 1.0 / nsam;" " for(int s=0; s<=nsam; ++s)" " {" " vec3 tc = mix(tc1, tc0, s*step);" " vec4 bm = texture(BumpMap, tc.xy);" " if(tc.z <= bm.w)" " {" " vec3 p = mix(p1, p0, s*step);" " vec3 ldir = normalize(LightPosition - p);" " float l = max(dot(ldir, bm.xzy), 0.0)*1.3;" " fragColor = texture(ColorMap, tc.xy).rgb*l;" " return;" " }" " }" " discard;" "}" )).Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); return prog; }
static Program make(void) { VertexShader vs; vs.Source( "#version 150\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPosition;" "uniform vec3 CameraPosition;" "in vec4 Position;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertViewDir = CameraPosition - gl_Position.xyz;" "}" ).Compile(); GeometryShader gs; gs.Source( "#version 150\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices=3) out;" "uniform mat4 CameraMatrix;" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec3 geomLightDir;" "out vec3 geomViewDir;" "out vec3 geomNormal;" "void main(void)" "{" " geomNormal = normalize(" " cross(" " gl_in[1].gl_Position.xyz-" " gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-" " gl_in[0].gl_Position.xyz " " )" " );" " for(int v=0; v!=3; ++v)" " {" " gl_Position = CameraMatrix * gl_in[v].gl_Position;" " geomLightDir = vertLightDir[v];" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ).Compile(); FragmentShader fs; fs.Source( "#version 150\n" "in vec3 geomLightDir;" "in vec3 geomViewDir;" "in vec3 geomNormal;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Normal = normalize(geomNormal);" " vec3 LightDir = normalize(geomLightDir);" " vec3 LightRefl = reflect(-LightDir, Normal);" " vec3 ViewDir = normalize(geomViewDir);" " fragColor = vec4(" " clamp(dot(Normal, ViewDir), 0, 1)," " clamp(dot(Normal, LightDir),0, 1)," " clamp(dot(ViewDir, LightRefl), 0, 1)," " gl_FragCoord.z" " );" "}" ).Compile(); Program prog(ObjectDesc("Data")); prog << vs << gs << fs; prog.Link().Use(); return std::move(prog); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , vs(ObjectDesc("Vertex")) , gs(ObjectDesc("Geometry")) , face_fs(ObjectDesc("Face fragment")) , frame_fs(ObjectDesc("Frame fragment")) , transf_prog(ObjectDesc("Transformation")) , face_prog(ObjectDesc("Face")) , frame_prog(ObjectDesc("Frame")) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 vertNormal;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;" " vertTexCoord = TexCoord;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 15) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in gl_PerVertex {" " vec4 gl_Position;" "} gl_in[];" "in vec3 vertNormal[];" "in vec2 vertTexCoord[];" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 geomNormal;" "out vec3 geomLight;" "out float geomGlow;" "flat out int geomTop;" "void main(void)" "{" " vec3 FaceNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " vec2 FaceCoord = 0.33333 * (" " vertTexCoord[0]+" " vertTexCoord[1]+" " vertTexCoord[2] " " );" " float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;" " Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;" " vec3 pos[3], norm[3];" " for(int i=0; i!=3; ++i)" " pos[i] = gl_in[i].gl_Position.xyz;" " for(int i=0; i!=3; ++i)" " norm[i] = cross(" " FaceNormal, " " normalize(pos[(i+1)%3] - pos[i])" " );" " vec3 pofs = FaceNormal * Offs;" " geomTop = 0;" " for(int i=0; i!=3; ++i)" " {" " geomNormal = norm[i];" " for(int j=0; j!=2; ++j)" " {" " vec3 tpos = pos[(i+j)%3];" " geomLight = LightPos-tpos;" " geomGlow = 1.0;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos, 1.0);" " EmitVertex();" " geomGlow = 0.7;" " geomLight = LightPos-tpos+pofs;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" " }" " geomGlow = 0.0;" " geomTop = 1;" " for(int i=0; i!=3; ++i)" " {" " geomLight = LightPos - (pos[i]+pofs);" " geomNormal = vertNormal[i];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(pos[i] + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); transf_prog.AttachShader(vs); transf_prog.AttachShader(gs); transf_prog.MakeSeparable(); transf_prog.Link(); transf_prog.Use(); ProgramUniform<Vec3f>(transf_prog, "LightPos").Set(4, 4, -8); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } face_fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLight;" "in float geomGlow;" "flat in int geomTop;" "uniform vec3 TopColor, SideColor;" "const vec3 LightColor = vec3(1.0, 1.0, 1.0);" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(" " normalize(geomLight)," " normalize(geomNormal)" " ), 0.0);" " vec3 color;" " if(geomTop != 0)" " {" " color = TopColor * d +" " LightColor * pow(d, 8.0);" " }" " else" " {" " color = SideColor * geomGlow +" " LightColor *" " pow(d, 2.0) * 0.2;" " }" " fragColor = vec4(color, 1.0);" "}" ); face_fs.Compile(); face_prog.AttachShader(face_fs); face_prog.MakeSeparable(); face_prog.Link(); ProgramUniform<Vec3f>(face_prog, "TopColor").Set(0.2f, 0.2f, 0.2f); ProgramUniform<Vec3f>(face_prog, "SideColor").Set(0.9f, 0.9f, 0.2f); face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.2, 0.1, 0.0, 1.0);" "}" ); frame_fs.Compile(); frame_prog.AttachShader(frame_fs); frame_prog.MakeSeparable(); frame_prog.Link(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); ProgramPipeline::Unbind(); Program::UseNone(); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
static Program make_transf_prog(void) { VertexShader vs; vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 vertNormal;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;" " vertTexCoord = TexCoord;" "}" ); vs.Compile(); GeometryShader gs; gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 15) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in gl_PerVertex {" " vec4 gl_Position;" "} gl_in[];" "in vec3 vertNormal[];" "in vec2 vertTexCoord[];" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 geomNormal;" "out vec3 geomLight;" "out float geomGlow;" "flat out int geomTop;" "void main(void)" "{" " vec3 FaceNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " vec2 FaceCoord = 0.33333 * (" " vertTexCoord[0]+" " vertTexCoord[1]+" " vertTexCoord[2] " " );" " float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;" " Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;" " vec3 pos[3], norm[3];" " for(int i=0; i!=3; ++i)" " pos[i] = gl_in[i].gl_Position.xyz;" " for(int i=0; i!=3; ++i)" " norm[i] = cross(" " FaceNormal, " " normalize(pos[(i+1)%3] - pos[i])" " );" " vec3 pofs = FaceNormal * Offs;" " geomTop = 0;" " for(int i=0; i!=3; ++i)" " {" " geomNormal = norm[i];" " for(int j=0; j!=2; ++j)" " {" " vec3 tpos = pos[(i+j)%3];" " geomLight = LightPos-tpos;" " geomGlow = 1.0;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos, 1.0);" " EmitVertex();" " geomGlow = 0.7;" " geomLight = LightPos-tpos+pofs;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" " }" " geomGlow = 0.0;" " geomTop = 1;" " for(int i=0; i!=3; ++i)" " {" " geomLight = LightPos - (pos[i]+pofs);" " geomNormal = vertNormal[i];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(pos[i] + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); Program prog; prog.AttachShader(vs); prog.AttachShader(gs); prog.MakeSeparable(); prog.Link(); ProgramUniform<Vec3f>(prog, "LightPos").Set(4, 4, -8); return prog; }
TorusExample(void) : make_torus(1.0, 0.5, 12, 12) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , light_pos_cam(prog, "LightPosCam") , front_color(prog, "FrontColor") , back_color(prog, "BackColor") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix, CameraMatrix;" "in vec4 Position;" "void main(void)" "{" " gl_Position = CameraMatrix *" " ModelMatrix * Position;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 8) out;" "uniform mat4 ProjectionMatrix;" "uniform vec4 LightPosCam;" "out vec3 geomLightDir;" "out float geomOpacity;" "void main(void)" "{" " vec4 c = vec4((" " gl_in[0].gl_Position.xyz+" " gl_in[1].gl_Position.xyz+" " gl_in[2].gl_Position.xyz " " ) * 0.333333, 1.0);" " for(int v = 0; v != 4; ++v)" " {" " vec4 b = gl_in[v%3].gl_Position;" " vec4 a = vec4(" " b.xyz + (c.xyz - b.xyz)*0.3," " 1.0" " );" " gl_Position = ProjectionMatrix * a;" " geomLightDir = (LightPosCam - a).xyz;" " geomOpacity = 1.0;" " EmitVertex();" " gl_Position = ProjectionMatrix * b;" " geomLightDir = (LightPosCam - b).xyz;" " geomOpacity = 0.0;" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); fs.Source( "#version 330\n" "in vec3 geomLightDir;" "in float geomOpacity;" "uniform vec3 FrontColor, BackColor;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLightDir);" " vec3 color = gl_FrontFacing?" " FrontColor:" " BackColor;" " fragColor = vec4(color*(4.0/l), geomOpacity);" "}" ); fs.Compile(); prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); prog.Link(); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); prog.Use(); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } gl.ClearColor(0.8f, 0.7f, 0.6f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::LEqual); gl.FrontFace(make_torus.FaceWinding()); }
static Program make(void) { Program prog; VertexShader vs; vs.Source( "#version 330\n" "in vec4 Position;" "in ivec3 TexCoord;" "out ivec3 vertTexCoord;" "void main(void)" "{" " gl_Position = Position;" " vertTexCoord = TexCoord;" "}" ).Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source( "#version 330\n" "layout (points) in;" "layout (triangle_strip, max_vertices=24) out;" "uniform float FadeCoef;" "uniform sampler3D Pattern, FadeMap;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix*CameraMatrix;" "uniform vec3 LightPosition = vec3(100, 120, 150);" "in ivec3 vertTexCoord[1];" "out vec3 geomNormal;" "out vec3 geomLightDir;" "out vec3 geomTexCoord;" "out float geomShadow;" "float get_cell(ivec3 offs)" "{" " ivec3 coord = vertTexCoord[0]+offs;" " float patt = texelFetch(Pattern, coord, 0).r;" " float fade = texelFetch(FadeMap, coord, 0).r;" " return clamp(" " (patt != 0.0)?" " (FadeCoef-fade)*256.0:" " 0.0, 0.0, 1.0" " );" "}" "const ivec3 coffs[6] = ivec3[6](" " ivec3(+1, 0, 0)," " ivec3(-1, 0, 0)," " ivec3( 0,+1, 0)," " ivec3( 0,-1, 0)," " ivec3( 0, 0,+1)," " ivec3( 0, 0,-1) " ");" "const mat3 tmats[6] = mat3[6](" " mat3( 0, 0, 1, 0,-1, 0, 1, 0, 0)," " mat3( 0, 0,-1, 0,-1, 0, -1, 0, 0)," " mat3(-1, 0, 0, 0, 0, 1, 0, 1, 0)," " mat3(-1, 0, 0, 0, 0,-1, 0,-1, 0)," " mat3( 1, 0, 0, 0, 1, 0, 0, 0, 1)," " mat3(-1, 0, 0, 0, 1, 0, 0, 0,-1) " ");" "const vec3[8] nvec = vec3[8](" " vec3( 0,-1,+1)," " vec3(+1,-1,+1)," " vec3(+1, 0,+1)," " vec3(+1,+1,+1)," " vec3( 0,+1,+1)," " vec3(-1,+1,+1)," " vec3(-1, 0,+1)," " vec3(-1,-1,+1) " ");" "void main(void)" "{" " float cc = get_cell(ivec3(0,0,0));" " if(cc > 0.0)" " {" " float c05 = 0.5*cc;" " float c0 = 0.5-c05;" " float c1 = 0.5+c05;" " for(int f=0; f!=6; ++f)" " if(get_cell(coffs[f]) < 1.0)" " {" " int config = 0x0;" " vec3 noffs[8];" " vec3 nml = tmats[f][2];" " float aoc = get_cell(ivec3(nml*2));" " aoc += 0.8*get_cell(ivec3(nml*3));" " for(int n=0; n!=8; ++n)" " {" " noffs[n] = nvec[n]*tmats[f];" " float nc = get_cell(ivec3(noffs[n]));" " aoc += 0.2*get_cell(ivec3(noffs[n]+nml));" " aoc += 0.1*get_cell(ivec3(noffs[n]+nml*2));" " config |= (nc>0.0)?0x1<<n:0x0;" " }" " float aom = float(config);" " geomNormal = tmats[f][2];" " geomShadow = max(1.0-sqrt(aoc), 0.0);" " vec3 cpos = gl_in[0].gl_Position.xyz;" " gl_Position = vec4(cpos+noffs[7]*c05, 1.0);" " geomLightDir = LightPosition - gl_Position.xyz;" " gl_Position = Matrix * gl_Position;" " geomTexCoord = vec3(c0, c1, aom);" " EmitVertex();" " gl_Position = vec4(cpos+noffs[1]*c05, 1.0);" " geomLightDir = LightPosition - gl_Position.xyz;" " gl_Position = Matrix * gl_Position;" " geomTexCoord = vec3(c1, c1, aom);" " EmitVertex();" " gl_Position = vec4(cpos+noffs[5]*c05, 1.0);" " geomLightDir = LightPosition - gl_Position.xyz;" " gl_Position = Matrix * gl_Position;" " geomTexCoord = vec3(c0, c0, aom);" " EmitVertex();" " gl_Position = vec4(cpos+noffs[3]*c05, 1.0);" " geomLightDir = LightPosition - gl_Position.xyz;" " gl_Position = Matrix * gl_Position;" " geomTexCoord = vec3(c1, c0, aom);" " EmitVertex();" " EndPrimitive();" " }" " }" "}" ).Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source( "#version 330\n" "uniform sampler2DArray AmbiOcclMaps;" "in vec3 geomNormal;" "in vec3 geomLightDir;" "in vec3 geomTexCoord;" "in float geomShadow;" "out vec3 fragColor;" "void main(void)" "{" " float amoc = texture(AmbiOcclMaps, geomTexCoord).r;" " float shdw = sqrt(0.5*(1.0+geomShadow));" " float ambi = 0.5;" " float diff = max(dot(geomNormal, normalize(geomLightDir)), 0)*0.6;" " float light = ambi*amoc*shdw + (0.8*amoc*shdw+0.2)*diff;" " fragColor = vec3(1,1,1)*light;" "}" ).Compile(); prog.AttachShader(fs); prog.Link().Use(); return std::move(prog); }
SinglePassEdgeExample(void) : make_shape(1, shapes::SubdivSphereInitialShape::Octohedron) , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , vs(ObjectDesc("Vertex")) , gs(ObjectDesc("Geometry")) , fs(ObjectDesc("Fragment")) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , viewport_dimensions(prog, "ViewportDimensions") , edge_width(prog, "EdgeWidth") { vs.Source(StrLit( "#version 330\n" "const vec3 LightPosition = vec3(10.0, 10.0, 7.0);" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "void main(void)" "{" " gl_Position = " " ModelMatrix *" " Position;" " vertNormal = (" " ModelMatrix *" " vec4(Position.xyz, 0.0)" " ).xyz;" " vertLightDir = " " LightPosition -" " gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" )); vs.Compile(); gs.Source(StrLit( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 3) out;" "uniform vec2 ViewportDimensions;" "in vec3 vertNormal[], vertLightDir[];" "noperspective out vec3 geomDist;" "flat out vec3 geomNormal;" "flat out vec3 geomColor;" "out vec3 geomLightDir;" "void main(void)" "{" " geomNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2]" " );" " geomColor = normalize(abs(" " vec3(1.0, 1.0, 1.0)-" " geomNormal" " ));" " 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;" " geomLightDir = vertLightDir[i];" " geomDist = EdgeMask[i] * DistVect;" " EmitVertex();" " }" " EndPrimitive();" "}" )); gs.Compile(); fs.Source(StrLit( "#version 330\n" "uniform float EdgeWidth;" "noperspective in vec3 geomDist;" "flat in vec3 geomNormal;" "flat 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/EdgeWidth, 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(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); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); gl.FrontFace(make_shape.FaceWinding()); prog.Use(); }
WritingExample(void) { VertexShader vs; // Set the vertex shader source vs.Source( "#version 330\n" "in vec4 Position;" "void main(void)" "{" " gl_Position = Position;" "}" ); // compile it vs.Compile(); GeometryShader gs; // Set the geometry shader source gs.Source( "#version 330\n" "layout(lines) in;" "layout(triangle_strip, max_vertices = 4) out;" "void main(void)" "{" " vec4 offs = vec4(0.02, 0.01, 0.0, 0.0);" " gl_Position = gl_in[0].gl_Position - offs;" " EmitVertex();" " gl_Position = gl_in[0].gl_Position + offs;" " EmitVertex();" " gl_Position = gl_in[1].gl_Position - offs;" " EmitVertex();" " gl_Position = gl_in[1].gl_Position + offs;" " EmitVertex();" " EndPrimitive();" "}" ); // compile it gs.Compile(); FragmentShader fs; // set the fragment shader source fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.0, 0.0, 0.0, 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(); const Vec2f points[] = { Vec2f(-0.33f, +0.50f), Vec2f(-0.45f, +0.70f), Vec2f(-0.66f, +0.70f), Vec2f(-0.66f, +0.30f), Vec2f(-0.66f, -0.20f), Vec2f(-0.35f, -0.15f), Vec2f(-0.30f, +0.05f), Vec2f(-0.20f, +0.50f), Vec2f(-0.30f, +0.50f), Vec2f(-0.33f, +0.50f), Vec2f(-0.50f, +0.45f), Vec2f(-0.10f, +0.40f), Vec2f(+0.10f, +0.55f), Vec2f(-0.20f, +0.40f), Vec2f(-0.30f, -0.10f), Vec2f( 0.00f, -0.10f), Vec2f(+0.10f, -0.10f), Vec2f(+0.20f, -0.10f), Vec2f(+0.10f, +0.55f), Vec2f(+0.20f, +0.00f), Vec2f(+0.30f, -0.70f), Vec2f( 0.00f, -0.75f), Vec2f(-0.40f, -0.75f), Vec2f( 0.00f, 0.00f), Vec2f(+0.40f, +0.10f), Vec2f(+0.60f, +0.10f), Vec2f(+0.70f, +0.90f), Vec2f(+0.55f, +0.90f), Vec2f(+0.35f, +0.90f), Vec2f(+0.10f, -0.10f), Vec2f(+0.55f, 0.00f), Vec2f(+0.90f, 0.10f), Vec2f(+0.70f, 0.10f), Vec2f(+0.90f, 0.20f) }; BezierCurves<Vec2f, double, 3> bezier( std::vector<Vec2f>( points, points+sizeof(points)/sizeof(points[0]) ) ); writing.Bind(); { auto data = bezier.Approximate(25); curve_n = data.size(); Bind(curve_verts, Buffer::Target::Array).Data(data); VertexAttribArray attr(prog, "Position"); attr.Setup(2, DataType::Float); attr.Enable(); } gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { // Set the vertex shader source and compile it vs.Source( "#version 330\n" "in vec4 Position;" "void main(void)" "{" " gl_Position = Position;" "}" ).Compile(); // Set the geometry shader source and compile it gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 108) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "out vec3 vertColor;" "void main(void)" "{" " for(int c=0; c!=36; ++c)" " {" " float angle = c * 10 * 2 * 3.14159 / 360.0;" " float cx = cos(angle);" " float sx = sin(angle);" " mat4 ModelMatrix = mat4(" " cx, 0.0, sx, 0.0," " 0.0, 1.0, 0.0, 0.0," " -sx, 0.0, cx, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ) * 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," " 12.0, 0.0, 0.0, 1.0 " " );" " for(int v=0; v!=gl_in.length(); ++v)" " {" " vec4 vert = gl_in[v].gl_Position;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " vert;" " vertColor = abs(normalize(ModelMatrix*vert)).xzy;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ).Compile(); // set the fragment shader source and compile it fs.Source( "#version 330\n" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(vertColor, 1.0);" "}" ).Compile(); // attach the shaders to the program prog << vs << gs << fs; // link and use it prog.Link().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).Enable(); } gl.ClearColor(0.9f, 0.9f, 0.9f, 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); }
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)); }
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); }
CloudExample(const ExampleParams& params) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , samples(25 + params.quality*params.quality*100) , positions(make_positions()) , sizes(make_sizes()) , cloud_tex(positions.size()) , light_path(make_light_path_cps()) { assert(positions.size() == sizes.size()); std::srand(123456); light_vs.Source( "#version 330\n" "in vec3 Position;" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "void main(void)" "{" " float s = 0.1;" " gl_Position = " " ProjectionMatrix*" " CameraMatrix*" " vec4(Position*s + LightPos, 1.0);" "}" ).Compile(); light_fs.Source( "#version 330\n" "out vec4 fragLight;" "void main(void)" "{" " fragLight = vec4(1.0, 1.0, 1.0, 1.0);" "}" ).Compile(); light_prog << light_vs << light_fs; light_prog.Link().Use(); light.Bind(); buffer.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); Buffer::Data(Buffer::Target::Array, data); (light_prog|"Position").Setup(n_per_vertex, DataType::Float).Enable(); } cloud_vs.Source( "#version 330\n" "in vec4 Position;" "in float Size;" "uniform int SampleCount;" "uniform mat4 CameraMatrix;" "uniform vec4 ViewZ;" "out float vertZOffs;" "out float vertSize;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " vertSize = Size;" " gl_Position = vec4(" " Position.xyz +" " ViewZ.xyz*vertZOffs*Size*0.5," " 1.0" " );" "}" ).Compile(); cloud_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "in float vertSize[];" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec4 ViewX, ViewY, ViewZ;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "void main(void)" "{" " float zo = vertZOffs[0];" " float s = vertSize[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " vec4 v = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX.xyz * xo[i] * s * 0.5+" " ViewY.xyz * yo[j] * s * 0.5," " 1.0" " );" " gl_Position = ProjectionMatrix * CameraMatrix * v;" " geomLightDir = LightPos - v.xyz;" " geomTexCoord = " " vec3(0.5, 0.5, 0.5)+" " ViewX.xyz*(xo[i])*0.707+" " ViewY.xyz*(yo[j])*0.707+" " ViewZ.xyz*(zo )*0.707;" " EmitVertex();" " }" " EndPrimitive();" "}" ).Compile(); cloud_fs.Source( "#version 330\n" "uniform sampler3D CloudTex;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "out vec4 fragColor;" "void main(void)" "{" " float d = texture(CloudTex, geomTexCoord).r;" " float o = 1.0;" " float s = 2.0/128.0;" " float r = s * 8.0;" " vec3 sampleOffs = normalize(geomLightDir) * s;" " vec3 samplePos = geomTexCoord;" " if(d > 0.01) while(o > 0.0)" " {" " if(samplePos.x<0.0 || samplePos.x>1.0)" " break;" " if(samplePos.y<0.0 || samplePos.y>1.0)" " break;" " if(samplePos.z<0.0 || samplePos.z>1.0)" " break;" " o -= texture(CloudTex, samplePos).r*r;" " samplePos += sampleOffs;" " }" " float a = 0.4 * d;" " float i = mix(0.2, 1.0, o);" " fragColor = vec4(i, i, i, a);" "}" ).Compile(); cloud_prog << cloud_vs << cloud_gs << cloud_fs; cloud_prog.Link().Use(); // bind the VAO for the clouds clouds.Bind(); // bind the VBO for the cloud positions pos_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); (cloud_prog|"Position").Setup(3, DataType::Float).Enable(); } // bind the VBO for the cloud sizes size_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, sizes); (cloud_prog|"Size").Setup(1, DataType::Float).Enable(); } // set the number of samples cloud_prog/"SampleCount" = GLint(samples); Texture::Active(0); cloud_prog/"CloudTex" = 0; for(std::size_t i=0, n=positions.size(); i!=n; ++i) { auto bound_tex = Bind(cloud_tex[i], Texture::Target::_3D); bound_tex.Image3D( images::Cloud( 128, 128, 128, Vec3f(0.1f, -0.5f, 0.3f), 0.5f ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); bound_tex.WrapR(TextureWrap::ClampToBorder); } gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Disable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
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); }
TriangleExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("TexCoord").Get(), shapes::Plane( Vec3f(), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-1.0f), 32, 32 ) ) { VertexShader vs; vs.Source(StrLit( "#version 330\n" "in vec3 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = vec4(Position, 1.0);" " vertTexCoord = TexCoord;" "}" )).Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source(StrLit( "#version 330\n" "#extension GL_ARB_gpu_shader5 : enable\n" "layout(triangles, invocations = 7) in;" "layout(triangle_strip, max_vertices = 21) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "uniform vec3 CameraPosition;" "in vec2 vertTexCoord[3];" "out gl_PerVertex {" " vec4 gl_Position;" " float gl_ClipDistance[3];" "};" "flat out mat3 geomPositionFront;" "flat out mat3 geomTexCoordFront;" "flat out vec3 geomWFront;" "noperspective out vec3 geomBarycentric;" "out vec3 geomPosition;" "out vec3 geomTexCoord;" "void main(void)" "{" " vec4 world_pos[8*3];" " vec3 tex_coord[8*3];" " vec4 view_pos[8*3];" " vec3 screen_pos[8*3];" " bool front_facing[8];" " int ft = gl_InvocationID+1;" " for(int pass=0; pass!=2; ++pass)" " {" " bool first = pass == 0;" " if(((ft == 0) && first) || (((ft != 0) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " int w = 2-v;" " world_pos[0+v] = gl_in[w].gl_Position;" " tex_coord[0+v] = vec3(vertTexCoord[w], 0.0);" " }" " }" " vec4 n = vec4(-0.15 * normalize(cross(" " gl_in[1].gl_Position.xyz-gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-gl_in[0].gl_Position.xyz " " )), 0.0);" " if(((ft == 1) && first) || (((ft != 1) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " world_pos[3+v] = gl_in[v].gl_Position + n;" " tex_coord[3+v] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " int k = 2+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+0+v*6] = gl_in[v].gl_Position;" " tex_coord[6+0+v*6] = vec3(vertTexCoord[v], 0.0);" " world_pos[6+1+v*6] = gl_in[w].gl_Position;" " tex_coord[6+1+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+2+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+2+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " k = 3+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+3+v*6] = gl_in[w].gl_Position;" " tex_coord[6+3+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+4+v*6] = gl_in[w].gl_Position + n;" " tex_coord[6+4+v*6] = vec3(vertTexCoord[w], 1.0);" " world_pos[6+5+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+5+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int t=first?ft:0; t!=8; ++t)" " {" " if(!first && (t == ft)) continue;" " int o = t*3;" " for(int v=0; v!=3; ++v)" " {" " int w = o+v;" " view_pos[w] = Matrix * world_pos[w];" " screen_pos[w] = view_pos[w].xyz/view_pos[w].w;" " }" " front_facing[t] = cross(" " screen_pos[o+1]-screen_pos[o+0]," " screen_pos[o+2]-screen_pos[o+0] " " ).z < 0.0;" " if(first) break;" " }" " if(first && !front_facing[ft]) return;" " }" " int o = ft*3;" " vec4 clip_plane[3];" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " vec3 p0 = world_pos[o+v].xyz;" " vec3 p1 = world_pos[o+w].xyz;" " vec3 p2 = CameraPosition;" " vec3 pv = normalize(cross(p1-p0, p2-p0));" " clip_plane[v] = vec4(pv, -dot(pv, p0));" " }" " vec3 lo = CameraPosition;" " vec3 p0 = world_pos[o+0].xyz;" " vec3 pu = world_pos[o+1].xyz-p0;" " vec3 pv = world_pos[o+2].xyz-p0;" " vec3 lp = lo-p0;" " float w0 = view_pos[o+0].w;" " float wu = view_pos[o+1].w-w0;" " float wv = view_pos[o+2].w-w0;" " vec3 t0 = tex_coord[o+0];" " vec3 tu = tex_coord[o+1]-t0;" " vec3 tv = tex_coord[o+2]-t0;" " for(int bt=0; bt!=8; ++bt)" " {" " int k = bt*3;" " if((ft != bt) && !front_facing[bt])" " {" " for(int v=0; v!=3; ++v)" " {" " vec3 lt = world_pos[k+v].xyz;" " mat3 im = mat3(lo-lt, pu, pv);" " vec3 ic = inverse(im)*lp;" " float s = ic.y;" " float t = ic.z;" " geomPositionFront[v] = p0+pu*s+pv*t;" " geomTexCoordFront[v] = t0+tu*s+tv*t;" " geomWFront[v] = w0+wu*s+wv*t;" " }" " for(int v=0; v!=3; ++v)" " {" " int w = k+v;" " gl_Position = view_pos[w];" " for(int c=0; c!=3; ++c)" " {" " gl_ClipDistance[c] = dot(" " clip_plane[c]," " world_pos[w]" " );" " }" " geomPosition = world_pos[w].xyz;" " geomTexCoord = tex_coord[w];" " geomBarycentric = vec3(0.0);" " geomBarycentric[v] = 1.0;" " EmitVertex();" " }" " EndPrimitive();" " }" " }" "}" )).Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source(StrLit( "#version 330\n" "uniform float Time;" "uniform sampler2D ColorMap;" "uniform sampler2D BumpMap;" "uniform vec3 LightPosition;" "flat in mat3 geomPositionFront;" "flat in mat3 geomTexCoordFront;" "flat in vec3 geomWFront;" "noperspective in vec3 geomBarycentric;" "in vec3 geomPosition;" "in vec3 geomTexCoord;" "out vec3 fragColor;" "vec3 vcdiv(vec3 a, vec3 b)" "{" " return vec3(a.x/b.x, a.y/b.y, a.z/b.z);" "}" "void main(void)" "{" " const vec3 one = vec3(1.0, 1.0, 1.0);" " vec3 bzfv = vcdiv(geomBarycentric,geomWFront);" " vec3 p0 = geomPosition;" " vec3 p1 = (geomPositionFront*bzfv)/dot(one,bzfv);" " vec3 tc0 = geomTexCoord;" " vec3 tc1 = (geomTexCoordFront*bzfv)/dot(one,bzfv);" " ivec2 ts = textureSize(BumpMap, 0);" " int mts = max(ts.x, ts.y);" " vec2 dtc = tc1.xy - tc0.xy;" " float mdtc = max(abs(dtc.x), abs(dtc.y));" " int nsam = max(min(int(mdtc*mts), mts/2), 1);" " float step = 1.0 / nsam;" " for(int s=0; s<=nsam; ++s)" " {" " vec3 tc = mix(tc1, tc0, s*step);" " vec4 bm = texture(BumpMap, tc.xy);" " if(tc.z <= bm.w)" " {" " vec3 p = mix(p1, p0, s*step);" " vec3 ldir = normalize(LightPosition - p);" " float l = max(dot(ldir, bm.xzy), 0.0)*1.3;" " fragColor = texture(ColorMap, tc.xy).rgb*l;" " return;" " }" " }" " discard;" "}" )).Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); shape.UseInProgram(prog); auto tex_image = images::LoadTexture("stones_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); auto bound_tex = Bind(color_tex, Texture::Target::_2D); bound_tex.Image2D(tex_image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); auto bound_tex = Bind(bump_tex, Texture::Target::_2D); bound_tex.Image2D( images::NormalMap( tex_image, images::NormalMap::FromAlpha() ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Disable(Capability::CullFace); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Functionality::ClipDistance, 1); gl.Enable(Functionality::ClipDistance, 2); }
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(); }
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); }
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(); }
static Program make() { Program prog; StrCRef vs_src( "#version 150\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec3 Tangent;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertTangent;" "out vec2 vertTexCoord;" "void main()" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix) * Normal;" " vertTangent = mat3(ModelMatrix) * Tangent;" " vertTexCoord = vec2(4.0*TexCoord.x,2.0*TexCoord.y+TexCoord.x);" "}"); VertexShader vs; vs.Source(vs_src).Compile(); prog.AttachShader(vs); StrCRef gs_src( "#version 150\n" "#extension GL_ARB_gpu_shader5 : enable\n" "layout(triangles, invocations = 28) in;" "layout(triangle_strip, max_vertices = 6) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "uniform vec3 CameraPosition;" "const float WindingDirection = -1;" "const float ShellHeight = 0.1;" "in vec3 vertNormal[3];" "in vec3 vertTangent[3];" "in vec2 vertTexCoord[3];" "out gl_PerVertex {" " vec4 gl_Position;" " float gl_ClipDistance[3];" "};" "flat out mat3 geomPositionFront;" "flat out mat3 geomNormalFront;" "flat out mat3 geomTangentFront;" "flat out mat3 geomTexCoordFront;" "flat out vec3 geomWFront;" "noperspective out vec3 geomBarycentric;" "out vec3 geomPosition;" "out vec3 geomNormal;" "out vec3 geomTangent;" "out vec3 geomTexCoord;" "mat3x4 get_world_pos(int id)" "{" " mat3x4 result;" " id -= 2;" " if(id == -2)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = gl_in[2-v].gl_Position;" " }" " }" " else if(id == -1)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = gl_in[v].gl_Position+" " vec4(ShellHeight*vertNormal[v], 0.0);" " }" " }" " else" " {" " int v = id/2;" " int w = (v+1)%3;" " if(id % 2 == 0)" " {" " result[0] = gl_in[v].gl_Position;" " result[1] = gl_in[w].gl_Position;" " result[2] = gl_in[v].gl_Position+" " vec4(ShellHeight*vertNormal[v], 0.0);" " }" " else" " {" " result[0] = gl_in[w].gl_Position;" " result[1] = gl_in[w].gl_Position+" " vec4(ShellHeight*vertNormal[w], 0.0);" " result[2] = gl_in[v].gl_Position+" " vec4(ShellHeight*vertNormal[v], 0.0);" " }" " }" " return result;" "}" "mat3x4 get_view_pos(mat3x4 pos)" "{" " for(int v=0; v!=3; ++v)" " pos[v] = Matrix * pos[v];" " return pos;" "}" "mat3 get_screen_pos(mat3x4 pos)" "{" " mat3 res;" " for(int v=0; v!=3; ++v)" " res[v] = pos[v].xyz/pos[v].w;" " return res;" "}" "bool is_front_facing(mat3x4 view_pos)" "{" " mat3 screen_pos = get_screen_pos(view_pos);" " return WindingDirection * cross(" " screen_pos[1]-screen_pos[0]," " screen_pos[2]-screen_pos[0] " " ).z < 0.0;" "}" "mat3 get_tex_coords(int id)" "{" " mat3 result;" " id -= 2;" " if(id == -2)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = vec3(vertTexCoord[2-v], 0.0);" " }" " }" " else if(id == -1)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = vec3(vertTexCoord[v], 1.0);" " }" " }" " else" " {" " int v = id/2;" " int w = (v+1)%3;" " if(id % 2 == 0)" " {" " result[0] = vec3(vertTexCoord[v], 0.0);" " result[1] = vec3(vertTexCoord[w], 0.0);" " result[2] = vec3(vertTexCoord[v], 1.0);" " }" " else" " {" " result[0] = vec3(vertTexCoord[w], 0.0);" " result[1] = vec3(vertTexCoord[w], 1.0);" " result[2] = vec3(vertTexCoord[v], 1.0);" " }" " }" " return result;" "}" "mat3 get_vectors(int id, vec3 attrib[3])" "{" " mat3 result;" " id -= 2;" " if(id == -2)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = attrib[2-v];" " }" " }" " else if(id == -1)" " {" " for(int v=0; v!=3; ++v)" " {" " result[v] = attrib[v];" " }" " }" " else" " {" " int v = id/2;" " int w = (v+1)%3;" " if(id % 2 == 0)" " {" " result[0] = attrib[v];" " result[1] = attrib[w];" " result[2] = attrib[v];" " }" " else" " {" " result[0] = attrib[w];" " result[1] = attrib[w];" " result[2] = attrib[v];" " }" " }" " return result;" "}" "void main()" "{" " int ft = gl_InvocationID/4+1;" " mat3x4 world_pos_f = get_world_pos(ft);" " mat3x4 view_pos_f = get_view_pos(world_pos_f);" " if(!is_front_facing(view_pos_f)) return;" " int bt[2];" " bt[0] = (gl_InvocationID%4)*2;" " bt[1] = bt[0]+1;" " mat3x4 world_pos[2];" " mat3x4 view_pos[2];" " bool front_facing[2];" " for(int b=0; b!=2; ++b)" " {" " if(ft == bt[b])" " {" " front_facing[b] = true;" " }" " else" " {" " world_pos[b] = get_world_pos(bt[b]);" " view_pos[b] = get_view_pos(world_pos[b]);" " front_facing[b] = is_front_facing(view_pos[b]);" " }" " }" " if(front_facing[0] && front_facing[1]) return;" " vec4 clip_plane[3];" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " vec3 p0 = world_pos_f[v].xyz;" " vec3 p1 = world_pos_f[w].xyz;" " vec3 p2 = CameraPosition;" " vec3 pv = WindingDirection*normalize(cross(p1-p0, p2-p0));" " clip_plane[v] = vec4(pv, -dot(pv, p0));" " }" " vec3 lo = CameraPosition;" " vec3 p0 = world_pos_f[0].xyz;" " vec3 pu = world_pos_f[1].xyz-p0;" " vec3 pv = world_pos_f[2].xyz-p0;" " vec3 lp = lo-p0;" " float w0 = view_pos_f[0].w;" " float wu = view_pos_f[1].w-w0;" " float wv = view_pos_f[2].w-w0;" " mat3 normal_f = get_vectors(ft, vertNormal);" " vec3 n0 = normal_f[0];" " vec3 nu = normal_f[1]-n0;" " vec3 nv = normal_f[2]-n0;" " mat3 tangent_f = get_vectors(ft, vertTangent);" " vec3 t0 = tangent_f[0];" " vec3 tu = tangent_f[1]-t0;" " vec3 tv = tangent_f[2]-t0;" " mat3 tex_coord_f = get_tex_coords(ft);" " vec3 tc0 = tex_coord_f[0];" " vec3 tcu = tex_coord_f[1]-tc0;" " vec3 tcv = tex_coord_f[2]-tc0;" " for(int b=0; b!=2; ++b)" " {" " if(front_facing[b]) continue;" " for(int v=0; v!=3; ++v)" " {" " vec3 lt = world_pos[b][v].xyz;" " mat3 im = mat3(lo-lt, pu, pv);" " vec3 ic = inverse(im)*lp;" " float s = ic.y;" " float t = ic.z;" " geomPositionFront[v] = p0+pu*s+pv*t;" " geomNormalFront[v] = n0+nu*s+nv*t;" " geomTangentFront[v] = t0+tu*s+tv*t;" " geomTexCoordFront[v] = tc0+tcu*s+tcv*t;" " geomWFront[v] = w0+wu*s+wv*t;" " }" " mat3 normal = get_vectors(bt[b], vertNormal);" " mat3 tangent = get_vectors(bt[b], vertTangent);" " mat3 tex_coord = get_tex_coords(bt[b]);" " for(int v=0; v!=3; ++v)" " {" " gl_Position = view_pos[b][v];" " for(int c=0; c!=3; ++c)" " {" " gl_ClipDistance[c] = dot(" " clip_plane[c]," " world_pos[b][v]" " );" " }" " geomPosition = world_pos[b][v].xyz;" " geomNormal = normal[v];" " geomTangent = tangent[v];" " geomTexCoord = tex_coord[v];" " geomBarycentric = vec3(0.0);" " geomBarycentric[v] = 1.0;" " EmitVertex();" " }" " EndPrimitive();" " }" "}"); GeometryShader gs; gs.Source(gs_src).Compile(); prog.AttachShader(gs); StrCRef fs_src( "#version 150\n" "#extension GL_EXT_gpu_shader4_1 : enable\n" "uniform float Time;" "uniform sampler2D ColorMap;" "uniform sampler2D BumpMap;" "uniform vec3 LightPosition;" "flat in mat3 geomPositionFront;" "flat in mat3 geomNormalFront;" "flat in mat3 geomTangentFront;" "flat in mat3 geomTexCoordFront;" "flat in vec3 geomWFront;" "noperspective in vec3 geomBarycentric;" "in vec3 geomPosition;" "in vec3 geomNormal;" "in vec3 geomTangent;" "in vec3 geomTexCoord;" "out vec3 fragColor;" "vec3 vcdiv(vec3 a, vec3 b)" "{" " return vec3(a.x/b.x, a.y/b.y, a.z/b.z);" "}" "void main()" "{" " const vec3 one = vec3(1.0, 1.0, 1.0);" " vec3 bzfv = vcdiv(geomBarycentric,geomWFront);" " float idobzfv = 1.0/dot(one,bzfv);" " vec3 p0 = geomPosition;" " vec3 p1 = (geomPositionFront*bzfv)*idobzfv;" " vec3 n0 = geomNormal;" " vec3 n1 = (geomNormalFront*bzfv)*idobzfv;" " vec3 t0 = geomTangent;" " vec3 t1 = (geomTangentFront*bzfv)*idobzfv;" " vec3 tc0 = geomTexCoord;" " vec3 tc1 = (geomTexCoordFront*bzfv)*idobzfv;" " float tl = textureQueryLod(BumpMap, tc1.xy).x;" " ivec2 ts = textureSize(BumpMap, int(tl));" " int mts = max(ts.x, ts.y);" " vec2 dtc = tc1.xy - tc0.xy;" " float mdtc = max(abs(dtc.x), abs(dtc.y));" " int nsam = max(min(int(mdtc*mts), mts), 1);" " float step = 1.0 / nsam;" " for(int s=0; s<=nsam; ++s)" " {" " vec3 tc = mix(tc1, tc0, s*step);" " vec4 bm = texture(BumpMap, tc.xy);" " if(tc.z <= bm.w+0.01)" " {" " vec3 p = mix(p1, p0, s*step);" " vec3 n = mix(n1, n0, s*step);" " vec3 t = mix(t1, t0, s*step);" " vec3 b = cross(n, t);" " vec3 ldir = normalize(LightPosition - p);" " vec3 nml = normalize(t*bm.x+b*bm.y+n*bm.z);" " float l = max(dot(ldir, nml), 0.0)*max(dot(ldir, n)+0.3, " "0.0)+0.2;" " fragColor = texture(ColorMap, tc.xy).rgb*l;" " return;" " }" " }" " discard;" "}"); FragmentShader fs; fs.Source(fs_src).Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); return prog; }
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); }
ParticlesExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , particle_count(100) , prev_time(0.0) , prev_spawn(0.0) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ModelMatrix, CameraMatrix;" "in vec4 Position;" "in float Age;" "out float vertAge;" "void main(void)" "{" " gl_Position = " " CameraMatrix *" " ModelMatrix *" " 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)" "{" " 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); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } positions.reserve(particle_count); directions.reserve(particle_count); // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages); VertexAttribArray attr(prog, "Age"); attr.Setup(1, DataType::Float); attr.Enable(); } ages.reserve(particle_count); Uniform<Mat4f>(prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, -10.0f, 0.0f) ); // 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); }