Beispiel #1
0
/**
*  @brief
*    Creates a geometry shader and sets the shader source code
*/
GeometryShader *ShaderLanguage::CreateGeometryShader(const String &sSourceCode, GeometryShader::EInputPrimitiveType nInputPrimitiveType, GeometryShader::EOutputPrimitiveType nOutputPrimitiveType, uint32 nNumOfOutputVertices, const String &sProfile, const String &sArguments, const String &sEntry)
{
	// Create the geometry shader instance
	GeometryShader *pGeometryShader = CreateGeometryShader();

	// Set the geometry shader source code
	if (pGeometryShader)
		pGeometryShader->SetSourceCode(sSourceCode, nInputPrimitiveType, nOutputPrimitiveType, nNumOfOutputVertices, sProfile, sArguments, sEntry);

	// Return the created geometry shader instance
	return pGeometryShader;
}
Beispiel #2
0
//-------------------------------------------------------------------------
// @brief 
//-------------------------------------------------------------------------
const unsigned int ShaderCache::getGeometryShader(const tinyxml2::XMLElement* element, const DeviceManager& deviceManager)
{
    GeometryShader shader;
    shader.deserialise(element);
    unsigned int resourceName = hashString(getResourceNameFromFileName(shader.getFileName()));
    if (getGeometryShader(resourceName) == nullptr)
    {
        if (shader.createShader(deviceManager))
        {
            m_geometryShaders.emplace(GeometryShaderHandle(resourceName, shader));
        }
    }

    return resourceName;
}
Beispiel #3
0
//----------------------------------------------------------------------------
ShaderProgramHandle* OpenGLDevice::__CreateProgram(ShaderProgram* program)
{
    GLuint __program = glCreateProgram();
    std::string linkingString("Linking program");

    VertexShader* vShader = program->GetVertexShader();
    if( vShader )
    {
        vShader->CreateDeviceResource(this);
        OpenGLShaderHandle* vsHandle = 
            (OpenGLShaderHandle*)vShader->GetShaderHandle();
        glAttachShader(__program, vsHandle->mShader);
        linkingString += " ";
        linkingString += vShader->GetShaderFileName();
    }

    FragmentShader* fShader = program->GetFragmentShader();
    if( fShader )
    {
        fShader->CreateDeviceResource(this);
        OpenGLShaderHandle* fsHandle =
            (OpenGLShaderHandle*)fShader->GetShaderHandle();
        glAttachShader(__program, fsHandle->mShader);
        linkingString += " ";
        linkingString += fShader->GetShaderFileName();
    }

    GeometryShader* gShader = program->GetGeometryShader();
    if( gShader )
    {
        gShader->CreateDeviceResource(this);
        OpenGLShaderHandle* gsHandle =
            (OpenGLShaderHandle*)gShader->GetShaderHandle();
        glAttachShader(__program, gsHandle->mShader);
        linkingString += " ";
        linkingString += gShader->GetShaderFileName();
    }

    ComputeShader* cShader = program->GetComputeShader();
    if( cShader )
    {
        cShader->CreateDeviceResource(this);
        OpenGLShaderHandle* csHandle =
            (OpenGLShaderHandle*)cShader->GetShaderHandle();
        glAttachShader(__program, csHandle->mShader);
        linkingString += " ";
        linkingString += cShader->GetShaderFileName();
    }

    TessellationControlShader* tcShader = program->GetTessellationControlShader();
    if( tcShader )
    {
        tcShader->CreateDeviceResource(this);
        OpenGLShaderHandle* tcsHandle =
            (OpenGLShaderHandle*)tcShader->GetShaderHandle();
        glAttachShader(__program, tcsHandle->mShader);
        linkingString += " ";
        linkingString += tcShader->GetShaderFileName();
    }

    TessellationEvaluationShader* teShader = program->GetTessellationEvaluationShader();
    if( teShader )
    {
        teShader->CreateDeviceResource(this);
        OpenGLShaderHandle* tesHandle =
            (OpenGLShaderHandle*)teShader->GetShaderHandle();
        glAttachShader(__program, tesHandle->mShader);
        linkingString += " ";
        linkingString += teShader->GetShaderFileName();
    }

    glLinkProgram(__program);
    GLint linked;
    glGetProgramiv(__program, GL_LINK_STATUS, &linked);
    if( !linked )
    {
        GLint iInfoLen = 0;
        glGetProgramiv(__program, GL_INFO_LOG_LENGTH, &iInfoLen);
        if( iInfoLen > 1 )
        {
            char* acInfoLog = new char[iInfoLen];
            glGetProgramInfoLog(__program, iInfoLen, 0, acInfoLog);
            linkingString += " failed";

            Terminal::Output(Terminal::OC_Error, "%s\n%s\n", 
                linkingString.c_str(), acInfoLog);
            delete[] acInfoLog;
        }

        RTGI_ASSERT(false);
        return 0;
    }

#ifdef RTGI_OUTPUT_SHADER_RESOURCE_LOADING
    linkingString += " finished";
    Terminal::Output(Terminal::OC_Success, "%s\n", linkingString.c_str());
#endif

    OPENGL_DEVICE_CHECK_ERROR;

    OpenGLShaderProgramHandle* programHandle = new OpenGLShaderProgramHandle();
    programHandle->Device = this;
    programHandle->mProgram = __program;
    return programHandle;
}
Beispiel #4
0
	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);
	}
