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(); }
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_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; }
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); }
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); }
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); }
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()); }
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); }
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)); }
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); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , vs(ObjectDesc("Vertex")) , gs(ObjectDesc("Geometry")) , face_fs(ObjectDesc("Face fragment")) , frame_fs(ObjectDesc("Frame fragment")) , transf_prog(ObjectDesc("Transformation")) , face_prog(ObjectDesc("Face")) , frame_prog(ObjectDesc("Frame")) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 vertNormal;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;" " vertTexCoord = TexCoord;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 15) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in gl_PerVertex {" " vec4 gl_Position;" "} gl_in[];" "in vec3 vertNormal[];" "in vec2 vertTexCoord[];" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 geomNormal;" "out vec3 geomLight;" "out float geomGlow;" "flat out int geomTop;" "void main(void)" "{" " vec3 FaceNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " vec2 FaceCoord = 0.33333 * (" " vertTexCoord[0]+" " vertTexCoord[1]+" " vertTexCoord[2] " " );" " float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;" " Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;" " vec3 pos[3], norm[3];" " for(int i=0; i!=3; ++i)" " pos[i] = gl_in[i].gl_Position.xyz;" " for(int i=0; i!=3; ++i)" " norm[i] = cross(" " FaceNormal, " " normalize(pos[(i+1)%3] - pos[i])" " );" " vec3 pofs = FaceNormal * Offs;" " geomTop = 0;" " for(int i=0; i!=3; ++i)" " {" " geomNormal = norm[i];" " for(int j=0; j!=2; ++j)" " {" " vec3 tpos = pos[(i+j)%3];" " geomLight = LightPos-tpos;" " geomGlow = 1.0;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos, 1.0);" " EmitVertex();" " geomGlow = 0.7;" " geomLight = LightPos-tpos+pofs;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" " }" " geomGlow = 0.0;" " geomTop = 1;" " for(int i=0; i!=3; ++i)" " {" " geomLight = LightPos - (pos[i]+pofs);" " geomNormal = vertNormal[i];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(pos[i] + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); transf_prog.AttachShader(vs); transf_prog.AttachShader(gs); transf_prog.MakeSeparable(); transf_prog.Link(); transf_prog.Use(); ProgramUniform<Vec3f>(transf_prog, "LightPos").Set(4, 4, -8); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } face_fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLight;" "in float geomGlow;" "flat in int geomTop;" "uniform vec3 TopColor, SideColor;" "const vec3 LightColor = vec3(1.0, 1.0, 1.0);" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(" " normalize(geomLight)," " normalize(geomNormal)" " ), 0.0);" " vec3 color;" " if(geomTop != 0)" " {" " color = TopColor * d +" " LightColor * pow(d, 8.0);" " }" " else" " {" " color = SideColor * geomGlow +" " LightColor *" " pow(d, 2.0) * 0.2;" " }" " fragColor = vec4(color, 1.0);" "}" ); face_fs.Compile(); face_prog.AttachShader(face_fs); face_prog.MakeSeparable(); face_prog.Link(); ProgramUniform<Vec3f>(face_prog, "TopColor").Set(0.2f, 0.2f, 0.2f); ProgramUniform<Vec3f>(face_prog, "SideColor").Set(0.9f, 0.9f, 0.2f); face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.2, 0.1, 0.0, 1.0);" "}" ); frame_fs.Compile(); frame_prog.AttachShader(frame_fs); frame_prog.MakeSeparable(); frame_prog.Link(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); ProgramPipeline::Unbind(); Program::UseNone(); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
TorusExample(void) : make_torus(1.0, 0.5, 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()); }
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(); }
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); }
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(); }
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); }