Beispiel #5
0
	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);
	}
Beispiel #6
0
	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_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;
	}
Beispiel #8
0
	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);
	}
Beispiel #9
0
	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);
	}
Beispiel #10
0
	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();
	}
Beispiel #12
0
	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);
	}
Beispiel #13
0
	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);
	}
Beispiel #14
0
//----------------------------------------------------------------------------
void OpenGLDevice::__GetUniformLocation(ShaderProgram* program, 
    ShaderUniform* uniform, const char* name)
{
    OpenGLShaderProgramHandle* programHandle = 
        (OpenGLShaderProgramHandle*)program->GetProgramHandle();
    RTGI_ASSERT(programHandle);

    GLint loc = glGetUniformLocation(programHandle->mProgram, name);
    if( !uniform->mUniformHandle )
    {
        uniform->mUniformHandle = new OpenGLShaderUniformHandle();
        uniform->mUniformHandle->Device = this;
    }
    ((OpenGLShaderUniformHandle*)uniform->mUniformHandle)->mUniform = loc;

#ifdef _DEBUG
    if( loc < 0 )
    {
        Terminal::Output(Terminal::OC_Warning_Level4, 
            "Uniform: \'%s\' not found in: \n", name);
        VertexShader* vs = program->GetVertexShader();
        if( vs )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                vs->GetShaderFileName().c_str());
        }
        FragmentShader* fs = program->GetFragmentShader();
        if( fs )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                fs->GetShaderFileName().c_str());
        }
        TessellationControlShader* tcs = program->GetTessellationControlShader();
        if( tcs )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                tcs->GetShaderFileName().c_str());
        }
        TessellationEvaluationShader* tes = program->GetTessellationEvaluationShader();
        if( tes )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                tes->GetShaderFileName().c_str());
        }
        GeometryShader* gs = program->GetGeometryShader();
        if( gs )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                gs->GetShaderFileName().c_str());
        }
        ComputeShader* cs = program->GetComputeShader();
        if( cs )
        {
            Terminal::Output(Terminal::OC_Warning_Level4, "    %s\n",
                cs->GetShaderFileName().c_str());
        }
    }
#endif

    OPENGL_DEVICE_CHECK_ERROR;
}
    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());
    }
Beispiel #16
0
int ContextD3D11::CreateGeometryShader(void* data, size_t length, GeometryShader& gs) {
  void* ptr;
  int hr = device_->CreateGeometryShader(data, length, NULL, (ID3D11GeometryShader**)&ptr);
  gs.set_internal_pointer(ptr);
  return hr;
}
Beispiel #17
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();
	}
	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());
	}
	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));
	}
Beispiel #21
0
 void DeviceContext::Bind(const GeometryShader& geometryShader)
 {
     _underlying->GSSetShader(geometryShader.GetUnderlying(), nullptr, 0);
 }
Beispiel #22
0
    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);
	}
Beispiel #24
0
	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);

	}
Beispiel #27
0
	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;
    }
Beispiel #29
0
	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);
	}
Beispiel #30
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);
	}